From 477e8308d4f087410e63f0e380e4447a2ec09c64 Mon Sep 17 00:00:00 2001 From: Rodrigo Queipo Date: Tue, 29 Jun 2021 17:07:07 -0300 Subject: [PATCH 1/2] Adds support for multiple comments on the same text object. --- src/PhpWord/Element/AbstractElement.php | 76 ++++++++++++++++--- src/PhpWord/Element/Comment.php | 8 +- .../Word2007/Element/AbstractElement.php | 49 +++++------- tests/PhpWord/Element/CommentTest.php | 33 ++++++++ 4 files changed, 119 insertions(+), 47 deletions(-) diff --git a/src/PhpWord/Element/AbstractElement.php b/src/PhpWord/Element/AbstractElement.php index 46372b71db..f2cb37c28f 100644 --- a/src/PhpWord/Element/AbstractElement.php +++ b/src/PhpWord/Element/AbstractElement.php @@ -129,18 +129,18 @@ abstract class AbstractElement protected $collectionRelation = false; /** - * The start position for the linked comment + * The start position for the linked comments * - * @var Comment + * @var \PHPOffice\PHPWord\Collection\Comments */ - protected $commentRangeStart; + protected $commentsRangeStart; /** - * The end position for the linked comment + * The end position for the linked comments * - * @var Comment + * @var \PHPOffice\PHPWord\Collection\Comments */ - protected $commentRangeEnd; + protected $commentsRangeEnd; /** * Get PhpWord @@ -287,6 +287,16 @@ public function getNestedLevel() return $this->nestedLevel; } + /** + * Get comments start + * + * @return \PhpOffice\PhpWord\Collection\Comments + */ + public function getCommentsRangeStart() + { + return $this->commentsRangeStart; + } + /** * Get comment start * @@ -294,7 +304,11 @@ public function getNestedLevel() */ public function getCommentRangeStart() { - return $this->commentRangeStart; + if ($this->commentsRangeStart != null) { + return $this->commentsRangeStart->getItem($this->commentsRangeStart->countItems()); + } + + return null; } /** @@ -307,8 +321,30 @@ public function setCommentRangeStart(Comment $value) if ($this instanceof Comment) { throw new \InvalidArgumentException('Cannot set a Comment on a Comment'); } - $this->commentRangeStart = $value; - $this->commentRangeStart->setStartElement($this); + if ($this->commentsRangeStart == null) { + $this->commentsRangeStart = new \PhpOffice\PhpWord\Collection\Comments(); + } + // Set ID early to avoid duplicates. + if ($value->getElementId() == null) { + $value->setElementId(); + } + foreach ($this->commentsRangeStart->getItems() as $comment) { + if ($value->getElementId() == $comment->getElementId()) { + return; + } + } + $this->commentsRangeStart->addItem($value); + $this->commentsRangeStart->getItem($this->commentsRangeStart->countItems())->setStartElement($this); + } + + /** + * Get comments end + * + * @return \PhpOffice\PhpWord\Collection\Comments + */ + public function getCommentsRangeEnd() + { + return $this->commentsRangeEnd; } /** @@ -318,7 +354,11 @@ public function setCommentRangeStart(Comment $value) */ public function getCommentRangeEnd() { - return $this->commentRangeEnd; + if ($this->commentsRangeEnd != null) { + return $this->commentsRangeEnd->getItem($this->commentsRangeEnd->countItems()); + } + + return null; } /** @@ -331,8 +371,20 @@ public function setCommentRangeEnd(Comment $value) if ($this instanceof Comment) { throw new \InvalidArgumentException('Cannot set a Comment on a Comment'); } - $this->commentRangeEnd = $value; - $this->commentRangeEnd->setEndElement($this); + if ($this->commentsRangeEnd == null) { + $this->commentsRangeEnd = new \PhpOffice\PhpWord\Collection\Comments(); + } + // Set ID early to avoid duplicates. + if ($value->getElementId() == null) { + $value->setElementId(); + } + foreach ($this->commentsRangeEnd->getItems() as $comment) { + if ($value->getElementId() == $comment->getElementId()) { + return; + } + } + $this->commentsRangeEnd->addItem($value); + $this->commentsRangeEnd->getItem($this->commentsRangeEnd->countItems())->setEnd($this); } /** diff --git a/src/PhpWord/Element/Comment.php b/src/PhpWord/Element/Comment.php index 96ad15ef4e..c337d06ed6 100644 --- a/src/PhpWord/Element/Comment.php +++ b/src/PhpWord/Element/Comment.php @@ -82,9 +82,7 @@ public function getInitials() public function setStartElement(AbstractElement $value) { $this->startElement = $value; - if ($value->getCommentRangeStart() == null) { - $value->setCommentRangeStart($this); - } + $value->setCommentRangeStart($this); } /** @@ -105,9 +103,7 @@ public function getStartElement() public function setEndElement(AbstractElement $value) { $this->endElement = $value; - if ($value->getCommentRangeEnd() == null) { - $value->setCommentRangeEnd($this); - } + $value->setCommentRangeEnd($this); } /** diff --git a/src/PhpWord/Writer/Word2007/Element/AbstractElement.php b/src/PhpWord/Writer/Word2007/Element/AbstractElement.php index ee0fb2f901..07ef51e84c 100644 --- a/src/PhpWord/Writer/Word2007/Element/AbstractElement.php +++ b/src/PhpWord/Writer/Word2007/Element/AbstractElement.php @@ -122,14 +122,10 @@ protected function endElementP() */ protected function writeCommentRangeStart() { - if ($this->element->getCommentRangeStart() != null) { - $comment = $this->element->getCommentRangeStart(); - //only set the ID if it is not yet set, otherwise it will overwrite it - if ($comment->getElementId() == null) { - $comment->setElementId(); + if ($this->element->getCommentsRangeStart() != null) { + foreach ($this->element->getCommentsRangeStart()->getItems() as $comment) { + $this->xmlWriter->writeElementBlock('w:commentRangeStart', array('w:id' => $comment->getElementId())); } - - $this->xmlWriter->writeElementBlock('w:commentRangeStart', array('w:id' => $comment->getElementId())); } } @@ -138,28 +134,23 @@ protected function writeCommentRangeStart() */ protected function writeCommentRangeEnd() { - if ($this->element->getCommentRangeEnd() != null) { - $comment = $this->element->getCommentRangeEnd(); - //only set the ID if it is not yet set, otherwise it will overwrite it, this should normally not happen - if ($comment->getElementId() == null) { - $comment->setElementId(); // @codeCoverageIgnore - } // @codeCoverageIgnore - - $this->xmlWriter->writeElementBlock('w:commentRangeEnd', array('w:id' => $comment->getElementId())); - $this->xmlWriter->startElement('w:r'); - $this->xmlWriter->writeElementBlock('w:commentReference', array('w:id' => $comment->getElementId())); - $this->xmlWriter->endElement(); - } elseif ($this->element->getCommentRangeStart() != null && $this->element->getCommentRangeStart()->getEndElement() == null) { - $comment = $this->element->getCommentRangeStart(); - //only set the ID if it is not yet set, otherwise it will overwrite it, this should normally not happen - if ($comment->getElementId() == null) { - $comment->setElementId(); // @codeCoverageIgnore - } // @codeCoverageIgnore - - $this->xmlWriter->writeElementBlock('w:commentRangeEnd', array('w:id' => $comment->getElementId())); - $this->xmlWriter->startElement('w:r'); - $this->xmlWriter->writeElementBlock('w:commentReference', array('w:id' => $comment->getElementId())); - $this->xmlWriter->endElement(); + if ($this->element->getCommentsRangeEnd() != null) { + foreach ($this->element->getCommentsRangeEnd()->getItems() as $comment) { + $this->xmlWriter->writeElementBlock('w:commentRangeEnd', array('w:id' => $comment->getElementId())); + $this->xmlWriter->startElement('w:r'); + $this->xmlWriter->writeElementBlock('w:commentReference', array('w:id' => $comment->getElementId())); + $this->xmlWriter->endElement(); + } + } + if ($this->element->getCommentsRangeStart() != null) { + foreach ($this->element->getCommentsRangeStart()->getItems() as $comment) { + if ($comment->getEndElement() == null) { + $this->xmlWriter->writeElementBlock('w:commentRangeEnd', array('w:id' => $comment->getElementId())); + $this->xmlWriter->startElement('w:r'); + $this->xmlWriter->writeElementBlock('w:commentReference', array('w:id' => $comment->getElementId())); + $this->xmlWriter->endElement(); + } + } } } diff --git a/tests/PhpWord/Element/CommentTest.php b/tests/PhpWord/Element/CommentTest.php index b9c3dfce5a..5205890cc0 100644 --- a/tests/PhpWord/Element/CommentTest.php +++ b/tests/PhpWord/Element/CommentTest.php @@ -46,6 +46,39 @@ public function testConstructDefault() $this->assertEquals($oText, $oComment->getEndElement()); } + /** + * Two comments on same text + */ + public function testTwoCommentsOnSameText() + { + $section = new Section(0); + $text = $section->addText('Text'); + + $comment1 = new Comment('Author1', new \DateTime(), 'A1'); + $comment1->addText('Comment1'); + + $comment2 = new Comment('Author2', new \DateTime(), 'A2'); + $comment2->addText('Comment2'); + + $comment1->setStartElement($text); + $comment2->setStartElement($text); + + $text->setCommentRangeStart($comment1); + $text->setCommentRangeEnd($comment1); + + $text->setCommentRangeStart($comment2); + $text->setCommentRangeEnd($comment2); + + $this->assertEquals(2, $text->getCommentsRangeStart()->countItems()); + $this->assertEquals(2, $text->getCommentsRangeEnd()->countItems()); + + $this->assertEquals($text->getCommentsRangeStart()->getItem(1)->getElementId(), $comment1->getElementId()); + $this->assertEquals($text->getCommentsRangeEnd()->getItem(1)->getElementId(), $comment1->getElementId()); + + $this->assertEquals($text->getCommentsRangeStart()->getItem(2)->getElementId(), $comment2->getElementId()); + $this->assertEquals($text->getCommentsRangeEnd()->getItem(2)->getElementId(), $comment2->getElementId()); + } + /** * Add text */ From 2fbba6772989f5fc31710165fac3b42956f441ba Mon Sep 17 00:00:00 2001 From: Rodrigo Queipo Date: Tue, 27 Jul 2021 21:35:01 -0300 Subject: [PATCH 2/2] Fix method name. --- src/PhpWord/Element/AbstractElement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpWord/Element/AbstractElement.php b/src/PhpWord/Element/AbstractElement.php index f2cb37c28f..577f75f63f 100644 --- a/src/PhpWord/Element/AbstractElement.php +++ b/src/PhpWord/Element/AbstractElement.php @@ -384,7 +384,7 @@ public function setCommentRangeEnd(Comment $value) } } $this->commentsRangeEnd->addItem($value); - $this->commentsRangeEnd->getItem($this->commentsRangeEnd->countItems())->setEnd($this); + $this->commentsRangeEnd->getItem($this->commentsRangeEnd->countItems())->setEndElement($this); } /**