Skip to content

Commit

Permalink
Merge pull request #2471 from PHPOffice/pr1652
Browse files Browse the repository at this point in the history
Word2007 Writer : Add PageNumber to TOC
  • Loading branch information
Progi1984 committed Sep 14, 2023
2 parents 7d5816b + 338fcc1 commit d1e7ed7
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 73 deletions.
1 change: 1 addition & 0 deletions docs/changes/1.x/1.2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- 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)
- 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)
- 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)
- 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)

### Bug fixes

Expand Down
13 changes: 9 additions & 4 deletions docs/usage/elements/title.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ If `depth` is 0, a Title will be inserted, otherwise a Heading1, Heading2, ...
<?php

$phpWord->addTitleStyle($depth, [$fontStyle], [$paragraphStyle]);
$section->addTitle($text, [$depth]);
$section->addTitle($text, $depth, $pageNumber);
```

- ``depth``.
- ``$fontStyle``. See [`Styles > Font`](../styles/font.md).
- ``$paragraphStyle``. See [`Styles > Paragraph`](../styles/paragraph.md).
`addTitleStyle` :
- ``$depth``
- ``$fontStyle``: See [`Styles > Font`](../styles/font.md).
- ``$paragraphStyle``: See [`Styles > Paragraph`](../styles/paragraph.md).

`addTitle` :
- ``$text``. Text to be displayed in the document. This can be `string` or a `\PhpOffice\PhpWord\Element\TextRun`
- ``$depth``
- ``$pageNumber`` : Number of the page

It's necessary to add a title style to your document because otherwise the title won't be detected as a real title.
2 changes: 1 addition & 1 deletion src/PhpWord/Element/AbstractContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
* @method Footnote addFootnote(mixed $pStyle = null)
* @method Endnote addEndnote(mixed $pStyle = null)
* @method CheckBox addCheckBox(string $name, $text, mixed $fStyle = null, mixed $pStyle = null)
* @method Title addTitle(mixed $text, int $depth = 1)
* @method Title addTitle(mixed $text, int $depth = 1, int $pageNumber = null)
* @method TOC addTOC(mixed $fontStyle = null, mixed $tocStyle = null, int $minDepth = 1, int $maxDepth = 9)
* @method PageBreak addPageBreak()
* @method Table addTable(mixed $style = null)
Expand Down
21 changes: 20 additions & 1 deletion src/PhpWord/Element/Title.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,20 @@ class Title extends AbstractElement
*/
protected $collectionRelation = true;

/**
* Page number.
*
* @var int
*/
private $pageNumber;

/**
* Create a new Title Element.
*
* @param string|TextRun $text
* @param int $depth
*/
public function __construct($text, $depth = 1)
public function __construct($text, $depth = 1, ?int $pageNumber = null)
{
if (is_string($text)) {
$this->text = SharedText::toUTF8($text);
Expand All @@ -75,6 +82,10 @@ public function __construct($text, $depth = 1)
if (array_key_exists($styleName, Style::getStyles())) {
$this->style = str_replace('_', '', $styleName);
}

if ($pageNumber !== null) {
$this->pageNumber = $pageNumber;
}
}

/**
Expand Down Expand Up @@ -106,4 +117,12 @@ public function getStyle()
{
return $this->style;
}

/**
* Get page number.
*/
public function getPageNumber(): ?int
{
return $this->pageNumber;
}
}
24 changes: 17 additions & 7 deletions src/PhpWord/Writer/Word2007/Element/TOC.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace PhpOffice\PhpWord\Writer\Word2007\Element;

use PhpOffice\PhpWord\Element\Title;
use PhpOffice\PhpWord\Element\TOC as TOCElement;
use PhpOffice\PhpWord\Shared\XMLWriter;
use PhpOffice\PhpWord\Style\Font;
Expand Down Expand Up @@ -63,11 +64,8 @@ public function write(): void

/**
* Write title.
*
* @param \PhpOffice\PhpWord\Element\Title $title
* @param bool $writeFieldMark
*/
private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $writeFieldMark): void
private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, Title $title, bool $writeFieldMark): void
{
$tocStyle = $element->getStyleTOC();
$fontStyle = $element->getStyleFont();
Expand Down Expand Up @@ -116,6 +114,20 @@ private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $
$xmlWriter->endElement();
$xmlWriter->endElement();

if ($title->getPageNumber() !== null) {
$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'separate');
$xmlWriter->endElement();
$xmlWriter->endElement();

$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:t');
$xmlWriter->text((string) $title->getPageNumber());
$xmlWriter->endElement();
$xmlWriter->endElement();
}

$xmlWriter->startElement('w:r');
$xmlWriter->startElement('w:fldChar');
$xmlWriter->writeAttribute('w:fldCharType', 'end');
Expand All @@ -129,10 +141,8 @@ private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $

/**
* Write style.
*
* @param int $indent
*/
private function writeStyle(XMLWriter $xmlWriter, TOCElement $element, $indent): void
private function writeStyle(XMLWriter $xmlWriter, TOCElement $element, int $indent): void
{
$tocStyle = $element->getStyleTOC();
$fontStyle = $element->getStyleFont();
Expand Down
47 changes: 27 additions & 20 deletions tests/PhpWordTests/Element/TitleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
declare(strict_types=1);

namespace PhpOffice\PhpWordTests\Element;

Expand All @@ -32,42 +33,48 @@
class TitleTest extends \PHPUnit\Framework\TestCase
{
/**
* Create new instance.
* Create new instance with string.
*/
public function testConstruct(): void
{
$oTitle = new Title('text');
$title = new Title('text');

self::assertInstanceOf('PhpOffice\\PhpWord\\Element\\Title', $oTitle);
self::assertEquals('text', $oTitle->getText());
}

/**
* Get style null.
*/
public function testStyleNull(): void
{
$oTitle = new Title('text');

self::assertNull($oTitle->getStyle());
self::assertInstanceOf(Title::class, $title);
self::assertEquals('text', $title->getText());
self::assertEquals(1, $title->getDepth());
self::assertNull($title->getPageNumber());
self::assertNull($title->getStyle());
}

/**
* Create new instance with TextRun.
*/
public function testConstructWithTextRun(): void
{
$oTextRun = new TextRun();
$oTextRun->addText('text');
$oTitle = new Title($oTextRun);
$textRun = new TextRun();
$textRun->addText('text');
$title = new Title($textRun);

self::assertInstanceOf('PhpOffice\\PhpWord\\Element\\TextRun', $oTitle->getText());
self::assertInstanceOf(TextRun::class, $title->getText());
self::assertEquals(1, $title->getDepth());
self::assertNull($title->getPageNumber());
self::assertNull($title->getStyle());
}

public function testConstructWithInvalidArgument(): void
{
$this->expectException(InvalidArgumentException::class);
$oPageBreak = new PageBreak();
new Title($oPageBreak);

new Title(new PageBreak());
}

public function testConstructWithPageNumber(): void
{
$title = new Title('text', 1, 0);

self::assertInstanceOf(Title::class, $title);
self::assertEquals('text', $title->getText());
self::assertEquals(0, $title->getPageNumber());
self::assertNull($title->getStyle());
}
}
56 changes: 56 additions & 0 deletions tests/PhpWordTests/Writer/Word2007/Element/TOCTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
*
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
declare(strict_types=1);

namespace PhpOffice\PhpWordTests\Writer\Word2007\Element;

use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWordTests\TestHelperDOCX;

/**
* Test class for PhpOffice\PhpWord\Writer\Word2007\Element subnamespace.
*/
class TOCTest extends \PHPUnit\Framework\TestCase
{
/**
* Executed after each method of the class.
*/
protected function tearDown(): void
{
TestHelperDOCX::clear();
}

public function testWriteTitlePageNumber(): void
{
$expectedPageNum = mt_rand(1, 1000);

$phpWord = new PhpWord();

$section = $phpWord->addSection();
$section->addTOC();
$section->addTitle('TestTitle 1', 1, $expectedPageNum);

$doc = TestHelperDOCX::getDocument($phpWord);

self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:hyperlink/w:r[1]/w:t'));
self::assertEquals('TestTitle 1', $doc->getElement('/w:document/w:body/w:p[1]/w:hyperlink/w:r[1]/w:t')->textContent);
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:hyperlink/w:r[5]/w:fldChar'));
self::assertEquals('separate', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:hyperlink/w:r[5]/w:fldChar', 'w:fldCharType'));
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:hyperlink/w:r[6]/w:t'));
self::assertEquals($expectedPageNum, $doc->getElement('/w:document/w:body/w:p[1]/w:hyperlink/w:r[6]/w:t')->textContent);
}
}
96 changes: 96 additions & 0 deletions tests/PhpWordTests/Writer/Word2007/Element/TitleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @see https://github.com/PHPOffice/PHPWord
*
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
declare(strict_types=1);

namespace PhpOffice\PhpWordTests\Writer\Word2007\Element;

use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWordTests\TestHelperDOCX;

/**
* Test class for PhpOffice\PhpWord\Writer\Word2007\Element subnamespace.
*/
class TitleTest extends \PHPUnit\Framework\TestCase
{
/**
* Executed after each method of the class.
*/
protected function tearDown(): void
{
TestHelperDOCX::clear();
}

public function testWriteTitleWithStyle(): void
{
$phpWord = new PhpWord();
$phpWord->addTitleStyle(0, ['size' => 14, 'italic' => true]);

$section = $phpWord->addSection();
$section->addTitle('Test Title0', 0);

$doc = TestHelperDOCX::getDocument($phpWord);

self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
self::assertEquals('Test Title0', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr/w:pStyle'));
self::assertEquals('Title', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:pStyle', 'w:val'));
}

public function testWriteTitleWithoutStyle(): void
{
$phpWord = new PhpWord();

$section = $phpWord->addSection();
$section->addTitle('Test Title0', 0);

$doc = TestHelperDOCX::getDocument($phpWord);

self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
self::assertEquals('Test Title0', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
self::assertFalse($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr'));
}

public function testWriteHeadingWithStyle(): void
{
$phpWord = new PhpWord();
$phpWord->addTitleStyle(1, ['bold' => true], ['spaceAfter' => 240]);

$section = $phpWord->addSection();
$section->addTitle('TestHeading 1', 1);

$doc = TestHelperDOCX::getDocument($phpWord);

self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
self::assertEquals('TestHeading 1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr/w:pStyle'));
self::assertEquals('Heading1', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:pStyle', 'w:val'));
}

public function testWriteHeadingWithoutStyle(): void
{
$phpWord = new PhpWord();

$section = $phpWord->addSection();
$section->addTitle('TestHeading 1', 1);

$doc = TestHelperDOCX::getDocument($phpWord);

self::assertTrue($doc->elementExists('/w:document/w:body/w:p[1]/w:r/w:t'));
self::assertEquals('TestHeading 1', $doc->getElement('/w:document/w:body/w:p[1]/w:r/w:t')->textContent);
self::assertFalse($doc->elementExists('/w:document/w:body/w:p[1]/w:pPr'));
}
}
Loading

0 comments on commit d1e7ed7

Please sign in to comment.