Skip to content

Commit 8392134

Browse files
Progi1984rodrigoq
andauthored
Word2007 Writer: Added support for multiples comment for the same text (#2665)
* Adds support for multiple comments on the same text object. * Fix method name. * Fixed some feedbacks --------- Co-authored-by: Rodrigo Queipo <[email protected]>
1 parent b0ed3db commit 8392134

File tree

15 files changed

+174
-74
lines changed

15 files changed

+174
-74
lines changed

docs/changes/1.x/1.3.0.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- RTF Writer : Support for Table Border Style fixing [#345](https://github.com/PHPOffice/PHPWord/issues/345) by [@Progi1984](https://github.com/Progi1984) in [#2656](https://github.com/PHPOffice/PHPWord/pull/2656)
1313
- Word2007 Reader: Support the page break (<w:lastRenderedPageBreak/>) by [@stanolacko](https://github.com/stanolacko) in [#2662](https://github.com/PHPOffice/PHPWord/pull/2662)
1414
- MsDoc Reader: Support for UTF-8 characters by [@Progi1984] fixing [#881](https://github.com/PHPOffice/PHPWord/issues/881), [#1454](https://github.com/PHPOffice/PHPWord/issues/1454), [#1817](https://github.com/PHPOffice/PHPWord/issues/1817), [#1927](https://github.com/PHPOffice/PHPWord/issues/1927), [#2383](https://github.com/PHPOffice/PHPWord/issues/2383), [#2565](https://github.com/PHPOffice/PHPWord/issues/2565) in [#2664](https://github.com/PHPOffice/PHPWord/pull/2664)
15+
- Word2007 Writer: Added support for multiples comment for the same text by [@rodrigoq](https://github.com/rodrigoq) fixing [#2109](https://github.com/PHPOffice/PHPWord/issues/2109) in [#2665](https://github.com/PHPOffice/PHPWord/pull/2665)
1516

1617
### Bug fixes
1718

samples/Sample_37_Comments.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
$imageComment->addText('Hey, Mars does look ');
4343
$imageComment->addText('red', ['color' => 'FF0000']);
4444
$phpWord->addComment($commentOnImage);
45-
$image = $section->addImage('resources/_mars.jpg');
45+
$image = $section->addImage(__DIR__ . '/resources/_mars.jpg');
4646
$image->setCommentRangeStart($commentOnImage);
4747

4848
$section->addTextBreak(2);
@@ -56,6 +56,21 @@
5656
$comment1->setEndElement($anotherText);
5757
$phpWord->addComment($comment1);
5858

59+
// We can also do things the other way round, link the comment to the element
60+
$lastText = $section->addText('with a last text and two comments');
61+
62+
$comment1 = new \PhpOffice\PhpWord\Element\Comment('Authors name', new \DateTime(), 'my_initials');
63+
$comment1->addText('Comment 1', ['bold' => true]);
64+
$comment1->setStartElement($lastText);
65+
$comment1->setEndElement($lastText);
66+
$phpWord->addComment($comment1);
67+
68+
$comment2 = new \PhpOffice\PhpWord\Element\Comment('Authors name', new \DateTime(), 'my_initials');
69+
$comment2->addText('Comment 2', ['bold' => true]);
70+
$comment2->setStartElement($lastText);
71+
$comment2->setEndElement($lastText);
72+
$phpWord->addComment($comment2);
73+
5974
// Save file
6075
echo write($phpWord, basename(__FILE__, '.php'), $writers);
6176
if (!CLI) {

src/PhpWord/Collection/AbstractCollection.php

+11-17
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,33 @@
2121
* Collection abstract class.
2222
*
2323
* @since 0.10.0
24+
* @template T
2425
*/
2526
abstract class AbstractCollection
2627
{
2728
/**
2829
* Items.
2930
*
30-
* @var \PhpOffice\PhpWord\Element\AbstractContainer[]
31+
* @var T[]
3132
*/
3233
private $items = [];
3334

3435
/**
3536
* Get items.
3637
*
37-
* @return \PhpOffice\PhpWord\Element\AbstractContainer[]
38+
* @return T[]
3839
*/
39-
public function getItems()
40+
public function getItems(): array
4041
{
4142
return $this->items;
4243
}
4344

4445
/**
4546
* Get item by index.
4647
*
47-
* @param int $index
48-
*
49-
* @return ?\PhpOffice\PhpWord\Element\AbstractContainer
48+
* @return ?T
5049
*/
51-
public function getItem($index)
50+
public function getItem(int $index)
5251
{
5352
if (array_key_exists($index, $this->items)) {
5453
return $this->items[$index];
@@ -60,10 +59,9 @@ public function getItem($index)
6059
/**
6160
* Set item.
6261
*
63-
* @param int $index
64-
* @param ?\PhpOffice\PhpWord\Element\AbstractContainer $item
62+
* @param ?T $item
6563
*/
66-
public function setItem($index, $item): void
64+
public function setItem(int $index, $item): void
6765
{
6866
if (array_key_exists($index, $this->items)) {
6967
$this->items[$index] = $item;
@@ -73,11 +71,9 @@ public function setItem($index, $item): void
7371
/**
7472
* Add new item.
7573
*
76-
* @param \PhpOffice\PhpWord\Element\AbstractContainer $item
77-
*
78-
* @return int
74+
* @param T $item
7975
*/
80-
public function addItem($item)
76+
public function addItem($item): int
8177
{
8278
$index = $this->countItems();
8379
$this->items[$index] = $item;
@@ -87,10 +83,8 @@ public function addItem($item)
8783

8884
/**
8985
* Get item count.
90-
*
91-
* @return int
9286
*/
93-
public function countItems()
87+
public function countItems(): int
9488
{
9589
return count($this->items);
9690
}

src/PhpWord/Collection/Bookmarks.php

+3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717

1818
namespace PhpOffice\PhpWord\Collection;
1919

20+
use PhpOffice\PhpWord\Element\Bookmark;
21+
2022
/**
2123
* Bookmarks collection.
2224
*
2325
* @since 0.12.0
26+
* @extends AbstractCollection<Bookmark>
2427
*/
2528
class Bookmarks extends AbstractCollection
2629
{

src/PhpWord/Collection/Charts.php

+3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717

1818
namespace PhpOffice\PhpWord\Collection;
1919

20+
use PhpOffice\PhpWord\Element\Chart;
21+
2022
/**
2123
* Charts collection.
2224
*
2325
* @since 0.12.0
26+
* @extends AbstractCollection<Chart>
2427
*/
2528
class Charts extends AbstractCollection
2629
{

src/PhpWord/Collection/Comments.php

+3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717

1818
namespace PhpOffice\PhpWord\Collection;
1919

20+
use PhpOffice\PhpWord\Element\Comment;
21+
2022
/**
2123
* Comments collection.
2224
*
2325
* @since 0.12.0
26+
* @extends AbstractCollection<Comment>
2427
*/
2528
class Comments extends AbstractCollection
2629
{

src/PhpWord/Collection/Endnotes.php

+3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717

1818
namespace PhpOffice\PhpWord\Collection;
1919

20+
use PhpOffice\PhpWord\Element\Endnote;
21+
2022
/**
2123
* Endnotes collection.
2224
*
2325
* @since 0.10.0
26+
* @extends AbstractCollection<Endnote>
2427
*/
2528
class Endnotes extends AbstractCollection
2629
{

src/PhpWord/Collection/Footnotes.php

+3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717

1818
namespace PhpOffice\PhpWord\Collection;
1919

20+
use PhpOffice\PhpWord\Element\Footnote;
21+
2022
/**
2123
* Footnotes collection.
2224
*
2325
* @since 0.10.0
26+
* @extends AbstractCollection<Footnote>
2427
*/
2528
class Footnotes extends AbstractCollection
2629
{

src/PhpWord/Collection/Titles.php

+3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717

1818
namespace PhpOffice\PhpWord\Collection;
1919

20+
use PhpOffice\PhpWord\Element\Title;
21+
2022
/**
2123
* Titles collection.
2224
*
2325
* @since 0.10.0
26+
* @extends AbstractCollection<Title>
2427
*/
2528
class Titles extends AbstractCollection
2629
{

src/PhpWord/Element/AbstractElement.php

+72-18
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919

2020
use DateTime;
2121
use InvalidArgumentException;
22+
use PhpOffice\PhpWord\Collection\Comments;
2223
use PhpOffice\PhpWord\Media;
2324
use PhpOffice\PhpWord\PhpWord;
25+
use PhpOffice\PhpWord\Style;
2426

2527
/**
2628
* Element abstract class.
@@ -32,7 +34,7 @@ abstract class AbstractElement
3234
/**
3335
* PhpWord object.
3436
*
35-
* @var ?\PhpOffice\PhpWord\PhpWord
37+
* @var ?PhpWord
3638
*/
3739
protected $phpWord;
3840

@@ -131,25 +133,25 @@ abstract class AbstractElement
131133
protected $collectionRelation = false;
132134

133135
/**
134-
* The start position for the linked comment.
136+
* The start position for the linked comments.
135137
*
136-
* @var Comment
138+
* @var Comments
137139
*/
138-
protected $commentRangeStart;
140+
protected $commentsRangeStart;
139141

140142
/**
141-
* The end position for the linked comment.
143+
* The end position for the linked comments.
142144
*
143-
* @var Comment
145+
* @var Comments
144146
*/
145-
protected $commentRangeEnd;
147+
protected $commentsRangeEnd;
146148

147149
/**
148150
* Get PhpWord.
149151
*
150-
* @return ?\PhpOffice\PhpWord\PhpWord
152+
* @return ?PhpWord
151153
*/
152-
public function getPhpWord()
154+
public function getPhpWord(): ?PhpWord
153155
{
154156
return $this->phpWord;
155157
}
@@ -287,14 +289,28 @@ public function getNestedLevel()
287289
return $this->nestedLevel;
288290
}
289291

292+
/**
293+
* Get comments start.
294+
*
295+
* @return Comments
296+
*/
297+
public function getCommentsRangeStart(): ?Comments
298+
{
299+
return $this->commentsRangeStart;
300+
}
301+
290302
/**
291303
* Get comment start.
292304
*
293305
* @return Comment
294306
*/
295-
public function getCommentRangeStart()
307+
public function getCommentRangeStart(): ?Comment
296308
{
297-
return $this->commentRangeStart;
309+
if ($this->commentsRangeStart != null) {
310+
return $this->commentsRangeStart->getItem($this->commentsRangeStart->countItems());
311+
}
312+
313+
return null;
298314
}
299315

300316
/**
@@ -305,18 +321,44 @@ public function setCommentRangeStart(Comment $value): void
305321
if ($this instanceof Comment) {
306322
throw new InvalidArgumentException('Cannot set a Comment on a Comment');
307323
}
308-
$this->commentRangeStart = $value;
309-
$this->commentRangeStart->setStartElement($this);
324+
if ($this->commentsRangeStart == null) {
325+
$this->commentsRangeStart = new Comments();
326+
}
327+
// Set ID early to avoid duplicates.
328+
if ($value->getElementId() == null) {
329+
$value->setElementId();
330+
}
331+
foreach ($this->commentsRangeStart->getItems() as $comment) {
332+
if ($value->getElementId() == $comment->getElementId()) {
333+
return;
334+
}
335+
}
336+
$idxItem = $this->commentsRangeStart->addItem($value);
337+
$this->commentsRangeStart->getItem($idxItem)->setStartElement($this);
338+
}
339+
340+
/**
341+
* Get comments end.
342+
*
343+
* @return Comments
344+
*/
345+
public function getCommentsRangeEnd(): ?Comments
346+
{
347+
return $this->commentsRangeEnd;
310348
}
311349

312350
/**
313351
* Get comment end.
314352
*
315353
* @return Comment
316354
*/
317-
public function getCommentRangeEnd()
355+
public function getCommentRangeEnd(): ?Comment
318356
{
319-
return $this->commentRangeEnd;
357+
if ($this->commentsRangeEnd != null) {
358+
return $this->commentsRangeEnd->getItem($this->commentsRangeEnd->countItems());
359+
}
360+
361+
return null;
320362
}
321363

322364
/**
@@ -327,8 +369,20 @@ public function setCommentRangeEnd(Comment $value): void
327369
if ($this instanceof Comment) {
328370
throw new InvalidArgumentException('Cannot set a Comment on a Comment');
329371
}
330-
$this->commentRangeEnd = $value;
331-
$this->commentRangeEnd->setEndElement($this);
372+
if ($this->commentsRangeEnd == null) {
373+
$this->commentsRangeEnd = new Comments();
374+
}
375+
// Set ID early to avoid duplicates.
376+
if ($value->getElementId() == null) {
377+
$value->setElementId();
378+
}
379+
foreach ($this->commentsRangeEnd->getItems() as $comment) {
380+
if ($value->getElementId() == $comment->getElementId()) {
381+
return;
382+
}
383+
}
384+
$idxItem = $this->commentsRangeEnd->addItem($value);
385+
$this->commentsRangeEnd->getItem($idxItem)->setEndElement($this);
332386
}
333387

334388
/**
@@ -428,7 +482,7 @@ public function isInSection()
428482
* Set new style value.
429483
*
430484
* @param mixed $styleObject Style object
431-
* @param null|array|\PhpOffice\PhpWord\Style|string $styleValue Style value
485+
* @param null|array|string|Style $styleValue Style value
432486
* @param bool $returnObject Always return object
433487
*
434488
* @return mixed

src/PhpWord/Element/Comment.php

+2-6
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,7 @@ public function getInitials()
8383
public function setStartElement(AbstractElement $value): void
8484
{
8585
$this->startElement = $value;
86-
if ($value->getCommentRangeStart() == null) {
87-
$value->setCommentRangeStart($this);
88-
}
86+
$value->setCommentRangeStart($this);
8987
}
9088

9189
/**
@@ -104,9 +102,7 @@ public function getStartElement()
104102
public function setEndElement(AbstractElement $value): void
105103
{
106104
$this->endElement = $value;
107-
if ($value->getCommentRangeEnd() == null) {
108-
$value->setCommentRangeEnd($this);
109-
}
105+
$value->setCommentRangeEnd($this);
110106
}
111107

112108
/**

src/PhpWord/PhpWord.php

-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ public function __call($function, $args)
134134
if (in_array($function, $addCollection)) {
135135
$key = ucfirst(str_replace('add', '', $function) . 's');
136136

137-
/** @var \PhpOffice\PhpWord\Collection\AbstractCollection $collectionObject */
138137
$collectionObject = $this->collections[$key];
139138

140139
return $collectionObject->addItem($args[0] ?? null);

0 commit comments

Comments
 (0)