From ac89cc39eaf97f0cb91b9df9b88d161a0fce24b1 Mon Sep 17 00:00:00 2001 From: antoine Date: Tue, 30 May 2017 00:31:32 +0200 Subject: [PATCH 1/2] Add possibility to control the footnote number --- docs/elements.rst | 23 ++- samples/Sample_06_Footnote.php | 8 +- src/PhpWord/Element/Section.php | 28 ++++ src/PhpWord/SimpleType/FootnoteProperties.php | 152 ++++++++++++++++++ src/PhpWord/Writer/Word2007/Part/Document.php | 27 ++++ .../SimpleType/FootnotePropertiesTest.php | 79 +++++++++ .../Writer/Word2007/Part/DocumentTest.php | 31 ++++ 7 files changed, 344 insertions(+), 4 deletions(-) create mode 100644 src/PhpWord/SimpleType/FootnoteProperties.php create mode 100644 tests/PhpWord/SimpleType/FootnotePropertiesTest.php diff --git a/docs/elements.rst b/docs/elements.rst index 27fd76b8..5b671936 100644 --- a/docs/elements.rst +++ b/docs/elements.rst @@ -333,11 +333,28 @@ On text: $footnote = $section->addFootnote(); $footnote->addText('Footnote text.'); -The footnote reference number will be displayed with decimal number -starting from 1. This number use ``FooterReference`` style which you can -redefine by ``addFontStyle`` method. Default value for this style is +By default the footnote reference number will be displayed with decimal number +starting from 1. This number uses the ``FooterReference`` style which you can +redefine with the ``addFontStyle`` method. Default value for this style is ``array('superScript' => true)``; +The footnote numbering can be controlled by setting the FootnoteProperties on the Section. + +.. code-block:: php + + $fp = new PhpWord\SimpleType\FootnoteProperties(); + //sets the position of the footnote (pageBottom (default), beneathText, sectEnd, docEnd) + $fp->setPos(FootnoteProperties::POSITION_DOC_END); + //set the number format to use (decimal (default), upperRoman, upperLetter, ...) + $fp->setNumFmt(FootnoteProperties::NUMBER_FORMAT_LOWER_ROMAN); + //force starting at other than 1 + $fp->setNumStart(2); + //when to restart counting (continuous (default), eachSect, eachPage) + $fp->setNumRestart(FootnoteProperties::RESTART_NUMBER_EACH_PAGE); + + //And finaly, set it on the Section + $section->setFootnoteProperties($properties); + Checkboxes ---------- diff --git a/samples/Sample_06_Footnote.php b/samples/Sample_06_Footnote.php index 30afcf81..f9c6b5f7 100644 --- a/samples/Sample_06_Footnote.php +++ b/samples/Sample_06_Footnote.php @@ -1,4 +1,6 @@ addText('But you can only put footnote in section, not in header or f $section->addText( 'You can also create the footnote directly from the section making it wrap in a paragraph ' - . 'like the footnote below this paragraph. But is is best used from within a textrun.' + . 'like the footnote below this paragraph. But is best used from within a textrun.' ); $footnote = $section->addFootnote(); $footnote->addText('The reference for this is wrapped in its own line'); +$footnoteProperties = new FootnoteProperties(); +$footnoteProperties->setNumFmt(FootnoteProperties::NUMBER_FORMAT_UPPER_ROMAN); +$section->setFootnoteProperties($footnoteProperties); + // Save file echo write($phpWord, basename(__FILE__, '.php'), $writers); if (!CLI) { diff --git a/src/PhpWord/Element/Section.php b/src/PhpWord/Element/Section.php index 1e926d2f..c0bfc3cf 100644 --- a/src/PhpWord/Element/Section.php +++ b/src/PhpWord/Element/Section.php @@ -18,6 +18,7 @@ namespace PhpOffice\PhpWord\Element; use PhpOffice\PhpWord\Style\Section as SectionStyle; +use PhpOffice\PhpWord\SimpleType\FootnoteProperties; class Section extends AbstractContainer { @@ -47,6 +48,13 @@ class Section extends AbstractContainer */ private $footers = array(); + /** + * The properties for the footnote of this section + * + * @var FootnoteProperties + */ + private $footnoteProperties; + /** * Create new instance * @@ -138,6 +146,26 @@ class Section extends AbstractContainer return $this->footers; } + /** + * Get the footnote properties + * + * @return \PhpOffice\PhpWord\Element\FooterProperties + */ + public function getFootnotePropoperties() + { + return $this->footnoteProperties; + } + + /** + * Set the footnote properties + * + * @param FootnoteProperties $footnoteProperties + */ + public function setFootnoteProperties(FootnoteProperties $footnoteProperties = null) + { + $this->footnoteProperties = $footnoteProperties; + } + /** * Is there a header for this section that is for the first page only? * diff --git a/src/PhpWord/SimpleType/FootnoteProperties.php b/src/PhpWord/SimpleType/FootnoteProperties.php new file mode 100644 index 00000000..812c055f --- /dev/null +++ b/src/PhpWord/SimpleType/FootnoteProperties.php @@ -0,0 +1,152 @@ +pos; + } + + public function setPos($pos) + { + if (in_array($pos, self::POSITION)) { + $this->pos = $pos; + } else { + throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', self::POSITION) . " possible"); + } + } + + public function getNumFmt() + { + return $this->numFmt; + } + + public function setNumFmt($numFmt) + { + if (in_array($numFmt, self::NUMBER_FORMAT)) { + $this->numFmt = $numFmt; + } else { + throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', self::NUMBER_FORMAT) . " possible"); + } + } + + public function getNumStart() + { + return $this->numStart; + } + + public function setNumStart($numStart) + { + $this->numStart = $numStart; + } + + public function getNumRestart() + { + return $this->numRestart; + } + + public function setNumRestart($numRestart) + { + if (in_array($numRestart, self::RESTART_NUMBER)) { + $this->numRestart= $numRestart; + } else { + throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', self::RESTART_NUMBER) . " possible"); + } + } +} diff --git a/src/PhpWord/Writer/Word2007/Part/Document.php b/src/PhpWord/Writer/Word2007/Part/Document.php index 411946f5..a2dc999b 100644 --- a/src/PhpWord/Writer/Word2007/Part/Document.php +++ b/src/PhpWord/Writer/Word2007/Part/Document.php @@ -21,6 +21,7 @@ use PhpOffice\Common\XMLWriter; use PhpOffice\PhpWord\Element\Section; use PhpOffice\PhpWord\Writer\Word2007\Element\Container; use PhpOffice\PhpWord\Writer\Word2007\Style\Section as SectionStyleWriter; +use PhpOffice\PhpWord\SimpleType\FootnoteProperties; /** * Word2007 document part writer: word/document.xml @@ -129,6 +130,32 @@ class Document extends AbstractPart $xmlWriter->endElement(); } + //footnote properties + if ($section->getFootnotePropoperties() !== null) { + $xmlWriter->startElement('w:footnotePr'); + if ($section->getFootnotePropoperties()->getPos() != null) { + $xmlWriter->startElement('w:pos'); + $xmlWriter->writeAttribute('w:val', $section->getFootnotePropoperties()->getPos()); + $xmlWriter->endElement(); + } + if ($section->getFootnotePropoperties()->getNumFmt() != null) { + $xmlWriter->startElement('w:numFmt'); + $xmlWriter->writeAttribute('w:val', $section->getFootnotePropoperties()->getNumFmt()); + $xmlWriter->endElement(); + } + if ($section->getFootnotePropoperties()->getNumStart() != null) { + $xmlWriter->startElement('w:numStart'); + $xmlWriter->writeAttribute('w:val', $section->getFootnotePropoperties()->getNumStart()); + $xmlWriter->endElement(); + } + if ($section->getFootnotePropoperties()->getNumRestart() != null) { + $xmlWriter->startElement('w:numRestart'); + $xmlWriter->writeAttribute('w:val', $section->getFootnotePropoperties()->getNumRestart()); + $xmlWriter->endElement(); + } + $xmlWriter->endElement(); + } + // Section settings $styleWriter = new SectionStyleWriter($xmlWriter, $section->getStyle()); $styleWriter->write(); diff --git a/tests/PhpWord/SimpleType/FootnotePropertiesTest.php b/tests/PhpWord/SimpleType/FootnotePropertiesTest.php new file mode 100644 index 00000000..193ad363 --- /dev/null +++ b/tests/PhpWord/SimpleType/FootnotePropertiesTest.php @@ -0,0 +1,79 @@ +setPos(FootnoteProperties::POSITION_DOC_END); + $footnoteProp->setNumFmt(FootnoteProperties::NUMBER_FORMAT_LOWER_ROMAN); + $footnoteProp->setNumStart(2); + $footnoteProp->setNumRestart(FootnoteProperties::RESTART_NUMBER_EACH_PAGE); + + $this->assertEquals(FootnoteProperties::POSITION_DOC_END, $footnoteProp->getPos()); + $this->assertEquals(FootnoteProperties::NUMBER_FORMAT_LOWER_ROMAN, $footnoteProp->getNumFmt()); + $this->assertEquals(2, $footnoteProp->getNumStart()); + $this->assertEquals(FootnoteProperties::RESTART_NUMBER_EACH_PAGE, $footnoteProp->getNumRestart()); + } + + /** + * Test throws exception if wrong position given + * + * @expectedException \InvalidArgumentException + */ + public function testWrongPos() + { + $footnoteProp= new FootnoteProperties(); + $footnoteProp->setPos(FootnoteProperties::NUMBER_FORMAT_LOWER_ROMAN); + } + + /** + * Test throws exception if wrong number format given + * + * @expectedException \InvalidArgumentException + */ + public function testWrongNumFmt() + { + $footnoteProp= new FootnoteProperties(); + $footnoteProp->setNumFmt(FootnoteProperties::POSITION_DOC_END); + } + + /** + * Test throws exception if wrong number restart given + * + * @expectedException \InvalidArgumentException + */ + public function testWrongNumRestart() + { + $footnoteProp= new FootnoteProperties(); + $footnoteProp->setNumRestart(FootnoteProperties::NUMBER_FORMAT_LOWER_ROMAN); + } +} diff --git a/tests/PhpWord/Writer/Word2007/Part/DocumentTest.php b/tests/PhpWord/Writer/Word2007/Part/DocumentTest.php index a9e6d861..0f64d7a7 100644 --- a/tests/PhpWord/Writer/Word2007/Part/DocumentTest.php +++ b/tests/PhpWord/Writer/Word2007/Part/DocumentTest.php @@ -20,6 +20,7 @@ use PhpOffice\PhpWord\PhpWord; use PhpOffice\PhpWord\SimpleType\Jc; use PhpOffice\PhpWord\Style\Font; use PhpOffice\PhpWord\TestHelperDOCX; +use PhpOffice\PhpWord\SimpleType\FootnoteProperties; /** * Test class for PhpOffice\PhpWord\Writer\Word2007\Part\Document @@ -57,6 +58,36 @@ class DocumentTest extends \PHPUnit_Framework_TestCase $this->assertEquals(2, $element->getAttribute('w:start')); } + /** + * Write section footnote properties + */ + public function testSectionFootnoteProperties() + { + $properties = new FootnoteProperties(); + $properties->setPos(FootnoteProperties::POSITION_DOC_END); + $properties->setNumFmt(FootnoteProperties::NUMBER_FORMAT_LOWER_ROMAN); + $properties->setNumStart(1); + $properties->setNumRestart(FootnoteProperties::RESTART_NUMBER_EACH_PAGE); + + $phpWord = new PhpWord(); + $section = $phpWord->addSection(); + $section->setFootnoteProperties($properties); + + $doc = TestHelperDOCX::getDocument($phpWord); + + $element = $doc->getElement('/w:document/w:body/w:sectPr/w:footnotePr/w:pos'); + $this->assertEquals(FootnoteProperties::POSITION_DOC_END, $element->getAttribute('w:val')); + + $element = $doc->getElement('/w:document/w:body/w:sectPr/w:footnotePr/w:numFmt'); + $this->assertEquals(FootnoteProperties::NUMBER_FORMAT_LOWER_ROMAN, $element->getAttribute('w:val')); + + $element = $doc->getElement('/w:document/w:body/w:sectPr/w:footnotePr/w:numStart'); + $this->assertEquals(1, $element->getAttribute('w:val')); + + $element = $doc->getElement('/w:document/w:body/w:sectPr/w:footnotePr/w:numRestart'); + $this->assertEquals(FootnoteProperties::RESTART_NUMBER_EACH_PAGE, $element->getAttribute('w:val')); + } + /** * Write elements */ From eff532e64fe4223dd8dbcb1d4bf2a70031749f4d Mon Sep 17 00:00:00 2001 From: antoine Date: Sat, 17 Jun 2017 01:01:54 +0200 Subject: [PATCH 2/2] make code php 5.3 -> 5.5 compatible --- src/PhpWord/SimpleType/FootnoteProperties.php | 64 +++++++++---------- .../SimpleType/FootnotePropertiesTest.php | 2 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/PhpWord/SimpleType/FootnoteProperties.php b/src/PhpWord/SimpleType/FootnoteProperties.php index 812c055f..f98f0a94 100644 --- a/src/PhpWord/SimpleType/FootnoteProperties.php +++ b/src/PhpWord/SimpleType/FootnoteProperties.php @@ -28,12 +28,6 @@ final class FootnoteProperties const RESTART_NUMBER_EACH_SECTION = 'eachSect'; const RESTART_NUMBER_EACH_PAGE = 'eachPage'; - const RESTART_NUMBER = array( - self::RESTART_NUMBER_CONTINUOUS, - self::RESTART_NUMBER_EACH_SECTION, - self::RESTART_NUMBER_EACH_PAGE - ); - const NUMBER_FORMAT_DECIMAL = 'decimal'; const NUMBER_FORMAT_UPPER_ROMAN = 'upperRoman'; const NUMBER_FORMAT_LOWER_ROMAN = 'lowerRoman'; @@ -45,31 +39,11 @@ final class FootnoteProperties const NUMBER_FORMAT_NONE = 'none'; const NUMBER_FORMAT_BULLET = 'bullet'; - const NUMBER_FORMAT = array( - self::NUMBER_FORMAT_DECIMAL, - self::NUMBER_FORMAT_UPPER_ROMAN, - self::NUMBER_FORMAT_LOWER_ROMAN, - self::NUMBER_FORMAT_UPPER_LETTER, - self::NUMBER_FORMAT_LOWER_LETTER, - self::NUMBER_FORMAT_ORDINAL, - self::NUMBER_FORMAT_CARDINAL_TEXT, - self::NUMBER_FORMAT_ORDINAL_TEXT, - self::NUMBER_FORMAT_NONE, - self::NUMBER_FORMAT_BULLET - ); - const POSITION_PAGE_BOTTOM = 'pageBottom'; const POSITION_BENEATH_TEXT = 'beneathText'; const POSITION_SECTION_END = 'sectEnd'; const POSITION_DOC_END = 'docEnd'; - const POSITION = array( - self::POSITION_PAGE_BOTTOM, - self::POSITION_BENEATH_TEXT, - self::POSITION_SECTION_END, - self::POSITION_DOC_END - ); - /** * Footnote Positioning Location * @@ -105,10 +79,17 @@ final class FootnoteProperties public function setPos($pos) { - if (in_array($pos, self::POSITION)) { + $position = array( + self::POSITION_PAGE_BOTTOM, + self::POSITION_BENEATH_TEXT, + self::POSITION_SECTION_END, + self::POSITION_DOC_END + ); + + if (in_array($pos, $position)) { $this->pos = $pos; } else { - throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', self::POSITION) . " possible"); + throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', $position) . " possible"); } } @@ -119,10 +100,23 @@ final class FootnoteProperties public function setNumFmt($numFmt) { - if (in_array($numFmt, self::NUMBER_FORMAT)) { + $numberFormat = array( + self::NUMBER_FORMAT_DECIMAL, + self::NUMBER_FORMAT_UPPER_ROMAN, + self::NUMBER_FORMAT_LOWER_ROMAN, + self::NUMBER_FORMAT_UPPER_LETTER, + self::NUMBER_FORMAT_LOWER_LETTER, + self::NUMBER_FORMAT_ORDINAL, + self::NUMBER_FORMAT_CARDINAL_TEXT, + self::NUMBER_FORMAT_ORDINAL_TEXT, + self::NUMBER_FORMAT_NONE, + self::NUMBER_FORMAT_BULLET + ); + + if (in_array($numFmt, $numberFormat)) { $this->numFmt = $numFmt; } else { - throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', self::NUMBER_FORMAT) . " possible"); + throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', $numberFormat) . " possible"); } } @@ -143,10 +137,16 @@ final class FootnoteProperties public function setNumRestart($numRestart) { - if (in_array($numRestart, self::RESTART_NUMBER)) { + $restartNumbers = array( + self::RESTART_NUMBER_CONTINUOUS, + self::RESTART_NUMBER_EACH_SECTION, + self::RESTART_NUMBER_EACH_PAGE + ); + + if (in_array($numRestart, $restartNumbers)) { $this->numRestart= $numRestart; } else { - throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', self::RESTART_NUMBER) . " possible"); + throw new \InvalidArgumentException("Invalid value, on of " . implode(', ', $restartNumbers) . " possible"); } } } diff --git a/tests/PhpWord/SimpleType/FootnotePropertiesTest.php b/tests/PhpWord/SimpleType/FootnotePropertiesTest.php index 193ad363..f977b32a 100644 --- a/tests/PhpWord/SimpleType/FootnotePropertiesTest.php +++ b/tests/PhpWord/SimpleType/FootnotePropertiesTest.php @@ -15,7 +15,7 @@ * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ -namespace PhpOffice\PhpWord\Style; +namespace PhpOffice\PhpWord\SimpleType; use PhpOffice\PhpWord\SimpleType\FootnoteProperties;