From 6c6ced59ae5566de3434dec1f8c4f6063850e5c7 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Fri, 30 Oct 2015 09:25:54 +0100 Subject: [PATCH 01/41] #121 : Set name of a slide --- .travis_shell_after_success.sh | 6 ++--- CHANGELOG.md | 4 +++ src/PhpPresentation/Slide.php | 27 +++++++++++++++++++ .../Writer/ODPresentation/Content.php | 5 +++- tests/PhpPresentation/Tests/SlideTest.php | 10 +++++++ .../Writer/ODPresentation/ContentTest.php | 27 ++++++++++++++++++- 6 files changed, 73 insertions(+), 6 deletions(-) diff --git a/.travis_shell_after_success.sh b/.travis_shell_after_success.sh index a88b576e7..d3138a248 100644 --- a/.travis_shell_after_success.sh +++ b/.travis_shell_after_success.sh @@ -5,8 +5,7 @@ echo "TRAVIS_REPO_SLUG: $TRAVIS_REPO_SLUG" echo "TRAVIS_PHP_VERSION: $TRAVIS_PHP_VERSION" echo "TRAVIS_PULL_REQUEST: $TRAVIS_PULL_REQUEST" -##if [ "$TRAVIS_REPO_SLUG" == "PHPOffice/PHPPresentation" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_PHP_VERSION" == "5.5" ]; then -if [ "$TRAVIS_REPO_SLUG" == "PHPOffice/PHPPowerPoint" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_PHP_VERSION" == "5.5" ]; then +if [ "$TRAVIS_REPO_SLUG" == "PHPOffice/PHPPresentation" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_PHP_VERSION" == "5.5" ]; then echo -e "Publishing PHPDoc...\n" @@ -16,8 +15,7 @@ if [ "$TRAVIS_REPO_SLUG" == "PHPOffice/PHPPowerPoint" ] && [ "$TRAVIS_PULL_REQUE cd $HOME git config --global user.email "travis@travis-ci.org" git config --global user.name "travis-ci" - ## git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/PHPOffice/PHPPresentation gh-pages > /dev/null - git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/PHPOffice/PHPPowerPoint gh-pages > /dev/null + git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/PHPOffice/PHPPresentation gh-pages > /dev/null cd gh-pages echo "--DEBUG : Suppression" diff --git a/CHANGELOG.md b/CHANGELOG.md index 91743ab13..db9b76bb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ # Changelog +## 0.6.0 - WIP +### Features +- ODPresentation Writer : Name of the slide - @Progi1984 GH-121 + ## 0.5.0 - 2015-10-08 ### Features diff --git a/src/PhpPresentation/Slide.php b/src/PhpPresentation/Slide.php index ca4b09e69..b37871e9a 100644 --- a/src/PhpPresentation/Slide.php +++ b/src/PhpPresentation/Slide.php @@ -114,6 +114,13 @@ class Slide implements ComparableInterface, ShapeContainerInterface */ protected $extentY; + /** + * Name of the title + * + * @var string + */ + protected $name; + /** * Create a new slide * @@ -462,4 +469,24 @@ public function setTransition(Transition $transition = null) return $this; } + + /** + * Get the name of the slide + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Set the name of the slide + * @param string $name + * @return $this + */ + public function setName($name = null) + { + $this->name = $name; + return $this; + } } diff --git a/src/PhpPresentation/Writer/ODPresentation/Content.php b/src/PhpPresentation/Writer/ODPresentation/Content.php index 9f4214c3c..d07b9ec41 100644 --- a/src/PhpPresentation/Writer/ODPresentation/Content.php +++ b/src/PhpPresentation/Writer/ODPresentation/Content.php @@ -268,7 +268,10 @@ public function writePart(PhpPresentation $pPhpPresentation) for ($i = 0; $i < $slideCount; ++$i) { $pSlide = $pPhpPresentation->getSlide($i); $objWriter->startElement('draw:page'); - $objWriter->writeAttribute('draw:name', 'page' . $i); + $name = $pSlide->getName(); + if (!is_null($name)) { + $objWriter->writeAttribute('draw:name', $name); + } $objWriter->writeAttribute('draw:master-page-name', 'Standard'); $objWriter->writeAttribute('draw:style-name', 'stylePage' . $i); // Images diff --git a/tests/PhpPresentation/Tests/SlideTest.php b/tests/PhpPresentation/Tests/SlideTest.php index 6b161ed25..519b8dca8 100644 --- a/tests/PhpPresentation/Tests/SlideTest.php +++ b/tests/PhpPresentation/Tests/SlideTest.php @@ -84,6 +84,16 @@ public function testGroup() $this->assertInstanceOf('PhpOffice\\PhpPresentation\\Shape\\Group', $object->createGroup()); } + public function testName() + { + $object = new Slide(); + $this->assertNull($object->getName()); + $this->assertInstanceOf('PhpOffice\\PhpPresentation\\Slide', $object->setName('AAAA')); + $this->assertEquals('AAAA', $object->getName()); + $this->assertInstanceOf('PhpOffice\\PhpPresentation\\Slide', $object->setName()); + $this->assertNull($object->getName()); + } + public function testTransition() { $object = new Slide(); diff --git a/tests/PhpPresentation/Tests/Writer/ODPresentation/ContentTest.php b/tests/PhpPresentation/Tests/Writer/ODPresentation/ContentTest.php index 0fb9ffab5..ffd9d725e 100644 --- a/tests/PhpPresentation/Tests/Writer/ODPresentation/ContentTest.php +++ b/tests/PhpPresentation/Tests/Writer/ODPresentation/ContentTest.php @@ -305,7 +305,32 @@ public function testRichTextShadow() } } } - + + public function testSlideName() + { + $phpPresentation = new PhpPresentation(); + $oSlide = $phpPresentation->getActiveSlide(); + + $element = '/office:document-content/office:body/office:presentation/draw:page'; + + $pres = TestHelperDOCX::getDocument($phpPresentation, 'ODPresentation'); + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'draw:name', 'content.xml')); + + $oSlide->setName('AAAA'); + + $pres = TestHelperDOCX::getDocument($phpPresentation, 'ODPresentation'); + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:name', 'content.xml')); + $this->assertEquals('AAAA', $pres->getElementAttribute($element, 'draw:name', 'content.xml')); + + $oSlide->setName(); + + $pres = TestHelperDOCX::getDocument($phpPresentation, 'ODPresentation'); + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'draw:name', 'content.xml')); + } + public function testStyleAlignment() { $phpPresentation = new PhpPresentation(); From a91b9d6027450f9a7758ac8c351c41fbf5d2af20 Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Fri, 30 Oct 2015 09:42:47 +0100 Subject: [PATCH 02/41] #121 : Set name of a slide (Reader & Documentation) --- docs/intro.rst | 4 ++++ docs/slides.rst | 11 +++++++++++ src/PhpPresentation/Reader/ODPresentation.php | 3 +++ .../Tests/Reader/ODPresentationTest.php | 10 ++++++++++ tests/resources/files/ODP_Slide_Name.odp | Bin 0 -> 12337 bytes 5 files changed, 28 insertions(+) create mode 100644 tests/resources/files/ODP_Slide_Name.odp diff --git a/docs/intro.rst b/docs/intro.rst index 1d01c9761..76abf3c95 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -46,6 +46,10 @@ Writers +---------------------------+----------------------+--------+-------+-------+-------+ | | Custom | | | | | +---------------------------+----------------------+--------+-------+-------+-------+ +| **Slides** | | ✓ | ✓ | | | ++---------------------------+----------------------+--------+-------+-------+-------+ +| | Name | | ✓ | | | ++---------------------------+----------------------+--------+-------+-------+-------+ | **Element Shape** | Image | ✓ | ✓ | | | +---------------------------+----------------------+--------+-------+-------+-------+ | | Hyperlink | ✓ | ✓ | | | diff --git a/docs/slides.rst b/docs/slides.rst index 9d7858730..79a9bf4e3 100644 --- a/docs/slides.rst +++ b/docs/slides.rst @@ -4,3 +4,14 @@ Slides ====== Slides are pages in a presentation. Slides are stored as a zero based array in ``PHPPresentation`` object. Use ``createSlide`` to create a new slide and retrieve the slide for other operation such as creating shapes for that slide. + +Name +------- + +By default, a slide has not a name. +You can define it with the method ``setName``. + +.. code-block:: php + + $oSlide = $oPHPPresentation->createSlide(); + $oSlide->setName('Title of the slide'); \ No newline at end of file diff --git a/src/PhpPresentation/Reader/ODPresentation.php b/src/PhpPresentation/Reader/ODPresentation.php index 996c6258d..af5ecc5a0 100644 --- a/src/PhpPresentation/Reader/ODPresentation.php +++ b/src/PhpPresentation/Reader/ODPresentation.php @@ -301,6 +301,9 @@ protected function loadSlide(\DOMElement $nodeSlide) // Core $this->oPhpPresentation->createSlide(); $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1); + if ($nodeSlide->hasAttribute('draw:name')) { + $this->oPhpPresentation->getActiveSlide()->setName($nodeSlide->getAttribute('draw:name')); + } foreach ($this->oXMLReader->getElements('draw:frame', $nodeSlide) as $oNodeFrame) { if ($this->oXMLReader->getElement('draw:image', $oNodeFrame)) { $this->loadShapeDrawing($oNodeFrame); diff --git a/tests/PhpPresentation/Tests/Reader/ODPresentationTest.php b/tests/PhpPresentation/Tests/Reader/ODPresentationTest.php index 9b866fd4b..56781f62b 100644 --- a/tests/PhpPresentation/Tests/Reader/ODPresentationTest.php +++ b/tests/PhpPresentation/Tests/Reader/ODPresentationTest.php @@ -464,4 +464,14 @@ public function testLoadFile01() $this->assertEquals('https://github.com/PHPOffice/PHPPresentation/', $oRichText->getHyperlink()->getUrl()); //$this->assertEquals('PHPPresentation', $oRichText->getHyperlink()->getTooltip()); } + + public function testSlideName() + { + $file = PHPPRESENTATION_TESTS_BASE_DIR . '/resources/files/ODP_Slide_Name.odp'; + $object = new ODPresentation(); + $oPhpPresentation = $object->load($file); + $this->assertInstanceOf('PhpOffice\\PhpPresentation\\PhpPresentation', $oPhpPresentation); + + $this->assertEquals('MaDiapo', $oPhpPresentation->getSlide(0)->getName()); + } } diff --git a/tests/resources/files/ODP_Slide_Name.odp b/tests/resources/files/ODP_Slide_Name.odp new file mode 100644 index 0000000000000000000000000000000000000000..4a8b2fdc1ea6cd20b24c45dfed143803b4c4b2fe GIT binary patch literal 12337 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