Skip to content

Commit 338fcc1

Browse files
jet-deskProgi1984
authored andcommitted
Word2007 Writer : Add PageNumber to TOC
1 parent 7d5816b commit 338fcc1

File tree

10 files changed

+227
-73
lines changed

10 files changed

+227
-73
lines changed

docs/changes/1.x/1.2.0.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- PDF Writer : Add config for defining the default font by [@MikeMaldini](https://github.com/MikeMaldini) in [#2262](https://github.com/PHPOffice/PHPWord/pull/2262) & [#2468](https://github.com/PHPOffice/PHPWord/pull/2468)
1414
- Word2007 Reader : Added support for Comments by [@shaedrich](https://github.com/shaedrich) in [#2161](https://github.com/PHPOffice/PHPWord/pull/2161) & [#2469](https://github.com/PHPOffice/PHPWord/pull/2469)
1515
- Word2007 Reader/Writer: Permit book-fold printing by [@potofcoffee](https://github.com/potofcoffee) in [#2225](https://github.com/PHPOffice/PHPWord/pull/2225) & [#2470](https://github.com/PHPOffice/PHPWord/pull/2470)
16+
- Word2007 Writer : Add PageNumber to TOC by [@jet-desk](https://github.com/jet-desk) in [#1652](https://github.com/PHPOffice/PHPWord/pull/1652) & [#2471](https://github.com/PHPOffice/PHPWord/pull/2471)
1617

1718
### Bug fixes
1819

docs/usage/elements/title.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@ If `depth` is 0, a Title will be inserted, otherwise a Heading1, Heading2, ...
88
<?php
99

1010
$phpWord->addTitleStyle($depth, [$fontStyle], [$paragraphStyle]);
11-
$section->addTitle($text, [$depth]);
11+
$section->addTitle($text, $depth, $pageNumber);
1212
```
1313

14-
- ``depth``.
15-
- ``$fontStyle``. See [`Styles > Font`](../styles/font.md).
16-
- ``$paragraphStyle``. See [`Styles > Paragraph`](../styles/paragraph.md).
14+
`addTitleStyle` :
15+
- ``$depth``
16+
- ``$fontStyle``: See [`Styles > Font`](../styles/font.md).
17+
- ``$paragraphStyle``: See [`Styles > Paragraph`](../styles/paragraph.md).
18+
19+
`addTitle` :
1720
- ``$text``. Text to be displayed in the document. This can be `string` or a `\PhpOffice\PhpWord\Element\TextRun`
21+
- ``$depth``
22+
- ``$pageNumber`` : Number of the page
1823

1924
It's necessary to add a title style to your document because otherwise the title won't be detected as a real title.

src/PhpWord/Element/AbstractContainer.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* @method Footnote addFootnote(mixed $pStyle = null)
3535
* @method Endnote addEndnote(mixed $pStyle = null)
3636
* @method CheckBox addCheckBox(string $name, $text, mixed $fStyle = null, mixed $pStyle = null)
37-
* @method Title addTitle(mixed $text, int $depth = 1)
37+
* @method Title addTitle(mixed $text, int $depth = 1, int $pageNumber = null)
3838
* @method TOC addTOC(mixed $fontStyle = null, mixed $tocStyle = null, int $minDepth = 1, int $maxDepth = 9)
3939
* @method PageBreak addPageBreak()
4040
* @method Table addTable(mixed $style = null)

src/PhpWord/Element/Title.php

+20-1
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,20 @@ class Title extends AbstractElement
5454
*/
5555
protected $collectionRelation = true;
5656

57+
/**
58+
* Page number.
59+
*
60+
* @var int
61+
*/
62+
private $pageNumber;
63+
5764
/**
5865
* Create a new Title Element.
5966
*
6067
* @param string|TextRun $text
6168
* @param int $depth
6269
*/
63-
public function __construct($text, $depth = 1)
70+
public function __construct($text, $depth = 1, ?int $pageNumber = null)
6471
{
6572
if (is_string($text)) {
6673
$this->text = SharedText::toUTF8($text);
@@ -75,6 +82,10 @@ public function __construct($text, $depth = 1)
7582
if (array_key_exists($styleName, Style::getStyles())) {
7683
$this->style = str_replace('_', '', $styleName);
7784
}
85+
86+
if ($pageNumber !== null) {
87+
$this->pageNumber = $pageNumber;
88+
}
7889
}
7990

8091
/**
@@ -106,4 +117,12 @@ public function getStyle()
106117
{
107118
return $this->style;
108119
}
120+
121+
/**
122+
* Get page number.
123+
*/
124+
public function getPageNumber(): ?int
125+
{
126+
return $this->pageNumber;
127+
}
109128
}

src/PhpWord/Writer/Word2007/Element/TOC.php

+17-7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace PhpOffice\PhpWord\Writer\Word2007\Element;
1919

20+
use PhpOffice\PhpWord\Element\Title;
2021
use PhpOffice\PhpWord\Element\TOC as TOCElement;
2122
use PhpOffice\PhpWord\Shared\XMLWriter;
2223
use PhpOffice\PhpWord\Style\Font;
@@ -63,11 +64,8 @@ public function write(): void
6364

6465
/**
6566
* Write title.
66-
*
67-
* @param \PhpOffice\PhpWord\Element\Title $title
68-
* @param bool $writeFieldMark
6967
*/
70-
private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $writeFieldMark): void
68+
private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, Title $title, bool $writeFieldMark): void
7169
{
7270
$tocStyle = $element->getStyleTOC();
7371
$fontStyle = $element->getStyleFont();
@@ -116,6 +114,20 @@ private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $
116114
$xmlWriter->endElement();
117115
$xmlWriter->endElement();
118116

117+
if ($title->getPageNumber() !== null) {
118+
$xmlWriter->startElement('w:r');
119+
$xmlWriter->startElement('w:fldChar');
120+
$xmlWriter->writeAttribute('w:fldCharType', 'separate');
121+
$xmlWriter->endElement();
122+
$xmlWriter->endElement();
123+
124+
$xmlWriter->startElement('w:r');
125+
$xmlWriter->startElement('w:t');
126+
$xmlWriter->text((string) $title->getPageNumber());
127+
$xmlWriter->endElement();
128+
$xmlWriter->endElement();
129+
}
130+
119131
$xmlWriter->startElement('w:r');
120132
$xmlWriter->startElement('w:fldChar');
121133
$xmlWriter->writeAttribute('w:fldCharType', 'end');
@@ -129,10 +141,8 @@ private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $
129141

130142
/**
131143
* Write style.
132-
*
133-
* @param int $indent
134144
*/
135-
private function writeStyle(XMLWriter $xmlWriter, TOCElement $element, $indent): void
145+
private function writeStyle(XMLWriter $xmlWriter, TOCElement $element, int $indent): void
136146
{
137147
$tocStyle = $element->getStyleTOC();
138148
$fontStyle = $element->getStyleFont();

tests/PhpWordTests/Element/TitleTest.php

+27-20
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*
1515
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
1616
*/
17+
declare(strict_types=1);
1718

1819
namespace PhpOffice\PhpWordTests\Element;
1920

@@ -32,42 +33,48 @@
3233
class TitleTest extends \PHPUnit\Framework\TestCase
3334
{
3435
/**
35-
* Create new instance.
36+
* Create new instance with string.
3637
*/
3738
public function testConstruct(): void
3839
{
39-
$oTitle = new Title('text');
40+
$title = new Title('text');
4041

41-
self::assertInstanceOf('PhpOffice\\PhpWord\\Element\\Title', $oTitle);
42-
self::assertEquals('text', $oTitle->getText());
43-
}
44-
45-
/**
46-
* Get style null.
47-
*/
48-
public function testStyleNull(): void
49-
{
50-
$oTitle = new Title('text');
51-
52-
self::assertNull($oTitle->getStyle());
42+
self::assertInstanceOf(Title::class, $title);
43+
self::assertEquals('text', $title->getText());
44+
self::assertEquals(1, $title->getDepth());
45+
self::assertNull($title->getPageNumber());
46+
self::assertNull($title->getStyle());
5347
}
5448

5549
/**
5650
* Create new instance with TextRun.
5751
*/
5852
public function testConstructWithTextRun(): void
5953
{
60-
$oTextRun = new TextRun();
61-
$oTextRun->addText('text');
62-
$oTitle = new Title($oTextRun);
54+
$textRun = new TextRun();
55+
$textRun->addText('text');
56+
$title = new Title($textRun);
6357

64-
self::assertInstanceOf('PhpOffice\\PhpWord\\Element\\TextRun', $oTitle->getText());
58+
self::assertInstanceOf(TextRun::class, $title->getText());
59+
self::assertEquals(1, $title->getDepth());
60+
self::assertNull($title->getPageNumber());
61+
self::assertNull($title->getStyle());
6562
}
6663

6764
public function testConstructWithInvalidArgument(): void
6865
{
6966
$this->expectException(InvalidArgumentException::class);
70-
$oPageBreak = new PageBreak();
71-
new Title($oPageBreak);
67+
68+
new Title(new PageBreak());
69+
}
70+
71+
public function testConstructWithPageNumber(): void
72+
{
73+
$title = new Title('text', 1, 0);
74+
75+
self::assertInstanceOf(Title::class, $title);
76+
self::assertEquals('text', $title->getText());
77+
self::assertEquals(0, $title->getPageNumber());
78+
self::assertNull($title->getStyle());
7279
}
7380
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
/**
3+
* This file is part of PHPWord - A pure PHP library for reading and writing
4+
* word processing documents.
5+
*
6+
* PHPWord is free software distributed under the terms of the GNU Lesser
7+
* General Public License version 3 as published by the Free Software Foundation.
8+
*
9+
* For the full copyright and license information, please read the LICENSE
10+
* file that was distributed with this source code. For the full list of
11+
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
12+
*
13+
* @see https://github.com/PHPOffice/PHPWord
14+
*
15+
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace PhpOffice\PhpWordTests\Writer\Word2007\Element;
20+
21+
use PhpOffice\PhpWord\PhpWord;
22+
use PhpOffice\PhpWordTests\TestHelperDOCX;
23+
24+
/**
25+
* Test class for PhpOffice\PhpWord\Writer\Word2007\Element subnamespace.
26+
*/
27+
class TOCTest extends \PHPUnit\Framework\TestCase
28+
{
29+
/**
30+
* Executed after each method of the class.
31+
*/
32+
protected function tearDown(): void
33+
{
34+
TestHelperDOCX::clear();
35+
}
36+
37+
public function testWriteTitlePageNumber(): void
38+
{
39+
$expectedPageNum = mt_rand(1, 1000);
40+
41+
$phpWord = new PhpWord();
42+
43+
$section = $phpWord->addSection();
44+
$section->addTOC();
45+
$section->addTitle('TestTitle 1', 1, $expectedPageNum);
46+
47+
$doc = TestHelperDOCX::getDocument($phpWord);
48+
49+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:hyperlink/w:r[1]/w:t'));
50+
self::assertEquals('TestTitle 1', $doc->getElement('/w:document/w:body/w:p[1]/w:hyperlink/w:r[1]/w:t')->textContent);
51+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:hyperlink/w:r[5]/w:fldChar'));
52+
self::assertEquals('separate', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:hyperlink/w:r[5]/w:fldChar', 'w:fldCharType'));
53+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:hyperlink/w:r[6]/w:t'));
54+
self::assertEquals($expectedPageNum, $doc->getElement('/w:document/w:body/w:p[1]/w:hyperlink/w:r[6]/w:t')->textContent);
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
/**
3+
* This file is part of PHPWord - A pure PHP library for reading and writing
4+
* word processing documents.
5+
*
6+
* PHPWord is free software distributed under the terms of the GNU Lesser
7+
* General Public License version 3 as published by the Free Software Foundation.
8+
*
9+
* For the full copyright and license information, please read the LICENSE
10+
* file that was distributed with this source code. For the full list of
11+
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
12+
*
13+
* @see https://github.com/PHPOffice/PHPWord
14+
*
15+
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace PhpOffice\PhpWordTests\Writer\Word2007\Element;
20+
21+
use PhpOffice\PhpWord\PhpWord;
22+
use PhpOffice\PhpWordTests\TestHelperDOCX;
23+
24+
/**
25+
* Test class for PhpOffice\PhpWord\Writer\Word2007\Element subnamespace.
26+
*/
27+
class TitleTest extends \PHPUnit\Framework\TestCase
28+
{
29+
/**
30+
* Executed after each method of the class.
31+
*/
32+
protected function tearDown(): void
33+
{
34+
TestHelperDOCX::clear();
35+
}
36+
37+
public function testWriteTitleWithStyle(): void
38+
{
39+
$phpWord = new PhpWord();
40+
$phpWord->addTitleStyle(0, ['size' => 14, 'italic' => true]);
41+
42+
$section = $phpWord->addSection();
43+
$section->addTitle('Test Title0', 0);
44+
45+
$doc = TestHelperDOCX::getDocument($phpWord);
46+
47+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
48+
self::assertEquals('Test Title0', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
49+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr/w:pStyle'));
50+
self::assertEquals('Title', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:pStyle', 'w:val'));
51+
}
52+
53+
public function testWriteTitleWithoutStyle(): void
54+
{
55+
$phpWord = new PhpWord();
56+
57+
$section = $phpWord->addSection();
58+
$section->addTitle('Test Title0', 0);
59+
60+
$doc = TestHelperDOCX::getDocument($phpWord);
61+
62+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
63+
self::assertEquals('Test Title0', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
64+
self::assertFalse($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr'));
65+
}
66+
67+
public function testWriteHeadingWithStyle(): void
68+
{
69+
$phpWord = new PhpWord();
70+
$phpWord->addTitleStyle(1, ['bold' => true], ['spaceAfter' => 240]);
71+
72+
$section = $phpWord->addSection();
73+
$section->addTitle('TestHeading 1', 1);
74+
75+
$doc = TestHelperDOCX::getDocument($phpWord);
76+
77+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
78+
self::assertEquals('TestHeading 1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
79+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr/w:pStyle'));
80+
self::assertEquals('Heading1', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:pStyle', 'w:val'));
81+
}
82+
83+
public function testWriteHeadingWithoutStyle(): void
84+
{
85+
$phpWord = new PhpWord();
86+
87+
$section = $phpWord->addSection();
88+
$section->addTitle('TestHeading 1', 1);
89+
90+
$doc = TestHelperDOCX::getDocument($phpWord);
91+
92+
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
93+
self::assertEquals('TestHeading 1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
94+
self::assertFalse($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr'));
95+
}
96+
}

0 commit comments

Comments
 (0)