diff --git a/.gitignore b/.gitignore index 534ea9100..54a5d8203 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,27 @@ +### Temporary files .DS_Store ._* .Spotlight-V100 .Trashes Thumbs.db Desktop.ini + +### IDE Jetbrains PhpStorm .idea +### IDE Eclipse +*.settings +*.project +*.buildpath + +### Continuous Integration build/ phpunit.xml composer.phar vendor -*.settings -*.project -*.buildpath +/batch_CI.bat -/samples/results -/phpunit.bat -/todo.txt +### Samples /samples/Sample_00_Test.php +/samples/#* +/samples/Github_*.* +/samples/results diff --git a/.travis.yml b/.travis.yml index ffcb8a349..62310d2c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,15 @@ language: php php: - 5.3 - - 5.3.3 - 5.4 - 5.5 - 5.6 + - 7.0 - hhvm matrix: allow_failures: + - php: 7.0 - php: hhvm env: @@ -47,3 +48,11 @@ after_script: ## Scrutinizer - wget https://scrutinizer-ci.com/ocular.phar - php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml + +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/0dbc70ac93ba40880eef + on_success: change # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: false # default: false \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f9d1b6df..a5d1f3a52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,46 @@ # Changelog +## 0.4.0 - 2015-07-07 + +### Features +- Added support for grouping shapes together in a Group - @Pr0phet GH-68 +- Added support for calculating the offset and extent on a Slide. - @Pr0phet GH-68 +- Added support for Horizontal bar chart - @rdoepke @Progi1984 GH-58 +- Added support for hyperlink on picture (ODPresentation & PowerPoint2007) - @Progi1984 GH-49 +- Added support for hyperlink on richtext (PowerPoint2007) - @JewrassicPark GH-49 +- Added support for notes slide (ODPresentation & PowerPoint2007) - @Progi1984 @JewrassicPark GH-63 +- Added option for explosion in Pie3D Chart (ODPresentation & PowerPoint2007) - @Progi1984 GH-76 +- ODPresentation Writer : Support for fill in RichText - @Progi1984 GH-79 +- ODPresentation Writer : Support for border style in RichText - @Progi1984 GH-79 +- ODPresentation Writer : Support for Area Chart - @Progi1984 GH-82 +- PowerPoint2007 Writer : Support for Area Chart - @Progi1984 GH-82 +- ODPresentation Writer : Support for Bar Chart - @Progi1984 GH-82 +- PowerPoint2007 Writer : Support for Bar Chart - @Progi1984 GH-82 +- Added units in DocumentLayout - @Progi1984 GH-87 +- Added support for transitions between slides - @Progi1984 +- ODPresentation Writer : Support for Pie Chart & Stack Percent Bar Charts - @jrking4 GH-108 +- PowerPoint2007 Writer : Support for Pie Chart & Stack Percent Bar Charts - @jrking4 GH-108 + +### Bugfix +- PSR-0 via composer broken - @Progi1984 GH-51 +- ODPresentation Writer : Title in Legend in chart doesn't displayed - @Progi1984 GH-79 +- ODPresentation Writer : Segments in Pie3D Chart are now in clockwise order, as in PowerPoint2007 Writer - @Progi1984 GH-79 +- ODPresentation Writer : Axis in Line Chart have not tick marks displayed, as in PowerPoint2007 Writer - @Progi1984 GH-79 +- ODPresentation Writer : Shadow don't work for RichTextShapes - @Progi1984 GH-81 +- PowerPoint2007 Writer : Fill don't work for RichTextShapes - @Progi1984 GH-61 +- PowerPoint2007 Writer : Border don't work for RichTextShapes - @Progi1984 GH-61 +- PowerPoint2007 Writer : Hyperlink in table doesn't work - @Progi1984 GH-70 +- PowerPoint2007 Writer : AutoFitNormal works with options (fontScale & lineSpacingReduction) - @Progi1984 @desigennaro GH-71 +- PowerPoint2007 Writer : Shadow don't work for RichTextShapes - @Progi1984 GH-81 +- PowerPoint2007 Writer : Visibility of the Title doesn't work - @Progi1984 GH-107 +- Refactor findLayoutIndex to findLayoutId where it assumes the slideLayout order was sorted. IMPROVED: unit tests - @kenliau GH-95 + +### Miscellaneous +- Improved the sample 04-Table for having a Text Run in a Cell - @Progi1984 GH-84 +- Improved the sample 04-Table for having two links in a Cell - @Progi1984 GH-93 +- Improved the documentation about Table Shapes and cell width - @Progi1984 GH-104 +- Some parts of code shared between PHPOffice projects have been moved to PhpOffice/Common - @Progi1984 +- Refactored the PowerPoint97 Reader for managing the group shape and improving evolutions - @Progi1984 GH-110 +- Added a sample (12) for PowerPoint97 Reader with tree of the PhpPowerPoint object - @Progi1984 GH-110 ## 0.3.0 - 2014-09-22 diff --git a/README.md b/README.md index 27359b299..dd3ffe4d1 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ [![Code Coverage](https://scrutinizer-ci.com/g/PHPOffice/PHPPowerPoint/badges/coverage.png?s=742a98745725c562955440edc8d2c39d7ff5ae25)](https://scrutinizer-ci.com/g/PHPOffice/PHPPowerPoint/) [![Total Downloads](https://poser.pugx.org/phpoffice/phppowerpoint/downloads.png)](https://packagist.org/packages/phpoffice/phppowerpoint) [![License](https://poser.pugx.org/phpoffice/phppowerpoint/license.png)](https://packagist.org/packages/phpoffice/phppowerpoint) +[![Join the chat at https://gitter.im/PHPOffice/PHPPowerPoint](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/PHPOffice/PHPPowerPoint) PHPPowerPoint is a library written in pure PHP that provides a set of classes to write to different presentation file formats, i.e. Microsoft [Office Open XML](http://en.wikipedia.org/wiki/Office_Open_XML) (OOXML or OpenXML) or OASIS [Open Document Format for Office Applications](http://en.wikipedia.org/wiki/OpenDocument) (OpenDocument or ODF). @@ -33,6 +34,7 @@ Read more about PHPPowerPoint: - Supports hyperlinks and rich-text strings - Add images with different styles (positioning, rotation, shadow) - Set printing options (header, footer, page margins, paper size, orientation) +- Set transitions between slides - Output to different file formats: PowerPoint 2007 (.pptx), OpenDocument Presentation (.odp), Serialized Presentation) - ... and lots of other things! diff --git a/VERSION b/VERSION index 341cf11fa..1d0ba9ea1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.0 \ No newline at end of file +0.4.0 diff --git a/composer.json b/composer.json index 02a5b27ea..6e156c85a 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "require": { "php": ">=5.3.0", "ext-xml": "*", - "ext-zip": "*" + "ext-zip": "*", + "phpoffice/common": "0.1.*" }, "require-dev": { "phpunit/phpunit": "3.7.*", @@ -29,15 +30,12 @@ "phpmd/phpmd": "2.*", "sebastian/phpcpd": "2.*", "phploc/phploc": "2.*", - "squizlabs/php_codesniffer": "1.*" + "squizlabs/php_codesniffer": "2.*" }, "suggest": { "ext-gd2": "Required to add images" }, "autoload": { - "psr-0": { - "PHPPowerPoint": "src/" - }, "psr-4": { "PhpOffice\\PhpPowerpoint\\": "src/PhpPowerpoint/" } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index d060f16dd..000000000 --- a/composer.lock +++ /dev/null @@ -1,3535 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "53951d1b3a8e84bcddf6ded82f7dfb46", - "packages": [ - - ], - "packages-dev": [ - { - "name": "cilex/cilex", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/Cilex/Cilex.git", - "reference": "7acd965a609a56d0345e8b6071c261fbdb926cb5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Cilex/Cilex/zipball/7acd965a609a56d0345e8b6071c261fbdb926cb5", - "reference": "7acd965a609a56d0345e8b6071c261fbdb926cb5", - "shasum": "" - }, - "require": { - "cilex/console-service-provider": "1.*", - "php": ">=5.3.3", - "pimple/pimple": "~1.0", - "symfony/finder": "~2.1", - "symfony/process": "~2.1" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*", - "symfony/validator": "~2.1" - }, - "suggest": { - "monolog/monolog": ">=1.0.0", - "symfony/validator": ">=1.0.0", - "symfony/yaml": ">=1.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "Cilex": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "description": "The PHP micro-framework for Command line tools based on the Symfony2 Components", - "homepage": "http://cilex.github.com", - "keywords": [ - "cli", - "microframework" - ], - "time": "2014-03-29 14:03:13" - }, - { - "name": "cilex/console-service-provider", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/Cilex/console-service-provider.git", - "reference": "25ee3d1875243d38e1a3448ff94bdf944f70d24e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Cilex/console-service-provider/zipball/25ee3d1875243d38e1a3448ff94bdf944f70d24e", - "reference": "25ee3d1875243d38e1a3448ff94bdf944f70d24e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "pimple/pimple": "1.*@dev", - "symfony/console": "~2.1" - }, - "require-dev": { - "cilex/cilex": "1.*@dev", - "silex/silex": "1.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "Cilex\\Provider\\Console": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" - }, - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "description": "Console Service Provider", - "keywords": [ - "cilex", - "console", - "pimple", - "service-provider", - "silex" - ], - "time": "2012-12-19 10:50:58" - }, - { - "name": "doctrine/annotations", - "version": "v1.1.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "40db0c96985aab2822edbc4848b3bd2429e02670" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/40db0c96985aab2822edbc4848b3bd2429e02670", - "reference": "40db0c96985aab2822edbc4848b3bd2429e02670", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "php": ">=5.3.2" - }, - "require-dev": { - "doctrine/cache": "1.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Annotations\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan H. Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/", - "role": "Creator" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2013-06-16 21:33:03" - }, - { - "name": "doctrine/lexer", - "version": "v1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "2f708a85bb3aab5d99dab8be435abd73e0b18acb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/2f708a85bb3aab5d99dab8be435abd73e0b18acb", - "reference": "2f708a85bb3aab5d99dab8be435abd73e0b18acb", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "lexer", - "parser" - ], - "time": "2013-01-12 18:59:04" - }, - { - "name": "dompdf/dompdf", - "version": "v0.6.1", - "source": { - "type": "git", - "url": "https://github.com/dompdf/dompdf.git", - "reference": "cf7d8a0a27270418850cc7d7ea532159e5eeb3eb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dompdf/dompdf/zipball/cf7d8a0a27270418850cc7d7ea532159e5eeb3eb", - "reference": "cf7d8a0a27270418850cc7d7ea532159e5eeb3eb", - "shasum": "" - }, - "require": { - "phenx/php-font-lib": "0.2.*" - }, - "type": "library", - "autoload": { - "classmap": [ - "include/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL" - ], - "authors": [ - { - "name": "Fabien Ménager", - "email": "fabien.menager@gmail.com" - }, - { - "name": "Brian Sweeney", - "email": "eclecticgeek@gmail.com" - } - ], - "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", - "homepage": "https://github.com/dompdf/dompdf", - "time": "2014-03-11 01:59:52" - }, - { - "name": "erusev/parsedown", - "version": "0.9.4", - "source": { - "type": "git", - "url": "https://github.com/erusev/parsedown.git", - "reference": "d29ff18299210b52a75a631a70963e7c8b35b04f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown/zipball/d29ff18299210b52a75a631a70963e7c8b35b04f", - "reference": "d29ff18299210b52a75a631a70963e7c8b35b04f", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Parsedown": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Emanuil Rusev", - "email": "hello@erusev.com", - "homepage": "http://erusev.com" - } - ], - "description": "Parser for Markdown.", - "homepage": "http://parsedown.org", - "keywords": [ - "markdown", - "parser" - ], - "time": "2014-02-06 12:16:14" - }, - { - "name": "jms/metadata", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/metadata.git", - "reference": "88ffa28bc987e4c26229fc84a2e541b6ed4e1459" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/88ffa28bc987e4c26229fc84a2e541b6ed4e1459", - "reference": "88ffa28bc987e4c26229fc84a2e541b6ed4e1459", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "doctrine/cache": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5.x-dev" - } - }, - "autoload": { - "psr-0": { - "Metadata\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Class/method/property metadata management in PHP", - "keywords": [ - "annotations", - "metadata", - "xml", - "yaml" - ], - "time": "2013-11-05 23:02:36" - }, - { - "name": "jms/parser-lib", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/parser-lib.git", - "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/parser-lib/zipball/c509473bc1b4866415627af0e1c6cc8ac97fa51d", - "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d", - "shasum": "" - }, - "require": { - "phpoption/phpoption": ">=0.9,<2.0-dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "JMS\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache2" - ], - "description": "A library for easily creating recursive-descent parsers.", - "time": "2012-11-18 18:08:43" - }, - { - "name": "jms/serializer", - "version": "0.16.0", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/serializer.git", - "reference": "c8a171357ca92b6706e395c757f334902d430ea9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/c8a171357ca92b6706e395c757f334902d430ea9", - "reference": "c8a171357ca92b6706e395c757f334902d430ea9", - "shasum": "" - }, - "require": { - "doctrine/annotations": "1.*", - "jms/metadata": "~1.1", - "jms/parser-lib": "1.*", - "php": ">=5.3.2", - "phpcollection/phpcollection": "~0.1" - }, - "require-dev": { - "doctrine/orm": "~2.1", - "doctrine/phpcr-odm": "~1.0.1", - "jackalope/jackalope-doctrine-dbal": "1.0.*", - "propel/propel1": "~1.7", - "symfony/filesystem": "2.*", - "symfony/form": "~2.1", - "symfony/translation": "~2.0", - "symfony/validator": "~2.0", - "symfony/yaml": "2.*", - "twig/twig": ">=1.8,<2.0-dev" - }, - "suggest": { - "symfony/yaml": "Required if you'd like to serialize data to YAML format." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.15-dev" - } - }, - "autoload": { - "psr-0": { - "JMS\\Serializer": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache2" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.", - "homepage": "http://jmsyst.com/libs/serializer", - "keywords": [ - "deserialization", - "jaxb", - "json", - "serialization", - "xml" - ], - "time": "2014-03-18 08:39:00" - }, - { - "name": "knplabs/knp-menu", - "version": "v1.1.2", - "source": { - "type": "git", - "url": "https://github.com/KnpLabs/KnpMenu.git", - "reference": "f8e867268f63f561c1adadd6cbb5d8524f921873" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/KnpLabs/KnpMenu/zipball/f8e867268f63f561c1adadd6cbb5d8524f921873", - "reference": "f8e867268f63f561c1adadd6cbb5d8524f921873", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "pimple/pimple": "*", - "silex/silex": "1.0.*", - "twig/twig": ">=1.2,<2.0-dev" - }, - "suggest": { - "pimple/pimple": "for the built-in implementations of the menu provider and renderer provider", - "silex/silex": "for the integration with your silex application", - "twig/twig": "for the TwigRenderer and the integration with your templates" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-0": { - "Knp\\Menu\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christophe Coevoet", - "email": "stof@notk.org" - }, - { - "name": "KnpLabs", - "homepage": "http://knplabs.com" - }, - { - "name": "Symfony Community", - "homepage": "https://github.com/KnpLabs/KnpMenu/contributors" - } - ], - "description": "An object oriented menu library", - "homepage": "http://knplabs.com", - "keywords": [ - "menu", - "tree" - ], - "time": "2012-06-10 16:20:40" - }, - { - "name": "monolog/monolog", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "25b16e801979098cb2f120e697bfce454b18bf23" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/25b16e801979098cb2f120e697bfce454b18bf23", - "reference": "25b16e801979098cb2f120e697bfce454b18bf23", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "psr/log": "~1.0" - }, - "require-dev": { - "aws/aws-sdk-php": "~2.4, >2.4.8", - "doctrine/couchdb": "~1.0@dev", - "graylog2/gelf-php": "~1.0", - "phpunit/phpunit": "~3.7.0", - "raven/raven": "~0.5", - "ruflin/elastica": "0.90.*" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-mongo": "Allow sending log messages to a MongoDB server", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "raven/raven": "Allow sending log messages to a Sentry server", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, - "autoload": { - "psr-4": { - "Monolog\\": "src/Monolog" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be", - "role": "Developer" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "time": "2014-06-04 16:30:04" - }, - { - "name": "nikic/php-parser", - "version": "v0.9.4", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1e5e280ae88a27effa2ae4aa2bd088494ed8594f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1e5e280ae88a27effa2ae4aa2bd088494ed8594f", - "reference": "1e5e280ae88a27effa2ae4aa2bd088494ed8594f", - "shasum": "" - }, - "require": { - "php": ">=5.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9-dev" - } - }, - "autoload": { - "psr-0": { - "PHPParser": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "time": "2013-08-25 17:11:40" - }, - { - "name": "pdepend/pdepend", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/pdepend/pdepend.git", - "reference": "b74f2bb68e86104cd97dfb8d74209692c9b465ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/b74f2bb68e86104cd97dfb8d74209692c9b465ce", - "reference": "b74f2bb68e86104cd97dfb8d74209692c9b465ce", - "shasum": "" - }, - "require": { - "symfony/config": "@stable", - "symfony/dependency-injection": "@stable", - "symfony/filesystem": "@stable" - }, - "require-dev": { - "phpunit/phpunit": "3.*@stable", - "squizlabs/php_codesniffer": "@stable" - }, - "bin": [ - "src/bin/pdepend" - ], - "type": "library", - "autoload": { - "psr-0": { - "PDepend\\": "src/main/php/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Official version of pdepend to be handled with Composer", - "time": "2014-05-21 09:48:10" - }, - { - "name": "phenx/php-font-lib", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/PhenX/php-font-lib.git", - "reference": "c30c7fc00a6b0d863e9bb4c5d5dd015298b2dc82" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PhenX/php-font-lib/zipball/c30c7fc00a6b0d863e9bb4c5d5dd015298b2dc82", - "reference": "c30c7fc00a6b0d863e9bb4c5d5dd015298b2dc82", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "classes/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL" - ], - "authors": [ - { - "name": "Fabien Ménager", - "email": "fabien.menager@gmail.com" - } - ], - "description": "A library to read, parse, export and make subsets of different types of font files.", - "homepage": "https://github.com/PhenX/php-font-lib", - "time": "2014-02-01 15:22:28" - }, - { - "name": "phpcollection/phpcollection", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-collection.git", - "reference": "b8bf55a0a929ca43b01232b36719f176f86c7e83" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-collection/zipball/b8bf55a0a929ca43b01232b36719f176f86c7e83", - "reference": "b8bf55a0a929ca43b01232b36719f176f86c7e83", - "shasum": "" - }, - "require": { - "phpoption/phpoption": "1.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.3-dev" - } - }, - "autoload": { - "psr-0": { - "PhpCollection": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache2" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "General-Purpose Collection Library for PHP", - "keywords": [ - "collection", - "list", - "map", - "sequence", - "set" - ], - "time": "2014-03-11 13:46:42" - }, - { - "name": "phpdocumentor/fileset", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/Fileset.git", - "reference": "bfa78d8fa9763dfce6d0e5d3730c1d8ab25d34b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/Fileset/zipball/bfa78d8fa9763dfce6d0e5d3730c1d8ab25d34b0", - "reference": "bfa78d8fa9763dfce6d0e5d3730c1d8ab25d34b0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/finder": "~2.1" - }, - "require-dev": { - "phpunit/phpunit": "~3.7" - }, - "type": "library", - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/", - "tests/unit/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Fileset component for collecting a set of files given directories and file paths", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "files", - "fileset", - "phpdoc" - ], - "time": "2013-08-06 21:07:42" - }, - { - "name": "phpdocumentor/graphviz", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/GraphViz.git", - "reference": "13595130b9bc185109f40f1b70f0b231f490f5fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/GraphViz/zipball/13595130b9bc185109f40f1b70f0b231f490f5fc", - "reference": "13595130b9bc185109f40f1b70f0b231f490f5fc", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~3.7" - }, - "type": "library", - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/", - "tests/unit" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2014-02-26 17:45:01" - }, - { - "name": "phpdocumentor/phpdocumentor", - "version": "v2.5.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/phpDocumentor2.git", - "reference": "bf9fa40f6d00412410025b2e16eb16c315eb0216" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/phpDocumentor2/zipball/bf9fa40f6d00412410025b2e16eb16c315eb0216", - "reference": "bf9fa40f6d00412410025b2e16eb16c315eb0216", - "shasum": "" - }, - "require": { - "cilex/cilex": "~1.0", - "dompdf/dompdf": "~0.6", - "erusev/parsedown": "~0.7", - "jms/serializer": "~0.12", - "knplabs/knp-menu": "~1.1", - "monolog/monolog": "~1.6", - "php": ">=5.3.3", - "phpdocumentor/fileset": "~1.0", - "phpdocumentor/graphviz": "~1.0", - "phpdocumentor/reflection": "~1.0", - "phpdocumentor/reflection-docblock": "~2.0", - "phpdocumentor/template-abstract": "~1.2", - "phpdocumentor/template-checkstyle": "~1.2", - "phpdocumentor/template-clean": "~1.0", - "phpdocumentor/template-new-black": "~1.3", - "phpdocumentor/template-old-ocean": "~1.3", - "phpdocumentor/template-responsive": "~1.3", - "phpdocumentor/template-responsive-twig": "~1.2", - "phpdocumentor/template-xml": "~1.0", - "phpdocumentor/template-zend": "~1.3", - "symfony/config": "~2.3", - "symfony/console": "~2.3", - "symfony/event-dispatcher": "~2.1", - "symfony/process": "~2.0", - "symfony/stopwatch": "~2.3", - "symfony/validator": "~2.2", - "twig/twig": "~1.3", - "zendframework/zend-cache": "2.1.*", - "zendframework/zend-config": "2.1.*", - "zendframework/zend-filter": "2.1.*", - "zendframework/zend-i18n": "2.1.*", - "zendframework/zend-serializer": "2.1.*", - "zendframework/zend-servicemanager": "2.1.*", - "zendframework/zend-stdlib": "2.1.*", - "zetacomponents/document": ">=1.3.1" - }, - "require-dev": { - "behat/behat": "~2.4", - "mikey179/vfsstream": "~1.2", - "mockery/mockery": ">=0.8.0", - "phpunit/phpunit": "~3.7", - "squizlabs/php_codesniffer": "~1.4", - "symfony/expression-language": "~2.4" - }, - "suggest": { - "ext-twig": "Enabling the twig extension improves the generation of twig based templates.", - "ext-xslcache": "Enabling the XSLCache extension improves the generation of xml based templates." - }, - "bin": [ - "bin/phpdoc.php", - "bin/phpdoc" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/", - "tests/unit/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Documentation Generator for PHP", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "api", - "application", - "dga", - "documentation", - "phpdoc" - ], - "time": "2014-05-17 12:25:35" - }, - { - "name": "phpdocumentor/reflection", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/Reflection.git", - "reference": "df82db631acd60739c8796b3c6d5e4da970808f3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/df82db631acd60739c8796b3c6d5e4da970808f3", - "reference": "df82db631acd60739c8796b3c6d5e4da970808f3", - "shasum": "" - }, - "require": { - "nikic/php-parser": "0.9.4", - "php": ">=5.3.3", - "phpdocumentor/reflection-docblock": "2.*", - "psr/log": "~1.0" - }, - "require-dev": { - "behat/behat": "~2.4", - "mockery/mockery": ">=0.7.0", - "phpunit/phpunit": "~3.7" - }, - "type": "library", - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/", - "tests/unit/", - "tests/mocks/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Reflection library to do Static Analysis for PHP Projects", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2014-03-28 11:20:22" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "0bca477a34baea39add016af90046f002a175619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/0bca477a34baea39add016af90046f002a175619", - "reference": "0bca477a34baea39add016af90046f002a175619", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*@stable" - }, - "suggest": { - "dflydev/markdown": "1.0.*", - "erusev/parsedown": "~0.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2014-03-28 09:21:30" - }, - { - "name": "phpdocumentor/template-abstract", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/template.abstract.git", - "reference": "43fa2db351d7a150803397721e778f9dd8a20b47" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/template.abstract/zipball/43fa2db351d7a150803397721e778f9dd8a20b47", - "reference": "43fa2db351d7a150803397721e778f9dd8a20b47", - "shasum": "" - }, - "require": { - "ext-xsl": "*", - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Simple bright template for phpDocumentor", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "documentation", - "phpdoc", - "template" - ], - "time": "2013-08-02 06:11:13" - }, - { - "name": "phpdocumentor/template-checkstyle", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/template.checkstyle.git", - "reference": "22a45684e737c8c3ec3f1a12edb7743b7a82ac8b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/template.checkstyle/zipball/22a45684e737c8c3ec3f1a12edb7743b7a82ac8b", - "reference": "22a45684e737c8c3ec3f1a12edb7743b7a82ac8b", - "shasum": "" - }, - "require": { - "ext-xsl": "*", - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Checkstyle XML output template for phpDocumentor2", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "documentation", - "phpdoc", - "template" - ], - "time": "2013-08-01 19:43:19" - }, - { - "name": "phpdocumentor/template-clean", - "version": "1.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/template.clean.git", - "reference": "78f2048c5ecd62f0b79dbac093687d78a66d1806" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/template.clean/zipball/78f2048c5ecd62f0b79dbac093687d78a66d1806", - "reference": "78f2048c5ecd62f0b79dbac093687d78a66d1806", - "shasum": "" - }, - "require": { - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A clean, responsive modern template for phpDocumentor for Twig aimed at usability", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "documentation", - "phpdoc", - "responsive", - "template" - ], - "time": "2014-03-29 08:22:15" - }, - { - "name": "phpdocumentor/template-new-black", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/template.new_black.git", - "reference": "be38beba2b2674be292f32f88efe8a60c658a139" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/template.new_black/zipball/be38beba2b2674be292f32f88efe8a60c658a139", - "reference": "be38beba2b2674be292f32f88efe8a60c658a139", - "shasum": "" - }, - "require": { - "ext-xsl": "*", - "phpdocumentor/template-abstract": "1.*", - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Web 2.0 template with dark sidebar for phpDocumentor", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "documentation", - "phpdoc", - "template" - ], - "time": "2013-08-02 06:16:30" - }, - { - "name": "phpdocumentor/template-old-ocean", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/template.old_ocean.git", - "reference": "3a0e2bcced4045a694d53b4607aad04e99d78489" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/template.old_ocean/zipball/3a0e2bcced4045a694d53b4607aad04e99d78489", - "reference": "3a0e2bcced4045a694d53b4607aad04e99d78489", - "shasum": "" - }, - "require": { - "ext-xsl": "*", - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Blue template with high contrast for the foreground", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "documentation", - "phpdoc", - "template" - ], - "time": "2013-08-02 06:21:07" - }, - { - "name": "phpdocumentor/template-responsive", - "version": "1.3.3", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/template.responsive.git", - "reference": "26f895a2ed3148e1686ae4d802f65a3ef04c04e1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/template.responsive/zipball/26f895a2ed3148e1686ae4d802f65a3ef04c04e1", - "reference": "26f895a2ed3148e1686ae4d802f65a3ef04c04e1", - "shasum": "" - }, - "require": { - "ext-xsl": "*", - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Responsive modern template for phpDocumentor", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "documentation", - "phpdoc", - "template" - ], - "time": "2014-03-29 08:55:54" - }, - { - "name": "phpdocumentor/template-responsive-twig", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/template.responsive-twig.git", - "reference": "cd6d82be6a4626d865fd01d40aad170cea08db0a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/template.responsive-twig/zipball/cd6d82be6a4626d865fd01d40aad170cea08db0a", - "reference": "cd6d82be6a4626d865fd01d40aad170cea08db0a", - "shasum": "" - }, - "require": { - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Responsive modern template for phpDocumentor for Twig", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "documentation", - "phpdoc", - "template" - ], - "time": "2014-03-30 21:02:00" - }, - { - "name": "phpdocumentor/template-xml", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/mvriel/template.xml.git", - "reference": "a372713be8ee99b16497e2580592e474ff51190c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mvriel/template.xml/zipball/a372713be8ee99b16497e2580592e474ff51190c", - "reference": "a372713be8ee99b16497e2580592e474ff51190c", - "shasum": "" - }, - "require": { - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Generates an XML representation of the project's structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "documentation", - "phpdoc", - "template" - ], - "time": "2013-08-01 20:23:32" - }, - { - "name": "phpdocumentor/template-zend", - "version": "1.3.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/template.zend.git", - "reference": "75913288bfd73d3bf4c1b1179c3963f3431e7a9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/template.zend/zipball/75913288bfd73d3bf4c1b1179c3963f3431e7a9d", - "reference": "75913288bfd73d3bf4c1b1179c3963f3431e7a9d", - "shasum": "" - }, - "require": { - "ext-xsl": "*", - "phpdocumentor/template-abstract": "1.*", - "phpdocumentor/unified-asset-installer": "~1.1" - }, - "type": "phpdocumentor-template", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Official Zend Framework Template for phpDocumentor2", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "ZendFramework", - "documentation", - "phpdoc", - "template", - "zend", - "zf" - ], - "time": "2013-12-05 08:51:57" - }, - { - "name": "phpdocumentor/unified-asset-installer", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/UnifiedAssetInstaller.git", - "reference": "241fb036268cd9da7d76da3db66e3eda66259c52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/UnifiedAssetInstaller/zipball/241fb036268cd9da7d76da3db66e3eda66259c52", - "reference": "241fb036268cd9da7d76da3db66e3eda66259c52", - "shasum": "" - }, - "require": { - "composer-plugin-api": "1.0.0" - }, - "require-dev": { - "composer/composer": "~1.0@dev", - "phpunit/phpunit": "~3.7" - }, - "type": "composer-installer", - "extra": { - "class": "\\phpDocumentor\\Composer\\UnifiedAssetInstaller" - }, - "autoload": { - "psr-0": { - "phpDocumentor\\Composer": [ - "src/", - "test/unit/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Asset installer for phpDocumentor", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "assets", - "installer", - "plugins", - "templates" - ], - "time": "2013-09-09 06:13:02" - }, - { - "name": "phploc/phploc", - "version": "2.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phploc.git", - "reference": "d177c22e2a08e448f7bdfa762045f7bd086834d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/d177c22e2a08e448f7bdfa762045f7bd086834d7", - "reference": "d177c22e2a08e448f7bdfa762045f7bd086834d7", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/finder-facade": ">=1.1.0", - "sebastian/git": ">=1.0.0", - "sebastian/version": ">=1.0.3", - "symfony/console": ">=2.2.0" - }, - "bin": [ - "phploc" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "A tool for quickly measuring the size of a PHP project.", - "homepage": "https://github.com/sebastianbergmann/phploc", - "time": "2014-04-27 06:47:27" - }, - { - "name": "phpmd/phpmd", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpmd/phpmd.git", - "reference": "68ced5452910d3555a38720bd87f5f2356c5a003" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/68ced5452910d3555a38720bd87f5f2356c5a003", - "reference": "68ced5452910d3555a38720bd87f5f2356c5a003", - "shasum": "" - }, - "require": { - "pdepend/pdepend": "2.0.*", - "php": ">=5.3.0", - "symfony/config": "@stable", - "symfony/dependency-injection": "@stable", - "symfony/filesystem": "@stable" - }, - "bin": [ - "src/bin/phpmd" - ], - "type": "library", - "autoload": { - "psr-0": { - "PHPMD\\": "src/main/php", - "PDepend\\": "vendor/pdepend/pdepend/src/main/php/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "../../pdepend/pdepend/src/main/php", - "src/main/php" - ], - "license": [ - "BSD-3-Clause" - ], - "description": "Official version of PHPMD handled with Composer.", - "time": "2014-05-21 12:45:23" - }, - { - "name": "phpoption/phpoption", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "5d099bcf0393908bf4ad69cc47dafb785d51f7f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/5d099bcf0393908bf4ad69cc47dafb785d51f7f5", - "reference": "5d099bcf0393908bf4ad69cc47dafb785d51f7f5", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-0": { - "PhpOption\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache2" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Option Type for PHP", - "keywords": [ - "language", - "option", - "php", - "type" - ], - "time": "2014-01-09 22:37:17" - }, - { - "name": "phpunit/php-code-coverage", - "version": "1.2.17", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6ef2bf3a1c47eca07ea95f0d8a902a6340390b34", - "reference": "6ef2bf3a1c47eca07ea95f0d8a902a6340390b34", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": ">=1.3.0@stable", - "phpunit/php-text-template": ">=1.2.0@stable", - "phpunit/php-token-stream": ">=1.1.3@stable" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*@dev" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.0.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2014-03-28 10:53:45" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.3.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "File/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2013-10-10 15:34:57" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "Text/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2014-01-30 17:20:04" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2013-08-02 07:42:54" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2014-03-03 05:10:30" - }, - { - "name": "phpunit/phpunit", - "version": "3.7.37", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ae6cefd7cc84586a5ef27e04bae11ee940ec63dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ae6cefd7cc84586a5ef27e04bae11ee940ec63dc", - "reference": "ae6cefd7cc84586a5ef27e04bae11ee940ec63dc", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpunit/php-code-coverage": "~1.2", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.1", - "phpunit/php-timer": "~1.0", - "phpunit/phpunit-mock-objects": "~1.2", - "symfony/yaml": "~2.0" - }, - "require-dev": { - "pear-pear.php.net/pear": "1.9.4" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "composer/bin/phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.7.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2014-04-30 12:24:19" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5794e3c5c5ba0fb037b11d8151add2a07fa82875", - "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-text-template": ">=1.1.1@stable" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2013-01-13 10:24:48" - }, - { - "name": "pimple/pimple", - "version": "v1.1.1", - "source": { - "type": "git", - "url": "https://github.com/fabpot/Pimple.git", - "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fabpot/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d", - "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-0": { - "Pimple": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - } - ], - "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", - "homepage": "http://pimple.sensiolabs.org", - "keywords": [ - "container", - "dependency injection" - ], - "time": "2013-11-22 08:30:29" - }, - { - "name": "psr/log", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Psr\\Log\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2012-12-21 11:40:51" - }, - { - "name": "sebastian/finder-facade", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/finder-facade.git", - "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/1e396fda3449fce9df032749fa4fa2619e0347e0", - "reference": "1e396fda3449fce9df032749fa4fa2619e0347e0", - "shasum": "" - }, - "require": { - "symfony/finder": ">=2.2.0", - "theseer/fdomdocument": ">=1.3.1" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", - "homepage": "https://github.com/sebastianbergmann/finder-facade", - "time": "2013-05-28 06:10:03" - }, - { - "name": "sebastian/git", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/git.git", - "reference": "572c35353fefcc8607d6fef0e362a9f3a5e84d96" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/git/zipball/572c35353fefcc8607d6fef0e362a9f3a5e84d96", - "reference": "572c35353fefcc8607d6fef0e362a9f3a5e84d96", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple wrapper for Git", - "homepage": "http://www.github.com/sebastianbergmann/git", - "keywords": [ - "git" - ], - "time": "2014-06-14 07:12:53" - }, - { - "name": "sebastian/phpcpd", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpcpd.git", - "reference": "a9462153f2dd90466a010179901d31fbff598365" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/a9462153f2dd90466a010179901d31fbff598365", - "reference": "a9462153f2dd90466a010179901d31fbff598365", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-timer": ">=1.0.4", - "sebastian/finder-facade": ">=1.1.0", - "sebastian/version": ">=1.0.3", - "symfony/console": ">=2.2.0", - "theseer/fdomdocument": "~1.4" - }, - "bin": [ - "phpcpd" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Copy/Paste Detector (CPD) for PHP code.", - "homepage": "https://github.com/sebastianbergmann/phpcpd", - "time": "2014-03-31 09:25:30" - }, - { - "name": "sebastian/version", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2014-03-07 15:35:33" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "1.5.3", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "396178ada8499ec492363587f037125bf7b07fcc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/396178ada8499ec492363587f037125bf7b07fcc", - "reference": "396178ada8499ec492363587f037125bf7b07fcc", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.1.2" - }, - "suggest": { - "phpunit/php-timer": "dev-master" - }, - "bin": [ - "scripts/phpcs" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-phpcs-fixer": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "CodeSniffer.php", - "CodeSniffer/CLI.php", - "CodeSniffer/Exception.php", - "CodeSniffer/File.php", - "CodeSniffer/Report.php", - "CodeSniffer/Reporting.php", - "CodeSniffer/Sniff.php", - "CodeSniffer/Tokens.php", - "CodeSniffer/Reports/", - "CodeSniffer/CommentParser/", - "CodeSniffer/Tokenizers/", - "CodeSniffer/DocGenerators/", - "CodeSniffer/Standards/AbstractPatternSniff.php", - "CodeSniffer/Standards/AbstractScopeSniff.php", - "CodeSniffer/Standards/AbstractVariableSniff.php", - "CodeSniffer/Standards/IncorrectPatternException.php", - "CodeSniffer/Standards/Generic/Sniffs/", - "CodeSniffer/Standards/MySource/Sniffs/", - "CodeSniffer/Standards/PEAR/Sniffs/", - "CodeSniffer/Standards/PSR1/Sniffs/", - "CodeSniffer/Standards/PSR2/Sniffs/", - "CodeSniffer/Standards/Squiz/Sniffs/", - "CodeSniffer/Standards/Zend/Sniffs/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenises PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2014-05-01 03:07:07" - }, - { - "name": "symfony/config", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Config", - "source": { - "type": "git", - "url": "https://github.com/symfony/Config.git", - "reference": "9c8caadb38ecc69ac35ab31af4d1996944b5a09f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/9c8caadb38ecc69ac35ab31af4d1996944b5a09f", - "reference": "9c8caadb38ecc69ac35ab31af4d1996944b5a09f", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/filesystem": "~2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Config\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Config Component", - "homepage": "http://symfony.com", - "time": "2014-04-22 08:11:23" - }, - { - "name": "symfony/console", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Console", - "source": { - "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "ef4ca73b0b3a10cbac653d3ca482d0cdd4502b2c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/ef4ca73b0b3a10cbac653d3ca482d0cdd4502b2c", - "reference": "ef4ca73b0b3a10cbac653d3ca482d0cdd4502b2c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Console\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "http://symfony.com", - "time": "2014-05-22 08:54:24" - }, - { - "name": "symfony/dependency-injection", - "version": "v2.5.0", - "target-dir": "Symfony/Component/DependencyInjection", - "source": { - "type": "git", - "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "5dfb4c2b74c4976efe1efa783370da656a2dd742" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/5dfb4c2b74c4976efe1efa783370da656a2dd742", - "reference": "5dfb4c2b74c4976efe1efa783370da656a2dd742", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/config": "~2.2", - "symfony/expression-language": "~2.4", - "symfony/yaml": "~2.0" - }, - "suggest": { - "symfony/config": "", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\DependencyInjection\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony DependencyInjection Component", - "homepage": "http://symfony.com", - "time": "2014-05-12 09:28:39" - }, - { - "name": "symfony/event-dispatcher", - "version": "v2.5.0", - "target-dir": "Symfony/Component/EventDispatcher", - "source": { - "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "cb62ec8dd05893fc8e4f0e6e21e326e1fc731fe8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/cb62ec8dd05893fc8e4f0e6e21e326e1fc731fe8", - "reference": "cb62ec8dd05893fc8e4f0e6e21e326e1fc731fe8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.0", - "symfony/dependency-injection": "~2.0", - "symfony/stopwatch": "~2.2" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\EventDispatcher\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com", - "time": "2014-04-29 10:13:57" - }, - { - "name": "symfony/filesystem", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Filesystem", - "source": { - "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "98e831eac836a0a5911626ce82684155f21d0e4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/98e831eac836a0a5911626ce82684155f21d0e4d", - "reference": "98e831eac836a0a5911626ce82684155f21d0e4d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Filesystem\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "http://symfony.com", - "time": "2014-04-16 10:36:21" - }, - { - "name": "symfony/finder", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Finder", - "source": { - "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "307aad2c541bbdf43183043645e186ef2cd6b973" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/307aad2c541bbdf43183043645e186ef2cd6b973", - "reference": "307aad2c541bbdf43183043645e186ef2cd6b973", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Finder\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "http://symfony.com", - "time": "2014-05-22 13:47:45" - }, - { - "name": "symfony/process", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Process", - "source": { - "type": "git", - "url": "https://github.com/symfony/Process.git", - "reference": "5d7d78e23894544740219e006320678cfa4cd45b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/5d7d78e23894544740219e006320678cfa4cd45b", - "reference": "5d7d78e23894544740219e006320678cfa4cd45b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Process\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Process Component", - "homepage": "http://symfony.com", - "time": "2014-05-23 09:02:52" - }, - { - "name": "symfony/stopwatch", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Stopwatch", - "source": { - "type": "git", - "url": "https://github.com/symfony/Stopwatch.git", - "reference": "724d73604ebe6c1c9bdf36533b556123bd9075a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/724d73604ebe6c1c9bdf36533b556123bd9075a1", - "reference": "724d73604ebe6c1c9bdf36533b556123bd9075a1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Stopwatch\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Stopwatch Component", - "homepage": "http://symfony.com", - "time": "2014-04-18 20:40:13" - }, - { - "name": "symfony/translation", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Translation", - "source": { - "type": "git", - "url": "https://github.com/symfony/Translation.git", - "reference": "5f23265dcf8927a84be832608069c9edca3cf5f4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/5f23265dcf8927a84be832608069c9edca3cf5f4", - "reference": "5f23265dcf8927a84be832608069c9edca3cf5f4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/config": "~2.0", - "symfony/yaml": "~2.2" - }, - "suggest": { - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Translation\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Translation Component", - "homepage": "http://symfony.com", - "time": "2014-05-22 13:47:45" - }, - { - "name": "symfony/validator", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Validator", - "source": { - "type": "git", - "url": "https://github.com/symfony/Validator.git", - "reference": "62f6f7735fbd3897b9347ae60fda4a40d0122640" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/62f6f7735fbd3897b9347ae60fda4a40d0122640", - "reference": "62f6f7735fbd3897b9347ae60fda4a40d0122640", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/translation": "~2.0" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0", - "egulias/email-validator": "~1.0", - "symfony/config": "~2.2", - "symfony/expression-language": "~2.4", - "symfony/http-foundation": "~2.1", - "symfony/intl": "~2.3", - "symfony/property-access": "~2.2", - "symfony/yaml": "~2.0" - }, - "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", - "egulias/email-validator": "Strict (RFC compliant) email validation", - "symfony/config": "", - "symfony/expression-language": "For using the 2.4 Expression validator", - "symfony/http-foundation": "", - "symfony/intl": "", - "symfony/property-access": "For using the 2.4 Validator API", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Validator\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Validator Component", - "homepage": "http://symfony.com", - "time": "2014-05-31 02:02:56" - }, - { - "name": "symfony/yaml", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Yaml", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "b4b09c68ec2f2727574544ef0173684281a5033c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/b4b09c68ec2f2727574544ef0173684281a5033c", - "reference": "b4b09c68ec2f2727574544ef0173684281a5033c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2014-05-16 14:25:18" - }, - { - "name": "theseer/fdomdocument", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/fDOMDocument.git", - "reference": "137aa3b13bef05b4e301899cbabdaf7d501847d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/137aa3b13bef05b4e301899cbabdaf7d501847d2", - "reference": "137aa3b13bef05b4e301899cbabdaf7d501847d2", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "lib-libxml": "*", - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "lead" - } - ], - "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", - "homepage": "https://github.com/theseer/fDOMDocument", - "time": "2014-02-19 00:20:43" - }, - { - "name": "twig/twig", - "version": "v1.15.1", - "source": { - "type": "git", - "url": "https://github.com/fabpot/Twig.git", - "reference": "1fb5784662f438d7d96a541e305e28b812e2eeed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fabpot/Twig/zipball/1fb5784662f438d7d96a541e305e28b812e2eeed", - "reference": "1fb5784662f438d7d96a541e305e28b812e2eeed", - "shasum": "" - }, - "require": { - "php": ">=5.2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15-dev" - } - }, - "autoload": { - "psr-0": { - "Twig_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - }, - { - "name": "Twig Team", - "homepage": "https://github.com/fabpot/Twig/graphs/contributors", - "role": "Contributors" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", - "keywords": [ - "templating" - ], - "time": "2014-02-13 10:19:29" - }, - { - "name": "zendframework/zend-cache", - "version": "2.1.6", - "target-dir": "Zend/Cache", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendCache.git", - "reference": "560355160f06cdc3ef549a7eef843af3bead7e39" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendCache/zipball/560355160f06cdc3ef549a7eef843af3bead7e39", - "reference": "560355160f06cdc3ef549a7eef843af3bead7e39", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "zendframework/zend-eventmanager": "self.version", - "zendframework/zend-servicemanager": "self.version", - "zendframework/zend-stdlib": "self.version" - }, - "require-dev": { - "zendframework/zend-serializer": "self.version" - }, - "suggest": { - "ext-apc": "APC >= 3.1.6 to use the APC storage adapter", - "ext-dba": "DBA, to use the DBA storage adapter", - "ext-memcached": "Memcached >= 1.0.0 to use the Memcached storage adapter", - "ext-wincache": "WinCache, to use the WinCache storage adapter", - "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-session": "Zend\\Session component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\Cache\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides a generic way to cache any data", - "keywords": [ - "cache", - "zf2" - ], - "time": "2014-03-03 23:00:17" - }, - { - "name": "zendframework/zend-config", - "version": "2.1.6", - "target-dir": "Zend/Config", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendConfig.git", - "reference": "a31c3980cf7ec88418a931e9cf4ba21079f47a08" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendConfig/zipball/a31c3980cf7ec88418a931e9cf4ba21079f47a08", - "reference": "a31c3980cf7ec88418a931e9cf4ba21079f47a08", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "zendframework/zend-stdlib": "self.version" - }, - "suggest": { - "zendframework/zend-json": "Zend\\Json to use the Json reader or writer classes", - "zendframework/zend-servicemanager": "Zend\\ServiceManager for use with the Config Factory to retrieve reader and writer instances" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\Config\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides a nested object property based user interface for accessing this configuration data within application code", - "keywords": [ - "config", - "zf2" - ], - "time": "2014-01-02 18:00:10" - }, - { - "name": "zendframework/zend-eventmanager", - "version": "2.1.6", - "target-dir": "Zend/EventManager", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendEventManager.git", - "reference": "89368704bb37303fba64c3ddd6bce0506aa7187c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendEventManager/zipball/89368704bb37303fba64c3ddd6bce0506aa7187c", - "reference": "89368704bb37303fba64c3ddd6bce0506aa7187c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "zendframework/zend-stdlib": "self.version" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\EventManager\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "keywords": [ - "eventmanager", - "zf2" - ], - "time": "2014-01-04 13:00:14" - }, - { - "name": "zendframework/zend-filter", - "version": "2.1.6", - "target-dir": "Zend/Filter", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendFilter.git", - "reference": "8ceece474b29d079e86976dbd3efffe6064b3d72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendFilter/zipball/8ceece474b29d079e86976dbd3efffe6064b3d72", - "reference": "8ceece474b29d079e86976dbd3efffe6064b3d72", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "zendframework/zend-stdlib": "self.version" - }, - "require-dev": { - "zendframework/zend-crypt": "self.version" - }, - "suggest": { - "zendframework/zend-crypt": "Zend\\Crypt component", - "zendframework/zend-i18n": "Zend\\I18n component", - "zendframework/zend-uri": "Zend\\Uri component for UriNormalize filter", - "zendframework/zend-validator": "Zend\\Validator component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\Filter\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides a set of commonly needed data filters", - "keywords": [ - "filter", - "zf2" - ], - "time": "2014-03-03 21:00:06" - }, - { - "name": "zendframework/zend-i18n", - "version": "2.1.6", - "target-dir": "Zend/I18n", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendI18n.git", - "reference": "10f56e0869761d62699782e4dd04eb77262cc353" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendI18n/zipball/10f56e0869761d62699782e4dd04eb77262cc353", - "reference": "10f56e0869761d62699782e4dd04eb77262cc353", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "zendframework/zend-stdlib": "self.version" - }, - "suggest": { - "ext-intl": "Required for most features of Zend\\I18n; included in default builds of PHP", - "zendframework/zend-eventmanager": "You should install this package to use the events in the translator", - "zendframework/zend-filter": "You should install this package to use the provided filters", - "zendframework/zend-resources": "Translation resources", - "zendframework/zend-validator": "You should install this package to use the provided validators", - "zendframework/zend-view": "You should install this package to use the provided view helpers" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\I18n\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "keywords": [ - "i18n", - "zf2" - ], - "time": "2014-01-04 13:00:19" - }, - { - "name": "zendframework/zend-json", - "version": "2.1.6", - "target-dir": "Zend/Json", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendJson.git", - "reference": "dd8a8239a7c08c7449a6ea219da3e2369bd90d92" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendJson/zipball/dd8a8239a7c08c7449a6ea219da3e2369bd90d92", - "reference": "dd8a8239a7c08c7449a6ea219da3e2369bd90d92", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "zendframework/zend-stdlib": "self.version" - }, - "suggest": { - "zendframework/zend-server": "Zend\\Server component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\Json\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP", - "keywords": [ - "json", - "zf2" - ], - "time": "2014-03-06 18:00:05" - }, - { - "name": "zendframework/zend-math", - "version": "2.1.6", - "target-dir": "Zend/Math", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendMath.git", - "reference": "b982ee2edafd4075b22372596ab2e2fdd0f6424e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendMath/zipball/b982ee2edafd4075b22372596ab2e2fdd0f6424e", - "reference": "b982ee2edafd4075b22372596ab2e2fdd0f6424e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-bcmath": "If using the bcmath functionality", - "ext-gmp": "If using the gmp functionality", - "ircmaxell/random-lib": "Fallback random byte generator for Zend\\Math\\Rand if OpenSSL/Mcrypt extensions are unavailable", - "zendframework/zend-servicemanager": ">= current version, if using the BigInteger::factory functionality" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\Math\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "keywords": [ - "math", - "zf2" - ], - "time": "2014-03-05 18:00:06" - }, - { - "name": "zendframework/zend-serializer", - "version": "2.1.6", - "target-dir": "Zend/Serializer", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendSerializer.git", - "reference": "d76b931d3ffa842a496c9fa319bbe285b5ddfade" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendSerializer/zipball/d76b931d3ffa842a496c9fa319bbe285b5ddfade", - "reference": "d76b931d3ffa842a496c9fa319bbe285b5ddfade", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "zendframework/zend-json": "self.version", - "zendframework/zend-math": "self.version", - "zendframework/zend-stdlib": "self.version" - }, - "suggest": { - "zendframework/zend-servicemanager": "To support plugin manager support" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\Serializer\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides an adapter based interface to simply generate storable representation of PHP types by different facilities, and recover", - "keywords": [ - "serializer", - "zf2" - ], - "time": "2014-01-02 18:00:26" - }, - { - "name": "zendframework/zend-servicemanager", - "version": "2.1.6", - "target-dir": "Zend/ServiceManager", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendServiceManager.git", - "reference": "de182a20dfdcf978c49570514103c7477ef16e4f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendServiceManager/zipball/de182a20dfdcf978c49570514103c7477ef16e4f", - "reference": "de182a20dfdcf978c49570514103c7477ef16e4f", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "zendframework/zend-di": "Zend\\Di component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\ServiceManager\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "keywords": [ - "servicemanager", - "zf2" - ], - "time": "2014-03-03 21:00:04" - }, - { - "name": "zendframework/zend-stdlib", - "version": "2.1.6", - "target-dir": "Zend/Stdlib", - "source": { - "type": "git", - "url": "https://github.com/zendframework/Component_ZendStdlib.git", - "reference": "e646729f2274f4552b6a92e38d8e458efe08ebc5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendStdlib/zipball/e646729f2274f4552b6a92e38d8e458efe08ebc5", - "reference": "e646729f2274f4552b6a92e38d8e458efe08ebc5", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "zendframework/zend-eventmanager": "To support aggregate hydrator usage", - "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev", - "dev-develop": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Zend\\Stdlib\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "keywords": [ - "stdlib", - "zf2" - ], - "time": "2014-01-04 13:00:28" - }, - { - "name": "zetacomponents/base", - "version": "1.8", - "source": { - "type": "git", - "url": "https://github.com/zetacomponents/Base.git", - "reference": "52ca69c1de55f3fa4f595779e5bc831da7ee176c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zetacomponents/Base/zipball/52ca69c1de55f3fa4f595779e5bc831da7ee176c", - "reference": "52ca69c1de55f3fa4f595779e5bc831da7ee176c", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "apache2" - ], - "authors": [ - { - "name": "Sergey Alexeev" - }, - { - "name": "Sebastian Bergmann" - }, - { - "name": "Jan Borsodi" - }, - { - "name": "Raymond Bosman" - }, - { - "name": "Frederik Holljen" - }, - { - "name": "Kore Nordmann" - }, - { - "name": "Derick Rethans" - }, - { - "name": "Vadym Savchuk" - }, - { - "name": "Tobias Schlitt" - }, - { - "name": "Alexandru Stanoi" - } - ], - "description": "The Base package provides the basic infrastructure that all packages rely on. Therefore every component relies on this package.", - "homepage": "https://github.com/zetacomponents", - "time": "2009-12-21 12:14:16" - }, - { - "name": "zetacomponents/document", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/zetacomponents/Document.git", - "reference": "688abfde573cf3fe0730f82538fbd7aa9fc95bc8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zetacomponents/Document/zipball/688abfde573cf3fe0730f82538fbd7aa9fc95bc8", - "reference": "688abfde573cf3fe0730f82538fbd7aa9fc95bc8", - "shasum": "" - }, - "require": { - "zetacomponents/base": "*" - }, - "require-dev": { - "zetacomponents/unit-test": "dev-master" - }, - "type": "library", - "autoload": { - "classmap": [ - "src" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Sebastian Bergmann" - }, - { - "name": "Kore Nordmann" - }, - { - "name": "Derick Rethans" - }, - { - "name": "Tobias Schlitt" - }, - { - "name": "Alexandru Stanoi" - } - ], - "description": "The Document components provides a general conversion framework for different semantic document markup languages like XHTML, Docbook, RST and similar.", - "homepage": "https://github.com/zetacomponents", - "time": "2013-12-19 11:40:00" - } - ], - "aliases": [ - - ], - "minimum-stability": "stable", - "stability-flags": [ - - ], - "platform": { - "php": ">=5.3.0", - "ext-xml": "*", - "ext-zip": "*" - }, - "platform-dev": [ - - ] -} diff --git a/docs/credits.rst b/docs/credits.rst index 9b6e46c68..379ff303d 100644 --- a/docs/credits.rst +++ b/docs/credits.rst @@ -2,3 +2,5 @@ Credits ======= + + Images from chart page come from the `LibreOffice Core `. \ No newline at end of file diff --git a/docs/faq.rst b/docs/faq.rst index 59c7629a9..0445d9da8 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -4,7 +4,7 @@ Frequently asked questions ========================== Is this the same with PHPPowerPoint that I found in CodePlex? -------------------------------------------------------- +------------------------------------------------------------- No. This one is much better with tons of new features that you can’t find in PHPPowerPoint 0.1. The development in CodePlex is halted and @@ -12,9 +12,38 @@ switched to GitHub to allow more participation from the crowd. The more the merrier, right? I’ve been running PHPPowerPoint from CodePlex flawlessly, but I can’t use the latest PHPPowerPoint from GitHub. Why? --------------------------------------------------------------------------------------------------------- +-------------------------------------------------------------------------------------------------------------------- PHPPowerPoint requires PHP 5.3+ since 0.2, while PHPPowerPoint 0.1 from CodePlex can run with PHP 5.2. There’s a lot of new features that we can get from -PHP 5.3 and it’s been around since 2014! You should upgrade your PHP +PHP 5.3 and it’s been around since 2009! You should upgrade your PHP version to use PHPPowerPoint 0.2+. + +Why am I getting a class not found error? +----------------------------------------- + +If you have followed the instructions for either adding this package to your +``composer.json`` or registering the autoloader, then perhaps you forgot to +include a ``use`` statement for the class(es) you are trying to access. + +Here's an example that allows you to refer to the ``MemoryDrawing`` class +without having to specify the full class name in your code: + +.. code-block:: php + + use PhpOffice\PhpPowerpoint\Shape\MemoryDrawing as MemoryDrawing; + +If you *have* followed the installation instructions and you *have* added +the necessary ``use`` statements to your code, then maybe you are still +referencing the ``PHPPowerPoint`` classes using the old PEAR/PSR-0 approach. +The 0.1 approach to naming classes used verbose class names to avoid +namespace collisions with other libraries. For example, the ``MemoryDrawing`` +class was actually called ``PHPPowerPoint_Shape_MemoryDrawing``. Version +0.2 of the library renamed the classes, moved to a namespaced approach +and switched to the PSR-0 autoloader. Interestingly, old code that was +still referencing classes using the verbose approach *still worked* (which +was pretty cool!). This is because the PSR-0 autoloader was correctly +translating the verbose class references into the correct file name and +location. However, ``PHPPowerPoint`` now relies exclusively on the PSR-4 +autoloader, so old code that may have been referencing the classes with +the verbose class names will need to be updated accordingly. diff --git a/docs/images/chart_columnpercent_52x60.png b/docs/images/chart_columnpercent_52x60.png new file mode 100644 index 000000000..a1de70236 Binary files /dev/null and b/docs/images/chart_columnpercent_52x60.png differ diff --git a/docs/images/chart_columns_52x60.png b/docs/images/chart_columns_52x60.png new file mode 100644 index 000000000..d72371728 Binary files /dev/null and b/docs/images/chart_columns_52x60.png differ diff --git a/docs/images/chart_columnstack_52x60.png b/docs/images/chart_columnstack_52x60.png new file mode 100644 index 000000000..a9c009c64 Binary files /dev/null and b/docs/images/chart_columnstack_52x60.png differ diff --git a/docs/index.rst b/docs/index.rst index 4539565e1..c59e73ac9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ contain the root `toctree` directive. Welcome to PHPPowerPoint's documentation -================================== +======================================== |PHPPowerPoint| @@ -24,6 +24,15 @@ PHPPowerPoint is a library written in pure PHP that provides a set of classes to faq credits references + +.. _shapesdocs: + +.. toctree:: + :maxdepth: 2 + :caption: Shapes + + shapes_chart + shapes_table Indices and tables ================== diff --git a/docs/references.rst b/docs/references.rst index d4fff575f..bea9c0cc4 100644 --- a/docs/references.rst +++ b/docs/references.rst @@ -18,8 +18,10 @@ ISO : `__ - `Part 4: Transitional Migration Features `__ + MSDN : +- `PowerPoint Viewer `__ - `DocumentFormat.OpenXml.Presentation Namespace on MSDN `__ - `Open XML SDK 2.5 with Validator `__ diff --git a/docs/shapes.rst b/docs/shapes.rst index e996f111d..c892bd19c 100644 --- a/docs/shapes.rst +++ b/docs/shapes.rst @@ -15,11 +15,12 @@ Every shapes have common properties that you can set by using fluent interface. - ``fill`` see *[Fill](#fill)* - ``border`` see *[Border](#border)* - ``shadow`` see *[Shadow](#shadow)* -- ``hyperlink` +- ``hyperlink`` Example: .. code-block:: php + $richtext = $slide->createRichTextShape() ->setHeight(300) ->setWidth(600) @@ -27,7 +28,7 @@ Example: ->setOffsetY(180); Rich text -------- +--------- Rich text shapes contain paragraphs of texts. To create a rich text shape, use ``createRichTextShape`` method of slide. @@ -35,6 +36,8 @@ Below are the properties that you can set for a rich text shape. - ``wrap`` - ``autoFit`` +- ``fontScale`` : font scale (in percentage) when autoFit = RichText::AUTOFIT_NORMAL +- ``lnSpcReduction`` : line spacing reduction (in percentage) when autoFit = RichText::AUTOFIT_NORMAL - ``horizontalOverflow`` - ``verticalOverflow`` - ``upright`` @@ -61,7 +64,7 @@ To create a line, use `createLineShape` method of slide. Chart ------- -To create a chart, use `createChartShape` method of slide. +The Chart has now :ref:`its own page `. Drawing ------- @@ -69,15 +72,13 @@ Drawing To create a drawing, use `createDrawingShape` method of slide. .. code-block:: php + $drawing = $slide->createDrawingShape(); $drawing->setName('Unique name') ->setDescription('Description of the drawing') ->setPath('/path/to/drawing.filename'); -Drawing +Table ------- -To create a table, use `createTableShape` method of slide. - -.. code-block:: php - $table = $slide->createTableShape($columns); +The Table has now :ref:`its own page `. diff --git a/docs/shapes_chart.rst b/docs/shapes_chart.rst new file mode 100644 index 000000000..d86e04b68 --- /dev/null +++ b/docs/shapes_chart.rst @@ -0,0 +1,89 @@ +.. _shapes_chart: + +Charts +====== + +To create a chart, use `createChartShape` method of Slide. + +Example: + +.. code-block:: php + + $chartShape = $slide->createChartShape(); + +Parts +------- + +Title +^^^^^ + +By default, the title of a chart is displayed. +For hiding it, you define its visibility to false. + +.. code-block:: php + + $chartShape = $slide->createChartShape(); + $oLine = new Line(); + $oShape->getPlotArea()->setType($oLine); + // Hide the title + $oShape->getTitle()->setVisible(false); + +Types +------- + +Area +^^^^ + +TODO + +Bar & Bar3D +^^^^^^^^^^^ + +Stacking +"""""""" + +You can stack multiples series in a same chart. After adding multiples series, you can define the bar grouping with `setBarGrouping` method of AbstractTypeBar. + +.. code-block:: php + + $oBarChart = new Bar(); + $oBarChart->addSeries($oSeries1); + $oBarChart->addSeries($oSeries2); + $oBarChart->addSeries($oSeries3); + $oBarChart->setBarGrouping(Bar::GROUPING_CLUSTERED); + // OR + $oBarChart->setBarGrouping(Bar::GROUPING_STACKED); + // OR + $oBarChart->setBarGrouping(Bar::GROUPING_PERCENTSTACKED); + +- Bar::GROUPING_CLUSTERED +.. image:: images/chart_columns_52x60.png + :width: 120px + :alt: Bar::GROUPING_CLUSTERED + +- Bar::GROUPING_STACKED +.. image:: images/chart_columnstack_52x60.png + :width: 120px + :alt: Bar::GROUPING_STACKED + +- Bar::GROUPING_PERCENTSTACKED +.. image:: images/chart_columnpercent_52x60.png + :width: 120px + :alt: Bar::GROUPING_PERCENTSTACKED + + +Line +^^^^ + +TODO + +Pie & Pie3D +^^^^^^^^^^^ + +TODO + +Scatter +^^^^^^^ + +TODO + diff --git a/docs/shapes_table.rst b/docs/shapes_table.rst new file mode 100644 index 000000000..09dc88f82 --- /dev/null +++ b/docs/shapes_table.rst @@ -0,0 +1,64 @@ +.. _shapes_table: + +Tables +====== + +To create a table, use `createTableShape` method of slide. + +Example: + +.. code-block:: php + + $tableShape = $slide->createTableShape($columns); + +Rows +------- + +A row is a child of a table. For creating a row, use `createRow` method of a Table shape. + +.. code-block:: php + + $tableShape = $slide->createTableShape($columns); + $row = $tableShape->createRow(); + +Cells +------- +A cell is a child of a row. + +You can access cell objects with `nextCell` method of a Row object. + +.. code-block:: php + + $tableShape = $slide->createTableShape($columns); + $row = $tableShape->createRow(); + // Get the first cell + $cellA1 = $row->nextCell(); + // Get the second cell + $cellA2 = $row->nextCell(); + +You can access cell object directly + +.. code-block:: php + + $tableShape = $slide->createTableShape($columns); + $row = $tableShape->createRow(); + // Get the first cell + $cellA1 = $row->getCell(0); + // Get the second cell + $cellA2 = $row->getCell(1); + + +Define the width of a cell +~~~~~~~~~~~~~~~~~~~~~~~~~~ +The width of cells are defined by the width of cell of the first row. +If not defined, all cells widths are calculated from the width of the shape and the number of columns. + +For defining the width of cell, you can use the `setWidth` method of a Cell object. +The width is in pixels. + +.. code-block:: php + + $tableShape = $slide->createTableShape($columns); + $row = $tableShape->createRow(); + $cellA1 = $row->nextCell(); + $cellA1->setWidth(100); \ No newline at end of file diff --git a/docs/styles.rst b/docs/styles.rst index 30b5c2e63..727840162 100644 --- a/docs/styles.rst +++ b/docs/styles.rst @@ -4,11 +4,12 @@ Styles ====== Fill -------- +---- Use this style to define fill of a shape as example below. .. code-block:: php + $shape->getFill() ->setFillType(Fill::FILL_GRADIENT_LINEAR) ->setRotation(270) @@ -23,11 +24,12 @@ Properties: - ``endColor`` Border -------- +------ Use this style to define border of a shape as example below. .. code-block:: php + $shape->getBorder() ->setLineStyle(Border::LINE_SINGLE) ->setLineWidth(4) @@ -41,11 +43,12 @@ Properties: - ``color`` Shadow -------- +------ Use this style to define shadow of a shape as example below. .. code-block:: php + $shape->getShadow() ->setVisible(true) ->setDirection(45) @@ -62,7 +65,7 @@ Properties: - ``alpha`` Alignment -------- +--------- - ``horizontal`` - ``vertical`` @@ -72,7 +75,7 @@ Alignment - ``marginRight`` Font -------- +---- - ``name`` - ``bold`` @@ -84,7 +87,7 @@ Font - ``color`` Bullet -------- +------ - ``bulletType`` - ``bulletFont`` @@ -93,10 +96,11 @@ Bullet - ``bulletNumericStartAt`` Color -------- +----- Colors can be applied to different objects, e.g. font or border. .. code-block:: php + $textRun = $shape->createTextRun('Text'); $textRun->getFont()->setColor(new Color('C00000')); diff --git a/phpmd.xml.dist b/phpmd.xml.dist index b39729659..87a53c279 100644 --- a/phpmd.xml.dist +++ b/phpmd.xml.dist @@ -9,12 +9,6 @@ - - - - - - diff --git a/samples/.gitignore b/samples/.gitignore deleted file mode 100644 index 9ca351d81..000000000 --- a/samples/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ - -*.odp -*.pptx -*.phppt \ No newline at end of file diff --git a/samples/Sample_01_Simple.php b/samples/Sample_01_Simple.php index b9526d61a..bc6440ce1 100644 --- a/samples/Sample_01_Simple.php +++ b/samples/Sample_01_Simple.php @@ -36,6 +36,7 @@ $shape->getShadow()->setVisible(true) ->setDirection(45) ->setDistance(10); +$shape->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPowerPoint/')->setTooltip('PHPPowerPoint'); // Create a shape (text) echo date('H:i:s') . ' Create a shape (rich text)'.EOL; diff --git a/samples/Sample_03_Serialized.php b/samples/Sample_02_Serialized.php similarity index 100% rename from samples/Sample_03_Serialized.php rename to samples/Sample_02_Serialized.php diff --git a/samples/Sample_04_InMemoryImage.php b/samples/Sample_03_Image.php similarity index 67% rename from samples/Sample_04_InMemoryImage.php rename to samples/Sample_03_Image.php index 3195b2be8..0b00ed0fc 100644 --- a/samples/Sample_04_InMemoryImage.php +++ b/samples/Sample_03_Image.php @@ -3,22 +3,13 @@ include_once 'Sample_Header.php'; use PhpOffice\PhpPowerpoint\PhpPowerpoint; +use PhpOffice\PhpPowerpoint\Shape\Drawing; use PhpOffice\PhpPowerpoint\Shape\MemoryDrawing; // Create new PHPPowerPoint object echo date('H:i:s') . ' Create new PHPPowerPoint object'.EOL; $objPHPPowerPoint = new PhpPowerpoint(); -// Set properties -echo date('H:i:s') . ' Set properties'.EOL; -$objPHPPowerPoint->getProperties()->setCreator('PHPOffice') - ->setLastModifiedBy('PHPPowerPoint Team') - ->setTitle('Sample 04 Title') - ->setSubject('Sample 04 Subject') - ->setDescription('Sample 04 Description') - ->setKeywords('office 2007 openxml libreoffice odt php') - ->setCategory('Sample Category'); - // Create slide echo date('H:i:s') . ' Create slide'.EOL; $currentSlide = $objPHPPowerPoint->getActiveSlide(); @@ -29,7 +20,7 @@ $textColor = imagecolorallocate($gdImage, 255, 255, 255); imagestring($gdImage, 1, 5, 5, 'Created with PHPPowerPoint', $textColor); -// Add a drawing to the worksheet +// Add a generated drawing to the slide echo date('H:i:s') . ' Add a drawing to the worksheet'.EOL; $shape = new MemoryDrawing(); $shape->setName('Sample image') @@ -42,6 +33,16 @@ ->setOffsetY(10); $currentSlide->addShape($shape); +// Add a file drawing (GIF) to the slide +$shape = new Drawing(); +$shape->setName('PHPPowerPoint logo') + ->setDescription('PHPPowerPoint logo') + ->setPath('./resources/phppowerpoint_logo.gif') + ->setHeight(36) + ->setOffsetX(10) + ->setOffsetY(100); +$currentSlide->addShape($shape); + // Save file echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); if (!CLI) { diff --git a/samples/Sample_06_Table.php b/samples/Sample_04_Table.php similarity index 70% rename from samples/Sample_06_Table.php rename to samples/Sample_04_Table.php index e16007f1c..f1b3c5b24 100644 --- a/samples/Sample_06_Table.php +++ b/samples/Sample_04_Table.php @@ -46,8 +46,7 @@ ->setEndColor(new Color('FFFFFFFF')); $cell = $row->nextCell(); $cell->setColSpan(3); -$cell->createTextRun('Title row')->getFont()->setBold(true) - ->setSize(16); +$cell->createTextRun('Title row')->getFont()->setBold(true)->setSize(16); $cell->getBorders()->getBottom()->setLineWidth(4) ->setLineStyle(Border::LINE_SINGLE) ->setDashStyle(Border::DASH_DASH); @@ -58,7 +57,7 @@ $row->setHeight(20); $row->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR) ->setRotation(90) - ->setStartColor(new Color( 'FFE06B20' )) + ->setStartColor(new Color('FFE06B20')) ->setEndColor(new Color('FFFFFFFF')); $row->nextCell()->createTextRun('R1C1')->getFont()->setBold(true); $row->nextCell()->createTextRun('R1C2')->getFont()->setBold(true); @@ -74,7 +73,7 @@ echo date('H:i:s') . ' Add row'.EOL; $row = $shape->createRow(); $row->getFill()->setFillType(Fill::FILL_SOLID) - ->setStartColor(new Color( 'FFE06B20' )) + ->setStartColor(new Color('FFE06B20')) ->setEndColor(new Color('FFE06B20')); $row->nextCell()->createTextRun('R2C1'); $row->nextCell()->createTextRun('R2C2'); @@ -84,12 +83,38 @@ echo date('H:i:s') . ' Add row'.EOL; $row = $shape->createRow(); $row->getFill()->setFillType(Fill::FILL_SOLID) - ->setStartColor(new Color( 'FFE06B20' )) + ->setStartColor(new Color('FFE06B20')) ->setEndColor(new Color('FFE06B20')); $row->nextCell()->createTextRun('R3C1'); $row->nextCell()->createTextRun('R3C2'); $row->nextCell()->createTextRun('R3C3'); +// Add row +echo date('H:i:s') . ' Add row'.EOL; +$row = $shape->createRow(); +$row->getFill()->setFillType(Fill::FILL_SOLID) + ->setStartColor(new Color('FFE06B20')) + ->setEndColor(new Color('FFE06B20')); +$cellC1 = $row->nextCell(); +$textRunC1 = $cellC1->createTextRun('Link'); +$textRunC1->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPowerPoint/')->setTooltip('PHPPowerPoint'); +$cellC2 = $row->nextCell(); +$textRunC2 = $cellC2->createTextRun('RichText with'); +$textRunC2->getFont()->setBold(true); +$textRunC2->getFont()->setSize(12); +$textRunC2->getFont()->setColor(new Color('FF000000')); +$cellC2->createBreak(); +$textRunC2 = $cellC2->createTextRun('Multiline'); +$textRunC2->getFont()->setBold(true); +$textRunC2->getFont()->setSize(14); +$textRunC2->getFont()->setColor(new Color('FF0088FF')); +$cellC3 = $row->nextCell(); +$textRunC3 = $cellC3->createTextRun('Link Github'); +$textRunC3->getHyperlink()->setUrl('https://github.com')->setTooltip('GitHub'); +$cellC3->createBreak(); +$textRunC3 = $cellC3->createTextRun('Link Google'); +$textRunC3->getHyperlink()->setUrl('https://google.com')->setTooltip('Google'); + // Save file echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); if (!CLI) { diff --git a/samples/Sample_05_Chart.php b/samples/Sample_05_Chart.php new file mode 100644 index 000000000..5ca0bb950 --- /dev/null +++ b/samples/Sample_05_Chart.php @@ -0,0 +1,567 @@ + 12, + 'Tuesday' => 15, + 'Wednesday' => 13, + 'Thursday' => 17, + 'Friday' => 14, + 'Saturday' => 9, + 'Sunday' => 7 + ); + + // Create templated slide + echo EOL . date('H:i:s') . ' Create templated slide' . EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); + + // Create a line chart (that should be inserted in a shape) + echo date('H:i:s') . ' Create a area chart (that should be inserted in a chart shape)' . EOL; + $areaChart = new Area(); + $series = new Series('Downloads', $seriesData); + $series->setShowSeriesName(true); + $series->setShowValue(true); + $series->getFill()->setStartColor(new Color('FF93A9CE')); + $areaChart->addSeries($series); + + // Create a shape (chart) + echo date('H:i:s') . ' Create a shape (chart)' . EOL; + $shape = $currentSlide->createChartShape(); + $shape->getTitle()->setVisible(false); + $shape->setName('PHPPowerPoint Daily Downloads')->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80); + $shape->setShadow($oShadow); + $shape->setFill($oFill); + $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getTitle()->setText('PHPPowerPoint Daily Downloads'); + $shape->getTitle()->getFont()->setItalic(true); + $shape->getPlotArea()->setType($areaChart); + $shape->getView3D()->setRotationX(30); + $shape->getView3D()->setPerspective(30); + $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getLegend()->getFont()->setItalic(true); +} + +function fnSlide_Bar(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create templated slide + echo EOL.date('H:i:s') . ' Create templated slide'.EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); + + // Generate sample data for first chart + echo date('H:i:s') . ' Generate sample data for chart'.EOL; + $series1Data = array('Jan' => 133, 'Feb' => 99, 'Mar' => 191, 'Apr' => 205, 'May' => 167, 'Jun' => 201, 'Jul' => 240, 'Aug' => 226, 'Sep' => 255, 'Oct' => 264, 'Nov' => 283, 'Dec' => 293); + $series2Data = array('Jan' => 266, 'Feb' => 198, 'Mar' => 271, 'Apr' => 305, 'May' => 267, 'Jun' => 301, 'Jul' => 340, 'Aug' => 326, 'Sep' => 344, 'Oct' => 364, 'Nov' => 383, 'Dec' => 379); + + // Create a bar chart (that should be inserted in a shape) + echo date('H:i:s') . ' Create a bar chart (that should be inserted in a chart shape)'.EOL; + $barChart = new Bar(); + $series1 = new Series('2009', $series1Data); + $series1->setShowSeriesName(true); + $series1->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4F81BD')); + $series1->getFont()->getColor()->setRGB('00FF00'); + $series1->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFE06B20')); + $series2 = new Series('2010', $series2Data); + $series2->setShowSeriesName(true); + $series2->getFont()->getColor()->setRGB('FF0000'); + $series2->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFC0504D')); + $barChart->addSeries($series1); + $barChart->addSeries($series2); + + // Create a shape (chart) + echo date('H:i:s') . ' Create a shape (chart)'.EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName('PHPPowerPoint Monthly Downloads') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80); + $shape->setShadow($oShadow); + $shape->setFill($oFill); + $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getTitle()->setText('PHPPowerPoint Monthly Downloads'); + $shape->getTitle()->getFont()->setItalic(true); + $shape->getTitle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); + $shape->getPlotArea()->getAxisX()->setTitle('Month'); + $shape->getPlotArea()->getAxisY()->setTitle('Downloads'); + $shape->getPlotArea()->setType($barChart); + $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getLegend()->getFont()->setItalic(true); +} + +function fnSlide_BarHorizontal(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create a bar chart (that should be inserted in a shape) + echo date('H:i:s') . ' Create a horizontal bar chart (that should be inserted in a chart shape) '.EOL; + $barChartHorz = clone $objPHPPowerPoint->getSlide(1)->getShapeCollection()->offsetGet(1)->getPlotArea()->getType(); + $barChartHorz->setBarDirection(Bar3D::DIRECTION_HORIZONTAL); + + // Create templated slide + echo EOL.date('H:i:s') . ' Create templated slide'.EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); + + // Create a shape (chart) + echo date('H:i:s') . ' Create a shape (chart)'.EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName('PHPPowerPoint Monthly Downloads') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80); + $shape->setShadow($oShadow); + $shape->setFill($oFill); + $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getTitle()->setText('PHPPowerPoint Monthly Downloads'); + $shape->getTitle()->getFont()->setItalic(true); + $shape->getTitle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); + $shape->getPlotArea()->getAxisX()->setTitle('Month'); + $shape->getPlotArea()->getAxisY()->setTitle('Downloads'); + $shape->getPlotArea()->setType($barChartHorz); + $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getLegend()->getFont()->setItalic(true); +} + +function fnSlide_BarStacked(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create templated slide + echo EOL . date( 'H:i:s' ) . ' Create templated slide' . EOL; + $currentSlide = createTemplatedSlide( $objPHPPowerPoint ); + + // Generate sample data for first chart + echo date( 'H:i:s' ) . ' Generate sample data for chart' . EOL; + $series1Data = array('Jan' => 133, 'Feb' => 99, 'Mar' => 191, 'Apr' => 205, 'May' => 167, 'Jun' => 201, 'Jul' => 240, 'Aug' => 226, 'Sep' => 255, 'Oct' => 264, 'Nov' => 283, 'Dec' => 293); + $series2Data = array('Jan' => 266, 'Feb' => 198, 'Mar' => 271, 'Apr' => 305, 'May' => 267, 'Jun' => 301, 'Jul' => 340, 'Aug' => 326, 'Sep' => 344, 'Oct' => 364, 'Nov' => 383, 'Dec' => 379); + $series3Data = array('Jan' => 233, 'Feb' => 146, 'Mar' => 238, 'Apr' => 175, 'May' => 108, 'Jun' => 257, 'Jul' => 199, 'Aug' => 201, 'Sep' => 88, 'Oct' => 147, 'Nov' => 287, 'Dec' => 105); + + // Create a bar chart (that should be inserted in a shape) + echo date( 'H:i:s' ) . ' Create a stacked bar chart (that should be inserted in a chart shape)' . EOL; + $StackedBarChart = new Bar(); + $series1 = new Series( '2009', $series1Data ); + $series1->setShowSeriesName( false ); + $series1->getFill()->setFillType( Fill::FILL_SOLID )->setStartColor( new Color( 'FF4F81BD' ) ); + $series1->getFont()->getColor()->setRGB( '00FF00' ); + $series1->setShowValue( true ); + $series1->setShowPercentage( false ); + $series2 = new Series( '2010', $series2Data ); + $series2->setShowSeriesName( false ); + $series2->getFont()->getColor()->setRGB( 'FF0000' ); + $series2->getFill()->setFillType( Fill::FILL_SOLID )->setStartColor( new Color( 'FFC0504D' ) ); + $series2->setShowValue( true ); + $series2->setShowPercentage( false ); + $series3 = new Series( '2011', $series3Data ); + $series3->setShowSeriesName( false ); + $series3->getFont()->getColor()->setRGB( 'FF0000' ); + $series3->getFill()->setFillType( Fill::FILL_SOLID )->setStartColor( new Color( 'FF804DC0' ) ); + $series3->setShowValue( true ); + $series3->setShowPercentage( false ); + $StackedBarChart->addSeries( $series1 ); + $StackedBarChart->addSeries( $series2 ); + $StackedBarChart->addSeries( $series3 ); + $StackedBarChart->setBarGrouping( Bar::GROUPING_STACKED ); + // Create a shape (chart) + echo date( 'H:i:s' ) . ' Create a shape (chart)' . EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName( 'PHPPowerPoint Monthly Downloads' ) + ->setResizeProportional( false ) + ->setHeight( 550 ) + ->setWidth( 700 ) + ->setOffsetX( 120 ) + ->setOffsetY( 80 ); + $shape->setShadow( $oShadow ); + $shape->setFill( $oFill ); + $shape->getBorder()->setLineStyle( Border::LINE_SINGLE ); + $shape->getTitle()->setText( 'PHPPowerPoint Monthly Downloads' ); + $shape->getTitle()->getFont()->setItalic( true ); + $shape->getTitle()->getAlignment()->setHorizontal( Alignment::HORIZONTAL_RIGHT ); + $shape->getPlotArea()->getAxisX()->setTitle( 'Month' ); + $shape->getPlotArea()->getAxisY()->setTitle( 'Downloads' ); + $shape->getPlotArea()->setType( $StackedBarChart ); + $shape->getLegend()->getBorder()->setLineStyle( Border::LINE_SINGLE ); + $shape->getLegend()->getFont()->setItalic( true ); +} +function fnSlide_BarPercentStacked(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create templated slide + echo EOL . date( 'H:i:s' ) . ' Create templated slide' . EOL; + $currentSlide = createTemplatedSlide( $objPHPPowerPoint ); + + // Generate sample data for first chart + echo date( 'H:i:s' ) . ' Generate sample data for chart' . EOL; + $series1Data = array('Jan' => 133, 'Feb' => 99, 'Mar' => 191, 'Apr' => 205, 'May' => 167, 'Jun' => 201, 'Jul' => 240, 'Aug' => 226, 'Sep' => 255, 'Oct' => 264, 'Nov' => 283, 'Dec' => 293); + $Series1Sum = array_sum($series1Data); + foreach ($series1Data as $CatName => $Value) { + $series1Data[$CatName]= round($Value / $Series1Sum, 2); + } + $series2Data = array('Jan' => 266, 'Feb' => 198, 'Mar' => 271, 'Apr' => 305, 'May' => 267, 'Jun' => 301, 'Jul' => 340, 'Aug' => 326, 'Sep' => 344, 'Oct' => 364, 'Nov' => 383, 'Dec' => 379); + $Series2Sum = array_sum($series2Data); + foreach ($series2Data as $CatName => $Value) { + $series2Data[$CatName] = round($Value / $Series2Sum, 2); + } + $series3Data = array('Jan' => 233, 'Feb' => 146, 'Mar' => 238, 'Apr' => 175, 'May' => 108, 'Jun' => 257, 'Jul' => 199, 'Aug' => 201, 'Sep' => 88, 'Oct' => 147, 'Nov' => 287, 'Dec' => 105); + $Series3Sum = array_sum( $series3Data ); + foreach ($series3Data as $CatName => $Value) { + $series3Data[$CatName] = round($Value / $Series3Sum,2); + } + + // Create a bar chart (that should be inserted in a shape) + echo date( 'H:i:s' ) . ' Create a percent stacked horizontal bar chart (that should be inserted in a chart shape)' . EOL; + $PercentStackedBarChartHoriz = new Bar(); + $series1 = new Series( '2009', $series1Data ); + $series1->setShowSeriesName( false ); + $series1->getFill()->setFillType( Fill::FILL_SOLID )->setStartColor( new Color( 'FF4F81BD' ) ); + $series1->getFont()->getColor()->setRGB( '00FF00' ); + $series1->setShowValue( true ); + $series1->setShowPercentage( false ); + // Set Data Label Format For Chart To Display Percent + $series1->setDlblNumFormat( '#%' ); + $series2 = new Series( '2010', $series2Data ); + $series2->setShowSeriesName( false ); + $series2->getFont()->getColor()->setRGB( 'FF0000' ); + $series2->getFill()->setFillType( Fill::FILL_SOLID )->setStartColor( new Color( 'FFC0504D' ) ); + $series2->setShowValue( true ); + $series2->setShowPercentage( false ); + $series2->setDlblNumFormat( '#%' ); + $series3 = new Series( '2011', $series3Data ); + $series3->setShowSeriesName( false ); + $series3->getFont()->getColor()->setRGB( 'FF0000' ); + $series3->getFill()->setFillType( Fill::FILL_SOLID )->setStartColor( new Color( 'FF804DC0' ) ); + $series3->setShowValue( true ); + $series3->setShowPercentage( false ); + $series3->setDlblNumFormat( '#%' ); + $PercentStackedBarChartHoriz->addSeries( $series1 ); + $PercentStackedBarChartHoriz->addSeries( $series2 ); + $PercentStackedBarChartHoriz->addSeries( $series3 ); + $PercentStackedBarChartHoriz->setBarGrouping( Bar::GROUPING_PERCENTSTACKED ); + $PercentStackedBarChartHoriz->setBarDirection( Bar3D::DIRECTION_HORIZONTAL ); + // Create a shape (chart) + echo date( 'H:i:s' ) . ' Create a shape (chart)' . EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName( 'PHPPowerPoint Monthly Downloads' ) + ->setResizeProportional( false ) + ->setHeight( 550 ) + ->setWidth( 700 ) + ->setOffsetX( 120 ) + ->setOffsetY( 80 ); + $shape->setShadow( $oShadow ); + $shape->setFill( $oFill ); + $shape->getBorder()->setLineStyle( Border::LINE_SINGLE ); + $shape->getTitle()->setText( 'PHPPowerPoint Monthly Downloads' ); + $shape->getTitle()->getFont()->setItalic( true ); + $shape->getTitle()->getAlignment()->setHorizontal( Alignment::HORIZONTAL_RIGHT ); + $shape->getPlotArea()->getAxisX()->setTitle( 'Month' ); + $shape->getPlotArea()->getAxisY()->setTitle( 'Downloads' ); + $shape->getPlotArea()->setType( $PercentStackedBarChartHoriz ); + $shape->getLegend()->getBorder()->setLineStyle( Border::LINE_SINGLE ); + $shape->getLegend()->getFont()->setItalic( true ); +} + +function fnSlide_Bar3D(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create templated slide + echo EOL.date('H:i:s') . ' Create templated slide'.EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); + + // Generate sample data for first chart + echo date('H:i:s') . ' Generate sample data for chart'.EOL; + $series1Data = array('Jan' => 133, 'Feb' => 99, 'Mar' => 191, 'Apr' => 205, 'May' => 167, 'Jun' => 201, 'Jul' => 240, 'Aug' => 226, 'Sep' => 255, 'Oct' => 264, 'Nov' => 283, 'Dec' => 293); + $series2Data = array('Jan' => 266, 'Feb' => 198, 'Mar' => 271, 'Apr' => 305, 'May' => 267, 'Jun' => 301, 'Jul' => 340, 'Aug' => 326, 'Sep' => 344, 'Oct' => 364, 'Nov' => 383, 'Dec' => 379); + + // Create a bar chart (that should be inserted in a shape) + echo date('H:i:s') . ' Create a bar chart (that should be inserted in a chart shape)'.EOL; + $bar3DChart = new Bar3D(); + $series1 = new Series('2009', $series1Data); + $series1->setShowSeriesName(true); + $series1->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4F81BD')); + $series1->getFont()->getColor()->setRGB('00FF00'); + $series1->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFE06B20')); + $series2 = new Series('2010', $series2Data); + $series2->setShowSeriesName(true); + $series2->getFont()->getColor()->setRGB('FF0000'); + $series2->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFC0504D')); + $bar3DChart->addSeries($series1); + $bar3DChart->addSeries($series2); + + // Create a shape (chart) + echo date('H:i:s') . ' Create a shape (chart)'.EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName('PHPPowerPoint Monthly Downloads') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80); + $shape->setShadow($oShadow); + $shape->setFill($oFill); + $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getTitle()->setText('PHPPowerPoint Monthly Downloads'); + $shape->getTitle()->getFont()->setItalic(true); + $shape->getTitle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); + $shape->getPlotArea()->getAxisX()->setTitle('Month'); + $shape->getPlotArea()->getAxisY()->setTitle('Downloads'); + $shape->getPlotArea()->setType($bar3DChart); + $shape->getView3D()->setRightAngleAxes(true); + $shape->getView3D()->setRotationX(20); + $shape->getView3D()->setRotationY(20); + $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getLegend()->getFont()->setItalic(true); +} + +function fnSlide_Bar3DHorizontal(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create a bar chart (that should be inserted in a shape) + echo date('H:i:s') . ' Create a horizontal bar chart (that should be inserted in a chart shape) '.EOL; + $bar3DChartHorz = clone $objPHPPowerPoint->getSlide(5)->getShapeCollection()->offsetGet(1)->getPlotArea()->getType(); + $bar3DChartHorz->setBarDirection(Bar3D::DIRECTION_HORIZONTAL); + + // Create templated slide + echo EOL.date('H:i:s') . ' Create templated slide'.EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); + + // Create a shape (chart) + echo date('H:i:s') . ' Create a shape (chart)'.EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName('PHPPowerPoint Monthly Downloads') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80); + $shape->setShadow($oShadow); + $shape->setFill($oFill); + $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getTitle()->setText('PHPPowerPoint Monthly Downloads'); + $shape->getTitle()->getFont()->setItalic(true); + $shape->getTitle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); + $shape->getPlotArea()->getAxisX()->setTitle('Month'); + $shape->getPlotArea()->getAxisY()->setTitle('Downloads'); + $shape->getPlotArea()->setType($bar3DChartHorz); + $shape->getView3D()->setRightAngleAxes(true); + $shape->getView3D()->setRotationX(20); + $shape->getView3D()->setRotationY(20); + $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getLegend()->getFont()->setItalic(true); +} + +function fnSlide_Pie3D(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create templated slide + echo EOL.date('H:i:s') . ' Create templated slide'.EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); + + // Generate sample data for second chart + echo date('H:i:s') . ' Generate sample data for chart'.EOL; + $seriesData = array('Monday' => 12, 'Tuesday' => 15, 'Wednesday' => 13, 'Thursday' => 17, 'Friday' => 14, 'Saturday' => 9, 'Sunday' => 7); + + // Create a pie chart (that should be inserted in a shape) + echo date('H:i:s') . ' Create a pie chart (that should be inserted in a chart shape)'.EOL; + $pie3DChart = new Pie3D(); + $pie3DChart->setExplosion(20); + $series = new Series('Downloads', $seriesData); + $series->setShowSeriesName(true); + $series->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4672A8')); + $series->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFAB4744')); + $series->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF8AA64F')); + $series->getDataPointFill(3)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF725990')); + $series->getDataPointFill(4)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4299B0')); + $series->getDataPointFill(5)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFDC853E')); + $series->getDataPointFill(6)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF93A9CE')); + $pie3DChart->addSeries($series); + + // Create a shape (chart) + echo date('H:i:s') . ' Create a shape (chart)'.EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName('PHPPowerPoint Daily Downloads') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80); + $shape->setShadow($oShadow); + $shape->setFill($oFill); + $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getTitle()->setText('PHPPowerPoint Daily Downloads'); + $shape->getTitle()->getFont()->setItalic(true); + $shape->getPlotArea()->setType($pie3DChart); + $shape->getView3D()->setRotationX(30); + $shape->getView3D()->setPerspective(30); + $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getLegend()->getFont()->setItalic(true); +} + +function fnSlide_Pie(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create templated slide + echo EOL.date('H:i:s') . ' Create templated slide'.EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); + + // Generate sample data for second chart + echo date('H:i:s') . ' Generate sample data for chart'.EOL; + $seriesData = array('Monday' => 18, 'Tuesday' => 23, 'Wednesday' => 14, 'Thursday' => 12, 'Friday' => 20, 'Saturday' => 8, 'Sunday' => 10); + + // Create a pie chart (that should be inserted in a shape) + echo date('H:i:s') . ' Create a non-3D pie chart (that should be inserted in a chart shape)'.EOL; + $pieChart = new Pie(); + $pieChart->setExplosion(15); + $series = new Series('Downloads', $seriesData); + $series->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF7CB5EC')); + $series->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF434348')); + $series->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF90ED7D')); + $series->getDataPointFill(3)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFF7A35C')); + $series->getDataPointFill(4)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF8085E9')); + $series->getDataPointFill(5)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFF15C80')); + $series->getDataPointFill(6)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFE4D354')); + $series->setShowPercentage( true ); + $series->setShowValue( false ); + $series->setShowSeriesName( false ); + $series->setShowCategoryName( true ); + $pieChart->addSeries($series); + + // Create a shape (chart) + echo date('H:i:s') . ' Create a shape (chart)'.EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName('PHPPowerPoint Daily Downloads') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80); + $shape->setShadow($oShadow); + $shape->setFill($oFill); + $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getTitle()->setText('PHPPowerPoint Daily Downloads'); + $shape->getTitle()->getFont()->setItalic(true); + $shape->getPlotArea()->setType($pieChart); + $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getLegend()->getFont()->setItalic(true); +} + +function fnSlide_Scatter(PhpPowerpoint $objPHPPowerPoint) { + global $oFill; + global $oShadow; + + // Create templated slide + echo EOL.date('H:i:s') . ' Create templated slide'.EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); // local function + + // Generate sample data for fourth chart + echo date('H:i:s') . ' Generate sample data for chart'.EOL; + $seriesData = array('Monday' => 0.1, 'Tuesday' => 0.33333, 'Wednesday' => 0.4444, 'Thursday' => 0.5, 'Friday' => 0.4666, 'Saturday' => 0.3666, 'Sunday' => 0.1666); + + // Create a scatter chart (that should be inserted in a shape) + echo date('H:i:s') . ' Create a scatter chart (that should be inserted in a chart shape)'.EOL; + $lineChart = new Scatter(); + $series = new Series('Downloads', $seriesData); + $series->setShowSeriesName(true); + $lineChart->addSeries($series); + + // Create a shape (chart) + echo date('H:i:s') . ' Create a shape (chart)'.EOL; + $shape = $currentSlide->createChartShape(); + $shape->setName('PHPPowerPoint Daily Download Distribution') + ->setResizeProportional(false) + ->setHeight(550) + ->setWidth(700) + ->setOffsetX(120) + ->setOffsetY(80); + $shape->setShadow($oShadow); + $shape->setFill($oFill); + $shape->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getTitle()->setText('PHPPowerPoint Daily Downloads'); + $shape->getTitle()->getFont()->setItalic(true); + $shape->getPlotArea()->setType($lineChart); + $shape->getView3D()->setRotationX(30); + $shape->getView3D()->setPerspective(30); + $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); + $shape->getLegend()->getFont()->setItalic(true); +} + +// Create new PHPPowerPoint object +echo date('H:i:s') . ' Create new PHPPowerPoint object'.EOL; +$objPHPPowerPoint = new PhpPowerpoint(); + +// Set properties +echo date('H:i:s') . ' Set properties'.EOL; +$objPHPPowerPoint->getProperties()->setCreator('PHPOffice') + ->setLastModifiedBy('PHPPowerPoint Team') + ->setTitle('Sample 07 Title') + ->setSubject('Sample 07 Subject') + ->setDescription('Sample 07 Description') + ->setKeywords('office 2007 openxml libreoffice odt php') + ->setCategory('Sample Category'); + +// Remove first slide +echo date('H:i:s') . ' Remove first slide'.EOL; +$objPHPPowerPoint->removeSlideByIndex(0); + +// Set Style +$oFill = new Fill(); +$oFill->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFE06B20')); + +$oShadow = new Shadow(); +$oShadow->setVisible(true)->setDirection(45)->setDistance(10); + +fnSlide_Area($objPHPPowerPoint); + +fnSlide_Bar($objPHPPowerPoint); + +fnSlide_BarStacked($objPHPPowerPoint); + +fnSlide_BarPercentStacked($objPHPPowerPoint); + +fnSlide_BarHorizontal($objPHPPowerPoint); + +fnSlide_Bar3D($objPHPPowerPoint); + +fnSlide_Bar3DHorizontal($objPHPPowerPoint); + +fnSlide_Pie3D($objPHPPowerPoint); + +fnSlide_Pie($objPHPPowerPoint); + +fnSlide_Scatter($objPHPPowerPoint); + +// Save file +echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_05_Chart_Line.php b/samples/Sample_05_Chart_Line.php new file mode 100644 index 000000000..66eae16ae --- /dev/null +++ b/samples/Sample_05_Chart_Line.php @@ -0,0 +1,121 @@ +getProperties()->setCreator('PHPOffice')->setLastModifiedBy('PHPPowerPoint Team')->setTitle('Sample 07 Title')->setSubject('Sample 07 Subject')->setDescription('Sample 07 Description')->setKeywords('office 2007 openxml libreoffice odt php')->setCategory('Sample Category'); + +// Remove first slide +echo date('H:i:s') . ' Remove first slide' . EOL; +$objPHPPowerPoint->removeSlideByIndex(0); + +// Set Style +$oFill = new Fill(); +$oFill->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFE06B20')); + +$oShadow = new Shadow(); +$oShadow->setVisible(true)->setDirection(45)->setDistance(10); + +// Generate sample data for chart +echo date('H:i:s') . ' Generate sample data for chart' . EOL; +$seriesData = array( + 'Monday' => 12, + 'Tuesday' => 15, + 'Wednesday' => 13, + 'Thursday' => 17, + 'Friday' => 14, + 'Saturday' => 9, + 'Sunday' => 7 +); + +// Create templated slide +echo EOL . date('H:i:s') . ' Create templated slide' . EOL; +$currentSlide = createTemplatedSlide($objPHPPowerPoint); + +// Create a line chart (that should be inserted in a shape) +echo date('H:i:s') . ' Create a line chart (that should be inserted in a chart shape)' . EOL; +$lineChart = new Line(); +$series = new Series('Downloads', $seriesData); +$series->setShowSeriesName(true); +$series->setShowValue(true); +$lineChart->addSeries($series); + +// Create a shape (chart) +echo date('H:i:s') . ' Create a shape (chart)' . EOL; +$shape = $currentSlide->createChartShape(); +$shape->setName('PHPPowerPoint Daily Downloads')->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80); +$shape->setShadow($oShadow); +$shape->setFill($oFill); +$shape->getBorder()->setLineStyle(Border::LINE_SINGLE); +$shape->getTitle()->setText('PHPPowerPoint Daily Downloads'); +$shape->getTitle()->getFont()->setItalic(true); +$shape->getPlotArea()->setType($lineChart); +$shape->getView3D()->setRotationX(30); +$shape->getView3D()->setPerspective(30); +$shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); +$shape->getLegend()->getFont()->setItalic(true); + +// Create templated slide +echo EOL . date('H:i:s') . ' Create templated slide' . EOL; +$currentSlide = createTemplatedSlide($objPHPPowerPoint); + +// Create a line chart (that should be inserted in a shape) +echo date('H:i:s') . ' Create a line chart (that should be inserted in a chart shape)' . EOL; +$lineChart1 = clone $lineChart; + +// Create a shape (chart) +echo date('H:i:s') . ' Create a shape (chart)' . EOL; +echo date('H:i:s') . ' Differences with previous : Values on right axis and Legend hidden' . EOL; +$shape1 = clone $shape; +$shape1->getLegend()->setVisible(false); +$shape1->setName('PHPPowerPoint Weekly Downloads'); +$shape1->getTitle()->setText('PHPPowerPoint Weekly Downloads'); +$shape1->getPlotArea()->setType($lineChart1); +$shape1->getPlotArea()->getAxisY()->setFormatCode('#,##0'); +$currentSlide->addShape($shape1); + +// Create templated slide +echo EOL . date('H:i:s') . ' Create templated slide' . EOL; +$currentSlide = createTemplatedSlide($objPHPPowerPoint); + +// Create a line chart (that should be inserted in a shape) +echo date('H:i:s') . ' Create a line chart (that should be inserted in a chart shape)' . EOL; +$lineChart2 = clone $lineChart; +$series2 = $lineChart2->getData(); +$series2[0]->getFill()->setFillType(Fill::FILL_SOLID); +$lineChart2->setData($series2); + +// Create a shape (chart) +echo date('H:i:s') . ' Create a shape (chart)' . EOL; +echo date('H:i:s') . ' Differences with previous : Values on right axis and Legend hidden' . EOL; +$shape2 = clone $shape; +$shape2->getLegend()->setVisible(false); +$shape2->setName('PHPPowerPoint Weekly Downloads'); +$shape2->getTitle()->setText('PHPPowerPoint Weekly Downloads'); +$shape2->getPlotArea()->setType($lineChart2); +$shape2->getPlotArea()->getAxisY()->setFormatCode('#,##0'); +$currentSlide->addShape($shape2); + +// Save file +echo EOL . write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); + +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_08_Chart_with_PHPExcel.php b/samples/Sample_05_Chart_with_PHPExcel.php similarity index 100% rename from samples/Sample_08_Chart_with_PHPExcel.php rename to samples/Sample_05_Chart_with_PHPExcel.php diff --git a/samples/Sample_06_Fill.php b/samples/Sample_06_Fill.php new file mode 100644 index 000000000..f4322e209 --- /dev/null +++ b/samples/Sample_06_Fill.php @@ -0,0 +1,72 @@ +getProperties()->setCreator('PHPOffice') + ->setLastModifiedBy('PHPPowerPoint Team') + ->setTitle('Sample 01 Title') + ->setSubject('Sample 01 Subject') + ->setDescription('Sample 01 Description') + ->setKeywords('office 2007 openxml libreoffice odt php') + ->setCategory('Sample Category'); + +// Create slide +echo date('H:i:s') . ' Create slide'.EOL; +$currentSlide = $objPHPPowerPoint->getActiveSlide(); + + +for($inc = 1 ; $inc <= 4 ; $inc++){ + // Create a shape (text) + echo date('H:i:s') . ' Create a shape (rich text)'.EOL; + $shape = $currentSlide->createRichTextShape() + ->setHeight(200) + ->setWidth(300); + if($inc == 1 || $inc == 3){ + $shape->setOffsetX(10); + } else { + $shape->setOffsetX(320); + } + if($inc == 1 || $inc == 2){ + $shape->setOffsetY(10); + } else { + $shape->setOffsetY(220); + } + $shape->getActiveParagraph()->getAlignment()->setHorizontal( Alignment::HORIZONTAL_CENTER ); + + switch ($inc) { + case 1 : + $shape->getFill()->setFillType(Fill::FILL_NONE); + break; + case 2 : + $shape->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR)->setRotation(90)->setStartColor(new Color( 'FF4672A8' ))->setEndColor(new Color( 'FF000000' )); + break; + case 3 : + $shape->getFill()->setFillType(Fill::FILL_GRADIENT_PATH)->setRotation(90)->setStartColor(new Color( 'FF4672A8' ))->setEndColor(new Color( 'FF000000' )); + break; + case 4 : + $shape->getFill()->setFillType(Fill::FILL_SOLID)->setRotation(90)->setStartColor(new Color( 'FF4672A8' ))->setEndColor(new Color( 'FF4672A8' )); + break; + } + + $textRun = $shape->createTextRun('Use PHPPowerPoint!'); + $textRun->getFont()->setBold(true) + ->setSize(30) + ->setColor( new Color('FFE06B20') ); +} + +// Save file +echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_07_Border.php b/samples/Sample_07_Border.php new file mode 100644 index 000000000..e1648a8f4 --- /dev/null +++ b/samples/Sample_07_Border.php @@ -0,0 +1,63 @@ +getProperties()->setCreator('PHPOffice')->setLastModifiedBy('PHPPowerPoint Team')->setTitle('Sample 01 Title')->setSubject('Sample 01 Subject')->setDescription('Sample 01 Description')->setKeywords('office 2007 openxml libreoffice odt php')->setCategory('Sample Category'); + +// Create slide +echo date('H:i:s') . ' Create slide' . EOL; +$currentSlide = $objPHPPowerPoint->getActiveSlide(); + + +for ($inc = 1; $inc <= 4; $inc++) { + // Create a shape (text) + echo date('H:i:s') . ' Create a shape (rich text)' . EOL; + $shape = $currentSlide->createRichTextShape()->setHeight(200)->setWidth(300); + if ($inc == 1 || $inc == 3) { + $shape->setOffsetX(10); + } else { + $shape->setOffsetX(320); + } + if ($inc == 1 || $inc == 2) { + $shape->setOffsetY(10); + } else { + $shape->setOffsetY(220); + } + $shape->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); + + switch ($inc) { + case 1: + $shape->getBorder()->setColor(new Color('FF4672A8'))->setDashStyle(Border::DASH_SOLID)->setLineStyle(Border::LINE_DOUBLE); + break; + case 2: + $shape->getBorder()->setColor(new Color('FF4672A8'))->setDashStyle(Border::DASH_DASH)->setLineStyle(Border::LINE_SINGLE); + break; + case 3: + $shape->getBorder()->setColor(new Color('FF4672A8'))->setDashStyle(Border::DASH_DOT)->setLineStyle(Border::LINE_THICKTHIN); + break; + case 4: + $shape->getBorder()->setColor(new Color('FF4672A8'))->setDashStyle(Border::DASH_LARGEDASHDOT)->setLineStyle(Border::LINE_THINTHICK); + break; + } + + $textRun = $shape->createTextRun('Use PHPPowerPoint!'); + $textRun->getFont()->setBold(true)->setSize(30)->setColor(new Color('FFE06B20')); +} + +// Save file +echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_07_Chart.php b/samples/Sample_07_Chart.php deleted file mode 100644 index 9be81e9ee..000000000 --- a/samples/Sample_07_Chart.php +++ /dev/null @@ -1,207 +0,0 @@ -getProperties()->setCreator('PHPOffice') - ->setLastModifiedBy('PHPPowerPoint Team') - ->setTitle('Sample 07 Title') - ->setSubject('Sample 07 Subject') - ->setDescription('Sample 07 Description') - ->setKeywords('office 2007 openxml libreoffice odt php') - ->setCategory('Sample Category'); - -// Remove first slide -echo date('H:i:s') . ' Remove first slide'.EOL; -$objPHPPowerPoint->removeSlideByIndex(0); - -// Set Style -$oFill = new Fill(); -$oFill->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFE06B20')); - -$oShadow = new Shadow(); -$oShadow->setVisible(true)->setDirection(45)->setDistance(10); - -// Create templated slide -echo date('H:i:s') . ' Create templated slide'.EOL; -$currentSlide = createTemplatedSlide($objPHPPowerPoint); - -// Generate sample data for first chart -echo date('H:i:s') . ' Generate sample data for first chart'.EOL; -$series1Data = array('Jan' => 133, 'Feb' => 99, 'Mar' => 191, 'Apr' => 205, 'May' => 167, 'Jun' => 201, 'Jul' => 240, 'Aug' => 226, 'Sep' => 255, 'Oct' => 264, 'Nov' => 283, 'Dec' => 293); -$series2Data = array('Jan' => 266, 'Feb' => 198, 'Mar' => 271, 'Apr' => 305, 'May' => 267, 'Jun' => 301, 'Jul' => 340, 'Aug' => 326, 'Sep' => 344, 'Oct' => 364, 'Nov' => 383, 'Dec' => 379); - -// Create a bar chart (that should be inserted in a shape) -echo date('H:i:s') . ' Create a bar chart (that should be inserted in a chart shape)'.EOL; -$bar3DChart = new Bar3D(); -$series1 = new Series('2009', $series1Data); -$series1->setShowSeriesName(true); -$series1->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4F81BD')); -$series1->getFont()->getColor()->setRGB('00FF00'); -$series1->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFE06B20')); -$series2 = new Series('2010', $series2Data); -$series2->setShowSeriesName(true); -$series2->getFont()->getColor()->setRGB('FF0000'); -$series2->getFill()->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFC0504D')); -$bar3DChart->addSeries($series1); -$bar3DChart->addSeries($series2); - -// Create a shape (chart) -echo date('H:i:s') . ' Create a shape (chart)'.EOL; -$shape = $currentSlide->createChartShape(); -$shape->setName('PHPPowerPoint Monthly Downloads') - ->setResizeProportional(false) - ->setHeight(550) - ->setWidth(700) - ->setOffsetX(120) - ->setOffsetY(80); -$shape->setShadow($oShadow); -$shape->setFill($oFill); -$shape->getBorder()->setLineStyle(Border::LINE_SINGLE); -$shape->getTitle()->setText('PHPPowerPoint Monthly Downloads'); -$shape->getTitle()->getFont()->setItalic(true); -$shape->getTitle()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT); -$shape->getPlotArea()->getAxisX()->setTitle('Month'); -$shape->getPlotArea()->getAxisY()->setTitle('Downloads'); -$shape->getPlotArea()->setType($bar3DChart); -$shape->getView3D()->setRightAngleAxes(true); -$shape->getView3D()->setRotationX(20); -$shape->getView3D()->setRotationY(20); -$shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); -$shape->getLegend()->getFont()->setItalic(true); - -// Create templated slide -echo date('H:i:s') . ' Create templated slide'.EOL; -$currentSlide = createTemplatedSlide($objPHPPowerPoint); - -// Generate sample data for second chart -echo date('H:i:s') . ' Generate sample data for second chart'.EOL; -$seriesData = array('Monday' => 12, 'Tuesday' => 15, 'Wednesday' => 13, 'Thursday' => 17, 'Friday' => 14, 'Saturday' => 9, 'Sunday' => 7); - -// Create a pie chart (that should be inserted in a shape) -echo date('H:i:s') . ' Create a pie chart (that should be inserted in a chart shape)'.EOL; -$pie3DChart = new Pie3D(); -$series = new Series('Downloads', $seriesData); -$series->setShowSeriesName(true); -$series->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4672A8')); -$series->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFAB4744')); -$series->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF8AA64F')); -$series->getDataPointFill(3)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF725990')); -$series->getDataPointFill(4)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4299B0')); -$series->getDataPointFill(5)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFDC853E')); -$series->getDataPointFill(6)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF93A9CE')); -$pie3DChart->addSeries($series); - -// Create a shape (chart) -echo date('H:i:s') . ' Create a shape (chart)'.EOL; -$shape = $currentSlide->createChartShape(); -$shape->setName('PHPPowerPoint Daily Downloads') - ->setResizeProportional(false) - ->setHeight(550) - ->setWidth(700) - ->setOffsetX(120) - ->setOffsetY(80); -$shape->setShadow($oShadow); -$shape->setFill($oFill); -$shape->getBorder()->setLineStyle(Border::LINE_SINGLE); -$shape->getTitle()->setText('PHPPowerPoint Daily Downloads'); -$shape->getTitle()->getFont()->setItalic(true); -$shape->getPlotArea()->setType($pie3DChart); -$shape->getView3D()->setRotationX(30); -$shape->getView3D()->setPerspective(30); -$shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); -$shape->getLegend()->getFont()->setItalic(true); - -// Create templated slide -echo date('H:i:s') . ' Create templated slide'.EOL; -$currentSlide = createTemplatedSlide($objPHPPowerPoint); // local function - -// Generate sample data for third chart -echo date('H:i:s') . ' Generate sample data for third chart'.EOL; -$seriesData = array('Monday' => 12, 'Tuesday' => 15, 'Wednesday' => 13, 'Thursday' => 17, 'Friday' => 14, 'Saturday' => 9, 'Sunday' => 7); - -// Create a line chart (that should be inserted in a shape) -echo date('H:i:s') . ' Create a line chart (that should be inserted in a chart shape)'.EOL; -$lineChart = new Line(); -$series = new Series('Downloads', $seriesData); -$series->setShowSeriesName(true); -$lineChart->addSeries($series); - -// Create a shape (chart) -echo date('H:i:s') . ' Create a shape (chart)'.EOL; -$shape = $currentSlide->createChartShape(); -$shape->setName('PHPPowerPoint Daily Downloads') - ->setResizeProportional(false) - ->setHeight(550) - ->setWidth(700) - ->setOffsetX(120) - ->setOffsetY(80); -$shape->setShadow($oShadow); -$shape->setFill($oFill); -$shape->getBorder()->setLineStyle(Border::LINE_SINGLE); -$shape->getTitle()->setText('PHPPowerPoint Daily Downloads'); -$shape->getTitle()->getFont()->setItalic(true); -$shape->getPlotArea()->setType($lineChart); -$shape->getView3D()->setRotationX(30); -$shape->getView3D()->setPerspective(30); -$shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); -$shape->getLegend()->getFont()->setItalic(true); - - -// Create templated slide -echo date('H:i:s') . ' Create templated slide'.EOL; -$currentSlide = createTemplatedSlide($objPHPPowerPoint); // local function - -// Generate sample data for fourth chart -echo date('H:i:s') . ' Generate sample data for fourth chart'.EOL; -$seriesData = array('Monday' => 0.1, 'Tuesday' => 0.33333, 'Wednesday' => 0.4444, 'Thursday' => 0.5, 'Friday' => 0.4666, 'Saturday' => 0.3666, 'Sunday' => 0.1666); - -// Create a scatter chart (that should be inserted in a shape) -echo date('H:i:s') . ' Create a scatter chart (that should be inserted in a chart shape)'.EOL; -$lineChart = new Scatter(); -$series = new Series('Downloads', $seriesData); -$series->setShowSeriesName(true); -$lineChart->addSeries($series); - -// Create a shape (chart) -echo date('H:i:s') . ' Create a shape (chart)'.EOL; -$shape = $currentSlide->createChartShape(); -$shape->setName('PHPPowerPoint Daily Download Distribution') - ->setResizeProportional(false) - ->setHeight(550) - ->setWidth(700) - ->setOffsetX(120) - ->setOffsetY(80); -$shape->setShadow($oShadow); -$shape->setFill($oFill); -$shape->getBorder()->setLineStyle(Border::LINE_SINGLE); -$shape->getTitle()->setText('PHPPowerPoint Daily Downloads'); -$shape->getTitle()->getFont()->setItalic(true); -$shape->getPlotArea()->setType($lineChart); -$shape->getView3D()->setRotationX(30); -$shape->getView3D()->setPerspective(30); -$shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE); -$shape->getLegend()->getFont()->setItalic(true); - -// Save file -echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); -if (!CLI) { - include_once 'Sample_Footer.php'; -} diff --git a/samples/Sample_08_Group.php b/samples/Sample_08_Group.php new file mode 100644 index 000000000..fd75ed7b0 --- /dev/null +++ b/samples/Sample_08_Group.php @@ -0,0 +1,57 @@ +getProperties()->setCreator('PHPOffice') + ->setLastModifiedBy('PHPPowerPoint Team') + ->setTitle('Sample 01 Title') + ->setSubject('Sample 01 Subject') + ->setDescription('Sample 01 Description') + ->setKeywords('office 2007 openxml libreoffice odt php') + ->setCategory('Sample Category'); + +// Create slide +echo date('H:i:s') . ' Create slide'.EOL; +$currentGroup = $objPHPPowerPoint->getActiveSlide()->createGroup(); + +// Create a shape (drawing) +echo date('H:i:s') . ' Create a shape (drawing)'.EOL; +$shape = $currentGroup->createDrawingShape(); +$shape->setName('PHPPowerPoint logo') + ->setDescription('PHPPowerPoint logo') + ->setPath('./resources/phppowerpoint_logo.gif') + ->setHeight(36) + ->setOffsetX(10) + ->setOffsetY(10); +$shape->getShadow()->setVisible(true) + ->setDirection(45) + ->setDistance(10); + +// Create a shape (text) +echo date('H:i:s') . ' Create a shape (rich text)'.EOL; +$shape = $currentGroup->createRichTextShape() + ->setHeight(300) + ->setWidth(600) + ->setOffsetX(170) + ->setOffsetY(180); +$shape->getActiveParagraph()->getAlignment()->setHorizontal( Alignment::HORIZONTAL_CENTER ); +$textRun = $shape->createTextRun('Thank you for using PHPPowerPoint!'); +$textRun->getFont()->setBold(true) + ->setSize(60) + ->setColor( new Color( 'FFE06B20' ) ); + +// Save file +echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_09_SlideNote.php b/samples/Sample_09_SlideNote.php new file mode 100644 index 000000000..152d92d6a --- /dev/null +++ b/samples/Sample_09_SlideNote.php @@ -0,0 +1,63 @@ +getProperties()->setCreator('PHPOffice')->setLastModifiedBy('PHPPowerPoint Team')->setTitle('Sample 01 Title')->setSubject('Sample 01 Subject')->setDescription('Sample 01 Description')->setKeywords('office 2007 openxml libreoffice odt php')->setCategory('Sample Category'); + +// Create slide +echo date('H:i:s') . ' Create slide' . EOL; +$currentSlide = $objPHPPowerPoint->getActiveSlide(); + +// Create a shape (drawing) +echo date('H:i:s') . ' Create a shape (drawing)'.EOL; +$shape = $currentSlide->createDrawingShape(); +$shape->setName('PHPPowerPoint logo') +->setDescription('PHPPowerPoint logo') +->setPath('./resources/phppowerpoint_logo.gif') +->setHeight(36) +->setOffsetX(10) +->setOffsetY(10); +$shape->getShadow()->setVisible(true) +->setDirection(45) +->setDistance(10); +$shape->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPowerPoint/')->setTooltip('PHPPowerPoint'); + +// Create a shape (text) +echo date('H:i:s') . ' Create a shape (rich text)'.EOL; +$shape = $currentSlide->createRichTextShape() + ->setHeight(300) + ->setWidth(600) + ->setOffsetX(170) + ->setOffsetY(180); +$shape->getActiveParagraph()->getAlignment()->setHorizontal( Alignment::HORIZONTAL_CENTER ); +$textRun = $shape->createTextRun('Thank you for using PHPPowerPoint!'); +$textRun->getFont()->setBold(true) +->setSize(60) +->setColor( new Color( 'FFE06B20' ) ); + +// Set Note +echo date('H:i:s') . ' Set Note' . EOL; +$oNote = $currentSlide->getNote(); +$oRichText = $oNote->createRichTextShape()->setHeight(300)->setWidth(600)->setOffsetX(170)->setOffsetY(180);; +$oRichText->createTextRun('A class library'); +$oRichText->createParagraph()->createTextRun('Written in PHP'); +$oRichText->createParagraph()->createTextRun('Representing a presentation'); +$oRichText->createParagraph()->createTextRun('Supports writing to different file formats'); + +// Save file +echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_10_Transition.php b/samples/Sample_10_Transition.php new file mode 100644 index 000000000..ed1106ef5 --- /dev/null +++ b/samples/Sample_10_Transition.php @@ -0,0 +1,71 @@ +getProperties()->setCreator('PHPOffice') + ->setLastModifiedBy('PHPPowerPoint Team') + ->setTitle('Sample 10 Title') + ->setSubject('Sample 10 Subject') + ->setDescription('Sample 10 Description') + ->setKeywords('office 2007 openxml libreoffice odt php') + ->setCategory('Sample Category'); + +// Create slide +echo date('H:i:s') . ' Create slide'.EOL; +$slide0 = $objPHPPowerPoint->getActiveSlide(); + +// Create a shape (drawing) +echo date('H:i:s') . ' Create a shape (drawing)'.EOL; +$shapeDrawing = $slide0->createDrawingShape(); +$shapeDrawing->setName('PHPPowerPoint logo') + ->setDescription('PHPPowerPoint logo') + ->setPath('./resources/phppowerpoint_logo.gif') + ->setHeight(36) + ->setOffsetX(10) + ->setOffsetY(10); +$shapeDrawing->getShadow()->setVisible(true) + ->setDirection(45) + ->setDistance(10); +$shapeDrawing->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPowerPoint/')->setTooltip('PHPPowerPoint'); + +// Create a shape (text) +echo date('H:i:s') . ' Create a shape (rich text)'.EOL; +$shapeRichText = $slide0->createRichTextShape() + ->setHeight(300) + ->setWidth(600) + ->setOffsetX(170) + ->setOffsetY(180); +$shapeRichText->getActiveParagraph()->getAlignment()->setHorizontal( Alignment::HORIZONTAL_CENTER ); +$textRun = $shapeRichText->createTextRun('Thank you for using PHPPowerPoint!'); +$textRun->getFont()->setBold(true) + ->setSize(60) + ->setColor( new Color( 'FFE06B20' ) ); + +$oTransition = new Transition(); +$oTransition->setManualTrigger(false); +$oTransition->setTimeTrigger(true, 4000); +$oTransition->setTransitionType(Transition::TRANSITION_SPLIT_IN_VERTICAL); +$slide0->setTransition($oTransition); + +// Create slide +echo date('H:i:s') . ' Create slide'.EOL; +$slide1 = $objPHPPowerPoint->createSlide(); +$slide1->addShape(clone $shapeDrawing); +$slide1->addShape(clone $shapeRichText); + +// Save file +echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_11_Shape.php b/samples/Sample_11_Shape.php new file mode 100644 index 000000000..36a17791d --- /dev/null +++ b/samples/Sample_11_Shape.php @@ -0,0 +1,82 @@ +createRichTextShape(); + $shape->setHeight(100); + $shape->setWidth(600); + $shape->setOffsetX(100); + $shape->setOffsetY(100); + $shape->getActiveParagraph()->getAlignment()->setHorizontal( Alignment::HORIZONTAL_LEFT ); + + $textRun = $shape->createTextRun('RichText with'); + $textRun->getFont()->setBold(true); + $textRun->getFont()->setSize(28); + $textRun->getFont()->setColor(new Color( 'FF000000' )); + + $shape->createBreak(); + + $textRun = $shape->createTextRun('Multiline'); + $textRun->getFont()->setBold(true); + $textRun->getFont()->setSize(60); + $textRun->getFont()->setColor(new Color( 'FF000000' )); +} + +function fnSlideRichTextShadow(PhpPowerpoint $objPHPPowerPoint) { + // Create templated slide + echo date('H:i:s') . ' Create templated slide'.EOL; + $currentSlide = createTemplatedSlide($objPHPPowerPoint); + + // Create a shape (text) + echo date('H:i:s') . ' Create a shape (rich text) with shadow'.EOL; + $shape = $currentSlide->createRichTextShape(); + $shape->setHeight(100); + $shape->setWidth(400); + $shape->setOffsetX(100); + $shape->setOffsetY(100); + $shape->getActiveParagraph()->getAlignment()->setHorizontal( Alignment::HORIZONTAL_LEFT ); + $shape->getShadow()->setVisible(true)->setAlpha(75)->setBlurRadius(2)->setDirection(45); + + $textRun = $shape->createTextRun('RichText with shadow'); + $textRun->getFont()->setColor(new Color( 'FF000000' )); +} + +// Create new PHPPowerPoint object +echo date('H:i:s') . ' Create new PHPPowerPoint object'.EOL; +$objPHPPowerPoint = new PhpPowerpoint(); + +// Set properties +echo date('H:i:s') . ' Set properties'.EOL; +$oProperties = $objPHPPowerPoint->getProperties(); +$oProperties->setCreator('PHPOffice') + ->setLastModifiedBy('PHPPowerPoint Team') + ->setTitle('Sample 11 Title') + ->setSubject('Sample 11 Subject') + ->setDescription('Sample 11 Description') + ->setKeywords('office 2007 openxml libreoffice odt php') + ->setCategory('Sample Category'); + +// Remove first slide +echo date('H:i:s') . ' Remove first slide'.EOL; +$objPHPPowerPoint->removeSlideByIndex(0); + +fnSlideRichText($objPHPPowerPoint); +fnSlideRichTextShadow($objPHPPowerPoint); + +// Save file +echo write($objPHPPowerPoint, basename(__FILE__, '.php'), $writers); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_12_Reader_PowerPoint97.php b/samples/Sample_12_Reader_PowerPoint97.php new file mode 100644 index 000000000..cec570d8f --- /dev/null +++ b/samples/Sample_12_Reader_PowerPoint97.php @@ -0,0 +1,172 @@ +oPhpPowerpoint = $oPHPPpt; + } + + public function display() + { + $this->append('
'); + $this->append('
'); + $this->append('
'); + $this->append('
'); + $this->append('
    '); + $this->displayPhpPowerpoint($this->oPhpPowerpoint); + $this->append('
'); + $this->append('
'); + $this->append('
'); + $this->append('
'); + $this->displayPhpPowerpointInfo($this->oPhpPowerpoint); + $this->append('
'); + $this->append('
'); + $this->append('
'); + + return $this->htmlOutput; + } + + protected function append($sHTML) + { + $this->htmlOutput .= $sHTML; + } + + protected function displayPhpPowerpoint(PhpPowerpoint $oPHPPpt) + { + $this->append('
  • PhpPowerpoint'); + $this->append('
      '); + $this->append('
    • Info "PhpPowerpoint"
    • '); + foreach ($oPHPPpt->getAllSlides() as $oSlide) { + $this->append('
    • Slide'); + $this->append('
        '); + $this->append('
      • Info "Slide"
      • '); + foreach ($oSlide->getShapeCollection() as $oShape) { + if($oShape instanceof Group) { + $this->append('
      • Shape "Group"'); + $this->append('
          '); + // $this->append('
        • Info "Group"
        • '); + foreach ($oShape->getShapeCollection() as $oShapeChild) { + $this->displayShape($oShapeChild); + } + $this->append('
        '); + $this->append('
      • '); + } else { + $this->displayShape($oShape); + } + } + $this->append('
      '); + $this->append('
    • '); + } + $this->append('
    '); + $this->append('
  • '); + } + + protected function displayShape(AbstractShape $shape) + { + if($shape instanceof MemoryDrawing) { + $this->append('
  • Shape "MemoryDrawing"
  • '); + } elseif($shape instanceof RichText) { + $this->append('
  • Shape "RichText"
  • '); + } else { + var_export($shape); + } + } + + protected function displayPhpPowerpointInfo(PhpPowerpoint $oPHPPpt) + { + $this->append('
    '); + $this->append('
    '); + $this->append('
    Number of slides
    '.$oPHPPpt->getSlideCount().'
    '); + $this->append('
    Document Layout Height
    '.$oPHPPpt->getLayout()->getCY(DocumentLayout::UNIT_MILLIMETER).' mm
    '); + $this->append('
    Document Layout Width
    '.$oPHPPpt->getLayout()->getCX(DocumentLayout::UNIT_MILLIMETER).' mm
    '); + $this->append('
    Properties : Category
    '.$oPHPPpt->getProperties()->getCategory().'
    '); + $this->append('
    Properties : Company
    '.$oPHPPpt->getProperties()->getCompany().'
    '); + $this->append('
    Properties : Created
    '.$oPHPPpt->getProperties()->getCreated().'
    '); + $this->append('
    Properties : Creator
    '.$oPHPPpt->getProperties()->getCreator().'
    '); + $this->append('
    Properties : Description
    '.$oPHPPpt->getProperties()->getDescription().'
    '); + $this->append('
    Properties : Keywords
    '.$oPHPPpt->getProperties()->getKeywords().'
    '); + $this->append('
    Properties : Last Modified By
    '.$oPHPPpt->getProperties()->getLastModifiedBy().'
    '); + $this->append('
    Properties : Modified
    '.$oPHPPpt->getProperties()->getModified().'
    '); + $this->append('
    Properties : Subject
    '.$oPHPPpt->getProperties()->getSubject().'
    '); + $this->append('
    Properties : Title
    '.$oPHPPpt->getProperties()->getTitle().'
    '); + $this->append('
    '); + $this->append('
    '); + + foreach ($oPHPPpt->getAllSlides() as $oSlide) { + $this->append('
    '); + $this->append('
    '); + $this->append('
    HashCode
    '.$oSlide->getHashCode().'
    '); + $this->append('
    Slide Layout
    '.$oSlide->getSlideLayout().'
    '); + $this->append('
    Offset X
    '.$oSlide->getOffsetX().'
    '); + $this->append('
    Offset Y
    '.$oSlide->getOffsetY().'
    '); + $this->append('
    Extent X
    '.$oSlide->getExtentX().'
    '); + $this->append('
    Extent Y
    '.$oSlide->getExtentY().'
    '); + $this->append('
    '); + $this->append('
    '); + + foreach ($oSlide->getShapeCollection() as $oShape) { + if($oShape instanceof Group) { + foreach ($oShape->getShapeCollection() as $oShapeChild) { + $this->displayShapeInfo($oShapeChild); + } + } else { + $this->displayShapeInfo($oShape); + } + } + } + } + + protected function displayShapeInfo(AbstractShape $oShape) + { + $this->append('
    '); + $this->append('
    '); + $this->append('
    HashCode
    '.$oShape->getHashCode().'
    '); + $this->append('
    Offset X
    '.$oShape->getOffsetX().'
    '); + $this->append('
    Offset Y
    '.$oShape->getOffsetY().'
    '); + $this->append('
    Height
    '.$oShape->getHeight().'
    '); + $this->append('
    Width
    '.$oShape->getWidth().'
    '); + $this->append('
    Rotation
    '.$oShape->getRotation().'°
    '); + $this->append('
    Hyperlink
    '.ucfirst(var_export($oShape->hasHyperlink(), true)).'
    '); + $this->append('
    Fill
    @Todo
    '); + $this->append('
    Border
    @Todo
    '); + if($oShape instanceof MemoryDrawing) { + ob_start(); + call_user_func($oShape->getRenderingFunction(), $oShape->getImageResource()); + $sShapeImgContents = ob_get_contents(); + ob_end_clean(); + $this->append('
    Mime-Type
    '.$oShape->getMimeType().'
    '); + $this->append('
    Image
    '); + } else { + // Add another shape + } + $this->append('
    '); + $this->append('
    '); + } +} + +$pptReader = PhpOffice\PhpPowerpoint\IOFactory::createReader('PowerPoint97'); +$oPHPPowerPoint = $pptReader->load('resources/Sample_12.ppt'); + +$oTree = new PhpPptTree($oPHPPowerPoint); +echo $oTree->display(); +if (!CLI) { + include_once 'Sample_Footer.php'; +} diff --git a/samples/Sample_Footer.php b/samples/Sample_Footer.php index 892f9262b..4aeadf902 100644 --- a/samples/Sample_Footer.php +++ b/samples/Sample_Footer.php @@ -6,5 +6,6 @@ + \ No newline at end of file diff --git a/samples/Sample_Header.php b/samples/Sample_Header.php index 4871f6c87..b85f26ab3 100644 --- a/samples/Sample_Header.php +++ b/samples/Sample_Header.php @@ -5,6 +5,7 @@ use PhpOffice\PhpPowerpoint\Autoloader; use PhpOffice\PhpPowerpoint\Settings; use PhpOffice\PhpPowerpoint\IOFactory; +use PhpOffice\PhpPowerpoint\Slide; error_reporting(E_ALL); define('CLI', (PHP_SAPI == 'cli') ? true : false); @@ -15,6 +16,8 @@ require_once __DIR__ . '/../src/PhpPowerpoint/Autoloader.php'; Autoloader::register(); +require_once __DIR__ . '/../vendor/autoload.php'; + // Set writers $writers = array('PowerPoint2007' => 'pptx', 'ODPresentation' => 'odp'); @@ -44,7 +47,7 @@ /** * Write documents * - * @param \PhpOffice\PhpWord\PhpWord $phpWord + * @param \PhpOffice\PhpPowerPoint\PhpPowerPoint $phpPowerPoint * @param string $filename * @param array $writers */ @@ -112,7 +115,7 @@ function getEndingNotes($writers) * Creates a templated slide * * @param PHPPowerPoint $objPHPPowerPoint - * @return PHPPowerPoint_Slide + * @return \PhpOffice\PhpPowerpoint\Slide */ function createTemplatedSlide(PhpOffice\PhpPowerpoint\PhpPowerpoint $objPHPPowerPoint) { diff --git a/samples/Sample_02_Presentation.php b/samples/Sample_X2_Presentation.php similarity index 100% rename from samples/Sample_02_Presentation.php rename to samples/Sample_X2_Presentation.php diff --git a/samples/Sample_05_Templated.php b/samples/Sample_X5_Templated.php similarity index 100% rename from samples/Sample_05_Templated.php rename to samples/Sample_X5_Templated.php diff --git a/samples/bootstrap/css/phppowerpoint.css b/samples/bootstrap/css/phppowerpoint.css index fc410ec21..5829df2ac 100644 --- a/samples/bootstrap/css/phppowerpoint.css +++ b/samples/bootstrap/css/phppowerpoint.css @@ -1,7 +1,6 @@ body { padding-top: 20px; padding-bottom: 20px; - min-height: 1000px; } .navbar { margin-bottom: 20px; @@ -12,3 +11,77 @@ body { .failed { color: #ff0000; } +.tree { + min-height:20px; + padding:19px; + margin-bottom:20px; + background-color:#fbfbfb; + -webkit-border-radius:4px; + -moz-border-radius:4px; +} +.tree li { + list-style-type:none; + margin:0; + padding:10px 5px 0 5px; + position:relative +} +.tree li::before, .tree li::after { + content:''; + left:-20px; + position:absolute; + right:auto +} +.tree li::before { + border-left:1px solid #999; + bottom:50px; + height:100%; + top:0; + width:1px +} +.tree li::after { + border-top:1px solid #999; + height:20px; + top:30px; + width:25px +} +.tree li span { + -moz-border-radius:5px; + -webkit-border-radius:5px; + border:1px solid #999; + border-radius:5px; + display:inline-block; + padding:3px 8px; + text-decoration:none +} +.tree li.parent_li>span { + cursor:pointer +} +.tree>ul>li::before, .tree>ul>li::after { + border:0 +} +.tree li:last-child::before { + height:30px +} +.tree li.parent_li>span:hover, .tree li.parent_li>span:hover+ul li span { + background:#eee; + border:1px solid #94a0b4; + color:#000 +} + +.tree .shape { + cursor: pointer; +} + +.infoBlk { + display:none; +} + +.pptTree { + background-color:#fbfbfb; +} +.pptTree dd { + margin-left: 20px; +} + +.pptTree dd img { + max-width: 50%; \ No newline at end of file diff --git a/samples/bootstrap/js/script.js b/samples/bootstrap/js/script.js new file mode 100644 index 000000000..27dccff33 --- /dev/null +++ b/samples/bootstrap/js/script.js @@ -0,0 +1,20 @@ + $(function () { + $('.tree li:has(ul)').addClass('parent_li').find(' > span').attr('title', 'Collapse this branch'); + $('.tree li.parent_li > span').on('click', function (e) { + var children = $(this).parent('li.parent_li').find(' > ul > li'); + if (children.is(":visible")) { + children.hide('fast'); + $(this).attr('title', 'Expand this branch').find(' > i').addClass('fa-plus-square').removeClass('fa-minus-square'); + } else { + children.show('fast'); + $(this).attr('title', 'Collapse this branch').find(' > i').addClass('fa-minus-square').removeClass('fa-plus-square'); + } + e.stopPropagation(); + }); + + $('.tree .shape').on('click', function (e) { + $('.infoBlk').hide(); + $('.infoBlk#' + $(this).attr('id') + 'Info').show(); + e.stopPropagation(); + }); + }); diff --git a/samples/resources/Sample_12.ppt b/samples/resources/Sample_12.ppt new file mode 100644 index 000000000..032c9605b Binary files /dev/null and b/samples/resources/Sample_12.ppt differ diff --git a/src/PhpPowerpoint/AbstractShape.php b/src/PhpPowerpoint/AbstractShape.php index 97107cf3a..3da295916 100644 --- a/src/PhpPowerpoint/AbstractShape.php +++ b/src/PhpPowerpoint/AbstractShape.php @@ -27,11 +27,11 @@ abstract class AbstractShape implements ComparableInterface { /** - * Slide + * Container * - * @var \PhpOffice\PhpPowerpoint\Slide + * @var \PhpOffice\PhpPowerpoint\ShapeContainerInterface */ - protected $slide; + protected $container; /** * Offset X @@ -109,68 +109,102 @@ abstract class AbstractShape implements ComparableInterface public function __construct() { // Initialise values - $this->slide = null; - $this->offsetX = 0; - $this->offsetY = 0; - $this->width = 0; - $this->height = 0; - $this->rotation = 0; - $this->fill = new Style\Fill(); - $this->border = new Style\Border(); - $this->shadow = new Style\Shadow(); + $this->container = null; + $this->offsetX = 0; + $this->offsetY = 0; + $this->width = 0; + $this->height = 0; + $this->rotation = 0; + $this->fill = new Style\Fill(); + $this->border = new Style\Border(); + $this->shadow = new Style\Shadow(); $this->border->setLineStyle(Style\Border::LINE_NONE); } + + public function __clone() + { + $this->container = null; + $this->fill = clone $this->fill; + $this->border = clone $this->border; + $this->shadow = clone $this->shadow; + } /** - * Get Slide + * Get Container, Slide or Group * - * @return \PhpOffice\PhpPowerpoint\Slide + * @return \PhpOffice\PhpPowerpoint\Container */ - public function getSlide() + public function getContainer() { - return $this->slide; + return $this->container; } /** - * Set Slide + * Set Container, Slide or Group * - * @param \PhpOffice\PhpPowerpoint\Slide $pValue + * @param \PhpOffice\PhpPowerpoint\ShapeContainerInterface $pValue * @param bool $pOverrideOld If a Slide has already been assigned, overwrite it and remove image from old Slide? * @throws \Exception * @return self */ - public function setSlide(Slide $pValue = null, $pOverrideOld = false) + public function setContainer(ShapeContainerInterface $pValue = null, $pOverrideOld = false) { - if (is_null($this->slide)) { - // Add drawing to \PhpOffice\PhpPowerpoint\Slide - $this->slide = $pValue; - if (!is_null($this->slide)) { - $this->slide->getShapeCollection()->append($this); + if (is_null($this->container)) { + // Add drawing to \PhpOffice\PhpPowerpoint\ShapeContainerInterface + $this->container = $pValue; + if (!is_null($this->container)) { + $this->container->getShapeCollection()->append($this); } } else { if ($pOverrideOld) { - // Remove drawing from old \PhpOffice\PhpPowerpoint\Slide - $iterator = $this->slide->getShapeCollection()->getIterator(); + // Remove drawing from old \PhpOffice\PhpPowerpoint\ShapeContainerInterface + $iterator = $this->container->getShapeCollection()->getIterator(); while ($iterator->valid()) { if ($iterator->current()->getHashCode() == $this->getHashCode()) { - $this->slide->getShapeCollection()->offsetUnset($iterator->key()); - $this->slide = null; + $this->container->getShapeCollection()->offsetUnset($iterator->key()); + $this->container = null; break; } + $iterator->next(); } // Set new \PhpOffice\PhpPowerpoint\Slide - $this->setSlide($pValue); + $this->setContainer($pValue); } else { - throw new \Exception("A \PhpOffice\PhpPowerpoint\Slide has already been assigned. Shapes can only exist on one \PhpOffice\PhpPowerpoint\Slide."); + throw new \Exception("A \PhpOffice\PhpPowerpoint\ShapeContainerInterface has already been assigned. Shapes can only exist on one \PhpOffice\PhpPowerpoint\ShapeContainerInterface."); } } return $this; } + /** + * Get Slide + * + * @return \PhpOffice\PhpPowerpoint\Container + * @deprecated + */ + public function getSlide() + { + return $this->getContainer(); + } + + /** + * Set Slide + * + * @param \PhpOffice\PhpPowerpoint\Slide $pValue + * @param bool $pOverrideOld If a Slide has already been assigned, overwrite it and remove image from old Slide? + * @throws \Exception + * @return self + * @deprecated + */ + public function setSlide(Slide $pValue = null, $pOverrideOld = false) + { + return $this->setContainer($pValue, $pOverrideOld); + } + /** * Get OffsetX * @@ -395,7 +429,7 @@ public function setHyperlink(Hyperlink $pHyperlink = null) */ public function getHashCode() { - return md5((is_object($this->slide)?$this->slide->getHashCode():'') . $this->offsetX . $this->offsetY . $this->width . $this->height . $this->rotation . $this->getFill()->getHashCode() . $this->shadow->getHashCode() . (is_null($this->hyperlink) ? '' : $this->hyperlink->getHashCode()) . __CLASS__); + return md5((is_object($this->container)?$this->container->getHashCode():'') . $this->offsetX . $this->offsetY . $this->width . $this->height . $this->rotation . $this->getFill()->getHashCode() . $this->shadow->getHashCode() . (is_null($this->hyperlink) ? '' : $this->hyperlink->getHashCode()) . __CLASS__); } /** diff --git a/src/PhpPowerpoint/DocumentLayout.php b/src/PhpPowerpoint/DocumentLayout.php index a28b077cb..1c82271b3 100644 --- a/src/PhpPowerpoint/DocumentLayout.php +++ b/src/PhpPowerpoint/DocumentLayout.php @@ -17,6 +17,8 @@ namespace PhpOffice\PhpPowerpoint; +use PhpOffice\Common\Drawing; + /** * \PhpOffice\PhpPowerpoint\DocumentLayout */ @@ -35,6 +37,12 @@ class DocumentLayout const LAYOUT_LETTER = 'letter'; const LAYOUT_OVERHEAD = 'overhead'; + const UNIT_EMU = 'emu'; + const UNIT_CENTIMETER = 'cm'; + const UNIT_INCH = 'in'; + const UNIT_MILLIMETER = 'mm'; + const UNIT_PIXEL = 'px'; + const UNIT_POINT = 'pt'; /** * Dimension types @@ -144,9 +152,9 @@ public function setDocumentLayout($pValue = self::LAYOUT_SCREEN_4X3, $isLandscap * * @return integer */ - public function getCX() + public function getCX($unit = self::UNIT_EMU) { - return $this->dimensionX; + return $this->convertUnit($this->dimensionX, self::UNIT_EMU, $unit); } /** @@ -154,15 +162,94 @@ public function getCX() * * @return integer */ - public function getCY() + public function getCY($unit = self::UNIT_EMU) + { + return $this->convertUnit($this->dimensionY, self::UNIT_EMU, $unit); + } + + /** + * Get Document Layout cx + * + * @return integer + */ + public function setCX($value, $unit = self::UNIT_EMU) + { + $this->layout = self::LAYOUT_CUSTOM; + $this->dimensionX = $this->convertUnit($value, $unit, self::UNIT_EMU); + return $this; + } + + /** + * Get Document Layout cy + * + * @return integer + */ + public function setCY($value, $unit = self::UNIT_EMU) + { + $this->layout = self::LAYOUT_CUSTOM; + $this->dimensionY = $this->convertUnit($value, $unit, self::UNIT_EMU); + return $this; + } + + /** + * Convert EMUs to differents units + * @param $value + * @param string $fromUnit + * @param string $toUnit + */ + protected function convertUnit($value, $fromUnit, $toUnit) { - return $this->dimensionY; + // Convert from $fromUnit to EMU + switch ($fromUnit) { + case self::UNIT_MILLIMETER: + $value *= 36000; + break; + case self::UNIT_CENTIMETER: + $value *= 360000; + break; + case self::UNIT_INCH: + $value *= 914400; + break; + case self::UNIT_PIXEL: + $value = Drawing::pixelsToEmu($value); + break; + case self::UNIT_POINT: + $value *= 12700; + break; + case self::UNIT_EMU: + default: + // no changes + } + + // Convert from EMU to $toUnit + switch ($toUnit) { + case self::UNIT_MILLIMETER: + $value /= 36000; + break; + case self::UNIT_CENTIMETER: + $value /= 360000; + break; + case self::UNIT_INCH: + $value /= 914400; + break; + case self::UNIT_PIXEL: + $value = Drawing::emuToPixels($value); + break; + case self::UNIT_POINT: + $value /= 12700; + break; + case self::UNIT_EMU: + default: + // no changes + } + return $value; } /** * Get Document Layout in millimeters * * @return integer + * @deprecated 0.4.0 getCX(DocumentLayout::UNIT_MILLIMETER) */ public function getLayoutXmilli() { @@ -173,6 +260,7 @@ public function getLayoutXmilli() * Get Document Layout in millimeters * * @return integer + * @deprecated 0.4.0 getCY(DocumentLayout::UNIT_MILLIMETER) */ public function getLayoutYmilli() { @@ -184,6 +272,7 @@ public function getLayoutYmilli() * * @param integer $pValue Layout width * @return \PhpOffice\PhpPowerpoint\DocumentLayout + * @deprecated 0.4.0 setCY($pValue, DocumentLayout::UNIT_MILLIMETER) */ public function setLayoutXmilli($pValue) { @@ -192,11 +281,13 @@ public function setLayoutXmilli($pValue) return $this; } + /** * Set Document Layout in millimeters * * @param integer $pValue Layout height * @return \PhpOffice\PhpPowerpoint\DocumentLayout + * @deprecated 0.4.0 setCY($pValue, DocumentLayout::UNIT_MILLIMETER) */ public function setLayoutYmilli($pValue) { diff --git a/src/PhpPowerpoint/GeometryCalculator.php b/src/PhpPowerpoint/GeometryCalculator.php new file mode 100644 index 000000000..a2909ab1f --- /dev/null +++ b/src/PhpPowerpoint/GeometryCalculator.php @@ -0,0 +1,96 @@ + 0, self::Y => 0); + + if ($container !== null && count($container->getShapeCollection()) != 0) { + $shapes = $container->getShapeCollection(); + if ($shapes[0] !== null) { + $offsets[self::X] = $shapes[0]->getOffsetX(); + $offsets[self::Y] = $shapes[0]->getOffsetY(); + } + + foreach ($shapes as $shape) { + if ($shape !== null) { + if ($shape->getOffsetX() < $offsets[self::X]) { + $offsets[self::X] = $shape->getOffsetX(); + } + + if ($shape->getOffsetY() < $offsets[self::Y]) { + $offsets[self::Y] = $shape->getOffsetY(); + } + } + } + } + + return $offsets; + } + + /** + * Calculate X and Y extents for a set of shapes within a container such as a slide or group. + * + * @param \PhpOffice\PhpPowerpoint\ShapeContainerInterface $container + * @return array + */ + public static function calculateExtents(ShapeContainerInterface $container) + { + $extents = array(self::X => 0, self::Y => 0); + + if ($container !== null && count($container->getShapeCollection()) != 0) { + $shapes = $container->getShapeCollection(); + if ($shapes[0] !== null) { + $extents[self::X] = $shapes[0]->getOffsetX() + $shapes[0]->getWidth(); + $extents[self::Y] = $shapes[0]->getOffsetY() + $shapes[0]->getHeight(); + } + + foreach ($shapes as $shape) { + if ($shape !== null) { + $extentX = $shape->getOffsetX() + $shape->getWidth(); + $extentY = $shape->getOffsetY() + $shape->getHeight(); + + if ($extentX > $extents[self::X]) { + $extents[self::X] = $extentX; + } + + if ($extentY > $extents[self::Y]) { + $extents[self::Y] = $extentY; + } + } + } + } + + return $extents; + } +} diff --git a/src/PhpPowerpoint/HashTable.php b/src/PhpPowerpoint/HashTable.php index 82dc80776..c9ead1efe 100644 --- a/src/PhpPowerpoint/HashTable.php +++ b/src/PhpPowerpoint/HashTable.php @@ -81,6 +81,7 @@ public function add(ComparableInterface $pSource) { // Determine hashcode $hashIndex = $pSource->getHashIndex(); + if (is_null($hashIndex)) { $hashCode = $pSource->getHashCode(); } elseif (isset($this->keyMap[$hashIndex])) { diff --git a/src/PhpPowerpoint/Reader/PowerPoint97.php b/src/PhpPowerpoint/Reader/PowerPoint97.php index 64ebd16a0..47fbe04bc 100644 --- a/src/PhpPowerpoint/Reader/PowerPoint97.php +++ b/src/PhpPowerpoint/Reader/PowerPoint97.php @@ -17,18 +17,20 @@ namespace PhpOffice\PhpPowerpoint\Reader; -use PhpOffice\PhpPowerpoint\Shared\OLERead; +use PhpOffice\Common\Microsoft\OLERead; use PhpOffice\PhpPowerpoint\Shape\Drawing; use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\MemoryDrawing; use PhpOffice\PhpPowerpoint\Style\Alignment; use PhpOffice\PhpPowerpoint\Style\Color; -use PhpOffice\PhpPowerpoint\Shape\RichText\Paragraph; use PhpOffice\PhpPowerpoint\Shape\RichText; use PhpOffice\PhpPowerpoint\AbstractShape; use PhpOffice\PhpPowerpoint\Style\Bullet; use PhpOffice\PhpPowerpoint\Shape\Hyperlink; use PhpOffice\PhpPowerpoint\Shape\Line; +use PhpOffice\Common\String; +use PhpOffice\PhpPowerPoint\Shape\Group; +use PhpOffice\PhpPowerpoint\Shape\PhpOffice\PhpPowerpoint\Shape; /** * Serialized format reader @@ -43,7 +45,7 @@ class PowerPoint97 implements ReaderInterface const OFFICEARTBLIPDIB = 0xF01F; const OFFICEARTBLIPTIFF = 0xF029; const OFFICEARTBLIPJPEG = 0xF02A; - + /** * @link http://msdn.microsoft.com/en-us/library/dd945336(v=office.12).aspx */ @@ -265,7 +267,7 @@ class PowerPoint97 implements ReaderInterface const RT_VIEWINFOATOM = 0x03FD; const RT_VISUALPAGEATOM = 0x2B01; const RT_VISUALSHAPEATOM = 0x2AFB; - + /** * @var http://msdn.microsoft.com/en-us/library/dd926394(v=office.12).aspx */ @@ -283,7 +285,7 @@ class PowerPoint97 implements ReaderInterface const SL_TWOROWSCOLUMN = 0x0000000B; const SL_VERTICALTITLEBODY = 0x00000011; const SL_VERTICALTWOROWS = 0x00000012; - + /** * Array with Fonts */ @@ -308,7 +310,7 @@ class PowerPoint97 implements ReaderInterface private $rgPersistDirEntry; /** * Offset (in bytes) from the beginning of the PowerPoint Document Stream to the PersistDirectoryAtom record for this user edit - * @var int[] + * @var int */ private $offsetPersistDirectory; /** @@ -316,6 +318,15 @@ class PowerPoint97 implements ReaderInterface * @var PhpPowerpoint */ private $oPhpPowerpoint; + /** + * Group Object + * @var Group + */ + private $oCurrentGroup; + /** + * @var boolean + */ + private $bFirstShapeGroup = false; /** * Stream "Powerpoint Document" * @var string @@ -341,7 +352,7 @@ class PowerPoint97 implements ReaderInterface * @var string */ private $streamPictures; - + /** * Can the current \PhpOffice\PhpPowerpoint\Reader\ReaderInterface read the file? * @@ -395,7 +406,7 @@ public function load($pFilename) // Unserialize... First make sure the file supports it! if (!$this->fileSupportsUnserializePHPPowerPoint($pFilename)) { - throw new \Exception("Invalid file format for PhpOffice\PhpPowerpoint\Reader\Serialized: " . $pFilename . "."); + throw new \Exception("Invalid file format for PhpOffice\PhpPowerpoint\Reader\PowerPoint97: " . $pFilename . "."); } return $this->loadFile($pFilename); @@ -411,7 +422,7 @@ private function loadFile($pFilename) { $this->oPhpPowerpoint = new PhpPowerpoint(); $this->oPhpPowerpoint->removeSlideByIndex(); - + // Read OLE Blocks $this->loadOLE($pFilename); // Read pictures in the Pictures Stream @@ -420,13 +431,13 @@ private function loadFile($pFilename) $this->loadCurrentUserStream(); // Read information in the PowerPoint Document Stream $this->loadPowerpointDocumentStream(); - + return $this->oPhpPowerpoint; } - + /** * Read OLE Part - * @param unknown $pFilename + * @param string $pFilename */ private function loadOLE($pFilename) { @@ -436,16 +447,16 @@ private function loadOLE($pFilename) // PowerPoint Document Stream $this->streamPowerpointDocument = $oOLE->getStream($oOLE->powerpointDocument); - + // Current User Stream $this->streamCurrentUser = $oOLE->getStream($oOLE->currentUser); - + // Get summary information data $this->streamSummaryInformation = $oOLE->getStream($oOLE->summaryInformation); - + // Get additional document summary information data $this->streamDocumentSummaryInformation = $oOLE->getStream($oOLE->docSummaryInfos); - + // Get pictures data $this->streamPictures = $oOLE->getStream($oOLE->pictures); } @@ -456,10 +467,12 @@ private function loadOLE($pFilename) */ private function loadPicturesStream() { + $stream = $this->streamPictures; + $pos = 0; $readSuccess = true; do { - $arrayRH = $this->loadRecordHeader($this->streamPictures, $pos); + $arrayRH = $this->loadRecordHeader($stream, $pos); $pos += 8; if ($arrayRH['recVer'] == 0x00 && ($arrayRH['recType'] == 0xF007 || ($arrayRH['recType'] >= 0xF018 && $arrayRH['recType'] <= 0xF117))) { //@link : http://msdn.microsoft.com/en-us/library/dd950560(v=office.12).aspx @@ -468,36 +481,18 @@ private function loadPicturesStream() throw new \Exception('Feature not implemented (l.'.__LINE__.')'); } if ($arrayRH['recType'] >= 0xF018 && $arrayRH['recType'] <= 0xF117) { - //@link : http://msdn.microsoft.com/en-us/library/dd910081(v=office.12).aspx - switch ($arrayRH['recType']) { - case self::OFFICEARTBLIPJPG: - case self::OFFICEARTBLIPPNG: - // rgbUid1 - $pos += 16; - $arrayRH['recLen'] -= 16; - if ($arrayRH['recInstance'] == 0x6E1) { - // rgbUid2 - $pos += 16; - $arrayRH['recLen'] -= 16; - } - // tag - $pos += 1; - $arrayRH['recLen'] -= 1; - // BLIPFileData - $this->arrayPictures[] = substr($this->streamPictures, $pos, $arrayRH['recLen']); - $pos += $arrayRH['recLen']; - break; - default: - throw new \Exception('Feature not implemented (l.'.__LINE__.' : '.dechex($arrayRH['recType'].')')); - break; + $arrayRecord = $this->readRecordOfficeArtBlip($stream, $pos - 8); + if ($arrayRecord['length'] > 0) { + $pos += $arrayRecord['length']; + $this->arrayPictures[] = $arrayRecord['picture']; } } } else { $readSuccess = false; } - } while ($readSuccess == true); + } while ($readSuccess === true); } - + /** * Stream Current User * @link http://msdn.microsoft.com/en-us/library/dd908567(v=office.12).aspx @@ -505,7 +500,7 @@ private function loadPicturesStream() private function loadCurrentUserStream() { $pos = 0; - + /** * CurrentUserAtom : http://msdn.microsoft.com/en-us/library/dd948895(v=office.12).aspx */ @@ -561,13 +556,12 @@ private function loadCurrentUserStream() if ($minorVersion != 0x00) { throw new \Exception('File PowerPoint 97 in error (Location : CurrentUserAtom > minorVersion).'); } - + // unused $pos += 2; - + // ansiUserName $ansiUserName = ''; - $char = false; do { $char = self::getInt1d($this->streamCurrentUser, $pos); if (($char >= 0x00 && $char <= 0x1F) || ($char >= 0x7F && $char <= 0x9F)) { @@ -576,7 +570,7 @@ private function loadCurrentUserStream() $ansiUserName .= chr($char); $pos += 1; } - } while ($char != false); + } while ($char !== false); // relVersion $relVersion = self::getInt4d($this->streamCurrentUser, $pos); @@ -584,7 +578,7 @@ private function loadCurrentUserStream() if ($relVersion != 0x00000008 && $relVersion != 0x00000009) { throw new \Exception('File PowerPoint 97 in error (Location : CurrentUserAtom > relVersion).'); } - + // unicodeUserName $unicodeUserName = ''; for ($inc = 0; $inc < $lenUserName; $inc++) { @@ -596,1511 +590,214 @@ private function loadCurrentUserStream() $pos += 2; } } - + /** * Stream Powerpoint Document * @link http://msdn.microsoft.com/en-us/library/dd921564(v=office.12).aspx */ private function loadPowerpointDocumentStream() { - $this->loadUserEditAtom(); - - $this->loadPersistDirectoryAtom(); - + $this->readRecordUserEditAtom($this->streamPowerpointDocument, $this->offsetToCurrentEdit); + + $this->readRecordPersistDirectoryAtom($this->streamPowerpointDocument, $this->offsetPersistDirectory); + foreach ($this->rgPersistDirEntry as $offsetDir) { $pos = $offsetDir; - + $rh = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); $pos += 8; switch ($rh['recType']) { case self::RT_DOCUMENT: - $this->readRTDocument($pos); + $this->readRecordDocumentContainer($this->streamPowerpointDocument, $pos); break; case self::RT_SLIDE: - $this->readRTSlide($pos); + $this->readRecordSlideContainer($this->streamPowerpointDocument, $pos); break; - case self::RT_MAINMASTER: - case self::RT_NOTES: default: + // throw new \Exception('Feature not implemented : l.'.__LINE__.'('.dechex($rh['recType']).')'); break; } } } - + /** - * UserEditAtom - * @link http://msdn.microsoft.com/en-us/library/dd945746(v=office.12).aspx - * @throws \Exception + * Read a record header + * @param string $stream + * @param integer $pos + * @return multitype */ - private function loadUserEditAtom() + private function loadRecordHeader($stream, $pos) { - $pos = $this->offsetToCurrentEdit; - - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0x0 || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != self::RT_USEREDITATOM || ($rHeader['recLen'] != 0x0000001C && $rHeader['recLen'] != 0x00000020)) { - throw new \Exception('File PowerPoint 97 in error (Location : UserEditAtom > RecordHeader).'); - } - - // lastSlideIdRef - $pos += 4; - // version - $pos += 2; - - // minorVersion - $minorVersion = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - if ($minorVersion != 0x00) { - throw new \Exception('File PowerPoint 97 in error (Location : UserEditAtom > minorVersion).'); - } - - // majorVersion - $majorVersion = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - if ($majorVersion != 0x03) { - throw new \Exception('File PowerPoint 97 in error (Location : UserEditAtom > majorVersion).'); - } - - // offsetLastEdit - $pos += 4; - // offsetPersistDirectory - $this->offsetPersistDirectory = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - - // docPersistIdRef - $docPersistIdRef = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - if ($docPersistIdRef != 0x00000001) { - throw new \Exception('File PowerPoint 97 in error (Location : UserEditAtom > docPersistIdRef).'); - } - - // persistIdSeed - $pos += 4; - // lastView - $pos += 2; - // unused - $pos += 2; + $rec = self::getInt2d($stream, $pos); + $recType = self::getInt2d($stream, $pos + 2); + $recLen = self::getInt4d($stream, $pos + 4); +// var_export(array( +// 'recVer' => ($rec >> 0) & bindec('1111'), +// 'recInstance' => ($rec >> 4) & bindec('111111111111'), +// 'recType' => $recType, +// 'recLen' => $recLen, +// )); +// echo EOL; + return array( + 'recVer' => ($rec >> 0) & bindec('1111'), + 'recInstance' => ($rec >> 4) & bindec('111111111111'), + 'recType' => $recType, + 'recLen' => $recLen, + ); } - + /** - * PersistDirectoryAtom - * @link http://msdn.microsoft.com/en-us/library/dd952680(v=office.12).aspx - * @throws \Exception + * Read 8-bit unsigned integer + * + * @param string $data + * @param int $pos + * @return int */ - private function loadPersistDirectoryAtom() + public static function getInt1d($data, $pos) { - $pos = $this->offsetPersistDirectory; - - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0x0 || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != self::RT_PERSISTDIRECTORYATOM) { - throw new \Exception('File PowerPoint 97 in error (Location : PersistDirectoryAtom > RecordHeader).'); - } - // rgPersistDirEntry - // @link : http://msdn.microsoft.com/en-us/library/dd947347(v=office.12).aspx - do { - $data = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - //$persistId = ($data >> 0) & bindec('11111111111111111111'); - $cPersist = ($data >> 20) & bindec('111111111111'); - - $rgPersistOffset = array(); - for ($inc = 0; $inc < $cPersist; $inc++) { - $rgPersistOffset[] = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - } - } while ($rHeader['recLen'] > 0); - $this->rgPersistDirEntry = $rgPersistOffset; + return ord($data[$pos]); } - + /** - * SlideContainer - * @link http://msdn.microsoft.com/en-us/library/dd946323(v=office.12).aspx + * Read 16-bit unsigned integer + * + * @param string $data * @param int $pos + * @return int */ - private function readRTSlide($pos) + public static function getInt2d($data, $pos) { - $oSlide = $this->oPhpPowerpoint->createSlide(); - // echo '@slide'.EOL; - - // *** slideAtom (32 bytes) - // slideAtom > rh - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0x2 || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != self::RT_SLIDEATOM) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > RecordHeader).'); - } - - // slideAtom > geom - $pos += 4; - - // slideAtom > rgPlaceholderTypes - $rgPlaceholderTypes = array(); - for ($inc = 0; $inc < 8; $inc++) { - $rgPlaceholderTypes[] = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - } - - // slideAtom > masterIdRef - $pos += 4; - // slideAtom > notesIdRef - $pos += 4; - // slideAtom > slideFlags - $pos += 2; - // slideAtom > unused; - $pos += 2; - // *** slideShowSlideInfoAtom (24 bytes) - $pos += 24; - - // perSlideHFContainer (variable) - // perSlideHFContainer > rh - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0xF || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != self::RT_HEADERSFOOTERS) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > perSlideHFContainer > RT_HeadersFooters).'); - } - $pos += $rHeader['recLen']; - - // *** rtSlideSyncInfo12 (variable) - // *** drawing (variable) - // drawing > rh - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0xF || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != self::RT_DRAWING) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > drawing > rh).'); - } - // print_r('@PPDrawing'.EOL); + return ord($data[$pos]) | (ord($data[$pos+1]) << 8); + } - // drawing > OfficeArtDg - // drawing > OfficeArtDg > rh - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0xF || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != 0xF002) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > drawing > OfficeArtDg > rh).'); + /** + * Read 32-bit signed integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function getInt4d($data, $pos) + { + // FIX: represent numbers correctly on 64-bit system + // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 + // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems + $or24 = ord($data[$pos + 3]); + if ($or24 >= 128) { + // negative number + $ord24 = -abs((256 - $or24) << 24); + } else { + $ord24 = ($or24 & 127) << 24; } - - // drawing > OfficeArtDg > drawingData - // drawing > OfficeArtDg > drawingData > rh - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0x0 || $rHeader['recInstance'] >= 0xFFE || $rHeader['recType'] != 0xF008 || $rHeader['recLen'] != 0x00000008) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > drawing > OfficeArtDg > drawingData > rh).'); + return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $ord24; + } + + /** + * A container record that specifies the animation and sound information for a shape. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd772900(v=office.12).aspx + */ + private function readRecordAnimationInfoContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_ANIMATIONINFO) { + // Record Header + $arrayReturn['length'] += 8; + // animationAtom + // animationSound + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); } - - // drawing > OfficeArtDg > drawingData > csp - $pos += 4; - // drawing > OfficeArtDg > drawingData > spidCur - $pos += 4; - - // drawing > OfficeArtDg > groupShape - // drawing > OfficeArtDg > groupShape > rh - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + + return $arrayReturn; + } + + /** + * A container record that specifies information about the document. + * @param string $stream + * @param integer $pos + * @link http://msdn.microsoft.com/en-us/library/dd947357(v=office.12).aspx + */ + private function readRecordDocumentContainer($stream, $pos) + { + $documentAtom = $this->loadRecordHeader($stream, $pos); $pos += 8; - if ($rHeader['recVer'] != 0xF || $rHeader['recInstance'] >= 0xF000 || $rHeader['recType'] != 0xF003) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > drawing > OfficeArtDg > groupShape > rh).'); + if ($documentAtom['recVer'] != 0x1 || $documentAtom['recInstance'] != 0x000 || $documentAtom['recType'] != self::RT_DOCUMENTATOM) { + throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom).'); } - - // drawing > OfficeArtDg > groupShape > rgfb - do { - $shape = null; - - $arrShpPrimaryOpt = array(); - $arrClientAnchor = array(); - $arrClientTextBox = array(); - $arrClientTextBox['hyperlink'] = array(); - $arrClientTextBox['text'] = ''; - $arrClientTextBox['numParts'] = 0; - $arrClientTextBox['numTexts'] = 0; - - $rhFB = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $rHeader['recLen'] -= 8; + $pos += $documentAtom['recLen']; - // print_r(EOL); - // print_r($rhFB); - // print_r(EOL); - if ($rhFB['recVer'] != 0xF || $rhFB['recInstance'] != 0x0000 || ($rhFB['recType'] != 0xF003 && $rhFB['recType'] != 0xF004)) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > drawing > OfficeArtDg > groupShape > rgfb).'); + $exObjList = $this->loadRecordHeader($stream, $pos); + if ($exObjList['recVer'] == 0xF && $exObjList['recInstance'] == 0x000 && $exObjList['recType'] == self::RT_EXTERNALOBJECTLIST) { + $pos += 8; + // exObjListAtom > rh + $exObjListAtom = $this->loadRecordHeader($stream, $pos); + if ($exObjListAtom['recVer'] != 0x0 || $exObjListAtom['recInstance'] != 0x000 || $exObjListAtom['recType'] != self::RT_EXTERNALOBJECTLISTATOM || $exObjListAtom['recLen'] != 0x00000004) { + throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom > exObjList > exObjListAtom).'); } - - switch ($rhFB['recType']) { - case 0xF003: // OfficeArtSpgrContainer - // OfficeArtSpgrContainer - // print_r('@OfficeArtSpgrContainer'.EOL); - break; - case 0xF004: // OfficeArtSpContainer - // shapeGroup - $shapeGroup = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($shapeGroup['recVer'] == 0x1 && $shapeGroup['recInstance'] == 0x0000 && $shapeGroup['recType'] == 0xF009 && $shapeGroup['recLen'] == 0x00000010) { - // print_r('$shapeGroup'.EOL); - $pos += 8; - $rHeader['recLen'] -= 8; - $arrShapeGroup['xLeft'] = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $arrShapeGroup['yTop'] = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $arrShapeGroup['xRight'] = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $arrShapeGroup['yBottom'] = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - } - - // shapeProp - $shapeProp = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($shapeProp['recVer'] == 0x2 && $shapeProp['recType'] == 0xF00A && $shapeProp['recLen'] == 0x00000008) { + $pos += 8; + // exObjListAtom > exObjIdSeed + $pos += 4; + // rgChildRec + $exObjList['recLen'] -= 12; + do { + $childRec = $this->loadRecordHeader($stream, $pos); + $pos += 8; + $exObjList['recLen'] -= 8; + switch ($childRec['recType']) { + case self::RT_EXTERNALHYPERLINK: + //@link : http://msdn.microsoft.com/en-us/library/dd944995(v=office.12).aspx + // exHyperlinkAtom > rh + $exHyperlinkAtom = $this->loadRecordHeader($stream, $pos); + if ($exHyperlinkAtom['recVer'] != 0x0 || $exHyperlinkAtom['recInstance'] != 0x000 || $exHyperlinkAtom['recType'] != self::RT_EXTERNALHYPERLINKATOM || $exObjListAtom['recLen'] != 0x00000004) { + throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom > exObjList > rgChildRec > RT_ExternalHyperlink).'); + } $pos += 8; - $rHeader['recLen'] -= 8; - // print_r('$shapeProp'.EOL); - - // spid - $pos += 4; - $rHeader['recLen'] -= 4; - // data + $exObjList['recLen'] -= 8; + // exHyperlinkAtom > exHyperlinkId + $exHyperlinkId = self::getInt4d($stream, $pos); $pos += 4; - $rHeader['recLen'] -= 4; - } - - // shapePrimaryOptions - $shapePrimaryOptions = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($shapePrimaryOptions['recVer'] == 0x3 && $shapePrimaryOptions['recType'] == 0xF00B) { - $pos += 8; - $rHeader['recLen'] -= 8; - // print_r('$shapePrimaryOptions'.EOL); - //@link : http://msdn.microsoft.com/en-us/library/dd906086(v=office.12).aspx - $officeArtFOPTE = array(); - for ($inc = 0; $inc < $shapePrimaryOptions['recInstance']; $inc++) { - $opid = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $shapePrimaryOptions['recLen'] -= 2; - $optOp = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $shapePrimaryOptions['recLen'] -= 4; - $officeArtFOPTE[] = array( - 'opid' => ($opid >> 0) & bindec('11111111111111'), - 'fBid' => ($opid >> 14) & bindec('1'), - 'fComplex' => ($opid >> 15) & bindec('1'), - 'op' => $optOp, - ); - } - //@link : http://code.metager.de/source/xref/kde/calligra/filters/libmso/OPID - foreach ($officeArtFOPTE as $opt) { - switch ($opt['opid']) { - case 0x007F: - // Transform : Protection Boolean Properties - //@link : http://msdn.microsoft.com/en-us/library/dd909131(v=office.12).aspx - break; - case 0x0080: - // Text : ltxid - //@link : http://msdn.microsoft.com/en-us/library/dd947446(v=office.12).aspx - break; - case 0x0081: - // Text : dxTextLeft - //@link : http://msdn.microsoft.com/en-us/library/dd953234(v=office.12).aspx - $arrShpPrimaryOpt['insetLeft'] = \PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']); - break; - case 0x0082: - // Text : dyTextTop - //@link : http://msdn.microsoft.com/en-us/library/dd925068(v=office.12).aspx - $arrShpPrimaryOpt['insetTop'] = \PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']); - break; - case 0x0083: - // Text : dxTextRight - //@link : http://msdn.microsoft.com/en-us/library/dd906782(v=office.12).aspx - $arrShpPrimaryOpt['insetRight'] = \PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']); - break; - case 0x0084: - // Text : dyTextBottom - //@link : http://msdn.microsoft.com/en-us/library/dd772858(v=office.12).aspx - $arrShpPrimaryOpt['insetBottom'] = \PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']); - break; - case 0x0085: - // Text : WrapText - //@link : http://msdn.microsoft.com/en-us/library/dd924770(v=office.12).aspx - break; - case 0x0087: - // Text : anchorText - //@link : http://msdn.microsoft.com/en-us/library/dd948575(v=office.12).aspx - break; - case 0x00BF: - // Text : Text Boolean Properties - //@link : http://msdn.microsoft.com/en-us/library/dd950905(v=office.12).aspx - break; - case 0x0104: - // Blip : pib - //@link : http://msdn.microsoft.com/en-us/library/dd772837(v=office.12).aspx - if ($opt['fComplex'] == 0) { - $arrShpPrimaryOpt['pib'] = $opt['op']; - } else { - // pib Complex - } - break; - case 0x140: - // Geometry : geoLeft - //@link : http://msdn.microsoft.com/en-us/library/dd947489(v=office.12).aspx - // print_r('geoLeft : '.$opt['op'].EOL); - break; - case 0x141: - // Geometry : geoTop - //@link : http://msdn.microsoft.com/en-us/library/dd949459(v=office.12).aspx - // print_r('geoTop : '.$opt['op'].EOL); - break; - case 0x142: - // Geometry : geoRight - //@link : http://msdn.microsoft.com/en-us/library/dd947117(v=office.12).aspx - // print_r('geoRight : '.$opt['op'].EOL); - break; - case 0x143: - // Geometry : geoBottom - //@link : http://msdn.microsoft.com/en-us/library/dd948602(v=office.12).aspx - // print_r('geoBottom : '.$opt['op'].EOL); - break; - case 0x144: - // Geometry : shapePath - //@link : http://msdn.microsoft.com/en-us/library/dd945249(v=office.12).aspx - $arrShpPrimaryOpt['line'] = true; - break; - case 0x145: - // Geometry : pVertices - //@link : http://msdn.microsoft.com/en-us/library/dd949814(v=office.12).aspx - if ($opt['fComplex'] == 1) { - $pos += $opt['op']; - $rHeader['recLen'] -= $opt['op']; - $shapePrimaryOptions['recLen'] -= $opt['op']; - } - break; - case 0x146: - // Geometry : pSegmentInfo - //@link : http://msdn.microsoft.com/en-us/library/dd905742(v=office.12).aspx - if ($opt['fComplex'] == 1) { - $pos += $opt['op']; - $rHeader['recLen'] -= $opt['op']; - $shapePrimaryOptions['recLen'] -= $opt['op']; - } - break; - case 0x155: - // Geometry : pAdjustHandles - //@link : http://msdn.microsoft.com/en-us/library/dd905890(v=office.12).aspx - if ($opt['fComplex'] == 1) { - $pos += $opt['op']; - $rHeader['recLen'] -= $opt['op']; - $shapePrimaryOptions['recLen'] -= $opt['op']; - } - break; - case 0x156: - // Geometry : pGuides - //@link : http://msdn.microsoft.com/en-us/library/dd910801(v=office.12).aspx - if ($opt['fComplex'] == 1) { - $pos += $opt['op']; - $rHeader['recLen'] -= $opt['op']; - $shapePrimaryOptions['recLen'] -= $opt['op']; - } - break; - case 0x157: - // Geometry : pInscribe - //@link : http://msdn.microsoft.com/en-us/library/dd904889(v=office.12).aspx - if ($opt['fComplex'] == 1) { - $pos += $opt['op']; - $rHeader['recLen'] -= $opt['op']; - $shapePrimaryOptions['recLen'] -= $opt['op']; - } - break; - case 0x17F: - // Geometry Boolean Properties - //@link : http://msdn.microsoft.com/en-us/library/dd944968(v=office.12).aspx - break; - case 0x0180: - // Fill : fillType - //@link : http://msdn.microsoft.com/en-us/library/dd947909(v=office.12).aspx - break; - case 0x0181: - // Fill : fillColor - //@link : http://msdn.microsoft.com/en-us/library/dd921332(v=office.12).aspx - $red = ($opt['op'] >> 0) & bindec('11111111'); - $green = ($opt['op'] >> 8) & bindec('11111111'); - $blue = ($opt['op'] >> 16) & bindec('11111111'); - - $strColor = str_pad(dechex($red), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($green), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($blue), 2, STR_PAD_LEFT, '0'); - // echo 'fillColor : '.$strColor.EOL; - break; - case 0x0183: - // Fill : fillBackColor - //@link : http://msdn.microsoft.com/en-us/library/dd950634(v=office.12).aspx - $red = ($opt['op'] >> 0) & bindec('11111111'); - $green = ($opt['op'] >> 8) & bindec('11111111'); - $blue = ($opt['op'] >> 16) & bindec('11111111'); - - $strColor = str_pad(dechex($red), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($green), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($blue), 2, STR_PAD_LEFT, '0'); - // echo 'fillBackColor : '.$strColor.EOL; - break; - case 0x0193: - // Fill : fillRectRight - //@link : http://msdn.microsoft.com/en-us/library/dd951294(v=office.12).aspx - // echo 'fillRectRight : '.\PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']).EOL; - break; - case 0x0194: - // Fill : fillRectBottom - //@link : http://msdn.microsoft.com/en-us/library/dd910194(v=office.12).aspx - // echo 'fillRectBottom : '.\PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']).EOL; - break; - case 0x01BF: - // Fill : Fill Style Boolean Properties - //@link : http://msdn.microsoft.com/en-us/library/dd909380(v=office.12).aspx - break; - case 0x01C0: - // Line Style : lineColor - //@link : http://msdn.microsoft.com/en-us/library/dd920397(v=office.12).aspx - $red = ($opt['op'] >> 0) & bindec('11111111'); - $green = ($opt['op'] >> 8) & bindec('11111111'); - $blue = ($opt['op'] >> 16) & bindec('11111111'); - - $strColor = str_pad(dechex($red), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($green), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($blue), 2, STR_PAD_LEFT, '0'); - - $arrShpPrimaryOpt['lineColor'] = $strColor; - break; - case 0x01C1: - // Line Style : lineOpacity - //@link : http://msdn.microsoft.com/en-us/library/dd923433(v=office.12).aspx - // echo 'lineOpacity : '.dechex($opt['op']).EOL; - break; - case 0x01C2: - // Line Style : lineBackColor - //@link : http://msdn.microsoft.com/en-us/library/dd947669(v=office.12).aspx - break; - case 0x01CB: - // Line Style : lineWidth - //@link : http://msdn.microsoft.com/en-us/library/dd926964(v=office.12).aspx - $arrShpPrimaryOpt['lineWidth'] = \PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']); - break; - case 0x01D6: - // Line Style : lineJoinStyle - //@link : http://msdn.microsoft.com/en-us/library/dd909643(v=office.12).aspx - break; - case 0x01D7: - // Line Style : lineEndCapStyle - //@link : http://msdn.microsoft.com/en-us/library/dd925071(v=office.12).aspx - break; - case 0x01FF: - // Line Style : Line Style Boolean Properties - //@link : http://msdn.microsoft.com/en-us/library/dd951605(v=office.12).aspx - break; - case 0x0201: - // Shadow Style : shadowColor - //@link : http://msdn.microsoft.com/en-us/library/dd923454(v=office.12).aspx - break; - case 0x0204: - // Shadow Style : shadowOpacity - //@link : http://msdn.microsoft.com/en-us/library/dd920720(v=office.12).aspx - break; - case 0x0205: - // Shadow Style : shadowOffsetX - //@link : http://msdn.microsoft.com/en-us/library/dd945280(v=office.12).aspx - $arrShpPrimaryOpt['shadowOffsetX'] = \PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']); - break; - case 0x0206: - // Shadow Style : shadowOffsetY - //@link : http://msdn.microsoft.com/en-us/library/dd907855(v=office.12).aspx - $arrShpPrimaryOpt['shadowOffsetY'] = \PhpOffice\PhpPowerpoint\Shared\Drawing::emuToPixels($opt['op']); - break; - case 0x023F: - // Shadow Style : Shadow Style Boolean Properties - //@link : http://msdn.microsoft.com/en-us/library/dd947887(v=office.12).aspx - break; - case 0x0304: - // Shape : bWMode - //@link : http://msdn.microsoft.com/en-us/library/dd947659(v=office.12).aspx - break; - case 0x033F: - // Shape Boolean Properties - //@link : http://msdn.microsoft.com/en-us/library/dd951345(v=office.12).aspx - break; - default: - throw new \Exception('Feature not implemented (l.'.__LINE__.' : '.dechex($opt['opid'].')')); - break; + $exObjList['recLen'] -= 4; + + $this->arrayHyperlinks[$exHyperlinkId] = array(); + // friendlyNameAtom + $friendlyNameAtom = $this->loadRecordHeader($stream, $pos); + if ($friendlyNameAtom['recVer'] == 0x0 && $friendlyNameAtom['recInstance'] == 0x000 && $friendlyNameAtom['recType'] == self::RT_CSTRING && $friendlyNameAtom['recLen'] % 2 == 0) { + $pos += 8; + $exObjList['recLen'] -= 8; + $this->arrayHyperlinks[$exHyperlinkId]['text'] = ''; + for ($inc = 0; $inc < ($friendlyNameAtom['recLen'] / 2); $inc++) { + $char = self::getInt2d($stream, $pos); + $pos += 2; + $exObjList['recLen'] -= 2; + $this->arrayHyperlinks[$exHyperlinkId]['text'] .= chr($char); } } - $pos += $shapePrimaryOptions['recLen']; - $rHeader['recLen'] -= $shapePrimaryOptions['recLen']; - } - - $shpSecondaryOptions1 = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $bShpSecondaryOpt1 = false; - if ($shpSecondaryOptions1['recVer'] == 0x3 && $shpSecondaryOptions1['recType'] == 0xF121) { - $pos += 8; - $rHeader['recLen'] -= 8; - $bShpSecondaryOpt1 = true; - // echo '@$rhShapeSecondaryOptions1'.EOL; - } - - $shpTertiaryOptions1 = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $bShpTertiaryOptions1 = false; - if ($shpTertiaryOptions1['recVer'] == 0x3 && $shpTertiaryOptions1['recType'] == 0xF122) { - $pos += 8; - $rHeader['recLen'] -= 8; - $bShpTertiaryOptions1 = true; - // echo '@$rhShapeTertiaryOptions1'.EOL; - } - - $rhChildAnchor = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($rhChildAnchor['recVer'] == 0x0 && $rhChildAnchor['recInstance'] == 0x000 && $rhChildAnchor['recType'] == 0xF00F && $rhChildAnchor['recLen'] == 0x00000010) { - $pos += 8; - $rHeader['recLen'] -= 8; - // echo '@$rhChildAnchor'.EOL; - } - - $rhClientAnchor = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $rHeader['recLen'] -= 8; - //@link : http://msdn.microsoft.com/en-us/library/dd922797(v=office.12).aspx - if ($rhClientAnchor['recVer'] == 0x0 && $rhClientAnchor['recInstance'] == 0x000 && $rhClientAnchor['recType'] == 0xF010 && ($rhClientAnchor['recLen'] == 0x00000008 || $rhClientAnchor['recLen'] == 0x00000010)) { - // echo '$rhClientAnchor'.EOL; - switch ($rhClientAnchor['recLen']) { - case 0x00000008: - // echo '$rhClientAnchor:0x000000008'.EOL; - $arrClientAnchor['top'] = (int) self::getInt2d($this->streamPowerpointDocument, $pos) / 6; - $arrClientAnchor['left'] = (int) self::getInt2d($this->streamPowerpointDocument, $pos + 2) / 6; - $arrClientAnchor['width'] = ((int) self::getInt2d($this->streamPowerpointDocument, $pos + 4) / 6) - $arrClientAnchor['left']; - $arrClientAnchor['height'] = ((int) self::getInt2d($this->streamPowerpointDocument, $pos + 6) / 6) - $arrClientAnchor['left']; - // print_r($arrClientAnchor); - $pos += 8; - break; - case 0x00000010: - // echo '@$rhClientAnchor:0x00000010'.EOL; - break; - } - } else { - $pos -= 8; - $rHeader['recLen'] += 8; - } - - //@link : http://msdn.microsoft.com/en-us/library/dd950927(v=office.12).aspx - $clientData = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $rHeader['recLen'] -= 8; - if ($clientData['recVer'] == 0xF && $clientData['recInstance'] == 0x000 && $clientData['recType'] == 0xF011) { - // echo '@$clientData'.EOL; - } else { - $pos -= 8; - $rHeader['recLen'] += 8; - } - - //@link : http://msdn.microsoft.com/en-us/library/dd910958(v=office.12).aspx - $clientTextbox = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $rHeader['recLen'] -= 8; - if ($clientTextbox['recVer'] == 0xF && $clientTextbox['recInstance'] == 0x000 && $clientTextbox['recType'] == 0xF00D) { - // echo '@$clientTextbox'.EOL; - $strLen = 0; - do { - $rhRgChildRec = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $rHeader['recLen'] -= 8; - $clientTextbox['recLen'] -= 8; - switch ($rhRgChildRec['recType']) { - case self::RT_INTERACTIVEINFO: - // echo '$clientTextbox:RT_InteractiveInfo'.EOL; - //@link : http://msdn.microsoft.com/en-us/library/dd948623(v=office.12).aspx - if ($rhRgChildRec['recInstance'] == 0x0000) { - //@link : http://msdn.microsoft.com/en-us/library/dd952348(v=office.12).aspx - $rhInteractiveAtom = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $rHeader['recLen'] -= 8; - $clientTextbox['recLen'] -= 8; - if ($rhInteractiveAtom['recVer'] != 0x0 || $rhInteractiveAtom['recInstance'] != 0x000 || $rhInteractiveAtom['recType'] != self::RT_INTERACTIVEINFOATOM || $rhInteractiveAtom['recLen'] != 0x00000010) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > drawing > OfficeArtDg > groupShape > rgfb > shapePrimaryOptions > clientTextbox).'); - } - // soundIdRef - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - // exHyperlinkIdRef - $exHyperlinkIdRef = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - // action - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - // oleVerb - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - // jump - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - // fAnimated (1 bit) - // fStopSound (1 bit) - // fCustomShowReturn (1 bit) - // fVisited (1 bit) - // reserved (4 bits) - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - // hyperlinkType - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - // unused - $pos += 3; - $rHeader['recLen'] -= 3; - $clientTextbox['recLen'] -= 3; - - // Shape - $arrClientTextBox['hyperlink'][]['id'] = $exHyperlinkIdRef; - } - if ($rhRgChildRec['recInstance'] == 0x0001) { - // echo '@todo l.'.__LINE__; - } - break; - case self::RT_STYLETEXTPROPATOM: - // echo '$clientTextbox:RT_StyleTextPropAtom'.EOL; - // @link : http://msdn.microsoft.com/en-us/library/dd950647(v=office.12).aspx - $strLenRT = $strLen + 1; - do { - // rgTextPFRun - $countRgTextPFRun = self::getInt4d($this->streamPowerpointDocument, $pos); - $strLenRT -= $countRgTextPFRun; - $arrClientTextBox['numTexts']++; - $arrClientTextBox['text'.$arrClientTextBox['numTexts']] = array(); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - - // indent - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - - $masks = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - - $masksData = array(); - $masksData['hasBullet'] = ($masks >> 0) & bindec('1'); - $masksData['bulletHasFont'] = ($masks >> 1) & bindec('1'); - $masksData['bulletHasColor'] = ($masks >> 2) & bindec('1'); - $masksData['bulletHasSize'] = ($masks >> 3) & bindec('1'); - $masksData['bulletFont'] = ($masks >> 4) & bindec('1'); - $masksData['bulletColor'] = ($masks >> 5) & bindec('1'); - $masksData['bulletSize'] = ($masks >> 6) & bindec('1'); - $masksData['bulletChar'] = ($masks >> 7) & bindec('1'); - $masksData['leftMargin'] = ($masks >> 8) & bindec('1'); - $masksData['unused'] = ($masks >> 9) & bindec('1'); - $masksData['indent'] = ($masks >> 10) & bindec('1'); - $masksData['align'] = ($masks >> 11) & bindec('1'); - $masksData['lineSpacing'] = ($masks >> 12) & bindec('1'); - $masksData['spaceBefore'] = ($masks >> 13) & bindec('1'); - $masksData['spaceAfter'] = ($masks >> 14) & bindec('1'); - $masksData['defaultTabSize'] = ($masks >> 15) & bindec('1'); - $masksData['fontAlign'] = ($masks >> 16) & bindec('1'); - $masksData['charWrap'] = ($masks >> 17) & bindec('1'); - $masksData['wordWrap'] = ($masks >> 18) & bindec('1'); - $masksData['overflow'] = ($masks >> 19) & bindec('1'); - $masksData['tabStops'] = ($masks >> 20) & bindec('1'); - $masksData['textDirection'] = ($masks >> 21) & bindec('1'); - $masksData['reserved1'] = ($masks >> 22) & bindec('1'); - $masksData['bulletBlip'] = ($masks >> 23) & bindec('1'); - $masksData['bulletScheme'] = ($masks >> 24) & bindec('1'); - $masksData['bulletHasScheme'] = ($masks >> 25) & bindec('1'); - - $bulletFlags = array(); - if ($masksData['hasBullet'] == 1 || $masksData['bulletHasFont'] == 1 || $masksData['bulletHasColor'] == 1 || $masksData['bulletHasSize '] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - - $bulletFlags['fHasBullet'] = ($data >> 0) & bindec('1'); - $bulletFlags['fBulletHasFont'] = ($data >> 1) & bindec('1'); - $bulletFlags['fBulletHasColor'] = ($data >> 2) & bindec('1'); - $bulletFlags['fBulletHasSize'] = ($data >> 3) & bindec('1'); - } - if ($masksData['bulletChar'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - $arrClientTextBox['text'.$arrClientTextBox['numTexts']]['bulletChar'] = chr($data); - } - if ($masksData['bulletFont'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['bulletSize'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['bulletColor'] == 1) { - $red = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - $green = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - $blue = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - $index = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - - if ($index == 0xFE) { - $strColor = str_pad(dechex($red), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($green), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($blue), 2, STR_PAD_LEFT, '0'); - } - } - if ($masksData['align'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - switch ($data) { - case 0x0000: - $arrClientTextBox['alignH'] = Alignment::HORIZONTAL_LEFT; - break; - case 0x0001: - $arrClientTextBox['alignH'] = Alignment::HORIZONTAL_CENTER; - break; - case 0x0002: - $arrClientTextBox['alignH'] = Alignment::HORIZONTAL_RIGHT; - break; - case 0x0003: - $arrClientTextBox['alignH'] = Alignment::HORIZONTAL_JUSTIFY; - break; - case 0x0004: - $arrClientTextBox['alignH'] = Alignment::HORIZONTAL_DISTRIBUTED; - break; - case 0x0005: - $arrClientTextBox['alignH'] = Alignment::HORIZONTAL_DISTRIBUTED; - break; - case 0x0006: - $arrClientTextBox['alignH'] = Alignment::HORIZONTAL_JUSTIFY; - break; - default: - break; - } - } - if ($masksData['lineSpacing'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['spaceBefore'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['spaceAfter'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['leftMargin'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - $arrClientTextBox['text'.$arrClientTextBox['numTexts']]['leftMargin'] = (int)round($data/6); - } - if ($masksData['indent'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - $arrClientTextBox['text'.$arrClientTextBox['numTexts']]['indent'] = (int)round($data/6); - } - if ($masksData['defaultTabSize'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['tabStops'] == 1) { - // echo '@todo l.'.__LINE__; - } - if ($masksData['fontAlign'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['charWrap'] == 1 || $masksData['wordWrap'] == 1 || $masksData['overflow'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['textDirection'] == 1) { - // echo '@todo l.'.__LINE__; - } - } while ($strLenRT > 0); - - $strLenRT = $strLen + 1; - do { - // rgTextCFRun - $countRgTextCFRun = self::getInt4d($this->streamPowerpointDocument, $pos); - $strLenRT -= $countRgTextCFRun; - $arrClientTextBox['numParts']++; - $arrClientTextBox['part'.$arrClientTextBox['numParts']] = array(); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - $arrClientTextBox['part'.$arrClientTextBox['numParts']]['length'] = $countRgTextCFRun; - - $masks = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - - $masksData = array(); - $masksData['bold'] = ($masks >> 0) & bindec('1'); - $masksData['italic'] = ($masks >> 1) & bindec('1'); - $masksData['underline'] = ($masks >> 2) & bindec('1'); - $masksData['unused1'] = ($masks >> 3) & bindec('1'); - $masksData['shadow'] = ($masks >> 4) & bindec('1'); - $masksData['fehint'] = ($masks >> 5) & bindec('1'); - $masksData['unused2'] = ($masks >> 6) & bindec('1'); - $masksData['kumi'] = ($masks >> 7) & bindec('1'); - $masksData['unused3'] = ($masks >> 8) & bindec('1'); - $masksData['emboss'] = ($masks >> 9) & bindec('1'); - $masksData['fHasStyle'] = ($masks >> 10) & bindec('1111'); - $masksData['unused4'] = ($masks >> 14) & bindec('11'); - $masksData['typeface'] = ($masks >> 16) & bindec('1'); - $masksData['size'] = ($masks >> 17) & bindec('1'); - $masksData['color'] = ($masks >> 18) & bindec('1'); - $masksData['position'] = ($masks >> 19) & bindec('1'); - $masksData['pp10ext'] = ($masks >> 20) & bindec('1'); - $masksData['oldEATypeface'] = ($masks >> 21) & bindec('1'); - $masksData['ansiTypeface'] = ($masks >> 22) & bindec('1'); - $masksData['symbolTypeface'] = ($masks >> 23) & bindec('1'); - $masksData['newEATypeface'] = ($masks >> 24) & bindec('1'); - $masksData['csTypeface'] = ($masks >> 25) & bindec('1'); - $masksData['pp11ext'] = ($masks >> 26) & bindec('1'); - if ($masksData['bold'] == 1 || $masksData['italic'] == 1 || $masksData['underline'] == 1 || $masksData['shadow'] == 1 || $masksData['fehint'] == 1 || $masksData['kumi'] == 1 || $masksData['emboss'] == 1 || $masksData['fHasStyle'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - - $fontStyleFlags['bold'] = ($data >> 0) & bindec('1'); - $fontStyleFlags['italic'] = ($data >> 1) & bindec('1'); - $fontStyleFlags['underline'] = ($data >> 2) & bindec('1'); - $fontStyleFlags['unused1'] = ($data >> 3) & bindec('1'); - $fontStyleFlags['shadow'] = ($data >> 4) & bindec('1'); - $fontStyleFlags['fehint'] = ($data >> 5) & bindec('1'); - $fontStyleFlags['unused2'] = ($data >> 6) & bindec('1'); - $fontStyleFlags['kumi'] = ($data >> 7) & bindec('1'); - $fontStyleFlags['unused3'] = ($data >> 8) & bindec('1'); - $fontStyleFlags['emboss'] = ($data >> 9) & bindec('1'); - $fontStyleFlags['pp9rt'] = ($data >> 10) & bindec('1111'); - $fontStyleFlags['unused4'] = ($data >> 14) & bindec('11'); - - $arrClientTextBox['part'.$arrClientTextBox['numParts']]['bold'] = ($fontStyleFlags['bold'] == 1) ? true : false; - $arrClientTextBox['part'.$arrClientTextBox['numParts']]['italic'] = ($fontStyleFlags['italic'] == 1) ? true : false; - $arrClientTextBox['part'.$arrClientTextBox['numParts']]['underline'] = ($fontStyleFlags['underline'] == 1) ? true : false; - } - if ($masksData['typeface'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - $arrClientTextBox['part'.$arrClientTextBox['numParts']]['fontName'] = isset($this->arrayFonts[$data]) ? $this->arrayFonts[$data] : ''; - } - if ($masksData['oldEATypeface'] == 1) { - // echo '@todo l.'.__LINE__; - } - if ($masksData['ansiTypeface'] == 1) { - // echo '@todo l.'.__LINE__; - } - if ($masksData['symbolTypeface'] == 1) { - // echo '@todo l.'.__LINE__; - } - if ($masksData['size'] == 1) { - $arrClientTextBox['part'.$arrClientTextBox['numParts']]['fontSize'] = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['color'] == 1) { - $red = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - $green = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - $blue = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - $index = self::getInt1d($this->streamPowerpointDocument, $pos); - $pos += 1; - $rHeader['recLen'] -= 1; - $clientTextbox['recLen'] -= 1; - - if ($index == 0xFE) { - $strColor = str_pad(dechex($red), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($green), 2, STR_PAD_LEFT, '0'); - $strColor .= str_pad(dechex($blue), 2, STR_PAD_LEFT, '0'); - - $arrClientTextBox['part'.$arrClientTextBox['numParts']]['color'] = new Color('FF'.$strColor); - } - } - if ($masksData['position'] == 1) { - // echo '@todo l.'.__LINE__; - } - } while ($strLenRT > 0); - break; - case self::RT_TEXTCHARSATOM: - // echo '$clientTextbox:RT_TextCharsAtom'.EOL; - // @link : http://msdn.microsoft.com/en-us/library/dd772921(v=office.12).aspx - $strLen = (int)($rhRgChildRec['recLen']/2); - for ($inc = 0; $inc < $rhRgChildRec['recLen']/2; $inc++) { - $char = self::getInt2d($this->streamPowerpointDocument, $pos); - if ($char == 0x0B) { - $char = 0x20; - } - $arrClientTextBox['text'] .= chr($char); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - // echo $arrClientTextBox['text'].EOL; - break; - case self::RT_TEXTHEADERATOM: - // echo '$clientTextbox:RT_TextHeaderAtom'.EOL; - // @link : http://msdn.microsoft.com/en-us/library/dd905272(v=office.12).aspx - // textType - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - break; - case self::RT_TEXTINTERACTIVEINFOATOM: - // echo '$clientTextbox:RT_TextInteractiveInfoAtom'.EOL; - //@link : http://msdn.microsoft.com/en-us/library/dd947973(v=office.12).aspx - if ($rhRgChildRec['recInstance'] == 0x0000) { - //@link : http://msdn.microsoft.com/en-us/library/dd944072(v=office.12).aspx - $arrClientTextBox['hyperlink'][count($arrClientTextBox['hyperlink']) - 1]['start'] = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - - $arrClientTextBox['hyperlink'][count($arrClientTextBox['hyperlink']) - 1]['end'] = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - } - if ($rhRgChildRec['recInstance'] == 0x0001) { - // echo '@todo l.'.__LINE__; - } - break; - case self::RT_TEXTSPECIALINFOATOM: - // echo '$clientTextbox:RT_TextSpecialInfoAtom'.EOL; - // @link : http://msdn.microsoft.com/en-us/library/dd945296(v=office.12).aspx - $strLenRT = $strLen + 1; - do { - $count = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - $strLenRT -= $count; - $data = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - $masksData = array(); - $masksData['spell'] = ($data >> 0) & bindec('1'); - $masksData['lang'] = ($data >> 1) & bindec('1'); - $masksData['altLang'] = ($data >> 2) & bindec('1'); - $masksData['unused1'] = ($data >> 3) & bindec('1'); - $masksData['unused2'] = ($data >> 4) & bindec('1'); - $masksData['fPp10ext'] = ($data >> 5) & bindec('1'); - $masksData['fBidi'] = ($data >> 6) & bindec('1'); - $masksData['unused3'] = ($data >> 7) & bindec('1'); - $masksData['reserved1'] = ($data >> 8) & bindec('1'); - $masksData['smartTag'] = ($data >> 9) & bindec('1'); - - if ($masksData['spell'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - $masksSpell = array(); - $masksSpell['error'] = ($data >> 0) & bindec('1'); - $masksSpell['clean'] = ($data >> 1) & bindec('1'); - $masksSpell['grammar'] = ($data >> 2) & bindec('1'); - } - if ($masksData['lang'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['altLang'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fBidi'] == 1) { - // echo '@todo l.'.__LINE__; - } - if ($masksData['fPp10ext'] == 1) { - // echo '@todo l.'.__LINE__; - } - if ($masksData['smartTag'] == 1) { - // echo '@todo l.'.__LINE__; - } - } while ($strLenRT > 0); - break; - case self::RT_TEXTRULERATOM: - // echo '$clientTextbox:RT_TextRulerAtom'.EOL; - // @link : http://msdn.microsoft.com/en-us/library/dd953212(v=office.12).aspx - $data = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $rHeader['recLen'] -= 4; - $clientTextbox['recLen'] -= 4; - $masksData = array(); - $masksData['fDefaultTabSize'] = ($data >> 0) & bindec('1'); - $masksData['fCLevels'] = ($data >> 1) & bindec('1'); - $masksData['fTabStops'] = ($data >> 2) & bindec('1'); - $masksData['fLeftMargin1'] = ($data >> 3) & bindec('1'); - $masksData['fLeftMargin2'] = ($data >> 4) & bindec('1'); - $masksData['fLeftMargin3'] = ($data >> 5) & bindec('1'); - $masksData['fLeftMargin4'] = ($data >> 6) & bindec('1'); - $masksData['fLeftMargin5'] = ($data >> 7) & bindec('1'); - $masksData['fIndent1'] = ($data >> 8) & bindec('1'); - $masksData['fIndent2'] = ($data >> 9) & bindec('1'); - $masksData['fIndent3'] = ($data >> 10) & bindec('1'); - $masksData['fIndent4'] = ($data >> 11) & bindec('1'); - $masksData['fIndent5'] = ($data >> 12) & bindec('1'); - - if ($masksData['fCLevels'] == 1) { - // echo '@todo l.'.__LINE__; - } - if ($masksData['fDefaultTabSize'] == 1) { - // echo '@todo l.'.__LINE__; - } - if ($masksData['fTabStops'] == 1) { - $count = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - $arrayTabStops = array(); - for ($inc = 0; $inc < $count; $inc++) { - $position = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - $type = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - $arrayTabStops[] = array( - 'position' => $position, - 'type' => $type, - ); - } - } - if ($masksData['fLeftMargin1'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fIndent1'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fLeftMargin2'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fIndent2'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fLeftMargin3'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fIndent3'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fLeftMargin4'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fIndent4'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fLeftMargin5'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - if ($masksData['fIndent5'] == 1) { - $data = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $rHeader['recLen'] -= 2; - $clientTextbox['recLen'] -= 2; - } - break; - default: - // echo EOL; - // print_r($rhRgChildRec); - // echo EOL; - // echo '@$type : '.dechex($rhRgChildRec['recType']).EOL; - } - } while ($clientTextbox['recLen'] > 0); - } else { - $pos -= 8; - $rHeader['recLen'] += 8; - } - $shpSecondaryOptions2 = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $rHeader['recLen'] -= 8; - if ($bShpSecondaryOpt1 == true && $shpSecondaryOptions2['recVer'] == 0x3 && $shpSecondaryOptions2['recType'] == 0xF121) { - } else { - $pos -= 8; - $rHeader['recLen'] += 8; - } - - $shpTertiaryOptions2 = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $rHeader['recLen'] -= 8; - if ($bShpTertiaryOptions1 == true && $shpTertiaryOptions2['recVer'] == 0x3 && $shpTertiaryOptions2['recType'] == 0xF122) { - } else { - $pos -= 8; - $rHeader['recLen'] += 8; - } - break; - } - - // Cleaning variables - if (empty($arrClientTextBox['hyperlink'])) { - unset($arrClientTextBox['hyperlink']); - } - if (empty($arrClientTextBox['text'])) { - unset($arrClientTextBox['text']); - } - if (empty($arrClientTextBox['numParts'])) { - unset($arrClientTextBox['numParts']); - } - if (empty($arrClientTextBox['numTexts'])) { - unset($arrClientTextBox['numTexts']); - } - // echo EOL; - if (isset($arrShpPrimaryOpt['pib']) && isset($this->arrayPictures[$arrShpPrimaryOpt['pib'] - 1])) { - // echo '//IMAGE'.EOL; - $gdImage = imagecreatefromstring($this->arrayPictures[$arrShpPrimaryOpt['pib'] - 1]); - - $shape = new MemoryDrawing(); - $shape->setImageResource($gdImage); - - if (isset($arrShpPrimaryOpt['shadowOffsetX']) && $arrShpPrimaryOpt['shadowOffsetX'] != 0 && isset($arrShpPrimaryOpt['shadowOffsetY']) && $arrShpPrimaryOpt['shadowOffsetY'] != 0) { - $shape->getShadow()->setVisible(true); - if ($arrShpPrimaryOpt['shadowOffsetX'] > 0 && $arrShpPrimaryOpt['shadowOffsetX'] == $arrShpPrimaryOpt['shadowOffsetY']) { - $shape->getShadow()->setDistance($arrShpPrimaryOpt['shadowOffsetX'])->setDirection(45); - } - } - if (!is_null($shape) && !empty($arrClientAnchor)) { - $shape->setOffsetX($arrClientAnchor['left']); - $shape->setOffsetY($arrClientAnchor['top']); - $shape->setWidth($arrClientAnchor['width']); - $shape->setHeight($arrClientAnchor['height']); - } - } - - if (!empty($arrClientTextBox) && isset($arrClientTextBox)) { - // echo '//TEXT'.EOL; - // echo '
    ';
    -                // print_r($arrClientTextBox);
    -                // echo '
    '; - $shape = new RichText(); - if (isset($arrClientTextBox['alignH'])) { - $shape->getActiveParagraph()->getAlignment()->setHorizontal($arrClientTextBox['alignH']); - } - - $start = 0; - // echo $arrClientTextBox['text'].EOL; - - $lastLevel = -1; - $lastMarginLeft = 0; - for ($inc = 1; $inc <= $arrClientTextBox['numParts']; $inc++) { - if ($arrClientTextBox['numParts'] == $arrClientTextBox['numTexts'] && isset($arrClientTextBox['text'.$inc])) { - if (isset($arrClientTextBox['text'.$inc]['bulletChar'])) { - $shape->getActiveParagraph()->getBulletStyle()->setBulletType(Bullet::TYPE_BULLET); - $shape->getActiveParagraph()->getBulletStyle()->setBulletChar($arrClientTextBox['text'.$inc]['bulletChar']); - } - // Indent - $indent = 0; - if (isset($arrClientTextBox['text'.$inc]['indent'])) { - $indent = $arrClientTextBox['text'.$inc]['indent']; - } - if (isset($arrClientTextBox['text'.$inc]['leftMargin'])) { - if ($lastMarginLeft > $arrClientTextBox['text'.$inc]['leftMargin']) { - $lastLevel--; - } - if ($lastMarginLeft < $arrClientTextBox['text'.$inc]['leftMargin']) { - $lastLevel++; - } - $shape->getActiveParagraph()->getAlignment()->setLevel($lastLevel); - $lastMarginLeft = $arrClientTextBox['text'.$inc]['leftMargin']; - - $shape->getActiveParagraph()->getAlignment()->setMarginLeft($arrClientTextBox['text'.$inc]['leftMargin']); - $shape->getActiveParagraph()->getAlignment()->setIndent($indent - $arrClientTextBox['text'.$inc]['leftMargin']); - } - - } - // Texte - $sText = substr($arrClientTextBox['text'], $start, $arrClientTextBox['part'.$inc]['length']); - $sHyperlinkURL = ''; - if (empty($sText)) { - // Is there a hyperlink ? - if (!empty($arrClientTextBox['hyperlink'])) { - foreach ($arrClientTextBox['hyperlink'] as $itmHyperlink) { - if ($itmHyperlink['start'] == $start && ($itmHyperlink['end'] - $itmHyperlink['start']) == $arrClientTextBox['part'.$inc]['length']) { - $sText = $this->arrayHyperlinks[$itmHyperlink['id']]['text']; - $sHyperlinkURL = $this->arrayHyperlinks[$itmHyperlink['id']]['url']; - break; - } - } - } - } - // New paragraph - $bCreateParagraph = false; - if (strpos($sText, "\r") != false) { - $bCreateParagraph = true; - $sText = str_replace("\r", '', $sText); - } - // TextRun - $txtRun = $shape->createTextRun($sText); - if (isset($arrClientTextBox['part'.$inc]['bold'])) { - $txtRun->getFont()->setBold($arrClientTextBox['part'.$inc]['bold']); - } - if (isset($arrClientTextBox['part'.$inc]['italic'])) { - $txtRun->getFont()->setItalic($arrClientTextBox['part'.$inc]['italic']); - } - if (isset($arrClientTextBox['part'.$inc]['underline'])) { - $txtRun->getFont()->setUnderline($arrClientTextBox['part'.$inc]['underline']); - } - if (isset($arrClientTextBox['part'.$inc]['fontName'])) { - $txtRun->getFont()->setName($arrClientTextBox['part'.$inc]['fontName']); - } - if (isset($arrClientTextBox['part'.$inc]['fontSize'])) { - $txtRun->getFont()->setSize($arrClientTextBox['part'.$inc]['fontSize']); - } - if (isset($arrClientTextBox['part'.$inc]['color'])) { - $txtRun->getFont()->setColor($arrClientTextBox['part'.$inc]['color']); - } - // Hyperlink - if (!empty($sHyperlinkURL)) { - $txtRun->setHyperlink(new Hyperlink($sHyperlinkURL)); - } - - $start += $arrClientTextBox['part'.$inc]['length']; - if ($bCreateParagraph) { - $shape->createParagraph(); - } - } - if (!is_null($shape) && !empty($arrClientAnchor)) { - $shape->setOffsetX($arrClientAnchor['left']); - $shape->setOffsetY($arrClientAnchor['top']); - $shape->setWidth($arrClientAnchor['width']); - $shape->setHeight($arrClientAnchor['height']); - } - } - if (isset($arrShpPrimaryOpt['line']) && $arrShpPrimaryOpt['line'] == true) { - // echo '//LINE'.EOL; - $shape = new Line(0, 0, 0, 0); - if (isset($arrShpPrimaryOpt['lineColor'])) { - $shape->getBorder()->getColor()->setARGB('FF'.$arrShpPrimaryOpt['lineColor']); - } - if (!empty($arrClientAnchor)) { - $shape->setOffsetX($arrClientAnchor['left']); - $shape->setOffsetY($arrClientAnchor['top']); - $shape->setWidth($arrClientAnchor['width']); - $shape->setHeight($arrShpPrimaryOpt['lineWidth']); - } - } - - if (isset($arrShpPrimaryOpt['insetBottom'])) { - $shape->setInsetBottom($arrShpPrimaryOpt['insetBottom']); - } - if (isset($arrShpPrimaryOpt['insetLeft'])) { - $shape->setInsetLeft($arrShpPrimaryOpt['insetLeft']); - } - if (isset($arrShpPrimaryOpt['insetRight'])) { - $shape->setInsetRight($arrShpPrimaryOpt['insetRight']); - } - if (isset($arrShpPrimaryOpt['insetTop'])) { - $shape->setInsetTop($arrShpPrimaryOpt['insetTop']); - } - - if (!is_null($shape) && $shape instanceof AbstractShape) { - // echo '//SHAPE'.EOL; - $oSlide->addShape($shape); - } - // echo '//END.....'.EOL.EOL.EOL; - } while ($rHeader['recLen'] > 0); - - - // *** slideSchemeColorSchemeAtom (40 bytes) - // slideSchemeColorSchemeAtom > rh - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0x0 || $rHeader['recInstance'] != 0x001 || $rHeader['recType'] != self::RT_COLORSCHEMEATOM || $rHeader['recLen'] != 0x00000020) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > slideSchemeColorSchemeAtom > rh).'); - } - // slideSchemeColorSchemeAtom > rgSchemeColor - $rgSchemeColor = array(); - for ($inc = 0; $inc <= 7; $inc++) { - $rgSchemeColor[] = array( - 'red' => self::getInt1d($this->streamPowerpointDocument, $pos + $inc * 4), - 'green' => self::getInt1d($this->streamPowerpointDocument, $pos + $inc * 4 + 1), - 'blue' => self::getInt1d($this->streamPowerpointDocument, $pos + $inc * 4 + 2), - ); - } - $pos += (8 * 4); - - // *** slideNameAtom (variable) - // *** slideProgTagsContainer (variable). - // slideProgTagsContainer > rh - $rHeader = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($rHeader['recVer'] != 0xF || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != self::RT_PROGTAGS) { - throw new \Exception('File PowerPoint 97 in error (Location : RTSlide > slideProgTagsContainer > rh).'); - } - } - - /** - * DocumentContainer - * @link http://msdn.microsoft.com/en-us/library/dd947357(v=office.12).aspx - * @param integer $pos - */ - private function readRTDocument($pos) - { - $documentAtom = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - if ($documentAtom['recVer'] != 0x1 || $documentAtom['recInstance'] != 0x000 || $documentAtom['recType'] != self::RT_DOCUMENTATOM) { - throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom).'); - } - $pos += $documentAtom['recLen']; - - $exObjList = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($exObjList['recVer'] == 0xF && $exObjList['recInstance'] == 0x000 && $exObjList['recType'] == self::RT_EXTERNALOBJECTLIST) { - $pos += 8; - // exObjListAtom > rh - $exObjListAtom = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($exObjListAtom['recVer'] != 0x0 || $exObjListAtom['recInstance'] != 0x000 || $exObjListAtom['recType'] != self::RT_EXTERNALOBJECTLISTATOM || $exObjListAtom['recLen'] != 0x00000004) { - throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom > exObjList > exObjListAtom).'); - } - $pos += 8; - // exObjListAtom > exObjIdSeed - $pos += 4; - // rgChildRec - $exObjList['recLen'] -= 12; - do { - $childRec = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - $pos += 8; - $exObjList['recLen'] -= 8; - switch ($childRec['recType']) { - case self::RT_EXTERNALHYPERLINK: - //@link : http://msdn.microsoft.com/en-us/library/dd944995(v=office.12).aspx - // exHyperlinkAtom > rh - $exHyperlinkAtom = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($exHyperlinkAtom['recVer'] != 0x0 || $exHyperlinkAtom['recInstance'] != 0x000 || $exHyperlinkAtom['recType'] != self::RT_EXTERNALHYPERLINKATOM || $exObjListAtom['recLen'] != 0x00000004) { - throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom > exObjList > rgChildRec > RT_ExternalHyperlink).'); - } - $pos += 8; - $exObjList['recLen'] -= 8; - // exHyperlinkAtom > exHyperlinkId - $exHyperlinkId = self::getInt4d($this->streamPowerpointDocument, $pos); - $pos += 4; - $exObjList['recLen'] -= 4; - - $this->arrayHyperlinks[$exHyperlinkId] = array(); - // friendlyNameAtom - $friendlyNameAtom = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($friendlyNameAtom['recVer'] == 0x0 && $friendlyNameAtom['recInstance'] == 0x000 && $friendlyNameAtom['recType'] == self::RT_CSTRING && $friendlyNameAtom['recLen'] % 2 == 0) { - $pos += 8; - $exObjList['recLen'] -= 8; - $this->arrayHyperlinks[$exHyperlinkId]['text'] = ''; - for ($inc = 0; $inc < ($friendlyNameAtom['recLen'] / 2); $inc++) { - $char = self::getInt2d($this->streamPowerpointDocument, $pos); - $pos += 2; - $exObjList['recLen'] -= 2; - $this->arrayHyperlinks[$exHyperlinkId]['text'] .= chr($char); - } - } - // targetAtom - $targetAtom = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); - if ($targetAtom['recVer'] == 0x0 && $targetAtom['recInstance'] == 0x001 && $targetAtom['recType'] == self::RT_CSTRING && $targetAtom['recLen'] % 2 == 0) { + // targetAtom + $targetAtom = $this->loadRecordHeader($stream, $pos); + if ($targetAtom['recVer'] == 0x0 && $targetAtom['recInstance'] == 0x001 && $targetAtom['recType'] == self::RT_CSTRING && $targetAtom['recLen'] % 2 == 0) { $pos += 8; $exObjList['recLen'] -= 8; $this->arrayHyperlinks[$exHyperlinkId]['url'] = ''; for ($inc = 0; $inc < ($targetAtom['recLen'] / 2); $inc++) { - $char = self::getInt2d($this->streamPowerpointDocument, $pos); + $char = self::getInt2d($stream, $pos); $pos += 2; $exObjList['recLen'] -= 2; $this->arrayHyperlinks[$exHyperlinkId]['url'] .= chr($char); } } // locationAtom - $locationAtom = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + $locationAtom = $this->loadRecordHeader($stream, $pos); if ($locationAtom['recVer'] == 0x0 && $locationAtom['recInstance'] == 0x003 && $locationAtom['recType'] == self::RT_CSTRING && $locationAtom['recLen'] % 2 == 0) { $pos += 8; $exObjList['recLen'] -= 8; $string = ''; for ($inc = 0; $inc < ($locationAtom['recLen'] / 2); $inc++) { - $char = self::getInt2d($this->streamPowerpointDocument, $pos); + $char = self::getInt2d($stream, $pos); $pos += 2; $exObjList['recLen'] -= 2; $string .= chr($char); @@ -2112,24 +809,24 @@ private function readRTDocument($pos) } } while ($exObjList['recLen'] > 0); } - + //@link : http://msdn.microsoft.com/en-us/library/dd907813(v=office.12).aspx - $documentTextInfo = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + $documentTextInfo = $this->loadRecordHeader($stream, $pos); if ($documentTextInfo['recVer'] == 0xF && $documentTextInfo['recInstance'] == 0x000 && $documentTextInfo['recType'] == self::RT_ENVIRONMENT) { $pos += 8; //@link : http://msdn.microsoft.com/en-us/library/dd952717(v=office.12).aspx - $kinsoku = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + $kinsoku = $this->loadRecordHeader($stream, $pos); if ($kinsoku['recVer'] == 0xF && $kinsoku['recInstance'] == 0x002 && $kinsoku['recType'] == self::RT_KINSOKU) { $pos += 8; $pos += $kinsoku['recLen']; } - + //@link : http://msdn.microsoft.com/en-us/library/dd948152(v=office.12).aspx - $fontCollection = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + $fontCollection = $this->loadRecordHeader($stream, $pos); if ($fontCollection['recVer'] == 0xF && $fontCollection['recInstance'] == 0x000 && $fontCollection['recType'] == self::RT_FONTCOLLECTION) { $pos += 8; do { - $fontEntityAtom = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + $fontEntityAtom = $this->loadRecordHeader($stream, $pos); $pos += 8; $fontCollection['recLen'] -= 8; if ($fontEntityAtom['recVer'] != 0x0 || $fontEntityAtom['recInstance'] > 128 || $fontEntityAtom['recType'] != self::RT_FONTENTITYATOM) { @@ -2137,22 +834,22 @@ private function readRTDocument($pos) } else { $string = ''; for ($inc = 0; $inc < 32; $inc++) { - $char = self::getInt2d($this->streamPowerpointDocument, $pos); + $char = self::getInt2d($stream, $pos); $pos += 2; $fontCollection['recLen'] -= 2; $string .= chr($char); } $this->arrayFonts[] = $string; - + // lfCharSet (1 byte) $pos += 1; $fontCollection['recLen'] -= 1; - + // fEmbedSubsetted (1 bit) // unused (7 bits) $pos += 1; $fontCollection['recLen'] -= 1; - + // rasterFontType (1 bit) // deviceFontType (1 bit) // truetypeFontType (1 bit) @@ -2160,111 +857,2367 @@ private function readRTDocument($pos) // reserved (4 bits) $pos += 1; $fontCollection['recLen'] -= 1; - + // lfPitchAndFamily (1 byte) $pos += 1; $fontCollection['recLen'] -= 1; } - - $fontEmbedData1 = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + + $fontEmbedData1 = $this->loadRecordHeader($stream, $pos); if ($fontEmbedData1['recVer'] == 0x0 && $fontEmbedData1['recInstance'] >= 0x000 && $fontEmbedData1['recInstance'] <= 0x003 && $fontEmbedData1['recType'] == self::RT_FONTEMBEDDATABLOB) { $pos += 8; $fontCollection['recLen'] -= 8; $pos += $fontEmbedData1['recLen']; $fontCollection['recLen'] -= $fontEmbedData1['recLen']; } - - $fontEmbedData2 = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + + $fontEmbedData2 = $this->loadRecordHeader($stream, $pos); if ($fontEmbedData2['recVer'] == 0x0 && $fontEmbedData2['recInstance'] >= 0x000 && $fontEmbedData2['recInstance'] <= 0x003 && $fontEmbedData2['recType'] == self::RT_FONTEMBEDDATABLOB) { $pos += 8; $fontCollection['recLen'] -= 8; $pos += $fontEmbedData2['recLen']; $fontCollection['recLen'] -= $fontEmbedData2['recLen']; } - - $fontEmbedData3 = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + + $fontEmbedData3 = $this->loadRecordHeader($stream, $pos); if ($fontEmbedData3['recVer'] == 0x0 && $fontEmbedData3['recInstance'] >= 0x000 && $fontEmbedData3['recInstance'] <= 0x003 && $fontEmbedData3['recType'] == self::RT_FONTEMBEDDATABLOB) { $pos += 8; $fontCollection['recLen'] -= 8; $pos += $fontEmbedData3['recLen']; $fontCollection['recLen'] -= $fontEmbedData3['recLen']; } - - $fontEmbedData4 = $this->loadRecordHeader($this->streamPowerpointDocument, $pos); + + $fontEmbedData4 = $this->loadRecordHeader($stream, $pos); if ($fontEmbedData4['recVer'] == 0x0 && $fontEmbedData4['recInstance'] >= 0x000 && $fontEmbedData4['recInstance'] <= 0x003 && $fontEmbedData4['recType'] == self::RT_FONTEMBEDDATABLOB) { $pos += 8; $fontCollection['recLen'] -= 8; $pos += $fontEmbedData4['recLen']; $fontCollection['recLen'] -= $fontEmbedData4['recLen']; } - + } while ($fontCollection['recLen'] > 0); } } } - + /** - * Read a record header + * An atom record that specifies information about a slide. * @param string $stream - * @param intger $pos - * @return multitype:boolean Ambigous + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd923801(v=office.12).aspx */ - private function loadRecordHeader($stream, $pos) + private function readRecordDrawingContainer($stream, $pos) { - $rec = self::getInt2d($stream, $pos); - $recType = self::getInt2d($stream, $pos + 2); - $recLen = self::getInt4d($stream, $pos + 4); - return array( - 'recVer' => ($rec >> 0) & bindec('1111'), - 'recInstance' => ($rec >> 4) & bindec('111111111111'), - 'recType' => $recType, - 'recLen' => $recLen, + $arrayReturn = array( + 'length' => 0, ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_DRAWING) { + // Record Header + $arrayReturn['length'] += 8; + + $officeArtDg = $this->readRecordOfficeArtDgContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $officeArtDg['length']; + } + + return $arrayReturn; } - + /** - * Read 8-bit unsigned integer - * - * @param string $data - * @param int $pos - * @return int + * An atom record that specifies a reference to an external object. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd910388(v=office.12).aspx */ - public static function getInt1d($data, $pos) + private function readRecordExObjRefAtom($stream, $pos) { - return ord($data[$pos]); + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_EXTERNALOBJECTREFATOM && $data['recLen'] == 0x00000004) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; } - + /** - * Read 16-bit unsigned integer - * - * @param string $data - * @param int $pos - * @return int + * An atom record that specifies a type of action to be performed. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd953300(v=office.12).aspx */ - public static function getInt2d($data, $pos) + private function readRecordInteractiveInfoAtom($stream, $pos) { - return ord($data[$pos]) | (ord($data[$pos+1]) << 8); + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_INTERACTIVEINFOATOM && $data['recLen'] == 0x00000010) { + // Record Header + $arrayReturn['length'] += 8; + // soundIdRef + $arrayReturn['length'] += 4; + // exHyperlinkIdRef + $arrayReturn['exHyperlinkIdRef'] = self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + // action + $arrayReturn['length'] += 1; + // oleVerb + $arrayReturn['length'] += 1; + // jump + $arrayReturn['length'] += 1; + // fAnimated (1 bit) + // fStopSound (1 bit) + // fCustomShowReturn (1 bit) + // fVisited (1 bit) + // reserved (4 bits) + $arrayReturn['length'] += 1; + // hyperlinkType + $arrayReturn['length'] += 1; + // unused + $arrayReturn['length'] += 3; + } + + return $arrayReturn; } - + /** - * Read 32-bit signed integer - * - * @param string $data - * @param int $pos - * @return int + * An atom record that specifies the name of a macro, a file name, or a named show. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd925121(v=office.12).aspx */ - public static function getInt4d($data, $pos) + private function readRecordMacroNameAtom($stream, $pos) { - // FIX: represent numbers correctly on 64-bit system - // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 - // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems - $or24 = ord($data[$pos + 3]); - if ($or24 >= 128) { - // negative number - $ord24 = -abs((256 - $or24) << 24); - } else { - $ord24 = ($or24 & 127) << 24; + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x002 && $data['recType'] == self::RT_CSTRING && $data['recLen'] % 2 == 0) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; } - return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $ord24; + + return $arrayReturn; + } + + /** + * A container record that specifies what actions to perform when interacting with an object by means of a mouse click. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd952348(v=office.12).aspx + */ + private function readRecordMouseClickInteractiveInfoContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_INTERACTIVEINFO) { + // Record Header + $arrayReturn['length'] += 8; + // interactiveInfoAtom + $interactiveInfoAtom = $this->readRecordInteractiveInfoAtom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $interactiveInfoAtom['length']; + if ($interactiveInfoAtom['length'] > 0) { + $arrayReturn['exHyperlinkIdRef'] = $interactiveInfoAtom['exHyperlinkIdRef']; + } + // macroNameAtom + $macroNameAtom = $this->readRecordMacroNameAtom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $macroNameAtom['length']; + } + + return $arrayReturn; + } + + /** + * A container record that specifies what actions to perform when interacting with an object by moving the mouse cursor over it. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd925811(v=office.12).aspx + */ + private function readRecordMouseOverInteractiveInfoContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x001 && $data['recType'] == self::RT_INTERACTIVEINFO) { + // Record Header + $arrayReturn['length'] += 8; + // interactiveInfoAtom + // macroNameAtom + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + + return $arrayReturn; + } + + /** + * The OfficeArtBlip record specifies BLIP file data. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd910081(v=office.12).aspx + */ + private function readRecordOfficeArtBlip($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + 'picture' => null + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && ($data['recType'] >= 0xF018 && $data['recType'] <= 0xF117)) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + switch ($data['recType']) { + case self::OFFICEARTBLIPJPG: + case self::OFFICEARTBLIPPNG: + // rgbUid1 + $arrayReturn['length'] += 16; + $data['recLen'] -= 16; + if ($data['recInstance'] == 0x6E1) { + // rgbUid2 + $arrayReturn['length'] += 16; + $data['recLen'] -= 16; + } + // tag + $arrayReturn['length'] += 1; + $data['recLen'] -= 1; + // BLIPFileData + $arrayReturn['picture'] = substr($this->streamPictures, $pos + $arrayReturn['length'], $data['recLen']); + $arrayReturn['length'] += $data['recLen']; + break; + default: + throw new \Exception('Feature not implemented (l.'.__LINE__.' : '.dechex($data['recType'].')')); + } + } + + return $arrayReturn; + } + + /** + * The OfficeArtChildAnchor record specifies four signed integers that specify the anchor for the shape that contains this record. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd922720(v=office.12).aspx + */ + private function readRecordOfficeArtChildAnchor($stream, $pos) + { + $arrayReturn = array( + 'length' => 0 + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == 0xF00F && $data['recLen'] == 0x00000010) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['left'] = (int) self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + $arrayReturn['top'] = (int) self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + $arrayReturn['width'] = (int) self::getInt4d($stream, $pos + $arrayReturn['length']) - $arrayReturn['left']; + $arrayReturn['length'] += 4; + $arrayReturn['height'] = (int) self::getInt4d($stream, $pos + $arrayReturn['length']) - $arrayReturn['top']; + $arrayReturn['length'] += 4; + } + + return $arrayReturn; + } + + + + /** + * An atom record that specifies the location of a shape. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd922797(v=office.12).aspx + */ + private function readRecordOfficeArtClientAnchor($stream, $pos) + { + $arrayReturn = array( + 'length' => 0 + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == 0xF010 && ($data['recLen'] == 0x00000008 || $data['recLen'] == 0x00000010)) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + switch ($data['recLen']) { + case 0x00000008: + $arrayReturn['top'] = (int) (self::getInt2d($stream, $pos + $arrayReturn['length']) / 6); + $arrayReturn['length'] += 2; + $arrayReturn['left'] = (int) (self::getInt2d($stream, $pos + $arrayReturn['length']) / 6); + $arrayReturn['length'] += 2; + $arrayReturn['width'] = (int) (self::getInt2d($stream, $pos + $arrayReturn['length']) / 6) - $arrayReturn['left']; + $arrayReturn['length'] += 2; + $arrayReturn['height'] = (int) (self::getInt2d($stream, $pos + $arrayReturn['length']) / 6) - $arrayReturn['left']; + $arrayReturn['length'] += 2; + $pos += 8; + break; + case 0x00000010: + throw new \Exception('PowerPoint97 Reader : record OfficeArtClientAnchor (0x00000010)'); + } + } + + return $arrayReturn; + } + /** + * A container record that specifies text related data for a shape. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd910958(v=office.12).aspx + */ + private function readRecordOfficeArtClientTextbox($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + 'text' => '', + 'numParts' => 0, + 'numTexts' => 0, + 'hyperlink' => array(), + ); + + $data = $this->loadRecordHeader($stream, $pos); + // recVer 0xF + // Doc : 0x0 https://msdn.microsoft.com/en-us/library/dd910958(v=office.12).aspx + // Sample : 0xF https://msdn.microsoft.com/en-us/library/dd953497(v=office.12).aspx + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == 0xF00D) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $strLen = 0; + do { + $rhChild = $this->loadRecordHeader($stream, $pos + $arrayReturn['length']); + /** + * @link : https://msdn.microsoft.com/en-us/library/dd947039(v=office.12).aspx + */ + // echo dechex($rhChild['recType']).'-'.$rhChild['recType'].EOL; + switch ($rhChild['recType']) { + case self::RT_INTERACTIVEINFO: + //@link : http://msdn.microsoft.com/en-us/library/dd948623(v=office.12).aspx + if ($rhChild['recInstance'] == 0x0000) { + $mouseClickInfo = $this->readRecordMouseClickInteractiveInfoContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $mouseClickInfo['length']; + $arrayReturn['hyperlink'][]['id'] = $mouseClickInfo['exHyperlinkIdRef']; + } + if ($rhChild['recInstance'] == 0x0001) { + $mouseOverInfo = $this->readRecordMouseOverInteractiveInfoContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $mouseOverInfo['length']; + } + break; + case self::RT_STYLETEXTPROPATOM: + $arrayReturn['length'] += 8; + // @link : http://msdn.microsoft.com/en-us/library/dd950647(v=office.12).aspx + // rgTextPFRun + $strLenRT = $strLen + 1; + do { + $strucTextPFRun = $this->readStructureTextPFRun($stream, $pos + $arrayReturn['length'], $strLenRT); + $arrayReturn['numTexts']++; + $arrayReturn['text'.$arrayReturn['numTexts']] = $strucTextPFRun; + if (isset($strucTextPFRun['alignH'])) { + $arrayReturn['alignH'] = $strucTextPFRun['alignH']; + } + $strLenRT = $strucTextPFRun['strLenRT']; + $arrayReturn['length'] += $strucTextPFRun['length']; + } while ($strLenRT > 0); + // rgTextCFRun + $strLenRT = $strLen + 1; + do { + $strucTextCFRun = $this->readStructureTextCFRun($stream, $pos + $arrayReturn['length'], $strLenRT); + $arrayReturn['numParts']++; + $arrayReturn['part'.$arrayReturn['numParts']] = $strucTextCFRun; + $strLenRT = $strucTextCFRun['strLenRT']; + $arrayReturn['length'] += $strucTextCFRun['length']; + } while ($strLenRT > 0); + break; + case self::RT_TEXTBYTESATOM: + $arrayReturn['length'] += 8; + // @link : https://msdn.microsoft.com/en-us/library/dd947905(v=office.12).aspx + $strLen = (int)$rhChild['recLen']; + for ($inc = 0; $inc < $strLen; $inc++) { + $char = self::getInt1d($stream, $pos + $arrayReturn['length']); + if ($char == 0x0B) { + $char = 0x20; + } + $arrayReturn['text'] .= String::chr($char); + $arrayReturn['length'] += 1; + } + break; + case self::RT_TEXTCHARSATOM: + $arrayReturn['length'] += 8; + // @link : http://msdn.microsoft.com/en-us/library/dd772921(v=office.12).aspx + $strLen = (int)($rhChild['recLen']/2); + for ($inc = 0; $inc < $strLen; $inc++) { + $char = self::getInt2d($stream, $pos + $arrayReturn['length']); + if ($char == 0x0B) { + $char = 0x20; + } + $arrayReturn['text'] .= String::chr($char); + $arrayReturn['length'] += 2; + } + break; + case self::RT_TEXTHEADERATOM: + $arrayReturn['length'] += 8; + // @link : http://msdn.microsoft.com/en-us/library/dd905272(v=office.12).aspx + // textType + $arrayReturn['length'] += 4; + break; + case self::RT_TEXTINTERACTIVEINFOATOM: + $arrayReturn['length'] += 8; + //@link : http://msdn.microsoft.com/en-us/library/dd947973(v=office.12).aspx + if ($rhChild['recInstance'] == 0x0000) { + //@todo : MouseClickTextInteractiveInfoAtom + $arrayReturn['hyperlink'][count($arrayReturn['hyperlink']) - 1]['start'] = self::getInt4d($stream, $pos + + $arrayReturn['length']); + $arrayReturn['length'] += 4; + + $arrayReturn['hyperlink'][count($arrayReturn['hyperlink']) - 1]['end'] = self::getInt4d($stream, $pos + + $arrayReturn['length']); + $arrayReturn['length'] += 4; + } + if ($rhChild['recInstance'] == 0x0001) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + break; + case self::RT_TEXTSPECIALINFOATOM: + $arrayReturn['length'] += 8; + // @link : http://msdn.microsoft.com/en-us/library/dd945296(v=office.12).aspx + $strLenRT = $strLen + 1; + do { + $structTextSIRun = $this->readStructureTextSIRun($stream, $pos + $arrayReturn['length'], $strLenRT); + $strLenRT = $structTextSIRun['strLenRT']; + $arrayReturn['length'] += $structTextSIRun['length']; + } while ($strLenRT > 0); + break; + case self::RT_TEXTRULERATOM: + $arrayReturn['length'] += 8; + // @link : http://msdn.microsoft.com/en-us/library/dd953212(v=office.12).aspx + $structRuler = $this->readStructureTextRuler($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $structRuler['length']; + break; + case self::RT_SLIDENUMBERMETACHARATOM: + $datasRecord = $this->readRecordSlideNumberMCAtom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $datasRecord['length']; + break; + default: + throw new \Exception('Feature not implemented (l.'.__LINE__.' : 0x'.dechex($rhChild['recType']).')'); + } + } while (($data['recLen'] - $arrayReturn['length']) > 0); + } + return $arrayReturn; + } + + /** + * The OfficeArtSpContainer record specifies a shape container. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd943794(v=office.12).aspx + */ + private function readRecordOfficeArtSpContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + 'shape' => null, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == 0xF004) { + // Record Header + $arrayReturn['length'] += 8; + // shapeGroup + $shapeGroup = $this->readRecordOfficeArtFSPGR($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $shapeGroup['length']; + + // shapeProp + $shapeProp = $this->readRecordOfficeArtFSP($stream, $pos + $arrayReturn['length']); + if ($shapeProp['length'] == 0) { + throw new \Exception('PowerPoint97 Reader : record OfficeArtFSP'); + } + $arrayReturn['length'] += $shapeProp['length']; + + if ($shapeProp['fDeleted'] == 0x1 && $shapeProp['fChild'] == 0x0) { + // deletedShape + $deletedShape = $this->readRecordOfficeArtFPSPL($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $deletedShape['length']; + } + + // shapePrimaryOptions + $shpPrimaryOptions = $this->readRecordOfficeArtFOPT($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $shpPrimaryOptions['length']; + + // shapeSecondaryOptions1 + $shpSecondaryOptions1 = $this->readRecordOfficeArtSecondaryFOPT($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $shpSecondaryOptions1['length']; + + // shapeTertiaryOptions1 + $shpTertiaryOptions1 = $this->readRecordOfficeArtTertiaryFOPT($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $shpTertiaryOptions1['length']; + + // childAnchor + $childAnchor = $this->readRecordOfficeArtChildAnchor($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $childAnchor['length']; + + // clientAnchor + $clientAnchor = $this->readRecordOfficeArtClientAnchor($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $clientAnchor['length']; + + // clientData + $clientData = $this->readRecordOfficeArtClientData($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $clientData['length']; + + // clientTextbox + $clientTextbox = $this->readRecordOfficeArtClientTextbox($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $clientTextbox['length']; + + // shapeSecondaryOptions2 + if ($shpSecondaryOptions1['length'] == 0) { + $shpSecondaryOptions2 = $this->readRecordOfficeArtSecondaryFOPT($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $shpSecondaryOptions2['length']; + } + + // shapeTertiaryOptions2 + if ($shpTertiaryOptions1['length'] == 0) { + $shpTertiaryOptions2 = $this->readRecordOfficeArtTertiaryFOPT($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $shpTertiaryOptions2['length']; + } + + // Core : Shape + // Informations about group are not defined + $arrayDimensions = array(); + $bIsGroup = false; + if (is_object($this->oCurrentGroup)) { + if (!$this->bFirstShapeGroup) { + if ($clientAnchor['length'] > 0) { + // $this->oCurrentGroup->setOffsetX($clientAnchor['left']); + // $this->oCurrentGroup->setOffsetY($clientAnchor['top']); + // $this->oCurrentGroup->setHeight($clientAnchor['height']); + // $this->oCurrentGroup->setWidth($clientAnchor['width']); + } + $bIsGroup = true; + $this->bFirstShapeGroup = true; + } else { + if ($childAnchor['length'] > 0) { + $arrayDimensions = $childAnchor; + } + } + } else { + if ($clientAnchor['length'] > 0) { + $arrayDimensions = $clientAnchor; + } + } + if (!$bIsGroup) { + // *** Shape *** + if (isset($shpPrimaryOptions['pib'])) { + // isDrawing + $drawingPib = $shpPrimaryOptions['pib']; + if (isset($this->arrayPictures[$drawingPib - 1])) { + $gdImage = imagecreatefromstring($this->arrayPictures[$drawingPib - 1]); + $arrayReturn['shape'] = new MemoryDrawing(); + $arrayReturn['shape']->setImageResource($gdImage); + } + } elseif (isset($shpPrimaryOptions['line']) && $shpPrimaryOptions['line']) { + // isLine + $arrayReturn['shape'] = new Line(0, 0, 0, 0); + } elseif ($clientTextbox['length'] > 0) { + $arrayReturn['shape'] = new RichText(); + if (isset($clientTextbox['alignH'])) { + $arrayReturn['shape']->getActiveParagraph()->getAlignment()->setHorizontal($clientTextbox['alignH']); + } + + $start = 0; + $lastLevel = -1; + $lastMarginLeft = 0; + for ($inc = 1; $inc <= $clientTextbox['numParts']; $inc++) { + if ($clientTextbox['numParts'] == $clientTextbox['numTexts'] && isset($clientTextbox['text'.$inc])) { + if (isset($clientTextbox['text'.$inc]['bulletChar'])) { + $arrayReturn['shape']->getActiveParagraph()->getBulletStyle()->setBulletType(Bullet::TYPE_BULLET); + $arrayReturn['shape']->getActiveParagraph()->getBulletStyle()->setBulletChar($clientTextbox['text'.$inc]['bulletChar']); + } + // Indent + $indent = 0; + if (isset($clientTextbox['text'.$inc]['indent'])) { + $indent = $clientTextbox['text'.$inc]['indent']; + } + if (isset($clientTextbox['text'.$inc]['leftMargin'])) { + if ($lastMarginLeft > $clientTextbox['text'.$inc]['leftMargin']) { + $lastLevel--; + } + if ($lastMarginLeft < $clientTextbox['text'.$inc]['leftMargin']) { + $lastLevel++; + } + $arrayReturn['shape']->getActiveParagraph()->getAlignment()->setLevel($lastLevel); + $lastMarginLeft = $clientTextbox['text'.$inc]['leftMargin']; + + $arrayReturn['shape']->getActiveParagraph()->getAlignment()->setMarginLeft($clientTextbox['text'.$inc]['leftMargin']); + $arrayReturn['shape']->getActiveParagraph()->getAlignment()->setIndent($indent - $clientTextbox['text'.$inc]['leftMargin']); + } + } + // Texte + $sText = substr(isset($clientTextbox['text']) ? $clientTextbox['text'] : '', $start, $clientTextbox['part'.$inc]['partLength']); + $sHyperlinkURL = ''; + if (empty($sText)) { + // Is there a hyperlink ? + if (isset($clientTextbox['hyperlink']) && is_array($clientTextbox['hyperlink']) && !empty($clientTextbox['hyperlink'])) { + foreach ($clientTextbox['hyperlink'] as $itmHyperlink) { + if ($itmHyperlink['start'] == $start && ($itmHyperlink['end'] - $itmHyperlink['start']) == $clientTextbox['part'.$inc]['partLength']) { + $sText = $this->arrayHyperlinks[$itmHyperlink['id']]['text']; + $sHyperlinkURL = $this->arrayHyperlinks[$itmHyperlink['id']]['url']; + break; + } + } + } + } + // New paragraph + $bCreateParagraph = false; + if (strpos($sText, "\r") !== false) { + $bCreateParagraph = true; + $sText = str_replace("\r", '', $sText); + } + // TextRun + $txtRun = $arrayReturn['shape']->createTextRun($sText); + if (isset($clientTextbox['part'.$inc]['bold'])) { + $txtRun->getFont()->setBold($clientTextbox['part'.$inc]['bold']); + } + if (isset($clientTextbox['part'.$inc]['italic'])) { + $txtRun->getFont()->setItalic($clientTextbox['part'.$inc]['italic']); + } + if (isset($clientTextbox['part'.$inc]['underline'])) { + $txtRun->getFont()->setUnderline($clientTextbox['part'.$inc]['underline']); + } + if (isset($clientTextbox['part'.$inc]['fontName'])) { + $txtRun->getFont()->setName($clientTextbox['part'.$inc]['fontName']); + } + if (isset($clientTextbox['part'.$inc]['fontSize'])) { + $txtRun->getFont()->setSize($clientTextbox['part'.$inc]['fontSize']); + } + if (isset($clientTextbox['part'.$inc]['color'])) { + $txtRun->getFont()->setColor($clientTextbox['part'.$inc]['color']); + } + // Hyperlink + if (!empty($sHyperlinkURL)) { + $txtRun->setHyperlink(new Hyperlink($sHyperlinkURL)); + } + + $start += $clientTextbox['part'.$inc]['partLength']; + if ($bCreateParagraph) { + $arrayReturn['shape']->createParagraph(); + } + } + } + + // *** Properties *** + // Dimensions + if ($arrayReturn['shape'] instanceof AbstractShape) { + if (!empty($arrayDimensions)) { + $arrayReturn['shape']->setOffsetX($arrayDimensions['left']); + $arrayReturn['shape']->setOffsetY($arrayDimensions['top']); + $arrayReturn['shape']->setHeight($arrayDimensions['height']); + $arrayReturn['shape']->setWidth($arrayDimensions['width']); + } + // Rotation + if (isset($shpPrimaryOptions['rotation'])) { + $rotation = $shpPrimaryOptions['rotation']; + $arrayReturn['shape']->setRotation($rotation); + } + // Shadow + if (isset($shpPrimaryOptions['shadowOffsetX']) && isset($shpPrimaryOptions['shadowOffsetY'])) { + $shadowOffsetX = $shpPrimaryOptions['shadowOffsetX']; + $shadowOffsetY = $shpPrimaryOptions['shadowOffsetY']; + if ($shadowOffsetX != 0 && $shadowOffsetX != 0) { + $arrayReturn['shape']->getShadow()->setVisible(true); + if ($shadowOffsetX > 0 && $shadowOffsetX == $shadowOffsetY) { + $arrayReturn['shape']->getShadow()->setDistance($shadowOffsetX)->setDirection(45); + } + } + } + // Specific Line + if ($arrayReturn['shape'] instanceof Line) { + if (isset($shpPrimaryOptions['lineColor'])) { + $arrayReturn['shape']->getBorder()->getColor()->setARGB('FF'.$shpPrimaryOptions['lineColor']); + } + if (isset($shpPrimaryOptions['lineWidth'])) { + $arrayReturn['shape']->setHeight($shpPrimaryOptions['lineWidth']); + } + } + // Specific RichText + if ($arrayReturn['shape'] instanceof RichText) { + if (isset($shpPrimaryOptions['insetBottom'])) { + $arrayReturn['shape']->setInsetBottom($shpPrimaryOptions['insetBottom']); + } + if (isset($shpPrimaryOptions['insetLeft'])) { + $arrayReturn['shape']->setInsetLeft($shpPrimaryOptions['insetLeft']); + } + if (isset($shpPrimaryOptions['insetRight'])) { + $arrayReturn['shape']->setInsetRight($shpPrimaryOptions['insetRight']); + } + if (isset($shpPrimaryOptions['insetTop'])) { + $arrayReturn['shape']->setInsetTop($shpPrimaryOptions['insetTop']); + } + } + } + } else { + // Rotation + if (isset($shpPrimaryOptions['rotation'])) { + $rotation = $shpPrimaryOptions['rotation']; + $this->oCurrentGroup->setRotation($rotation); + } + } + } + + return $arrayReturn; + } + + /** + * The OfficeArtSpgrContainer record specifies a container for groups of shapes. + * @param string $stream + * @param integer $pos + * @param boolean $bInGroup + * @link : https://msdn.microsoft.com/en-us/library/dd910416(v=office.12).aspx + */ + private function readRecordOfficeArtSpgrContainer($stream, $pos, $bInGroup = false) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == 0xF003) { + $arrayReturn['length'] += 8; + + do { + $rhFileBlock = $this->loadRecordHeader($stream, $pos + $arrayReturn['length']); + if (!($rhFileBlock['recVer'] == 0xF && $rhFileBlock['recInstance'] == 0x0000 && ($rhFileBlock['recType'] == 0xF003 || $rhFileBlock['recType'] == 0xF004))) { + throw new \Exception('PowerPoint97 Reader : readRecordOfficeArtSpgrContainer.'); + } + + switch ($rhFileBlock['recType']) { + case 0xF003: + // Core + $this->oCurrentGroup = $this->oPhpPowerpoint->getActiveSlide()->createGroup(); + $this->bFirstShapeGroup = false; + // OfficeArtSpgrContainer + $fileBlock = $this->readRecordOfficeArtSpgrContainer($stream, $pos + $arrayReturn['length'], true); + $arrayReturn['length'] += $fileBlock['length']; + $data['recLen'] -= $fileBlock['length']; + break; + case 0xF004: + // Core + if (!$bInGroup) { + $this->oCurrentGroup = null; + } + // OfficeArtSpContainer + $fileBlock = $this->readRecordOfficeArtSpContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $fileBlock['length']; + $data['recLen'] -= $fileBlock['length']; + // Core + //@todo + if (!is_null($fileBlock['shape'])) { + if ($bInGroup) { + $this->oCurrentGroup->addShape($fileBlock['shape']); + } else { + $this->oPhpPowerpoint->getActiveSlide()->addShape($fileBlock['shape']); + } + } + + break; + } + } while ($data['recLen'] > 0); + } + return $arrayReturn; + } + + /** + * The OfficeArtTertiaryFOPT record specifies a table of OfficeArtRGFOPTE records,. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd950206(v=office.12).aspx + */ + private function readRecordOfficeArtTertiaryFOPT($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x3 && $data['recType'] == 0xF122) { + // Record Header + $arrayReturn['length'] += 8; + + $officeArtFOPTE = array(); + for ($inc = 0; $inc < $data['recInstance']; $inc++) { + $opid = self::getInt2d($this->streamPowerpointDocument, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $optOp = self::getInt4d($this->streamPowerpointDocument, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + $officeArtFOPTE[] = array( + 'opid' => ($opid >> 0) & bindec('11111111111111'), + 'fBid' => ($opid >> 14) & bindec('1'), + 'fComplex' => ($opid >> 15) & bindec('1'), + 'op' => $optOp, + ); + } + //@link : http://code.metager.de/source/xref/kde/calligra/filters/libmso/OPID + foreach ($officeArtFOPTE as $opt) { + switch ($opt['opid']) { + case 0x039F: + // Table properties + //@link : https://msdn.microsoft.com/en-us/library/dd922773(v=office.12).aspx + break; + case 0x03A0: + // Table Row Properties + //@link : https://msdn.microsoft.com/en-us/library/dd923419(v=office.12).aspx + if ($opt['fComplex'] == 0x1) { + $arrayReturn['length'] += $opt['op']; + } + break; + case 0x03A9: + // GroupShape : metroBlob + //@link : https://msdn.microsoft.com/en-us/library/dd943388(v=office.12).aspx + if ($opt['fComplex'] == 0x1) { + $arrayReturn['length'] += $opt['op']; + } + break; + case 0x01FF: + // Line Style Boolean + //@link : https://msdn.microsoft.com/en-us/library/dd951605(v=office.12).aspx + break; + default: + throw new \Exception('Feature not implemented (l.'.__LINE__.' : 0x'.dechex($opt['opid']).')'); + } + } + } + return $arrayReturn; + } + + /** + * The OfficeArtDgContainer record specifies the container for all the file records for the objects in a drawing. + * @param string $stream + * @param integer $pos + * @link : https://msdn.microsoft.com/en-us/library/dd924455(v=office.12).aspx + */ + private function readRecordOfficeArtDgContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == 0xF002) { + // Record Header + $arrayReturn['length'] += 8; + // drawingData + $drawingData = $this->readRecordOfficeArtFDG($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $drawingData['length']; + // regroupItems + //@todo + // groupShape + $groupShape = $this->readRecordOfficeArtSpgrContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $groupShape['length']; + // shape + $shape = $this->readRecordOfficeArtSpContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $shape['length']; + // solvers1 + //@todo + // deletedShapes + //@todo + // solvers1 + //@todo + } + + return $arrayReturn; + } + + /** + * The OfficeArtFDG record specifies the number of shapes, the drawing identifier, and the shape identifier of the last shape in a drawing. + * @param string $stream + * @param integer $pos + * @link : https://msdn.microsoft.com/en-us/library/dd946757(v=office.12).aspx + */ + private function readRecordOfficeArtFDG($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] <= 0xFFE && $data['recType'] == 0xF008 && $data['recLen'] == 0x00000008) { + // Record Header + $arrayReturn['length'] += 8; + // Length + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * The OfficeArtFOPT record specifies a table of OfficeArtRGFOPTE records. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd943404(v=office.12).aspx + */ + private function readRecordOfficeArtFOPT($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x3 && $data['recType'] == 0xF00B) { + // Record Header + $arrayReturn['length'] += 8; + + //@link : http://msdn.microsoft.com/en-us/library/dd906086(v=office.12).aspx + $officeArtFOPTE = array(); + for ($inc = 0; $inc < $data['recInstance']; $inc++) { + $opid = self::getInt2d($this->streamPowerpointDocument, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $data['recLen'] -= 2; + $optOp = self::getInt4d($this->streamPowerpointDocument, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + $data['recLen'] -= 4; + $officeArtFOPTE[] = array( + 'opid' => ($opid >> 0) & bindec('11111111111111'), + 'fBid' => ($opid >> 14) & bindec('1'), + 'fComplex' => ($opid >> 15) & bindec('1'), + 'op' => $optOp, + ); + } + //@link : http://code.metager.de/source/xref/kde/calligra/filters/libmso/OPID + foreach ($officeArtFOPTE as $opt) { + // echo $opt['opid'].'-0x'.dechex($opt['opid']).EOL; + switch ($opt['opid']) { + case 0x0004: + // Transform : rotation + //@link : https://msdn.microsoft.com/en-us/library/dd949750(v=office.12).aspx + $arrayReturn['rotation'] = $opt['op']; + break; + case 0x007F: + // Transform : Protection Boolean Properties + //@link : http://msdn.microsoft.com/en-us/library/dd909131(v=office.12).aspx + break; + case 0x0080: + // Text : ltxid + //@link : http://msdn.microsoft.com/en-us/library/dd947446(v=office.12).aspx + break; + case 0x0081: + // Text : dxTextLeft + //@link : http://msdn.microsoft.com/en-us/library/dd953234(v=office.12).aspx + $arrayReturn['insetLeft'] = \PhpOffice\Common\Drawing::emuToPixels($opt['op']); + break; + case 0x0082: + // Text : dyTextTop + //@link : http://msdn.microsoft.com/en-us/library/dd925068(v=office.12).aspx + $arrayReturn['insetTop'] = \PhpOffice\Common\Drawing::emuToPixels($opt['op']); + break; + case 0x0083: + // Text : dxTextRight + //@link : http://msdn.microsoft.com/en-us/library/dd906782(v=office.12).aspx + $arrayReturn['insetRight'] = \PhpOffice\Common\Drawing::emuToPixels($opt['op']); + break; + case 0x0084: + // Text : dyTextBottom + //@link : http://msdn.microsoft.com/en-us/library/dd772858(v=office.12).aspx + $arrayReturn['insetBottom'] = \PhpOffice\Common\Drawing::emuToPixels($opt['op']); + break; + case 0x0085: + // Text : WrapText + //@link : http://msdn.microsoft.com/en-us/library/dd924770(v=office.12).aspx + break; + case 0x0087: + // Text : anchorText + //@link : http://msdn.microsoft.com/en-us/library/dd948575(v=office.12).aspx + break; + case 0x00BF: + // Text : Text Boolean Properties + //@link : http://msdn.microsoft.com/en-us/library/dd950905(v=office.12).aspx + break; + case 0x0104: + // Blip : pib + //@link : http://msdn.microsoft.com/en-us/library/dd772837(v=office.12).aspx + if ($opt['fComplex'] == 0) { + $arrayReturn['pib'] = $opt['op']; + $data['recLen'] -= $opt['op']; + } else { + // pib Complex + } + break; + case 0x13F: + // Blip Boolean Properties + //@link : https://msdn.microsoft.com/en-us/library/dd944215(v=office.12).aspx + break; + case 0x140: + // Geometry : geoLeft + //@link : http://msdn.microsoft.com/en-us/library/dd947489(v=office.12).aspx + // print_r('geoLeft : '.$opt['op'].EOL); + break; + case 0x141: + // Geometry : geoTop + //@link : http://msdn.microsoft.com/en-us/library/dd949459(v=office.12).aspx + // print_r('geoTop : '.$opt['op'].EOL); + break; + case 0x142: + // Geometry : geoRight + //@link : http://msdn.microsoft.com/en-us/library/dd947117(v=office.12).aspx + // print_r('geoRight : '.$opt['op'].EOL); + break; + case 0x143: + // Geometry : geoBottom + //@link : http://msdn.microsoft.com/en-us/library/dd948602(v=office.12).aspx + // print_r('geoBottom : '.$opt['op'].EOL); + break; + case 0x144: + // Geometry : shapePath + //@link : http://msdn.microsoft.com/en-us/library/dd945249(v=office.12).aspx + $arrayReturn['line'] = true; + break; + case 0x145: + // Geometry : pVertices + //@link : http://msdn.microsoft.com/en-us/library/dd949814(v=office.12).aspx + if ($opt['fComplex'] == 1) { + $arrayReturn['length'] += $opt['op']; + $data['recLen'] -= $opt['op']; + } + break; + case 0x146: + // Geometry : pSegmentInfo + //@link : http://msdn.microsoft.com/en-us/library/dd905742(v=office.12).aspx + if ($opt['fComplex'] == 1) { + $arrayReturn['length'] += $opt['op']; + $data['recLen'] -= $opt['op']; + } + break; + case 0x155: + // Geometry : pAdjustHandles + //@link : http://msdn.microsoft.com/en-us/library/dd905890(v=office.12).aspx + if ($opt['fComplex'] == 1) { + $arrayReturn['length'] += $opt['op']; + $data['recLen'] -= $opt['op']; + } + break; + case 0x156: + // Geometry : pGuides + //@link : http://msdn.microsoft.com/en-us/library/dd910801(v=office.12).aspx + if ($opt['fComplex'] == 1) { + $arrayReturn['length'] += $opt['op']; + $data['recLen'] -= $opt['op']; + } + break; + case 0x157: + // Geometry : pInscribe + //@link : http://msdn.microsoft.com/en-us/library/dd904889(v=office.12).aspx + if ($opt['fComplex'] == 1) { + $arrayReturn['length'] += $opt['op']; + $data['recLen'] -= $opt['op']; + } + break; + case 0x17F: + // Geometry Boolean Properties + //@link : http://msdn.microsoft.com/en-us/library/dd944968(v=office.12).aspx + break; + case 0x0180: + // Fill : fillType + //@link : http://msdn.microsoft.com/en-us/library/dd947909(v=office.12).aspx + break; + case 0x0181: + // Fill : fillColor + //@link : http://msdn.microsoft.com/en-us/library/dd921332(v=office.12).aspx + $strColor = str_pad(dechex(($opt['op'] >> 0) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex(($opt['op'] >> 8) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex(($opt['op'] >> 16) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + // echo 'fillColor : '.$strColor.EOL; + break; + case 0x0183: + // Fill : fillBackColor + //@link : http://msdn.microsoft.com/en-us/library/dd950634(v=office.12).aspx + $strColor = str_pad(dechex(($opt['op'] >> 0) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex(($opt['op'] >> 8) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex(($opt['op'] >> 16) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + // echo 'fillBackColor : '.$strColor.EOL; + break; + case 0x0193: + // Fill : fillRectRight + //@link : http://msdn.microsoft.com/en-us/library/dd951294(v=office.12).aspx + // echo 'fillRectRight : '.\PhpOffice\Common\Drawing::emuToPixels($opt['op']).EOL; + break; + case 0x0194: + // Fill : fillRectBottom + //@link : http://msdn.microsoft.com/en-us/library/dd910194(v=office.12).aspx + // echo 'fillRectBottom : '.\PhpOffice\Common\Drawing::emuToPixels($opt['op']).EOL; + break; + case 0x01BF: + // Fill : Fill Style Boolean Properties + //@link : http://msdn.microsoft.com/en-us/library/dd909380(v=office.12).aspx + break; + case 0x01C0: + // Line Style : lineColor + //@link : http://msdn.microsoft.com/en-us/library/dd920397(v=office.12).aspx + $strColor = str_pad(dechex(($opt['op'] >> 0) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex(($opt['op'] >> 8) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex(($opt['op'] >> 16) & bindec('11111111')), 2, STR_PAD_LEFT, '0'); + $arrayReturn['lineColor'] = $strColor; + break; + case 0x01C1: + // Line Style : lineOpacity + //@link : http://msdn.microsoft.com/en-us/library/dd923433(v=office.12).aspx + // echo 'lineOpacity : '.dechex($opt['op']).EOL; + break; + case 0x01C2: + // Line Style : lineBackColor + //@link : http://msdn.microsoft.com/en-us/library/dd947669(v=office.12).aspx + break; + case 0x01CB: + // Line Style : lineWidth + //@link : http://msdn.microsoft.com/en-us/library/dd926964(v=office.12).aspx + $arrayReturn['lineWidth'] = \PhpOffice\Common\Drawing::emuToPixels($opt['op']); + break; + case 0x01D6: + // Line Style : lineJoinStyle + //@link : http://msdn.microsoft.com/en-us/library/dd909643(v=office.12).aspx + break; + case 0x01D7: + // Line Style : lineEndCapStyle + //@link : http://msdn.microsoft.com/en-us/library/dd925071(v=office.12).aspx + break; + case 0x01FF: + // Line Style : Line Style Boolean Properties + //@link : http://msdn.microsoft.com/en-us/library/dd951605(v=office.12).aspx + break; + case 0x0201: + // Shadow Style : shadowColor + //@link : http://msdn.microsoft.com/en-us/library/dd923454(v=office.12).aspx + break; + case 0x0204: + // Shadow Style : shadowOpacity + //@link : http://msdn.microsoft.com/en-us/library/dd920720(v=office.12).aspx + break; + case 0x0205: + // Shadow Style : shadowOffsetX + //@link : http://msdn.microsoft.com/en-us/library/dd945280(v=office.12).aspx + $arrayReturn['shadowOffsetX'] = \PhpOffice\Common\Drawing::emuToPixels($opt['op']); + break; + case 0x0206: + // Shadow Style : shadowOffsetY + //@link : http://msdn.microsoft.com/en-us/library/dd907855(v=office.12).aspx + $arrayReturn['shadowOffsetY'] = \PhpOffice\Common\Drawing::emuToPixels($opt['op']); + break; + case 0x023F: + // Shadow Style : Shadow Style Boolean Properties + //@link : http://msdn.microsoft.com/en-us/library/dd947887(v=office.12).aspx + break; + case 0x0304: + // Shape : bWMode + //@link : http://msdn.microsoft.com/en-us/library/dd947659(v=office.12).aspx + break; + case 0x033F: + // Shape Boolean Properties + //@link : http://msdn.microsoft.com/en-us/library/dd951345(v=office.12).aspx + break; + case 0x0380: + // Group Shape Property Set : wzName + //@link : http://msdn.microsoft.com/en-us/library/dd950681(v=office.12).aspx + if ($opt['fComplex'] == 1) { + $arrayReturn['length'] += $opt['op']; + $data['recLen'] -= $opt['op']; + } + break; + case 0x03BF: + // Group Shape Property Set : Group Shape Boolean Properties + //@link : http://msdn.microsoft.com/en-us/library/dd949807(v=office.12).aspx + break; + default: + throw new \Exception('Feature not implemented (l.'.__LINE__.' : 0x'.dechex($opt['opid']).')'); + } + } + if ($data['recLen'] > 0) { + $arrayReturn['length'] += $data['recLen']; + } + } + + return $arrayReturn; + } + + /** + * The OfficeArtFPSPL record specifies the former hierarchical position of the containing object that is either a shape or a group of shapes. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd947479(v=office.12).aspx + */ + private function readRecordOfficeArtFPSPL($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == 0xF11D && $data['recLen'] == 0x00000004) { + $arrayReturn['length'] += 8; + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * The OfficeArtFSP record specifies an instance of a shape. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd925898(v=office.12).aspx + */ + private function readRecordOfficeArtFSP($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x2 && $data['recType'] == 0xF00A && $data['recLen'] == 0x00000008) { + $arrayReturn['length'] += 8; + // spid + $arrayReturn['length'] += 4; + // data + $data = self::getInt4d($this->streamPowerpointDocument, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + $arrayReturn['fGroup'] = ($data >> 0) & bindec('1'); + $arrayReturn['fChild'] = ($data >> 1) & bindec('1'); + $arrayReturn['fPatriarch'] = ($data >> 2) & bindec('1'); + $arrayReturn['fDeleted'] = ($data >> 3) & bindec('1'); + } + + return $arrayReturn; + } + + /** + * The OfficeArtFSPGR record specifies the coordinate system of the group shape that the anchors of the child shape are expressed in. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd925381(v=office.12).aspx + */ + private function readRecordOfficeArtFSPGR($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x1 && $data['recInstance'] == 0x000 && $data['recType'] == 0xF009 && $data['recLen'] == 0x00000010) { + $arrayReturn['length'] += 8; + //$arrShapeGroup['xLeft'] = self::getInt4d($this->streamPowerpointDocument, $pos); + $arrayReturn['length'] += 4; + //$arrShapeGroup['yTop'] = self::getInt4d($this->streamPowerpointDocument, $pos); + $arrayReturn['length'] += 4; + //$arrShapeGroup['xRight'] = self::getInt4d($this->streamPowerpointDocument, $pos); + $arrayReturn['length'] += 4; + //$arrShapeGroup['yBottom'] = self::getInt4d($this->streamPowerpointDocument, $pos); + $arrayReturn['length'] += 4; + } + + return $arrayReturn; + } + + /** + * The OfficeArtSecondaryFOPT record specifies a table of OfficeArtRGFOPTE records. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd950259(v=office.12).aspx + */ + private function readRecordOfficeArtSecondaryFOPT($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x3 && $data['recType'] == 0xF121) { + // Record Header + $arrayReturn['length'] += 8; + // Length + $arrayReturn['length'] += $data['recLen']; + } + return $arrayReturn; + } + + /** + * A container record that specifies information about a shape. + * @param string $stream + * @param integer $pos + * @link : https://msdn.microsoft.com/en-us/library/dd950927(v=office.12).aspx + */ + private function readRecordOfficeArtClientData($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == 0xF011) { + $arrayReturn['length'] += 8; + // shapeFlagsAtom (9 bytes) + $dataShapeFlagsAtom = $this->readRecordShapeFlagsAtom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataShapeFlagsAtom['length']; + + // shapeFlags10Atom (9 bytes) + $dataShapeFlags10Atom = $this->readRecordShapeFlags10Atom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataShapeFlags10Atom['length']; + + // exObjRefAtom (12 bytes) + $dataExObjRefAtom = $this->readRecordExObjRefAtom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataExObjRefAtom['length']; + + // animationInfo (variable) + $dataAnimationInfo = $this->readRecordAnimationInfoContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataAnimationInfo['length']; + + // mouseClickInteractiveInfo (variable) + $mouseClickInfo = $this->readRecordMouseClickInteractiveInfoContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $mouseClickInfo['length']; + + // mouseOverInteractiveInfo (variable) + $mouseOverInfo = $this->readRecordMouseOverInteractiveInfoContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $mouseOverInfo['length']; + + // placeholderAtom (16 bytes) + $dataPlaceholderAtom = $this->readRecordPlaceholderAtom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataPlaceholderAtom['length']; + + // recolorInfoAtom (variable) + $dataRecolorInfo = $this->readRecordRecolorInfoAtom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataRecolorInfo['length']; + + // rgShapeClientRoundtripData (variable) + $array = array( + self::RT_PROGTAGS, + self::RT_ROUNDTRIPNEWPLACEHOLDERID12ATOM, + self::RT_ROUNDTRIPSHAPEID12ATOM, + self::RT_ROUNDTRIPHFPLACEHOLDER12ATOM, + self::RT_ROUNDTRIPSHAPECHECKSUMFORCL12ATOM, + ); + do { + $dataHeaderRG = $this->loadRecordHeader($stream, $pos + $arrayReturn['length']); + if (in_array($dataHeaderRG['recType'], $array)) { + switch ($dataHeaderRG['recType']) { + case self::RT_PROGTAGS: + $dataRG = $this->readRecordShapeProgTagsContainer($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataRG['length']; + break; + case self::RT_ROUNDTRIPHFPLACEHOLDER12ATOM: + $dataRG = $this->readRecordRoundTripHFPlaceholder12Atom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataRG['length']; + break; + case self::RT_ROUNDTRIPSHAPEID12ATOM: + $dataRG = $this->readRecordRoundTripShapeId12Atom($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += $dataRG['length']; + break; + default: + throw new \Exception('Feature not implemented (l.'.__LINE__.' : 0x'.dechex($dataHeaderRG['recType']).')'); + } + } + } while (in_array($dataHeaderRG['recType'], $array)); + } + + return $arrayReturn; + } + + /** + * An atom record that specifies a persist object directory. Each persist object identifier specified MUST be unique in that persist object directory. + * @link http://msdn.microsoft.com/en-us/library/dd952680(v=office.12).aspx + * @param string $stream + * @param integer $pos + * @throws \Exception + */ + private function readRecordPersistDirectoryAtom($stream, $pos) + { + $rHeader = $this->loadRecordHeader($stream, $pos); + $pos += 8; + if ($rHeader['recVer'] != 0x0 || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != self::RT_PERSISTDIRECTORYATOM) { + throw new \Exception('File PowerPoint 97 in error (Location : PersistDirectoryAtom > RecordHeader).'); + } + // rgPersistDirEntry + // @link : http://msdn.microsoft.com/en-us/library/dd947347(v=office.12).aspx + do { + $data = self::getInt4d($stream, $pos); + $pos += 4; + $rHeader['recLen'] -= 4; + //$persistId = ($data >> 0) & bindec('11111111111111111111'); + $cPersist = ($data >> 20) & bindec('111111111111'); + + $rgPersistOffset = array(); + for ($inc = 0; $inc < $cPersist; $inc++) { + $rgPersistOffset[] = self::getInt4d($stream, $pos); + $pos += 4; + $rHeader['recLen'] -= 4; + } + } while ($rHeader['recLen'] > 0); + $this->rgPersistDirEntry = $rgPersistOffset; + } + + /** + * A container record that specifies information about the headers (1) and footers within a slide. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd904856(v=office.12).aspx + */ + private function readRecordPerSlideHeadersFootersContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_HEADERSFOOTERS) { + // Record Header + $arrayReturn['length'] += 8; + // Length + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * An atom record that specifies whether a shape is a placeholder shape. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd923930(v=office.12).aspx + */ + private function readRecordPlaceholderAtom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_PLACEHOLDERATOM && $data['recLen'] == 0x00000008) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * An atom record that specifies a collection of re-color mappings for a metafile ([MS-WMF]). + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd904899(v=office.12).aspx + */ + private function readRecordRecolorInfoAtom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_RECOLORINFOATOM) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * An atom record that specifies that a shape is a header or footerplaceholder shape. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd910800(v=office.12).aspx + */ + private function readRecordRoundTripHFPlaceholder12Atom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_ROUNDTRIPHFPLACEHOLDER12ATOM && $data['recLen'] == 0x00000001) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * An atom record that specifies a shape identifier. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd772926(v=office.12).aspx + */ + private function readRecordRoundTripShapeId12Atom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_ROUNDTRIPSHAPEID12ATOM && $data['recLen'] == 0x00000004) { + // Record Header + $arrayReturn['length'] += 8; + // Length + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * A container record that specifies information about a slide that synchronizes to a slide in a slide library. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd923801(v=office.12).aspx + */ + private function readRecordRoundTripSlideSyncInfo12Container($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_ROUNDTRIPSLIDESYNCINFO12) { + // Record Header + $arrayReturn['length'] += 8; + // Length + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * An atom record that specifies shape-level Boolean flags. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd908949(v=office.12).aspx + */ + private function readRecordShapeFlags10Atom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_SHAPEFLAGS10ATOM && $data['recLen'] == 0x00000001) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * An atom record that specifies shape-level Boolean flags. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd925824(v=office.12).aspx + */ + private function readRecordShapeFlagsAtom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_SHAPEATOM && $data['recLen'] == 0x00000001) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * A container record that specifies programmable tags with additional binary shape data. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd911033(v=office.12).aspx + */ + private function readRecordShapeProgBinaryTagContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_PROGBINARYTAG) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * A container record that specifies programmable tags with additional shape data. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd911266(v=office.12).aspx + */ + private function readRecordShapeProgTagsContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_PROGTAGS) { + // Record Header + $arrayReturn['length'] += 8; + + $length = 0; + do { + $dataHeaderRG = $this->loadRecordHeader($stream, $pos + $arrayReturn['length'] + $length); + switch ($dataHeaderRG['recType']) { + case self::RT_PROGBINARYTAG: + $dataRG = $this->readRecordShapeProgBinaryTagContainer($stream, $pos + $arrayReturn['length'] + $length); + $length += $dataRG['length']; + break; + //case self::RT_PROGSTRINGTAG: + default: + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + } while ($length < $data['recLen']); + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * An atom record that specifies information about a slide. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd923801(v=office.12).aspx + */ + private function readRecordSlideAtom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x2 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_SLIDEATOM) { + // Record Header + $arrayReturn['length'] += 8; + // slideAtom > geom + $arrayReturn['length'] += 4; + // slideAtom > rgPlaceholderTypes + $rgPlaceholderTypes = array(); + for ($inc = 0; $inc < 8; $inc++) { + $rgPlaceholderTypes[] = self::getInt1d($this->streamPowerpointDocument, $pos); + $arrayReturn['length'] += 1; + } + + // slideAtom > masterIdRef + $arrayReturn['length'] += 4; + // slideAtom > notesIdRef + $arrayReturn['length'] += 4; + // slideAtom > slideFlags + $arrayReturn['length'] += 2; + // slideAtom > unused; + $arrayReturn['length'] += 2; + } + + return $arrayReturn; + } + + /** + * A container record that specifies a presentation slide or title master slide. + * @param string $stream + * @param int $pos + * @link http://msdn.microsoft.com/en-us/library/dd946323(v=office.12).aspx + */ + private function readRecordSlideContainer($stream, $pos) + { + // Core + $this->oPhpPowerpoint->createSlide(); + $this->oPhpPowerpoint->setActiveSlideIndex($this->oPhpPowerpoint->getSlideCount() - 1); + + // *** slideAtom (32 bytes) + $slideAtom = $this->readRecordSlideAtom($stream, $pos); + if ($slideAtom['length'] == 0) { + throw new \Exception('PowerPoint97 Reader : record SlideAtom'); + } + $pos += $slideAtom['length']; + + // *** slideShowSlideInfoAtom (24 bytes) + $slideShowInfoAtom = $this->readRecordSlideShowSlideInfoAtom($stream, $pos); + $pos += $slideShowInfoAtom['length']; + + // *** perSlideHFContainer (variable) : optional + $perSlideHFContainer = $this->readRecordPerSlideHeadersFootersContainer($stream, $pos); + $pos += $perSlideHFContainer['length']; + + // *** rtSlideSyncInfo12 (variable) : optional + $rtSlideSyncInfo12 = $this->readRecordRoundTripSlideSyncInfo12Container($stream, $pos); + $pos += $rtSlideSyncInfo12['length']; + + // *** drawing (variable) + $drawing = $this->readRecordDrawingContainer($stream, $pos); + $pos += $drawing['length']; + + // *** slideSchemeColorSchemeAtom (40 bytes) + $slideSchemeColorAtom = $this->readRecordSlideSchemeColorSchemeAtom($stream, $pos); + if ($slideSchemeColorAtom['length'] == 0) { + throw new \Exception('PowerPoint97 Reader : record SlideSchemeColorSchemeAtom'); + } + $pos += $slideSchemeColorAtom['length']; + + // *** slideNameAtom (variable) + $slideNameAtom = $this->readRecordSlideNameAtom($stream, $pos); + $pos += $slideNameAtom['length']; + + // *** slideProgTagsContainer (variable). + $slideProgTags = $this->readRecordSlideProgTagsContainer($stream, $pos); + $pos += $slideProgTags['length']; + + // *** rgRoundTripSlide (variable) + } + + /** + * An atom record that specifies the name of a slide. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd906297(v=office.12).aspx + */ + private function readRecordSlideNameAtom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + 'slideName' => '', + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x003 && $data['recType'] == self::RT_CSTRING && $data['recLen'] % 2 == 0) { + // Record Header + $arrayReturn['length'] += 8; + // Length + $strLen = ($data['recLen'] / 2); + for ($inc = 0; $inc < $strLen; $inc++) { + $char = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $arrayReturn['slideName'] .= String::chr($char); + } + } + + return $arrayReturn; + } + + /** + * An atom record that specifies a slide number metacharacter. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd945703(v=office.12).aspx + */ + private function readRecordSlideNumberMCAtom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_SLIDENUMBERMETACHARATOM && $data['recLen'] == 0x00000004) { + // Record Header + $arrayReturn['length'] += 8; + // Datas + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + + + /** + * A container record that specifies programmable tags with additional slide data. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd951946(v=office.12).aspx + */ + private function readRecordSlideProgTagsContainer($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0xF && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_PROGTAGS) { + // Record Header + $arrayReturn['length'] += 8; + // Length + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * A container record that specifies the color scheme used by a slide. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd949420(v=office.12).aspx + */ + private function readRecordSlideSchemeColorSchemeAtom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x001 && $data['recType'] == self::RT_COLORSCHEMEATOM && $data['recLen'] == 0x00000020) { + // Record Header + $arrayReturn['length'] += 8; + // Length + $rgSchemeColor = array(); + for ($inc = 0; $inc <= 7; $inc++) { + $rgSchemeColor[] = array( + 'red' => self::getInt1d($stream, $pos + $arrayReturn['length'] + $inc * 4), + 'green' => self::getInt1d($stream, $pos + $arrayReturn['length'] + $inc * 4 + 1), + 'blue' => self::getInt1d($stream, $pos + $arrayReturn['length'] + $inc * 4 + 2), + ); + } + $arrayReturn['length'] += (8 * 4); + } + + return $arrayReturn; + } + + /** + * An atom record that specifies what transition effect to perform during a slide show, and how to advance to the next presentation slide. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd943408(v=office.12).aspx + */ + private function readRecordSlideShowSlideInfoAtom($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = $this->loadRecordHeader($stream, $pos); + if ($data['recVer'] == 0x0 && $data['recInstance'] == 0x000 && $data['recType'] == self::RT_SLIDESHOWSLIDEINFOATOM && $data['recLen'] == 0x00000010) { + // Record Header + $arrayReturn['length'] += 8; + // Length; + $arrayReturn['length'] += $data['recLen']; + } + + return $arrayReturn; + } + + /** + * UserEditAtom + * @link http://msdn.microsoft.com/en-us/library/dd945746(v=office.12).aspx + * @param string $stream + * @param integer $pos + * @throws \Exception + */ + private function readRecordUserEditAtom($stream, $pos) + { + $rHeader = $this->loadRecordHeader($stream, $pos); + $pos += 8; + if ($rHeader['recVer'] != 0x0 || $rHeader['recInstance'] != 0x000 || $rHeader['recType'] != self::RT_USEREDITATOM || ($rHeader['recLen'] != 0x0000001C && $rHeader['recLen'] != 0x00000020)) { + throw new \Exception('File PowerPoint 97 in error (Location : UserEditAtom > RecordHeader).'); + } + + // lastSlideIdRef + $pos += 4; + // version + $pos += 2; + + // minorVersion + $minorVersion = self::getInt1d($stream, $pos); + $pos += 1; + if ($minorVersion != 0x00) { + throw new \Exception('File PowerPoint 97 in error (Location : UserEditAtom > minorVersion).'); + } + + // majorVersion + $majorVersion = self::getInt1d($stream, $pos); + $pos += 1; + if ($majorVersion != 0x03) { + throw new \Exception('File PowerPoint 97 in error (Location : UserEditAtom > majorVersion).'); + } + + // offsetLastEdit + $pos += 4; + // offsetPersistDirectory + $this->offsetPersistDirectory = self::getInt4d($stream, $pos); + $pos += 4; + + // docPersistIdRef + $docPersistIdRef = self::getInt4d($stream, $pos); + $pos += 4; + if ($docPersistIdRef != 0x00000001) { + throw new \Exception('File PowerPoint 97 in error (Location : UserEditAtom > docPersistIdRef).'); + } + + // persistIdSeed + $pos += 4; + // lastView + $pos += 2; + // unused + $pos += 2; + } + + /** + * A structure that specifies the character-level formatting of a run of text. + * @param string $stream + * @param int $pos + * @param int $strLenRT + * @link https://msdn.microsoft.com/en-us/library/dd945870(v=office.12).aspx + */ + private function readStructureTextCFRun($stream, $pos, $strLenRT) + { + $arrayReturn = array( + 'length' => 0, + 'strLenRT' => $strLenRT, + ); + + // rgTextCFRun + $countRgTextCFRun = self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['strLenRT'] -= $countRgTextCFRun; + $arrayReturn['length'] += 4; + $arrayReturn['partLength'] = $countRgTextCFRun; + + $masks = self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + + $masksData = array(); + $masksData['bold'] = ($masks >> 0) & bindec('1'); + $masksData['italic'] = ($masks >> 1) & bindec('1'); + $masksData['underline'] = ($masks >> 2) & bindec('1'); + $masksData['unused1'] = ($masks >> 3) & bindec('1'); + $masksData['shadow'] = ($masks >> 4) & bindec('1'); + $masksData['fehint'] = ($masks >> 5) & bindec('1'); + $masksData['unused2'] = ($masks >> 6) & bindec('1'); + $masksData['kumi'] = ($masks >> 7) & bindec('1'); + $masksData['unused3'] = ($masks >> 8) & bindec('1'); + $masksData['emboss'] = ($masks >> 9) & bindec('1'); + $masksData['fHasStyle'] = ($masks >> 10) & bindec('1111'); + $masksData['unused4'] = ($masks >> 14) & bindec('11'); + $masksData['typeface'] = ($masks >> 16) & bindec('1'); + $masksData['size'] = ($masks >> 17) & bindec('1'); + $masksData['color'] = ($masks >> 18) & bindec('1'); + $masksData['position'] = ($masks >> 19) & bindec('1'); + $masksData['pp10ext'] = ($masks >> 20) & bindec('1'); + $masksData['oldEATypeface'] = ($masks >> 21) & bindec('1'); + $masksData['ansiTypeface'] = ($masks >> 22) & bindec('1'); + $masksData['symbolTypeface'] = ($masks >> 23) & bindec('1'); + $masksData['newEATypeface'] = ($masks >> 24) & bindec('1'); + $masksData['csTypeface'] = ($masks >> 25) & bindec('1'); + $masksData['pp11ext'] = ($masks >> 26) & bindec('1'); + if ($masksData['bold'] == 1 || $masksData['italic'] == 1 || $masksData['underline'] == 1 || $masksData['shadow'] == 1 || $masksData['fehint'] == 1 || $masksData['kumi'] == 1 || $masksData['emboss'] == 1 || $masksData['fHasStyle'] == 1) { + $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + + $fontStyleFlags = array(); + $fontStyleFlags['bold'] = ($data >> 0) & bindec('1'); + $fontStyleFlags['italic'] = ($data >> 1) & bindec('1'); + $fontStyleFlags['underline'] = ($data >> 2) & bindec('1'); + $fontStyleFlags['unused1'] = ($data >> 3) & bindec('1'); + $fontStyleFlags['shadow'] = ($data >> 4) & bindec('1'); + $fontStyleFlags['fehint'] = ($data >> 5) & bindec('1'); + $fontStyleFlags['unused2'] = ($data >> 6) & bindec('1'); + $fontStyleFlags['kumi'] = ($data >> 7) & bindec('1'); + $fontStyleFlags['unused3'] = ($data >> 8) & bindec('1'); + $fontStyleFlags['emboss'] = ($data >> 9) & bindec('1'); + $fontStyleFlags['pp9rt'] = ($data >> 10) & bindec('1111'); + $fontStyleFlags['unused4'] = ($data >> 14) & bindec('11'); + + $arrayReturn['bold'] = ($fontStyleFlags['bold'] == 1) ? true : false; + $arrayReturn['italic'] = ($fontStyleFlags['italic'] == 1) ? true : false; + $arrayReturn['underline'] = ($fontStyleFlags['underline'] == 1) ? true : false; + } + if ($masksData['typeface'] == 1) { + $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $arrayReturn['fontName'] = isset($this->arrayFonts[$data]) ? $this->arrayFonts[$data] : ''; + } + if ($masksData['oldEATypeface'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['ansiTypeface'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['symbolTypeface'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['size'] == 1) { + $arrayReturn['fontSize'] = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['color'] == 1) { + $red = self::getInt1d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 1; + $green = self::getInt1d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 1; + $blue = self::getInt1d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 1; + $index = self::getInt1d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 1; + + if ($index == 0xFE) { + $strColor = str_pad(dechex($red), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex($green), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex($blue), 2, STR_PAD_LEFT, '0'); + + $arrayReturn['color'] = new Color('FF'.$strColor); + } + } + if ($masksData['position'] == 1) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + + return $arrayReturn; + } + + /** + * A structure that specifies the paragraph-level formatting of a run of text. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd923535(v=office.12).aspx + */ + private function readStructureTextPFRun($stream, $pos, $strLenRT) + { + $arrayReturn = array( + 'length' => 0, + 'strLenRT' => $strLenRT, + ); + + // rgTextPFRun + $countRgTextPFRun = self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['strLenRT'] -= $countRgTextPFRun; + $arrayReturn['length'] += 4; + + // indent + $arrayReturn['length'] += 2; + + $masks = self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + + $masksData = array(); + $masksData['hasBullet'] = ($masks >> 0) & bindec('1'); + $masksData['bulletHasFont'] = ($masks >> 1) & bindec('1'); + $masksData['bulletHasColor'] = ($masks >> 2) & bindec('1'); + $masksData['bulletHasSize'] = ($masks >> 3) & bindec('1'); + $masksData['bulletFont'] = ($masks >> 4) & bindec('1'); + $masksData['bulletColor'] = ($masks >> 5) & bindec('1'); + $masksData['bulletSize'] = ($masks >> 6) & bindec('1'); + $masksData['bulletChar'] = ($masks >> 7) & bindec('1'); + $masksData['leftMargin'] = ($masks >> 8) & bindec('1'); + $masksData['unused'] = ($masks >> 9) & bindec('1'); + $masksData['indent'] = ($masks >> 10) & bindec('1'); + $masksData['align'] = ($masks >> 11) & bindec('1'); + $masksData['lineSpacing'] = ($masks >> 12) & bindec('1'); + $masksData['spaceBefore'] = ($masks >> 13) & bindec('1'); + $masksData['spaceAfter'] = ($masks >> 14) & bindec('1'); + $masksData['defaultTabSize'] = ($masks >> 15) & bindec('1'); + $masksData['fontAlign'] = ($masks >> 16) & bindec('1'); + $masksData['charWrap'] = ($masks >> 17) & bindec('1'); + $masksData['wordWrap'] = ($masks >> 18) & bindec('1'); + $masksData['overflow'] = ($masks >> 19) & bindec('1'); + $masksData['tabStops'] = ($masks >> 20) & bindec('1'); + $masksData['textDirection'] = ($masks >> 21) & bindec('1'); + $masksData['reserved1'] = ($masks >> 22) & bindec('1'); + $masksData['bulletBlip'] = ($masks >> 23) & bindec('1'); + $masksData['bulletScheme'] = ($masks >> 24) & bindec('1'); + $masksData['bulletHasScheme'] = ($masks >> 25) & bindec('1'); + + $bulletFlags = array(); + if ($masksData['hasBullet'] == 1 || $masksData['bulletHasFont'] == 1 || $masksData['bulletHasColor'] == 1 || $masksData['bulletHasSize'] == 1) { + $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + + $bulletFlags['fHasBullet'] = ($data >> 0) & bindec('1'); + $bulletFlags['fBulletHasFont'] = ($data >> 1) & bindec('1'); + $bulletFlags['fBulletHasColor'] = ($data >> 2) & bindec('1'); + $bulletFlags['fBulletHasSize'] = ($data >> 3) & bindec('1'); + } + if ($masksData['bulletChar'] == 1) { + $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $arrayReturn['bulletChar'] = chr($data); + } + if ($masksData['bulletFont'] == 1) { + // $data = self::getInt2d($stream, $pos); + $arrayReturn['length'] += 2; + } + if ($masksData['bulletSize'] == 1) { + // $data = self::getInt2d($stream, $pos); + $arrayReturn['length'] += 2; + } + if ($masksData['bulletColor'] == 1) { + $red = self::getInt1d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 1; + $green = self::getInt1d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 1; + $blue = self::getInt1d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 1; + $index = self::getInt1d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 1; + + if ($index == 0xFE) { + $strColor = str_pad(dechex($red), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex($green), 2, STR_PAD_LEFT, '0'); + $strColor .= str_pad(dechex($blue), 2, STR_PAD_LEFT, '0'); + } + } + if ($masksData['align'] == 1) { + $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + switch ($data) { + case 0x0000: + $arrayReturn['alignH'] = Alignment::HORIZONTAL_LEFT; + break; + case 0x0001: + $arrayReturn['alignH'] = Alignment::HORIZONTAL_CENTER; + break; + case 0x0002: + $arrayReturn['alignH'] = Alignment::HORIZONTAL_RIGHT; + break; + case 0x0003: + $arrayReturn['alignH'] = Alignment::HORIZONTAL_JUSTIFY; + break; + case 0x0004: + $arrayReturn['alignH'] = Alignment::HORIZONTAL_DISTRIBUTED; + break; + case 0x0005: + $arrayReturn['alignH'] = Alignment::HORIZONTAL_DISTRIBUTED; + break; + case 0x0006: + $arrayReturn['alignH'] = Alignment::HORIZONTAL_JUSTIFY; + break; + default: + break; + } + } + if ($masksData['lineSpacing'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['spaceBefore'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['spaceAfter'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['leftMargin'] == 1) { + $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $arrayReturn['leftMargin'] = (int)round($data/6); + } + if ($masksData['indent'] == 1) { + $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $arrayReturn['indent'] = (int)round($data/6); + } + if ($masksData['defaultTabSize'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['tabStops'] == 1) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + if ($masksData['fontAlign'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['charWrap'] == 1 || $masksData['wordWrap'] == 1 || $masksData['overflow'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['textDirection'] == 1) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + + return $arrayReturn; + } + + + /** + * A structure that specifies language and spelling information for a run of text. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd909603(v=office.12).aspx + */ + private function readStructureTextSIRun($stream, $pos, $strLenRT) + { + $arrayReturn = array( + 'length' => 0, + 'strLenRT' => $strLenRT, + ); + + $arrayReturn['strLenRT'] -= self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + + $data = self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + $masksData = array(); + $masksData['spell'] = ($data >> 0) & bindec('1'); + $masksData['lang'] = ($data >> 1) & bindec('1'); + $masksData['altLang'] = ($data >> 2) & bindec('1'); + $masksData['unused1'] = ($data >> 3) & bindec('1'); + $masksData['unused2'] = ($data >> 4) & bindec('1'); + $masksData['fPp10ext'] = ($data >> 5) & bindec('1'); + $masksData['fBidi'] = ($data >> 6) & bindec('1'); + $masksData['unused3'] = ($data >> 7) & bindec('1'); + $masksData['reserved1'] = ($data >> 8) & bindec('1'); + $masksData['smartTag'] = ($data >> 9) & bindec('1'); + + if ($masksData['spell'] == 1) { + $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $masksSpell = array(); + $masksSpell['error'] = ($data >> 0) & bindec('1'); + $masksSpell['clean'] = ($data >> 1) & bindec('1'); + $masksSpell['grammar'] = ($data >> 2) & bindec('1'); + } + if ($masksData['lang'] == 1) { + // $data = self::getInt2d($stream, $pos); + $arrayReturn['length'] += 2; + } + if ($masksData['altLang'] == 1) { + // $data = self::getInt2d($stream, $pos); + $arrayReturn['length'] += 2; + } + if ($masksData['fBidi'] == 1) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + if ($masksData['fPp10ext'] == 1) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + if ($masksData['smartTag'] == 1) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + + return $arrayReturn; + } + + /** + * A structure that specifies tabbing, margins, and indentation for text. + * @param string $stream + * @param integer $pos + * @link https://msdn.microsoft.com/en-us/library/dd922749(v=office.12).aspx + */ + private function readStructureTextRuler($stream, $pos) + { + $arrayReturn = array( + 'length' => 0, + ); + + $data = self::getInt4d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 4; + + $masksData = array(); + $masksData['fDefaultTabSize'] = ($data >> 0) & bindec('1'); + $masksData['fCLevels'] = ($data >> 1) & bindec('1'); + $masksData['fTabStops'] = ($data >> 2) & bindec('1'); + $masksData['fLeftMargin1'] = ($data >> 3) & bindec('1'); + $masksData['fLeftMargin2'] = ($data >> 4) & bindec('1'); + $masksData['fLeftMargin3'] = ($data >> 5) & bindec('1'); + $masksData['fLeftMargin4'] = ($data >> 6) & bindec('1'); + $masksData['fLeftMargin5'] = ($data >> 7) & bindec('1'); + $masksData['fIndent1'] = ($data >> 8) & bindec('1'); + $masksData['fIndent2'] = ($data >> 9) & bindec('1'); + $masksData['fIndent3'] = ($data >> 10) & bindec('1'); + $masksData['fIndent4'] = ($data >> 11) & bindec('1'); + $masksData['fIndent5'] = ($data >> 12) & bindec('1'); + + if ($masksData['fCLevels'] == 1) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + if ($masksData['fDefaultTabSize'] == 1) { + throw new \Exception('Feature not implemented (l.'.__LINE__.')'); + } + if ($masksData['fTabStops'] == 1) { + $count = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $arrayTabStops = array(); + for ($inc = 0; $inc < $count; $inc++) { + $position = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $type = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + $arrayTabStops[] = array( + 'position' => $position, + 'type' => $type, + ); + } + } + if ($masksData['fLeftMargin1'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fIndent1'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fLeftMargin2'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fIndent2'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fLeftMargin3'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fIndent3'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fLeftMargin4'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fIndent4'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fLeftMargin5'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + if ($masksData['fIndent5'] == 1) { + // $data = self::getInt2d($stream, $pos + $arrayReturn['length']); + $arrayReturn['length'] += 2; + } + + return $arrayReturn; } } diff --git a/src/PhpPowerpoint/Reader/Serialized.php b/src/PhpPowerpoint/Reader/Serialized.php index ad65619fc..b8cac323d 100644 --- a/src/PhpPowerpoint/Reader/Serialized.php +++ b/src/PhpPowerpoint/Reader/Serialized.php @@ -18,7 +18,7 @@ namespace PhpOffice\PhpPowerpoint\Reader; use PhpOffice\PhpPowerpoint\Shape\AbstractDrawing; -use PhpOffice\PhpPowerpoint\Shared\File; +use PhpOffice\Common\File; /** * Serialized format reader diff --git a/src/PhpPowerpoint/Shape/AbstractDrawing.php b/src/PhpPowerpoint/Shape/AbstractDrawing.php index 89c9439b3..b5e915a36 100644 --- a/src/PhpPowerpoint/Shape/AbstractDrawing.php +++ b/src/PhpPowerpoint/Shape/AbstractDrawing.php @@ -84,6 +84,14 @@ public function __construct() // Initialize parent parent::__construct(); } + + public function __clone() + { + parent::__clone(); + + self::$imageCounter++; + $this->imageIndex = self::$imageCounter; + } /** * Get image index diff --git a/src/PhpPowerpoint/Shape/Chart.php b/src/PhpPowerpoint/Shape/Chart.php index 57b04b3a0..46cbffac0 100644 --- a/src/PhpPowerpoint/Shape/Chart.php +++ b/src/PhpPowerpoint/Shape/Chart.php @@ -77,6 +77,16 @@ public function __construct() // Initialize parent parent::__construct(); } + + public function __clone() + { + parent::__clone(); + + $this->title = clone $this->title; + $this->legend = clone $this->legend; + $this->plotArea = clone $this->plotArea; + $this->view3D = clone $this->view3D; + } /** * Get Title diff --git a/src/PhpPowerpoint/Shape/Chart/PlotArea.php b/src/PhpPowerpoint/Shape/Chart/PlotArea.php index e5e717365..4cd6838d1 100644 --- a/src/PhpPowerpoint/Shape/Chart/PlotArea.php +++ b/src/PhpPowerpoint/Shape/Chart/PlotArea.php @@ -18,7 +18,6 @@ namespace PhpOffice\PhpPowerpoint\Shape\Chart; use PhpOffice\PhpPowerpoint\ComparableInterface; -use PhpOffice\PhpPowerpoint\Shape\Chart\Type\AbstractType; /** * \PhpOffice\PhpPowerpoint\Shape\Chart\PlotArea @@ -28,7 +27,7 @@ class PlotArea implements ComparableInterface /** * Type * - * @var \PhpOffice\PhpPowerpoint\Shape\Chart\AbstractType + * @var \PhpOffice\PhpPowerpoint\Shape\Chart\Type\AbstractType */ private $type; @@ -83,6 +82,12 @@ public function __construct() $this->axisX = new Axis(); $this->axisY = new Axis(); } + + public function __clone() + { + $this->axisX = clone $this->axisX; + $this->axisY = clone $this->axisY; + } /** * Get type @@ -102,10 +107,10 @@ public function getType() /** * Set type * - * @param \PhpOffice\PhpPowerpoint\Shape\Chart\AbstractType $value + * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\AbstractType $value * @return \PhpOffice\PhpPowerpoint\Shape\Chart\PlotArea */ - public function setType(AbstractType $value) + public function setType(Type\AbstractType $value) { $this->type = $value; diff --git a/src/PhpPowerpoint/Shape/Chart/Series.php b/src/PhpPowerpoint/Shape/Chart/Series.php index 5268608d1..f4ce1b58f 100644 --- a/src/PhpPowerpoint/Shape/Chart/Series.php +++ b/src/PhpPowerpoint/Shape/Chart/Series.php @@ -44,6 +44,13 @@ class Series implements ComparableInterface */ private $title = 'Series Title'; + /** + * Data Label Number Format + * + * @var string + */ + private $DlblNumFormat = ''; + /** * Fill * @@ -160,6 +167,38 @@ public function setTitle($value = 'Series Title') return $this; } + /** + * Get Data Label NumFormat + * + * @return string + */ + public function getDlblNumFormat() + { + return $this->DlblNumFormat; + } + + /** + * Has Data Label NumFormat + * + * @return string + */ + public function hasDlblNumFormat() + { + return !empty($this->DlblNumFormat); + } + + /** + * Set Data Label NumFormat + * + * @param string $value + * @return \PhpOffice\PhpPowerpoint\Shape\Chart\Series + */ + public function setDlblNumFormat($value = '') + { + $this->DlblNumFormat = $value; + return $this; + } + /** * Get Fill * @@ -170,6 +209,18 @@ public function getFill() return $this->fill; } + /** + * Set Fill + * + * @param \PhpOffice\PhpPowerpoint\Style\Fill $fill + * @return Series + */ + public function setFill(Fill $fill = null) + { + $this->fill = $fill; + return $this; + } + /** * Get DataPointFill * diff --git a/src/PhpPowerpoint/Shape/Chart/Type/AbstractType.php b/src/PhpPowerpoint/Shape/Chart/Type/AbstractType.php index ee6f988cf..20cdfbc78 100644 --- a/src/PhpPowerpoint/Shape/Chart/Type/AbstractType.php +++ b/src/PhpPowerpoint/Shape/Chart/Type/AbstractType.php @@ -115,7 +115,7 @@ public function addSeries(Series $value) /** * Get Data * - * @return array + * @return \PhpOffice\PhpPowerpoint\Shape\Chart\Series[] */ public function getData() { diff --git a/src/PhpPowerpoint/Shape/Chart/Type/AbstractTypeBar.php b/src/PhpPowerpoint/Shape/Chart/Type/AbstractTypeBar.php new file mode 100644 index 000000000..56c46c964 --- /dev/null +++ b/src/PhpPowerpoint/Shape/Chart/Type/AbstractTypeBar.php @@ -0,0 +1,108 @@ +barDirection = $value; + return $this; + } + + /** + * Get orientation + * + * @return string + */ + public function getBarDirection() + { + return $this->barDirection; + } + + /** + * Set bar grouping (stack or expanded style bar) + * + * @param string $value + * @return \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar + */ + public function setBarGrouping($value = self::GROUPING_CLUSTERED) + { + $this->barGrouping = $value; + return $this; + } + + /** + * Get grouping (stack or expanded style bar) + * + * @return string + */ + public function getBarGrouping() + { + return $this->barGrouping; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + $hash = ''; + foreach ($this->getData() as $series) { + $hash .= $series->getHashCode(); + } + return $hash; + } +} diff --git a/src/PhpPowerpoint/Shape/Chart/Type/AbstractTypePie.php b/src/PhpPowerpoint/Shape/Chart/Type/AbstractTypePie.php new file mode 100644 index 000000000..c5931e2a8 --- /dev/null +++ b/src/PhpPowerpoint/Shape/Chart/Type/AbstractTypePie.php @@ -0,0 +1,76 @@ +hasAxisX = false; + $this->hasAxisY = false; + } + + /** + * Explosion of the Pie + * + * @var integer + */ + protected $explosion = 0; + + /** + * Set explosion + * + * @param integer $value + * @return \PhpOffice\PhpPowerpoint\Shape\Chart\Type\AbstractTypePie + */ + public function setExplosion($value = 0) + { + $this->explosion = $value; + return $this; + } + + /** + * Get orientation + * + * @return string + */ + public function getExplosion() + { + return $this->explosion; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + $hash = ''; + foreach ($this->getData() as $series) { + $hash .= $series->getHashCode(); + } + return $hash; + } +} diff --git a/src/PhpPowerpoint/Shape/Chart/Type/Area.php b/src/PhpPowerpoint/Shape/Chart/Type/Area.php new file mode 100644 index 000000000..94766af05 --- /dev/null +++ b/src/PhpPowerpoint/Shape/Chart/Type/Area.php @@ -0,0 +1,40 @@ +getData() as $series) { + $hash .= $series->getHashCode(); + } + return md5($hash . __CLASS__); + } +} diff --git a/src/PhpPowerpoint/Shape/Chart/Type/Bar.php b/src/PhpPowerpoint/Shape/Chart/Type/Bar.php new file mode 100644 index 000000000..cd27d4f49 --- /dev/null +++ b/src/PhpPowerpoint/Shape/Chart/Type/Bar.php @@ -0,0 +1,36 @@ +getData() as $series) { - $hash .= $series->getHashCode(); - } - return md5($hash . __CLASS__); + return md5(parent::getHashCode() . __CLASS__); } } diff --git a/src/PhpPowerpoint/Shape/Chart/Type/Pie.php b/src/PhpPowerpoint/Shape/Chart/Type/Pie.php new file mode 100644 index 000000000..d5ab1aa1b --- /dev/null +++ b/src/PhpPowerpoint/Shape/Chart/Type/Pie.php @@ -0,0 +1,36 @@ +hasAxisX = false; - $this->hasAxisY = false; - } - /** * Get hash code * @@ -40,10 +31,6 @@ public function __construct() */ public function getHashCode() { - $hash = ''; - foreach ($this->getData() as $series) { - $hash .= $series->getHashCode(); - } - return md5($hash . __CLASS__); + return md5(parent::getHashCode() . __CLASS__); } } diff --git a/src/PhpPowerpoint/Shape/Group.php b/src/PhpPowerpoint/Shape/Group.php new file mode 100644 index 000000000..444e3b691 --- /dev/null +++ b/src/PhpPowerpoint/Shape/Group.php @@ -0,0 +1,263 @@ +offsetX = null; + $this->offsetY = null; + + // Shape collection + $this->shapeCollection = new \ArrayObject(); + } + + /** + * Get collection of shapes + * + * @return \ArrayObject|\PhpOffice\PhpPowerpoint\AbstractShape[] + */ + public function getShapeCollection() + { + return $this->shapeCollection; + } + + /** + * Add shape to slide + * + * @param \PhpOffice\PhpPowerpoint\AbstractShape $shape + * @return \PhpOffice\PhpPowerpoint\AbstractShape + */ + public function addShape(AbstractShape $shape) + { + $shape->setContainer($this); + + return $shape; + } + + /** + * Get X Offset + * + * @return int + */ + public function getOffsetX() + { + if ($this->offsetX === null) { + $offsets = GeometryCalculator::calculateOffsets($this); + $this->offsetX = $offsets[GeometryCalculator::X]; + $this->offsetY = $offsets[GeometryCalculator::Y]; + } + + return $this->offsetX; + } + + /** + * Ignores setting the X Offset, preserving the default behavior. + * + * @param int $pValue + * @return self + */ + public function setOffsetX($pValue = 0) + { + return $this; + } + + /** + * Get Y Offset + * + * @return int + */ + public function getOffsetY() + { + if ($this->offsetY === null) { + $offsets = GeometryCalculator::calculateOffsets($this); + $this->offsetX = $offsets[GeometryCalculator::X]; + $this->offsetY = $offsets[GeometryCalculator::Y]; + } + + return $this->offsetY; + } + + /** + * Ignores setting the Y Offset, preserving the default behavior. + * + * @param int $pValue + * @return self + */ + public function setOffsetY($pValue = 0) + { + return $this; + } + + /** + * Get X Extent + * + * @return int + */ + public function getExtentX() + { + if ($this->extentX === null) { + $extents = GeometryCalculator::calculateExtents($this); + $this->extentX = $extents[GeometryCalculator::X]; + $this->extentY = $extents[GeometryCalculator::Y]; + } + + return $this->extentX; + } + + /** + * Get Y Extent + * + * @return int + */ + public function getExtentY() + { + if ($this->extentY === null) { + $extents = GeometryCalculator::calculateExtents($this); + $this->extentX = $extents[GeometryCalculator::X]; + $this->extentY = $extents[GeometryCalculator::Y]; + } + + return $this->extentY; + } + + /** + * Ignores setting the width, preserving the default behavior. + * + * @param int $pValue + * @return self + */ + public function setWidth($pValue = 0) + { + return $this; + } + + /** + * Ignores setting the height, preserving the default behavior. + * + * @param int $pValue + * @return self + */ + public function setHeight($pValue = 0) + { + return $this; + } + + /** + * Create rich text shape + * + * @return \PhpOffice\PhpPowerpoint\Shape\RichText + */ + public function createRichTextShape() + { + $shape = new RichText(); + $this->addShape($shape); + + return $shape; + } + + /** + * Create line shape + * + * @param int $fromX Starting point x offset + * @param int $fromY Starting point y offset + * @param int $toX Ending point x offset + * @param int $toY Ending point y offset + * @return \PhpOffice\PhpPowerpoint\Shape\Line + */ + public function createLineShape($fromX, $fromY, $toX, $toY) + { + $shape = new Line($fromX, $fromY, $toX, $toY); + $this->addShape($shape); + + return $shape; + } + + /** + * Create chart shape + * + * @return \PhpOffice\PhpPowerpoint\Shape\Chart + */ + public function createChartShape() + { + $shape = new Chart(); + $this->addShape($shape); + + return $shape; + } + + /** + * Create drawing shape + * + * @return \PhpOffice\PhpPowerpoint\Shape\Drawing + */ + public function createDrawingShape() + { + $shape = new Drawing(); + $this->addShape($shape); + + return $shape; + } + + /** + * Create table shape + * + * @param int $columns Number of columns + * @return \PhpOffice\PhpPowerpoint\Shape\Table + */ + public function createTableShape($columns = 1) + { + $shape = new Table($columns); + $this->addShape($shape); + + return $shape; + } +} diff --git a/src/PhpPowerpoint/Shape/RichText.php b/src/PhpPowerpoint/Shape/RichText.php index f3c1f1194..6aecc79f8 100644 --- a/src/PhpPowerpoint/Shape/RichText.php +++ b/src/PhpPowerpoint/Shape/RichText.php @@ -35,7 +35,7 @@ class RichText extends AbstractShape implements ComparableInterface const AUTOFIT_DEFAULT = 'spAutoFit'; const AUTOFIT_SHAPE = 'spAutoFit'; const AUTOFIT_NOAUTOFIT = 'noAutofit'; - const AUTOFIT_NORMAL = 'normAutoFit'; + const AUTOFIT_NORMAL = 'normAutofit'; /** Overflow */ const OVERFLOW_CLIP = 'clip'; @@ -143,6 +143,18 @@ class RichText extends AbstractShape implements ComparableInterface * @var boolean */ private $autoShrinkVertical; + + /** + * The percentage of the original font size to which the text is scaled + * @var float + */ + private $fontScale; + + /** + * The percentage of the reduction of the line spacing + * @var float + */ + private $lnSpcReduction; /** * Create a new \PhpOffice\PhpPowerpoint\Shape\RichText instance @@ -374,15 +386,45 @@ public function getAutoFit() return $this->autoFit; } + /** + * Get pourcentage of fontScale + * + * @return float + */ + public function getFontScale() + { + return $this->fontScale; + } + + /** + * Get pourcentage of the line space reduction + * + * @return float + */ + public function getLineSpaceReduction() + { + return $this->lnSpcReduction; + } + /** * Set autofit * * @param $value string + * @param $fontScale float + * @param $lnSpcReduction float * @return \PhpOffice\PhpPowerpoint\Shape\RichText */ - public function setAutoFit($value = self::AUTOFIT_DEFAULT) + public function setAutoFit($value = self::AUTOFIT_DEFAULT, $fontScale = null, $lnSpcReduction = null) { $this->autoFit = $value; + + if (!is_null($fontScale)) { + $this->fontScale = $fontScale; + } + + if (!is_null($lnSpcReduction)) { + $this->lnSpcReduction = $lnSpcReduction; + } return $this; } diff --git a/src/PhpPowerpoint/ShapeContainerInterface.php b/src/PhpPowerpoint/ShapeContainerInterface.php new file mode 100644 index 000000000..fd578fc3f --- /dev/null +++ b/src/PhpPowerpoint/ShapeContainerInterface.php @@ -0,0 +1,67 @@ +open($zipFile) === true) { - $returnValue = ($zip->getFromName($archiveFile) !== false); - $zip->close(); - - return $returnValue; - } else { - return false; - } - } else { - // Regular file_exists - return file_exists($pFilename); - } - } - - /** - * Returns canonicalized absolute pathname, also for ZIP archives - * - * @param string $pFilename - * @return string - */ - public static function realpath($pFilename) - { - // Try using realpath() - $returnValue = realpath($pFilename); - - // Found something? - if ($returnValue == '' || is_null($returnValue)) { - $pathArray = explode('/', $pFilename); - while (in_array('..', $pathArray) && $pathArray[0] != '..') { - for ($i = 0; $i < count($pathArray); ++$i) { - if ($pathArray[$i] == '..' && $i > 0) { - unset($pathArray[$i]); - unset($pathArray[$i - 1]); - break; - } - } - } - $returnValue = implode('/', $pathArray); - } - - // Return - return $returnValue; - } -} diff --git a/src/PhpPowerpoint/Shared/Font.php b/src/PhpPowerpoint/Shared/Font.php deleted file mode 100644 index dfcaa3077..000000000 --- a/src/PhpPowerpoint/Shared/Font.php +++ /dev/null @@ -1,57 +0,0 @@ -data = file_get_contents($sFileName, false, null, 0, 8); - - // Check OLE identifier - if ($this->data != self::IDENTIFIER_OLE) { - throw new \Exception('The filename ' . $sFileName . ' is not recognised as an OLE file'); - } - - // Get the file data - $this->data = file_get_contents($sFileName); - - // Total number of sectors used for the SAT - $this->numBigBlockDepotBlocks = self::getInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); - - // SecID of the first sector of the directory stream - $this->rootStartBlock = self::getInt4d($this->data, self::ROOT_START_BLOCK_POS); - - // SecID of the first sector of the SSAT (or -2 if not extant) - $this->sbdStartBlock = self::getInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS); - - // SecID of the first sector of the MSAT (or -2 if no additional sectors are used) - $this->extensionBlock = self::getInt4d($this->data, self::EXTENSION_BLOCK_POS); - - // Total number of sectors used by MSAT - $this->numExtensionBlocks = self::getInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS); - - $bigBlockDepotBlocks = array(); - $pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS; - - $bbdBlocks = $this->numBigBlockDepotBlocks; - - if ($this->numExtensionBlocks != 0) { - $bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4; - } - - for ($i = 0; $i < $bbdBlocks; ++$i) { - $bigBlockDepotBlocks[$i] = self::getInt4d($this->data, $pos); - $pos += 4; - } - - for ($j = 0; $j < $this->numExtensionBlocks; ++$j) { - $pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE; - $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1); - - for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) { - $bigBlockDepotBlocks[$i] = self::getInt4d($this->data, $pos); - $pos += 4; - } - - $bbdBlocks += $blocksToRead; - if ($bbdBlocks < $this->numBigBlockDepotBlocks) { - $this->extensionBlock = self::getInt4d($this->data, $pos); - } - } - - $pos = 0; - $this->bigBlockChain = ''; - $bbs = self::BIG_BLOCK_SIZE / 4; - for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) { - $pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE; - - $this->bigBlockChain .= substr($this->data, $pos, 4*$bbs); - $pos += 4*$bbs; - } - - $pos = 0; - $sbdBlock = $this->sbdStartBlock; - $this->smallBlockChain = ''; - while ($sbdBlock != -2) { - $pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE; - - $this->smallBlockChain .= substr($this->data, $pos, 4*$bbs); - $pos += 4*$bbs; - - $sbdBlock = self::getInt4d($this->bigBlockChain, $sbdBlock*4); - } - - // read the directory stream - $block = $this->rootStartBlock; - $this->entry = $this->readData($block); - - $this->readPropertySets(); - } - - /** - * Extract binary stream data - * - * @return string - */ - public function getStream($stream) - { - if ($stream === null) { - return null; - } - - $streamData = ''; - - if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) { - $rootdata = $this->readData($this->props[$this->rootentry]['startBlock']); - - $block = $this->props[$stream]['startBlock']; - - while ($block != -2) { - $pos = $block * self::SMALL_BLOCK_SIZE; - $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE); - - $block = self::getInt4d($this->smallBlockChain, $block*4); - } - - return $streamData; - } else { - $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; - if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { - ++$numBlocks; - } - - if ($numBlocks == 0) { - return ''; - } - - $block = $this->props[$stream]['startBlock']; - - while ($block != -2) { - $pos = ($block + 1) * self::BIG_BLOCK_SIZE; - $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); - $block = self::getInt4d($this->bigBlockChain, $block*4); - } - - return $streamData; - } - } - - /** - * Read a standard stream (by joining sectors using information from SAT) - * - * @param int $blID Sector ID where the stream starts - * @return string Data for standard stream - */ - private function readData($blID) - { - $block = $blID; - $data = ''; - - while ($block != -2) { - $pos = ($block + 1) * self::BIG_BLOCK_SIZE; - $data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); - $block = self::getInt4d($this->bigBlockChain, $block*4); - } - return $data; - } - - /** - * Read entries in the directory stream. - */ - private function readPropertySets() - { - $offset = 0; - - // loop through entires, each entry is 128 bytes - $entryLen = strlen($this->entry); - while ($offset < $entryLen) { - // entry data (128 bytes) - $data = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE); - - // size in bytes of name - $nameSize = ord($data[self::SIZE_OF_NAME_POS]) | (ord($data[self::SIZE_OF_NAME_POS+1]) << 8); - - // type of entry - $type = ord($data[self::TYPE_POS]); - - // sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook) - // sectorID of first sector of the short-stream container stream, if this entry is root entry - $startBlock = self::getInt4d($data, self::START_BLOCK_POS); - - $size = self::getInt4d($data, self::SIZE_POS); - - $name = str_replace("\x00", "", substr($data, 0, $nameSize)); - - - $this->props[] = array ( - 'name' => $name, - 'type' => $type, - 'startBlock' => $startBlock, - 'size' => $size); - - // tmp helper to simplify checks - $upName = strtoupper($name); - - switch ($upName){ - case 'ROOT ENTRY': - case 'R': - $this->rootentry = count($this->props) - 1; - break; - case chr(1).'COMPOBJ': - break; - case chr(1).'OLE': - break; - case chr(5).'SUMMARYINFORMATION': - $this->summaryInformation = count($this->props) - 1; - break; - case chr(5).'DOCUMENTSUMMARYINFORMATION': - $this->docSummaryInfos = count($this->props) - 1; - break; - case 'CURRENT USER': - $this->currentUser = count($this->props) - 1; - break; - case 'PICTURES': - $this->pictures = count($this->props) - 1; - break; - case 'POWERPOINT DOCUMENT': - $this->powerpointDocument = count($this->props) - 1; - break; - default: - throw new \Exception('OLE Block Not defined: $upName : '.$upName. ' - $name : "'.$name.'"'); - break; - } - - $offset += self::PROPERTY_STORAGE_BLOCK_SIZE; - } - } - - /** - * Read 4 bytes of data at specified position - * - * @param string $data - * @param int $pos - * @return int - */ - private static function getInt4d($data, $pos) - { - // FIX: represent numbers correctly on 64-bit system - // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 - // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems - $or24 = ord($data[$pos + 3]); - if ($or24 >= 128) { - // negative number - $ord24 = -abs((256 - $or24) << 24); - } else { - $ord24 = ($or24 & 127) << 24; - } - return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $ord24; - } -} diff --git a/src/PhpPowerpoint/Shared/String.php b/src/PhpPowerpoint/Shared/String.php deleted file mode 100644 index c51eb339f..000000000 --- a/src/PhpPowerpoint/Shared/String.php +++ /dev/null @@ -1,78 +0,0 @@ -) - * element or in the shared string element. - * - * @param string $value Value to escape - * @return string - */ - public static function controlCharacterPHP2OOXML($value = '') - { - if (empty(self::$controlCharacters)) { - self::buildControlCharacters(); - } - - return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $value); - } - - /** - * Return a number formatted for being integrated in xml files - * @param float $number - * @param integer $decimals - */ - public static function numberFormat($number, $decimals) - { - return number_format($number, $decimals, '.', ''); - } -} diff --git a/src/PhpPowerpoint/Shared/XMLWriter.php b/src/PhpPowerpoint/Shared/XMLWriter.php deleted file mode 100644 index 411cb3e0b..000000000 --- a/src/PhpPowerpoint/Shared/XMLWriter.php +++ /dev/null @@ -1,129 +0,0 @@ -xmlWriter = new \XMLWriter(); - - // Open temporary storage - if ($pTemporaryStorage == self::STORAGE_MEMORY) { - $this->xmlWriter->openMemory(); - } else { - // Create temporary filename - $this->tempFileName = @tempnam($pTemporaryStorageDir, 'xml'); - - // Open storage - $this->xmlWriter->openUri($this->tempFileName); - } - - // Set default values - $this->xmlWriter->setIndent(true); - } - - /** - * Destructor - */ - public function __destruct() - { - // Desctruct XMLWriter - unset($this->xmlWriter); - - // Unlink temporary files - if ($this->tempFileName != '') { - @unlink($this->tempFileName); - } - } - - /** - * Catch function calls (and pass them to internal XMLWriter) - * - * @param mixed $function - * @param mixed $args - */ - public function __call($function, $args) - { - try { - @call_user_func_array(array( - $this->xmlWriter, - $function - ), $args); - } catch (\Exception $ex) { - // Do nothing! - } - } - - /** - * Get written data - * - * @return string - */ - public function getData() - { - if ($this->tempFileName == '') { - return $this->xmlWriter->outputMemory(true); - } else { - $this->xmlWriter->flush(); - return file_get_contents($this->tempFileName); - } - } -} diff --git a/src/PhpPowerpoint/Slide.php b/src/PhpPowerpoint/Slide.php index 163f0a63e..0536b9b75 100644 --- a/src/PhpPowerpoint/Slide.php +++ b/src/PhpPowerpoint/Slide.php @@ -17,17 +17,21 @@ namespace PhpOffice\PhpPowerpoint; +use PhpOffice\PhpPowerpoint\GeometryCalculator; use PhpOffice\PhpPowerpoint\Shape\Chart; use PhpOffice\PhpPowerpoint\Shape\Drawing; +use PhpOffice\PhpPowerpoint\Shape\Group; use PhpOffice\PhpPowerpoint\Shape\Line; use PhpOffice\PhpPowerpoint\Shape\RichText; use PhpOffice\PhpPowerpoint\Shape\Table; use PhpOffice\PhpPowerpoint\Slide\Layout; +use PhpOffice\PhpPowerpoint\Slide\Note; +use PhpOffice\PhpPowerpoint\Slide\Transition; /** * Slide class */ -class Slide implements ComparableInterface +class Slide implements ComparableInterface, ShapeContainerInterface { /** * Parent presentation @@ -64,6 +68,17 @@ class Slide implements ComparableInterface */ private $slideMasterId = 1; + /** + * + * @var \PhpOffice\PhpPowerpoint\Slide\Note + */ + private $slideNote; + /** + * + * @var \PhpOffice\PhpPowerpoint\Slide\Transition + */ + private $slideTransition; + /** * Hash index * @@ -71,6 +86,34 @@ class Slide implements ComparableInterface */ private $hashIndex; + /** + * Offset X + * + * @var int + */ + protected $offsetX; + + /** + * Offset Y + * + * @var int + */ + protected $offsetY; + + /** + * Extent X + * + * @var int + */ + protected $extentX; + + /** + * Extent Y + * + * @var int + */ + protected $extentY; + /** * Create a new slide * @@ -93,7 +136,7 @@ public function __construct(PhpPowerpoint $pParent = null) /** * Get collection of shapes * - * @return \PhpOffice\PhpPowerpoint\AbstractShape[] + * @return \ArrayObject|\PhpOffice\PhpPowerpoint\AbstractShape[] */ public function getShapeCollection() { @@ -108,7 +151,7 @@ public function getShapeCollection() */ public function addShape(AbstractShape $shape) { - $shape->setSlide($this); + $shape->setContainer($this); return $shape; } @@ -182,6 +225,19 @@ public function createTableShape($columns = 1) return $shape; } + + /** + * Creates a group within this slide + * + * @return \PhpOffice\PhpPowerpoint\Shape\Group + */ + public function createGroup() + { + $shape = new Group(); + $this->addShape($shape); + + return $shape; + } /** * Get parent @@ -300,4 +356,110 @@ public function copy() return $copied; } + + /** + * Get X Offset + * + * @return int + */ + public function getOffsetX() + { + if ($this->offsetX === null) { + $offsets = GeometryCalculator::calculateOffsets($this); + $this->offsetX = $offsets[GeometryCalculator::X]; + $this->offsetY = $offsets[GeometryCalculator::Y]; + } + return $this->offsetX; + } + + /** + * Get Y Offset + * + * @return int + */ + public function getOffsetY() + { + if ($this->offsetY === null) { + $offsets = GeometryCalculator::calculateOffsets($this); + $this->offsetX = $offsets[GeometryCalculator::X]; + $this->offsetY = $offsets[GeometryCalculator::Y]; + } + return $this->offsetY; + } + + /** + * Get X Extent + * + * @return int + */ + public function getExtentX() + { + if ($this->extentX === null) { + $extents = GeometryCalculator::calculateExtents($this); + $this->extentX = $extents[GeometryCalculator::X]; + $this->extentY = $extents[GeometryCalculator::Y]; + } + return $this->extentX; + } + + /** + * Get Y Extent + * + * @return int + */ + public function getExtentY() + { + if ($this->extentY === null) { + $extents = GeometryCalculator::calculateExtents($this); + $this->extentX = $extents[GeometryCalculator::X]; + $this->extentY = $extents[GeometryCalculator::Y]; + } + return $this->extentY; + } + + /** + * + * @return \PhpOffice\PhpPowerpoint\Slide\Note + */ + public function getNote() + { + if (is_null($this->slideNote)) { + $this->setNote(); + } + return $this->slideNote; + } + + /** + * + * @param \PhpOffice\PhpPowerpoint\Slide\Note $note + * @return \PhpOffice\PhpPowerpoint\Slide + */ + public function setNote(Note $note = null) + { + $this->slideNote = (is_null($note) ? new Note() : $note); + $this->slideNote->setParent($this); + + return $this; + } + + /** + * + * @return \PhpOffice\PhpPowerpoint\Slide\Transition + */ + public function getTransition() + { + return $this->slideTransition; + } + + /** + * + * @param \PhpOffice\PhpPowerpoint\Slide\Transition $transition + * @return \PhpOffice\PhpPowerpoint\Slide + */ + public function setTransition(Transition $transition = null) + { + $this->slideTransition = $transition; + + return $this; + } } diff --git a/src/PhpPowerpoint/Slide/Note.php b/src/PhpPowerpoint/Slide/Note.php new file mode 100644 index 000000000..66252928d --- /dev/null +++ b/src/PhpPowerpoint/Slide/Note.php @@ -0,0 +1,259 @@ +parent = $pParent; + + // Shape collection + $this->shapeCollection = new \ArrayObject(); + + // Set identifier + $this->identifier = md5(rand(0, 9999) . time()); + } + + /** + * Get collection of shapes + * + * @return \ArrayObject|\PhpOffice\PhpPowerpoint\AbstractShape[] + */ + public function getShapeCollection() + { + return $this->shapeCollection; + } + + /** + * Add shape to slide + * + * @param \PhpOffice\PhpPowerpoint\AbstractShape $shape + * @return \PhpOffice\PhpPowerpoint\AbstractShape + */ + public function addShape(AbstractShape $shape) + { + $shape->setContainer($this); + + return $shape; + } + + /** + * Create rich text shape + * + * @return \PhpOffice\PhpPowerpoint\Shape\RichText + */ + public function createRichTextShape() + { + $shape = new RichText(); + $this->addShape($shape); + + return $shape; + } + + /** + * Get parent + * + * @return Slide + */ + public function getParent() + { + return $this->parent; + } + + /** + * Set parent + * + * @param Slide $parent + * @return Note + */ + public function setParent(Slide $parent) + { + $this->parent = $parent; + return $this; + } + + + /** + * Get X Offset + * + * @return int + */ + public function getOffsetX() + { + if ($this->offsetX === null) { + $offsets = GeometryCalculator::calculateOffsets($this); + $this->offsetX = $offsets[GeometryCalculator::X]; + $this->offsetY = $offsets[GeometryCalculator::Y]; + } + return $this->offsetX; + } + + /** + * Get Y Offset + * + * @return int + */ + public function getOffsetY() + { + if ($this->offsetY === null) { + $offsets = GeometryCalculator::calculateOffsets($this); + $this->offsetX = $offsets[GeometryCalculator::X]; + $this->offsetY = $offsets[GeometryCalculator::Y]; + } + return $this->offsetY; + } + + /** + * Get X Extent + * + * @return int + */ + public function getExtentX() + { + if ($this->extentX === null) { + $extents = GeometryCalculator::calculateExtents($this); + $this->extentX = $extents[GeometryCalculator::X]; + $this->extentY = $extents[GeometryCalculator::Y]; + } + return $this->extentX; + } + + /** + * Get Y Extent + * + * @return int + */ + public function getExtentY() + { + if ($this->extentY === null) { + $extents = GeometryCalculator::calculateExtents($this); + $this->extentX = $extents[GeometryCalculator::X]; + $this->extentY = $extents[GeometryCalculator::Y]; + } + return $this->extentY; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + return md5($this->identifier . __CLASS__); + } + + /** + * Get hash index + * + * Note that this index may vary during script execution! Only reliable moment is + * while doing a write of a workbook and when changes are not allowed. + * + * @return string Hash index + */ + public function getHashIndex() + { + return $this->hashIndex; + } + + /** + * Set hash index + * + * Note that this index may vary during script execution! Only reliable moment is + * while doing a write of a workbook and when changes are not allowed. + * + * @param string $value Hash index + */ + public function setHashIndex($value) + { + $this->hashIndex = $value; + } +} diff --git a/src/PhpPowerpoint/Slide/Transition.php b/src/PhpPowerpoint/Slide/Transition.php new file mode 100644 index 000000000..0900f47fa --- /dev/null +++ b/src/PhpPowerpoint/Slide/Transition.php @@ -0,0 +1,167 @@ +speed = $speed; + } else { + $this->speed = null; + } + + return $this; + } + + public function getSpeed() + { + return $this->speed; + } + + public function setManualTrigger($value = false) + { + if (is_bool($value)) { + $this->hasManualTrigger = $value; + } + return $this; + } + + public function hasManualTrigger() + { + return $this->hasManualTrigger; + } + + public function setTimeTrigger($value = false, $advanceTime = 1000) + { + if (is_bool($value)) { + $this->hasTimeTrigger = $value; + } + $this->advanceTimeTrigger = null; + if ($this->hasTimeTrigger === true) { + $this->advanceTimeTrigger = (int) $advanceTime; + } + return $this; + } + + public function hasTimeTrigger() + { + return $this->hasTimeTrigger; + } + + public function getAdvanceTimeTrigger() + { + return $this->advanceTimeTrigger; + } + + public function setTransitionType($type = null) + { + $this->transitionType = $type; + return $this; + } + + public function getTransitionType() + { + return $this->transitionType; + } +} diff --git a/src/PhpPowerpoint/Writer/ODPresentation.php b/src/PhpPowerpoint/Writer/ODPresentation.php index 81d52fcc7..44e81cb81 100644 --- a/src/PhpPowerpoint/Writer/ODPresentation.php +++ b/src/PhpPowerpoint/Writer/ODPresentation.php @@ -38,7 +38,7 @@ class ODPresentation implements WriterInterface /** * Private PHPPowerPoint * - * @var PHPPowerPoint + * @var \PhpOffice\PhpPowerpoint\PhpPowerpoint */ private $presentation; @@ -78,9 +78,9 @@ class ODPresentation implements WriterInterface /** * Create a new \PhpOffice\PhpPowerpoint\Writer\ODPresentation * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerpoint $pPHPPowerPoint */ - public function __construct(PHPPowerPoint $pPHPPowerPoint = null) + public function __construct(PhpPowerpoint $pPHPPowerPoint = null) { // Assign PHPPowerPoint $this->setPHPPowerPoint($pPHPPowerPoint); @@ -127,10 +127,34 @@ public function save($pFilename) } } + $writerPartChart = $this->getWriterPart('charts'); + if (!$writerPartChart instanceof ObjectsChart) { + throw new \Exception('The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation\ObjectsChart'); + } + $writerPartContent = $this->getWriterPart('content'); + if (!$writerPartContent instanceof Content) { + throw new \Exception('The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation\Content'); + } $writerPartDrawing = $this->getWriterPart('Drawing'); if (!$writerPartDrawing instanceof Drawing) { throw new \Exception('The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation\Drawing'); } + $writerPartManifest = $this->getWriterPart('manifest'); + if (!$writerPartManifest instanceof Manifest) { + throw new \Exception('The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation\Manifest'); + } + $writerPartMeta = $this->getWriterPart('meta'); + if (!$writerPartMeta instanceof Meta) { + throw new \Exception('The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation\Meta'); + } + $writerPartMimetype = $this->getWriterPart('mimetype'); + if (!$writerPartMimetype instanceof Mimetype) { + throw new \Exception('The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation\Mimetype'); + } + $writerPartStyles = $this->getWriterPart('styles'); + if (!$writerPartStyles instanceof Styles) { + throw new \Exception('The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation\Styles'); + } // Create drawing dictionary $this->drawingHashTable->addFromSource($writerPartDrawing->allDrawings($this->presentation)); @@ -147,23 +171,23 @@ public function save($pFilename) // Add mimetype to ZIP file //@todo Not in ZIPARCHIVE::CM_STORE mode - $objZip->addFromString('mimetype', $this->getWriterPart('mimetype')->writePart()); + $objZip->addFromString('mimetype', $writerPartMimetype->writePart()); // Add content.xml to ZIP file - $objZip->addFromString('content.xml', $this->getWriterPart('content')->writePart($this->presentation)); + $objZip->addFromString('content.xml', $writerPartContent->writePart($this->presentation)); // Add meta.xml to ZIP file - $objZip->addFromString('meta.xml', $this->getWriterPart('meta')->writePart($this->presentation)); + $objZip->addFromString('meta.xml', $writerPartMeta->writePart($this->presentation)); // Add styles.xml to ZIP file - $objZip->addFromString('styles.xml', $this->getWriterPart('styles')->writePart($this->presentation)); + $objZip->addFromString('styles.xml', $writerPartStyles->writePart($this->presentation)); // Add META-INF/manifest.xml - $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('manifest')->writePart()); + $objZip->addFromString('META-INF/manifest.xml', $writerPartManifest->writePart()); // Add charts foreach ($this->chartArray as $keyChart => $shapeChart) { - $arrayFile = $this->getWriterPart('charts')->writePart($shapeChart); + $arrayFile = $writerPartChart->writePart($shapeChart); foreach ($arrayFile as $file => $content) { if (!empty($content)) { $objZip->addFromString('Object '.$keyChart.'/' . $file, $content); @@ -222,7 +246,9 @@ public function save($pFilename) if (copy($pFilename, $originalFilename) === false) { throw new \Exception("Could not copy temporary zip file $pFilename to $originalFilename."); } - @unlink($pFilename); + if (@unlink($pFilename) === false) { + throw new \Exception('The file '.$pFilename.' could not be deleted.'); + } } } else { throw new \Exception("PHPPowerPoint object unassigned."); @@ -232,7 +258,7 @@ public function save($pFilename) /** * Get PHPPowerPoint object * - * @return PHPPowerPoint + * @return PhpPowerpoint * @throws \Exception */ public function getPHPPowerPoint() @@ -247,11 +273,11 @@ public function getPHPPowerPoint() /** * Get PHPPowerPoint object * - * @param PHPPowerPoint $pPHPPowerPoint PHPPowerPoint object + * @param PhpPowerpoint $pPHPPowerPoint PhpPowerpoint object * @throws \Exception * @return \PhpOffice\PhpPowerpoint\Writer\PowerPoint2007 */ - public function setPHPPowerPoint(PHPPowerPoint $pPHPPowerPoint = null) + public function setPHPPowerPoint(PhpPowerpoint $pPHPPowerPoint = null) { $this->presentation = $pPHPPowerPoint; diff --git a/src/PhpPowerpoint/Writer/ODPresentation/AbstractPart.php b/src/PhpPowerpoint/Writer/ODPresentation/AbstractPart.php index eb35ebeac..9c8b94c0c 100644 --- a/src/PhpPowerpoint/Writer/ODPresentation/AbstractPart.php +++ b/src/PhpPowerpoint/Writer/ODPresentation/AbstractPart.php @@ -17,8 +17,8 @@ namespace PhpOffice\PhpPowerpoint\Writer\ODPresentation; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\PhpPowerpoint; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; use PhpOffice\PhpPowerpoint\Writer\WriterInterface; use PhpOffice\PhpPowerpoint\Writer\ODPresentation; diff --git a/src/PhpPowerpoint/Writer/ODPresentation/Content.php b/src/PhpPowerpoint/Writer/ODPresentation/Content.php index deb87fc6d..e5e82f3a2 100644 --- a/src/PhpPowerpoint/Writer/ODPresentation/Content.php +++ b/src/PhpPowerpoint/Writer/ODPresentation/Content.php @@ -17,10 +17,15 @@ namespace PhpOffice\PhpPowerpoint\Writer\ODPresentation; +use PhpOffice\Common\Drawing as CommonDrawing; +use PhpOffice\Common\String; +use PhpOffice\Common\XMLWriter; +use PhpOffice\PhpPowerpoint\Slide; use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\AbstractDrawing; use PhpOffice\PhpPowerpoint\Shape\Chart; use PhpOffice\PhpPowerpoint\Shape\Drawing as ShapeDrawing; +use PhpOffice\PhpPowerpoint\Shape\Group; use PhpOffice\PhpPowerpoint\Shape\Line; use PhpOffice\PhpPowerpoint\Shape\MemoryDrawing; use PhpOffice\PhpPowerpoint\Shape\RichText\BreakElement; @@ -28,14 +33,12 @@ use PhpOffice\PhpPowerpoint\Shape\RichText\TextElement; use PhpOffice\PhpPowerpoint\Shape\RichText; use PhpOffice\PhpPowerpoint\Shape\Table; -use PhpOffice\PhpPowerpoint\Shape\Table\Cell; -use PhpOffice\PhpPowerpoint\Shape\Table\Row; -use PhpOffice\PhpPowerpoint\Shared\Drawing as SharedDrawing; -use PhpOffice\PhpPowerpoint\Shared\String; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; +use PhpOffice\PhpPowerpoint\Slide\Note; +use PhpOffice\PhpPowerpoint\Slide\Transition; use PhpOffice\PhpPowerpoint\Style\Alignment; use PhpOffice\PhpPowerpoint\Style\Border; use PhpOffice\PhpPowerpoint\Style\Fill; +use PhpOffice\PhpPowerpoint\Style\Shadow; use PhpOffice\PhpPowerpoint\Writer\ODPresentation; /** @@ -43,6 +46,35 @@ */ class Content extends AbstractPart { + + /** + * Stores bullet styles for text shapes that include lists. + * + * @var array + */ + private $arrStyleBullet = array(); + + /** + * Stores paragraph information for text shapes. + * + * @var array + */ + private $arrStyleParagraph = array(); + + /** + * Stores font styles for text shapes that include lists. + * + * @var array + */ + private $arrStyleTextFont = array(); + + /** + * Used to track the current shape ID. + * + * @var integer + */ + private $shapeId; + /** * Write content file to XML format * @@ -92,271 +124,44 @@ public function writePart(PhpPowerpoint $pPHPPowerPoint) $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0'); $objWriter->writeAttribute('office:version', '1.2'); - //=============================================== - // Styles - //=============================================== - $arrStyleBullet = array(); - $arrStyleParagraph = array(); - $arrStyleTextFont = array(); - // office:automatic-styles $objWriter->startElement('office:automatic-styles'); - $shapeId = 0; + $this->shapeId = 0; + $incSlide = 0; foreach ($pPHPPowerPoint->getAllSlides() as $pSlide) { + // Slides + $this->writeStyleSlide($objWriter, $pSlide, $incSlide); + // Images $shapes = $pSlide->getShapeCollection(); foreach ($shapes as $shape) { - // Increment $shapeId - ++$shapeId; + // Increment $this->shapeId + ++$this->shapeId; // Check type if ($shape instanceof RichText) { - // style:style - $objWriter->startElement('style:style'); - $objWriter->writeAttribute('style:name', 'gr' . $shapeId); - $objWriter->writeAttribute('style:family', 'graphic'); - $objWriter->writeAttribute('style:parent-style-name', 'standard'); - // style:graphic-properties - $objWriter->startElement('style:graphic-properties'); - if (is_bool($shape->hasAutoShrinkVertical())) { - $objWriter->writeAttribute('draw:auto-grow-height', var_export($shape->hasAutoShrinkVertical(), true)); - } - if (is_bool($shape->hasAutoShrinkHorizontal())) { - $objWriter->writeAttribute('draw:auto-grow-width', var_export($shape->hasAutoShrinkHorizontal(), true)); - } - switch ($shape->getFill()->getFillType()){ - case Fill::FILL_NONE: - default: - $objWriter->writeAttribute('draw:fill', 'none'); - $objWriter->writeAttribute('draw:fill-color', '#'.$shape->getFill()->getStartColor()->getRGB()); - break; - } - switch ($shape->getBorder()->getLineStyle()){ - case Border::LINE_NONE: - default: - $objWriter->writeAttribute('draw:stroke', 'none'); - $objWriter->writeAttribute('svg:stroke-color', '#'.$shape->getBorder()->getColor()->getRGB()); - } - - $objWriter->writeAttribute('fo:wrap-option', 'wrap'); - // > style:graphic-properties - $objWriter->endElement(); - // > style:style - $objWriter->endElement(); - - $paragraphs = $shape->getParagraphs(); - $paragraphId = 0; - foreach ($paragraphs as $paragraph) { - ++$paragraphId; - - // Style des paragraphes - if (!isset($arrStyleParagraph[$paragraph->getHashCode()])) { - $arrStyleParagraph[$paragraph->getHashCode()] = $paragraph; - } - - // Style des listes - if (!isset($arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()])) { - $arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['oStyle'] = $paragraph->getBulletStyle(); - $arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level'] = ''; - } - if (strpos($arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level'], ';' . $paragraph->getAlignment()->getLevel()) === false) { - $arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level'] .= ';' . $paragraph->getAlignment()->getLevel(); - $arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['oAlign_' . $paragraph->getAlignment()->getLevel()] = $paragraph->getAlignment(); - } - - $richtexts = $paragraph->getRichTextElements(); - $richtextId = 0; - foreach ($richtexts as $richtext) { - ++$richtextId; - // Not a line break - if ($richtext instanceof Run) { - // Style des font text - if (!isset($arrStyleTextFont[$richtext->getFont()->getHashCode()])) { - $arrStyleTextFont[$richtext->getFont()->getHashCode()] = $richtext->getFont(); - } - } - } - } + $this->writeTxtStyle($objWriter, $shape); } if ($shape instanceof AbstractDrawing) { - if ($shape->getShadow()->isVisible()) { - // style:style - $objWriter->startElement('style:style'); - $objWriter->writeAttribute('style:name', 'gr' . $shapeId); - $objWriter->writeAttribute('style:family', 'graphic'); - $objWriter->writeAttribute('style:parent-style-name', 'standard'); - - // style:graphic-properties - $objWriter->startElement('style:graphic-properties'); - $objWriter->writeAttribute('draw:stroke', 'none'); - $objWriter->writeAttribute('draw:fill', 'none'); - $objWriter->writeAttribute('draw:shadow', 'visible'); - $objWriter->writeAttribute('draw:shadow-color', '#' . $shape->getShadow()->getColor()->getRGB()); - if ($shape->getShadow()->getDirection() == 0 || $shape->getShadow()->getDirection() == 360) { - $objWriter->writeAttribute('draw:shadow-offset-x', SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - $objWriter->writeAttribute('draw:shadow-offset-y', '0cm'); - } elseif ($shape->getShadow()->getDirection() == 45) { - $objWriter->writeAttribute('draw:shadow-offset-x', SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - $objWriter->writeAttribute('draw:shadow-offset-y', SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - } elseif ($shape->getShadow()->getDirection() == 90) { - $objWriter->writeAttribute('draw:shadow-offset-x', '0cm'); - $objWriter->writeAttribute('draw:shadow-offset-y', SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - } elseif ($shape->getShadow()->getDirection() == 135) { - $objWriter->writeAttribute('draw:shadow-offset-x', '-' . SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - $objWriter->writeAttribute('draw:shadow-offset-y', SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - } elseif ($shape->getShadow()->getDirection() == 180) { - $objWriter->writeAttribute('draw:shadow-offset-x', '-' . SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - $objWriter->writeAttribute('draw:shadow-offset-y', '0cm'); - } elseif ($shape->getShadow()->getDirection() == 225) { - $objWriter->writeAttribute('draw:shadow-offset-x', '-' . SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - $objWriter->writeAttribute('draw:shadow-offset-y', '-' . SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - } elseif ($shape->getShadow()->getDirection() == 270) { - $objWriter->writeAttribute('draw:shadow-offset-x', '0cm'); - $objWriter->writeAttribute('draw:shadow-offset-y', '-' . SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - } elseif ($shape->getShadow()->getDirection() == 315) { - $objWriter->writeAttribute('draw:shadow-offset-x', SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - $objWriter->writeAttribute('draw:shadow-offset-y', '-' . SharedDrawing::pixelsToCentimeters($shape->getShadow()->getDistance()) . 'cm'); - } - $objWriter->writeAttribute('draw:shadow-opacity', (100 - $shape->getShadow()->getAlpha()) . '%'); - $objWriter->writeAttribute('style:mirror', 'none'); - $objWriter->endElement(); - - $objWriter->endElement(); - } + $this->writeDrawingStyle($objWriter, $shape); } if ($shape instanceof Line) { - // style:style - $objWriter->startElement('style:style'); - $objWriter->writeAttribute('style:name', 'gr' . $shapeId); - $objWriter->writeAttribute('style:family', 'graphic'); - $objWriter->writeAttribute('style:parent-style-name', 'standard'); - - // style:graphic-properties - $objWriter->startElement('style:graphic-properties'); - $objWriter->writeAttribute('draw:fill', 'none'); - switch ($shape->getBorder()->getLineStyle()) { - case Border::LINE_NONE: - $objWriter->writeAttribute('draw:stroke', 'none'); - break; - case Border::LINE_SINGLE: - $objWriter->writeAttribute('draw:stroke', 'solid'); - break; - default: - $objWriter->writeAttribute('draw:stroke', 'none'); - break; - } - $objWriter->writeAttribute('svg:stroke-color', '#'.$shape->getBorder()->getColor()->getRGB()); - $objWriter->writeAttribute('svg:stroke-width', String::numberFormat(SharedDrawing::pixelsToCentimeters((SharedDrawing::pointsToPixels($shape->getBorder()->getLineWidth()))), 3).'cm'); - $objWriter->endElement(); - - $objWriter->endElement(); + $this->writeLineStyle($objWriter, $shape); } if ($shape instanceof Table) { - foreach ($shape->getRows() as $keyRow => $shapeRow) { - // style:style - $objWriter->startElement('style:style'); - $objWriter->writeAttribute('style:name', 'gr' . $shapeId.'r'.$keyRow); - $objWriter->writeAttribute('style:family', 'table-row'); - - // style:table-row-properties - $objWriter->startElement('style:table-row-properties'); - $objWriter->writeAttribute('style:row-height', String::numberFormat(SharedDrawing::pixelsToCentimeters(SharedDrawing::pointsToPixels($shapeRow->getHeight())), 3).'cm'); - $objWriter->endElement(); - - $objWriter->endElement(); - - foreach ($shapeRow->getCells() as $keyCell => $shapeCell) { - // style:style - $objWriter->startElement('style:style'); - $objWriter->writeAttribute('style:name', 'gr' . $shapeId.'r'.$keyRow.'c'.$keyCell); - $objWriter->writeAttribute('style:family', 'table-cell'); - - // style:graphic-properties - $objWriter->startElement('style:graphic-properties'); - if ($shapeCell->getFill()->getFillType() == Fill::FILL_SOLID) { - $objWriter->writeAttribute('draw:fill', 'solid'); - $objWriter->writeAttribute('draw:fill-color', '#'.$shapeCell->getFill()->getStartColor()->getRGB()); - } - if ($shapeCell->getFill()->getFillType() == Fill::FILL_GRADIENT_LINEAR) { - $objWriter->writeAttribute('draw:fill', 'gradient'); - $objWriter->writeAttribute('draw:fill-gradient-name', 'gradient_'.$shapeCell->getFill()->getHashCode()); - } - $objWriter->endElement(); - // startElement('style:paragraph-properties'); - if ($shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getTop()->getHashCode() - && $shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getLeft()->getHashCode() - && $shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getRight()->getHashCode()) { - $lineStyle = 'none'; - $lineWidth = String::numberFormat($shapeCell->getBorders()->getBottom()->getLineWidth() / 1.75, 2); - $lineColor = $shapeCell->getBorders()->getBottom()->getColor()->getRGB(); - switch ($shapeCell->getBorders()->getBottom()->getLineStyle()){ - case Border::LINE_SINGLE: - $lineStyle = 'solid'; - } - $objWriter->writeAttribute('fo:border', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); - } else { - $lineStyle = 'none'; - $lineWidth = String::numberFormat($shapeCell->getBorders()->getBottom()->getLineWidth() / 1.75, 2); - $lineColor = $shapeCell->getBorders()->getBottom()->getColor()->getRGB(); - switch ($shapeCell->getBorders()->getBottom()->getLineStyle()){ - case Border::LINE_SINGLE: - $lineStyle = 'solid'; - } - $objWriter->writeAttribute('fo:border-bottom', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); - // TOP - $lineStyle = 'none'; - $lineWidth = String::numberFormat($shapeCell->getBorders()->getTop()->getLineWidth() / 1.75, 2); - $lineColor = $shapeCell->getBorders()->getTop()->getColor()->getRGB(); - switch ($shapeCell->getBorders()->getTop()->getLineStyle()){ - case Border::LINE_SINGLE: - $lineStyle = 'solid'; - } - $objWriter->writeAttribute('fo:border-top', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); - // RIGHT - $lineStyle = 'none'; - $lineWidth = String::numberFormat($shapeCell->getBorders()->getRight()->getLineWidth() / 1.75, 2); - $lineColor = $shapeCell->getBorders()->getRight()->getColor()->getRGB(); - switch ($shapeCell->getBorders()->getRight()->getLineStyle()){ - case Border::LINE_SINGLE: - $lineStyle = 'solid'; - } - $objWriter->writeAttribute('fo:border-right', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); - // LEFT - $lineStyle = 'none'; - $lineWidth = String::numberFormat($shapeCell->getBorders()->getLeft()->getLineWidth() / 1.75, 2); - $lineColor = $shapeCell->getBorders()->getLeft()->getColor()->getRGB(); - switch ($shapeCell->getBorders()->getLeft()->getLineStyle()){ - case Border::LINE_SINGLE: - $lineStyle = 'solid'; - } - $objWriter->writeAttribute('fo:border-left', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); - } - $objWriter->endElement(); - - $objWriter->endElement(); - - foreach ($shapeCell->getParagraphs() as $shapeParagraph) { - foreach ($shapeParagraph->getRichTextElements() as $shapeRichText) { - if ($shapeRichText instanceof Run) { - // Style des font text - if (!isset($arrStyleTextFont[$shapeRichText->getFont()->getHashCode()])) { - $arrStyleTextFont[$shapeRichText->getFont()->getHashCode()] = $shapeRichText->getFont(); - } - } - } - } - } - } + $this->writeTableStyle($objWriter, $shape); + } + if ($shape instanceof Group) { + $this->writeGroupStyle($objWriter, $shape); } } + + $incSlide++; } // Style : Bullet - if (!empty($arrStyleBullet)) { - foreach ($arrStyleBullet as $key => $item) { + if (!empty($this->arrStyleBullet)) { + foreach ($this->arrStyleBullet as $key => $item) { $oStyle = $item['oStyle']; $arrLevel = explode(';', $item['level']); // style:style @@ -372,11 +177,11 @@ public function writePart(PhpPowerpoint $pPHPPowerPoint) // style:list-level-properties $objWriter->startElement('style:list-level-properties'); if ($oAlign->getIndent() < 0) { - $objWriter->writeAttribute('text:space-before', SharedDrawing::pixelsToCentimeters($oAlign->getMarginLeft() - (-1 * $oAlign->getIndent())) . 'cm'); - $objWriter->writeAttribute('text:min-label-width', SharedDrawing::pixelsToCentimeters(-1 * $oAlign->getIndent()) . 'cm'); + $objWriter->writeAttribute('text:space-before', CommonDrawing::pixelsToCentimeters($oAlign->getMarginLeft() - (-1 * $oAlign->getIndent())) . 'cm'); + $objWriter->writeAttribute('text:min-label-width', CommonDrawing::pixelsToCentimeters(-1 * $oAlign->getIndent()) . 'cm'); } else { - $objWriter->writeAttribute('text:space-before', (SharedDrawing::pixelsToCentimeters($oAlign->getMarginLeft() - $oAlign->getIndent())) . 'cm'); - $objWriter->writeAttribute('text:min-label-width', SharedDrawing::pixelsToCentimeters($oAlign->getIndent()) . 'cm'); + $objWriter->writeAttribute('text:space-before', (CommonDrawing::pixelsToCentimeters($oAlign->getMarginLeft() - $oAlign->getIndent())) . 'cm'); + $objWriter->writeAttribute('text:min-label-width', CommonDrawing::pixelsToCentimeters($oAlign->getIndent()) . 'cm'); } $objWriter->endElement(); @@ -394,8 +199,8 @@ public function writePart(PhpPowerpoint $pPHPPowerPoint) } } // Style : Paragraph - if (!empty($arrStyleParagraph)) { - foreach ($arrStyleParagraph as $key => $item) { + if (!empty($this->arrStyleParagraph)) { + foreach ($this->arrStyleParagraph as $key => $item) { // style:style $objWriter->startElement('style:style'); $objWriter->writeAttribute('style:name', 'P_' . $key); @@ -427,8 +232,8 @@ public function writePart(PhpPowerpoint $pPHPPowerPoint) } } // Style : Text : Font - if (!empty($arrStyleTextFont)) { - foreach ($arrStyleTextFont as $key => $item) { + if (!empty($this->arrStyleTextFont)) { + foreach ($this->arrStyleTextFont as $key => $item) { // style:style $objWriter->startElement('style:style'); $objWriter->writeAttribute('style:name', 'T_' . $key); @@ -459,31 +264,39 @@ public function writePart(PhpPowerpoint $pPHPPowerPoint) // Write slides $slideCount = $pPHPPowerPoint->getSlideCount(); - $shapeId = 0; + $this->shapeId = 0; for ($i = 0; $i < $slideCount; ++$i) { $pSlide = $pPHPPowerPoint->getSlide($i); $objWriter->startElement('draw:page'); $objWriter->writeAttribute('draw:name', 'page' . $i); $objWriter->writeAttribute('draw:master-page-name', 'Standard'); + $objWriter->writeAttribute('draw:style-name', 'stylePage' . $i); // Images $shapes = $pSlide->getShapeCollection(); foreach ($shapes as $shape) { - // Increment $shapeId - ++$shapeId; + // Increment $this->shapeId + ++$this->shapeId; // Check type if ($shape instanceof RichText) { - $this->writeShapeTxt($objWriter, $shape, $shapeId); + $this->writeShapeTxt($objWriter, $shape); } elseif ($shape instanceof Table) { - $this->writeShapeTable($objWriter, $shape, $shapeId); + $this->writeShapeTable($objWriter, $shape); } elseif ($shape instanceof Line) { - $this->writeShapeLine($objWriter, $shape, $shapeId); + $this->writeShapeLine($objWriter, $shape); } elseif ($shape instanceof Chart) { - $this->writeShapeChart($objWriter, $shape, $shapeId); + $this->writeShapeChart($objWriter, $shape); } elseif ($shape instanceof AbstractDrawing) { - $this->writeShapePic($objWriter, $shape, $shapeId); + $this->writeShapePic($objWriter, $shape); + } elseif ($shape instanceof Group) { + $this->writeShapeGroup($objWriter, $shape); } } + // Slide Note + if ($pSlide->getNote() instanceof Note) { + $this->writeSlideNote($objWriter, $pSlide->getNote()); + } + $objWriter->endElement(); } $objWriter->endElement(); @@ -497,22 +310,19 @@ public function writePart(PhpPowerpoint $pPHPPowerPoint) /** * Write picture * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter + * @param \PhpOffice\Common\XMLWriter $objWriter * @param \PhpOffice\PhpPowerpoint\Shape\AbstractDrawing $shape - * @param int $shapeId */ - public function writeShapePic(XMLWriter $objWriter, AbstractDrawing $shape, $shapeId) + public function writeShapePic(XMLWriter $objWriter, AbstractDrawing $shape) { // draw:frame $objWriter->startElement('draw:frame'); $objWriter->writeAttribute('draw:name', $shape->getName()); - $objWriter->writeAttribute('svg:width', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm'); - $objWriter->writeAttribute('svg:height', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm'); - $objWriter->writeAttribute('svg:x', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); - $objWriter->writeAttribute('svg:y', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); - if ($shape->getShadow()->isVisible()) { - $objWriter->writeAttribute('draw:style-name', 'gr' . $shapeId); - } + $objWriter->writeAttribute('svg:width', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm'); + $objWriter->writeAttribute('svg:height', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm'); + $objWriter->writeAttribute('svg:x', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); + $objWriter->writeAttribute('svg:y', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); + $objWriter->writeAttribute('draw:style-name', 'gr' . $this->shapeId); // draw:image $objWriter->startElement('draw:image'); if ($shape instanceof ShapeDrawing) { @@ -525,37 +335,54 @@ public function writeShapePic(XMLWriter $objWriter, AbstractDrawing $shape, $sha $objWriter->writeAttribute('xlink:actuate', 'onLoad'); $objWriter->writeElement('text:p'); $objWriter->endElement(); + + if ($shape->hasHyperlink()) { + // office:event-listeners + $objWriter->startElement('office:event-listeners'); + // presentation:event-listener + $objWriter->startElement('presentation:event-listener'); + $objWriter->writeAttribute('script:event-name', 'dom:click'); + $objWriter->writeAttribute('presentation:action', 'show'); + $objWriter->writeAttribute('xlink:href', $shape->getHyperlink()->getUrl()); + $objWriter->writeAttribute('xlink:type', 'simple'); + $objWriter->writeAttribute('xlink:show', 'embed'); + $objWriter->writeAttribute('xlink:actuate', 'onRequest'); + // > presentation:event-listener + $objWriter->endElement(); + // > office:event-listeners + $objWriter->endElement(); + } + $objWriter->endElement(); } /** * Write text * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter + * @param \PhpOffice\Common\XMLWriter $objWriter * @param \PhpOffice\PhpPowerpoint\Shape\RichText $shape - * @param int $shapeId */ - public function writeShapeTxt(XMLWriter $objWriter, RichText $shape, $shapeId) + public function writeShapeTxt(XMLWriter $objWriter, RichText $shape) { // draw:frame $objWriter->startElement('draw:frame'); - $objWriter->writeAttribute('draw:style-name', 'gr' . $shapeId); - $objWriter->writeAttribute('svg:width', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm'); - $objWriter->writeAttribute('svg:height', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm'); - $objWriter->writeAttribute('svg:x', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); - $objWriter->writeAttribute('svg:y', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); + $objWriter->writeAttribute('draw:style-name', 'gr' . $this->shapeId); + $objWriter->writeAttribute('svg:width', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm'); + $objWriter->writeAttribute('svg:height', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm'); + $objWriter->writeAttribute('svg:x', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); + $objWriter->writeAttribute('svg:y', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); // draw:text-box $objWriter->startElement('draw:text-box'); $paragraphs = $shape->getParagraphs(); $paragraphId = 0; $sCstShpLastBullet = ''; - $iCstShpLastBulletLvl = 0; + $iCstShpLastBulletLvl = 0; $bCstShpHasBullet = false; foreach ($paragraphs as $paragraph) { // Close the bullet list - if ($sCstShpLastBullet != 'bullet' && $bCstShpHasBullet == true) { + if ($sCstShpLastBullet != 'bullet' && $bCstShpHasBullet === true) { for ($iInc = $iCstShpLastBulletLvl; $iInc >= 0; $iInc--) { // text:list-item $objWriter->endElement(); @@ -583,7 +410,7 @@ public function writeShapeTxt(XMLWriter $objWriter, RichText $shape, $shapeId) if ($richtext instanceof Run) { $objWriter->writeAttribute('text:style-name', 'T_' . $richtext->getFont()->getHashCode()); } - if ($richtext->hasHyperlink() == true && $richtext->getHyperlink()->getUrl() != '') { + if ($richtext->hasHyperlink() === true && $richtext->getHyperlink()->getUrl() != '') { // text:a $objWriter->startElement('text:a'); $objWriter->writeAttribute('xlink:href', $richtext->getHyperlink()->getUrl()); @@ -648,7 +475,7 @@ public function writeShapeTxt(XMLWriter $objWriter, RichText $shape, $shapeId) if ($richtext instanceof Run) { $objWriter->writeAttribute('text:style-name', 'T_' . $richtext->getFont()->getHashCode()); } - if ($richtext->hasHyperlink() == true && $richtext->getHyperlink()->getUrl() != '') { + if ($richtext->hasHyperlink() === true && $richtext->getHyperlink()->getUrl() != '') { // text:a $objWriter->startElement('text:a'); $objWriter->writeAttribute('xlink:href', $richtext->getHyperlink()->getUrl()); @@ -676,7 +503,7 @@ public function writeShapeTxt(XMLWriter $objWriter, RichText $shape, $shapeId) } // Close the bullet list - if ($sCstShpLastBullet == 'bullet' && $bCstShpHasBullet == true) { + if ($sCstShpLastBullet == 'bullet' && $bCstShpHasBullet === true) { for ($iInc = $iCstShpLastBulletLvl; $iInc >= 0; $iInc--) { // text:list-item $objWriter->endElement(); @@ -692,20 +519,18 @@ public function writeShapeTxt(XMLWriter $objWriter, RichText $shape, $shapeId) } /** - * * @param XMLWriter $objWriter * @param Line $shape - * @param integer $shapeId */ - public function writeShapeLine(XMLWriter $objWriter, Line $shape, $shapeId) + public function writeShapeLine(XMLWriter $objWriter, Line $shape) { // draw:line $objWriter->startElement('draw:line'); - $objWriter->writeAttribute('draw:style-name', 'gr' . $shapeId); - $objWriter->writeAttribute('svg:x1', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); - $objWriter->writeAttribute('svg:y1', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); - $objWriter->writeAttribute('svg:x2', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetX()+$shape->getWidth()), 3) . 'cm'); - $objWriter->writeAttribute('svg:y2', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetY()+$shape->getHeight()), 3) . 'cm'); + $objWriter->writeAttribute('draw:style-name', 'gr' . $this->shapeId); + $objWriter->writeAttribute('svg:x1', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); + $objWriter->writeAttribute('svg:y1', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); + $objWriter->writeAttribute('svg:x2', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()+$shape->getWidth()), 3) . 'cm'); + $objWriter->writeAttribute('svg:y2', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()+$shape->getHeight()), 3) . 'cm'); // text:p $objWriter->writeElement('text:p'); @@ -717,16 +542,15 @@ public function writeShapeLine(XMLWriter $objWriter, Line $shape, $shapeId) * Write table Shape * @param XMLWriter $objWriter * @param Table $shape - * @param integer $shapeId */ - public function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) + public function writeShapeTable(XMLWriter $objWriter, Table $shape) { // draw:frame $objWriter->startElement('draw:frame'); - $objWriter->writeAttribute('svg:x', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); - $objWriter->writeAttribute('svg:y', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); - $objWriter->writeAttribute('svg:height', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm'); - $objWriter->writeAttribute('svg:width', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm'); + $objWriter->writeAttribute('svg:x', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); + $objWriter->writeAttribute('svg:y', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); + $objWriter->writeAttribute('svg:height', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm'); + $objWriter->writeAttribute('svg:width', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm'); // table:table $objWriter->startElement('table:table'); @@ -734,7 +558,7 @@ public function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) foreach ($shape->getRows() as $keyRow => $shapeRow) { // table:table-row $objWriter->startElement('table:table-row'); - $objWriter->writeAttribute('table:style-name', 'gr'.$shapeId.'r'.$keyRow); + $objWriter->writeAttribute('table:style-name', 'gr'.$this->shapeId.'r'.$keyRow); //@todo getFill $numColspan = 0; @@ -742,7 +566,7 @@ public function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) if ($numColspan == 0) { // table:table-cell $objWriter->startElement('table:table-cell'); - $objWriter->writeAttribute('table:style-name', 'gr' . $shapeId.'r'.$keyRow.'c'.$keyCell); + $objWriter->writeAttribute('table:style-name', 'gr' . $this->shapeId.'r'.$keyRow.'c'.$keyCell); if ($shapeCell->getColspan() > 1) { $objWriter->writeAttribute('table:number-columns-spanned', $shapeCell->getColspan()); $numColspan = $shapeCell->getColspan() - 1; @@ -754,10 +578,30 @@ public function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) // text:span foreach ($shapeCell->getParagraphs() as $shapeParagraph) { foreach ($shapeParagraph->getRichTextElements() as $shapeRichText) { - $objWriter->startElement('text:span'); - $objWriter->writeAttribute('text:style-name', 'T_' . $shapeRichText->getFont()->getHashCode()); - $objWriter->text($shapeRichText->getText()); - $objWriter->endElement(); + if ($shapeRichText instanceof TextElement || $shapeRichText instanceof Run) { + // text:span + $objWriter->startElement('text:span'); + if ($shapeRichText instanceof Run) { + $objWriter->writeAttribute('text:style-name', 'T_' . $shapeRichText->getFont()->getHashCode()); + } + if ($shapeRichText->hasHyperlink() === true && $shapeRichText->getHyperlink()->getUrl() != '') { + // text:a + $objWriter->startElement('text:a'); + $objWriter->writeAttribute('xlink:href', $shapeRichText->getHyperlink()->getUrl()); + $objWriter->text($shapeRichText->getText()); + $objWriter->endElement(); + } else { + $objWriter->text($shapeRichText->getText()); + } + $objWriter->endElement(); + } elseif ($shapeRichText instanceof BreakElement) { + // text:span + $objWriter->startElement('text:span'); + // text:line-break + $objWriter->startElement('text:line-break'); + $objWriter->endElement(); + $objWriter->endElement(); + } } } @@ -785,27 +629,26 @@ public function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) * Write table Chart * @param XMLWriter $objWriter * @param Chart $shape - * @param integer $shapeId */ - public function writeShapeChart(XMLWriter $objWriter, Chart $shape, $shapeId) + public function writeShapeChart(XMLWriter $objWriter, Chart $shape) { $parentWriter = $this->getParentWriter(); if (!$parentWriter instanceof ODPresentation) { throw new \Exception('The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation'); } - $parentWriter->chartArray[$shapeId] = $shape; + $parentWriter->chartArray[$this->shapeId] = $shape; // draw:frame $objWriter->startElement('draw:frame'); $objWriter->writeAttribute('draw:name', $shape->getTitle()->getText()); - $objWriter->writeAttribute('svg:x', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); - $objWriter->writeAttribute('svg:y', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); - $objWriter->writeAttribute('svg:height', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm'); - $objWriter->writeAttribute('svg:width', String::numberFormat(SharedDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm'); + $objWriter->writeAttribute('svg:x', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm'); + $objWriter->writeAttribute('svg:y', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm'); + $objWriter->writeAttribute('svg:height', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm'); + $objWriter->writeAttribute('svg:width', String::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm'); // draw:object $objWriter->startElement('draw:object'); - $objWriter->writeAttribute('xlink:href', './Object '.$shapeId); + $objWriter->writeAttribute('xlink:href', './Object '.$this->shapeId); $objWriter->writeAttribute('xlink:type', 'simple'); $objWriter->writeAttribute('xlink:show', 'embed'); @@ -814,4 +657,595 @@ public function writeShapeChart(XMLWriter $objWriter, Chart $shape, $shapeId) // > draw:frame $objWriter->endElement(); } + + /** + * Writes a group of shapes + * + * @param XMLWriter $objWriter + * @param Group $group + */ + public function writeShapeGroup(XMLWriter $objWriter, Group $group) + { + // draw:g + $objWriter->startElement('draw:g'); + + $shapes = $group->getShapeCollection(); + foreach ($shapes as $shape) { + // Increment $this->shapeId + ++$this->shapeId; + + // Check type + if ($shape instanceof RichText) { + $this->writeShapeTxt($objWriter, $shape); + } elseif ($shape instanceof Table) { + $this->writeShapeTable($objWriter, $shape); + } elseif ($shape instanceof Line) { + $this->writeShapeLine($objWriter, $shape); + } elseif ($shape instanceof Chart) { + $this->writeShapeChart($objWriter, $shape); + } elseif ($shape instanceof AbstractDrawing) { + $this->writeShapePic($objWriter, $shape); + } elseif ($shape instanceof Group) { + $this->writeShapeGroup($objWriter, $shape); + } + } + + $objWriter->endElement(); // draw:g + } + + /** + * Writes the style information for a group of shapes + * + * @param XMLWriter $objWriter + * @param Group $group + */ + public function writeGroupStyle(XMLWriter $objWriter, Group $group) + { + $shapes = $group->getShapeCollection(); + foreach ($shapes as $shape) { + // Increment $this->shapeId + ++$this->shapeId; + + // Check type + if ($shape instanceof RichText) { + $this->writeTxtStyle($objWriter, $shape); + } + if ($shape instanceof AbstractDrawing) { + $this->writeDrawingStyle($objWriter, $shape); + } + if ($shape instanceof Line) { + $this->writeLineStyle($objWriter, $shape); + } + if ($shape instanceof Table) { + $this->writeTableStyle($objWriter, $shape); + } + } + } + + /** + * Write the default style information for a RichText shape + * + * @param \PhpOffice\Common\XMLWriter $objWriter + * @param \PhpOffice\PhpPowerpoint\Shape\RichText $shape + */ + public function writeTxtStyle(XMLWriter $objWriter, RichText $shape) + { + // style:style + $objWriter->startElement('style:style'); + $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId); + $objWriter->writeAttribute('style:family', 'graphic'); + $objWriter->writeAttribute('style:parent-style-name', 'standard'); + // style:graphic-properties + $objWriter->startElement('style:graphic-properties'); + if ($shape->getShadow()->isVisible()) { + $this->writeStylePartShadow($objWriter, $shape->getShadow()); + } + if (is_bool($shape->hasAutoShrinkVertical())) { + $objWriter->writeAttribute('draw:auto-grow-height', var_export($shape->hasAutoShrinkVertical(), true)); + } + if (is_bool($shape->hasAutoShrinkHorizontal())) { + $objWriter->writeAttribute('draw:auto-grow-width', var_export($shape->hasAutoShrinkHorizontal(), true)); + } + // Fill + switch ($shape->getFill()->getFillType()) { + case Fill::FILL_GRADIENT_LINEAR: + case Fill::FILL_GRADIENT_PATH: + $objWriter->writeAttribute('draw:fill', 'gradient'); + $objWriter->writeAttribute('draw:fill-gradient-name', 'gradient_'.$shape->getFill()->getHashCode()); + break; + case Fill::FILL_SOLID: + $objWriter->writeAttribute('draw:fill', 'solid'); + $objWriter->writeAttribute('draw:fill-color', '#'.$shape->getFill()->getStartColor()->getRGB()); + break; + case Fill::FILL_NONE: + default: + $objWriter->writeAttribute('draw:fill', 'none'); + $objWriter->writeAttribute('draw:fill-color', '#'.$shape->getFill()->getStartColor()->getRGB()); + break; + } + // Border + if ($shape->getBorder()->getLineStyle() == Border::LINE_NONE) { + $objWriter->writeAttribute('draw:stroke', 'none'); + } else { + $objWriter->writeAttribute('svg:stroke-color', '#'.$shape->getBorder()->getColor()->getRGB()); + $objWriter->writeAttribute('svg:stroke-width', number_format(CommonDrawing::pointsToCentimeters($shape->getBorder()->getLineWidth()), 3, '.', '').'cm'); + switch ($shape->getBorder()->getDashStyle()) { + case Border::DASH_SOLID: + $objWriter->writeAttribute('draw:stroke', 'solid'); + break; + case Border::DASH_DASH: + case Border::DASH_DASHDOT: + case Border::DASH_DOT: + case Border::DASH_LARGEDASH: + case Border::DASH_LARGEDASHDOT: + case Border::DASH_LARGEDASHDOTDOT: + case Border::DASH_SYSDASH: + case Border::DASH_SYSDASHDOT: + case Border::DASH_SYSDASHDOTDOT: + case Border::DASH_SYSDOT: + $objWriter->writeAttribute('draw:stroke', 'dash'); + $objWriter->writeAttribute('draw:stroke-dash', 'strokeDash_'.$shape->getBorder()->getDashStyle()); + break; + default: + $objWriter->writeAttribute('draw:stroke', 'none'); + break; + } + } + + $objWriter->writeAttribute('fo:wrap-option', 'wrap'); + // > style:graphic-properties + $objWriter->endElement(); + // > style:style + $objWriter->endElement(); + + $paragraphs = $shape->getParagraphs(); + $paragraphId = 0; + foreach ($paragraphs as $paragraph) { + ++$paragraphId; + + // Style des paragraphes + if (!isset($this->arrStyleParagraph[$paragraph->getHashCode()])) { + $this->arrStyleParagraph[$paragraph->getHashCode()] = $paragraph; + } + + // Style des listes + if (!isset($this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()])) { + $this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['oStyle'] = $paragraph->getBulletStyle(); + $this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level'] = ''; + } + if (strpos($this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level'], ';' . $paragraph->getAlignment()->getLevel()) === false) { + $this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level'] .= ';' . $paragraph->getAlignment()->getLevel(); + $this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['oAlign_' . $paragraph->getAlignment()->getLevel()] = $paragraph->getAlignment(); + } + + $richtexts = $paragraph->getRichTextElements(); + $richtextId = 0; + foreach ($richtexts as $richtext) { + ++$richtextId; + // Not a line break + if ($richtext instanceof Run) { + // Style des font text + if (!isset($this->arrStyleTextFont[$richtext->getFont()->getHashCode()])) { + $this->arrStyleTextFont[$richtext->getFont()->getHashCode()] = $richtext->getFont(); + } + } + } + } + } + + /** + * Write the default style information for an AbstractDrawing + * + * @param \PhpOffice\Common\XMLWriter $objWriter + * @param \PhpOffice\PhpPowerpoint\Shape\AbstractDrawing $shape + */ + public function writeDrawingStyle(XMLWriter $objWriter, AbstractDrawing $shape) + { + // style:style + $objWriter->startElement('style:style'); + $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId); + $objWriter->writeAttribute('style:family', 'graphic'); + $objWriter->writeAttribute('style:parent-style-name', 'standard'); + + // style:graphic-properties + $objWriter->startElement('style:graphic-properties'); + $objWriter->writeAttribute('draw:stroke', 'none'); + $objWriter->writeAttribute('draw:fill', 'none'); + if ($shape->getShadow()->isVisible()) { + $this->writeStylePartShadow($objWriter, $shape->getShadow()); + } + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write the default style information for a Line shape. + * + * @param XMLWriter $objWriter + * @param Line $shape + */ + public function writeLineStyle(XMLWriter $objWriter, Line $shape) + { + // style:style + $objWriter->startElement('style:style'); + $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId); + $objWriter->writeAttribute('style:family', 'graphic'); + $objWriter->writeAttribute('style:parent-style-name', 'standard'); + + // style:graphic-properties + $objWriter->startElement('style:graphic-properties'); + $objWriter->writeAttribute('draw:fill', 'none'); + switch ($shape->getBorder()->getLineStyle()) { + case Border::LINE_NONE: + $objWriter->writeAttribute('draw:stroke', 'none'); + break; + case Border::LINE_SINGLE: + $objWriter->writeAttribute('draw:stroke', 'solid'); + break; + default: + $objWriter->writeAttribute('draw:stroke', 'none'); + break; + } + $objWriter->writeAttribute('svg:stroke-color', '#'.$shape->getBorder()->getColor()->getRGB()); + $objWriter->writeAttribute('svg:stroke-width', String::numberFormat(CommonDrawing::pixelsToCentimeters((CommonDrawing::pointsToPixels($shape->getBorder()->getLineWidth()))), 3).'cm'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write the default style information for a Table shape + * + * @param XMLWriter $objWriter + * @param Table $shape + */ + public function writeTableStyle(XMLWriter $objWriter, Table $shape) + { + foreach ($shape->getRows() as $keyRow => $shapeRow) { + // style:style + $objWriter->startElement('style:style'); + $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId.'r'.$keyRow); + $objWriter->writeAttribute('style:family', 'table-row'); + + // style:table-row-properties + $objWriter->startElement('style:table-row-properties'); + $objWriter->writeAttribute('style:row-height', String::numberFormat(CommonDrawing::pixelsToCentimeters(CommonDrawing::pointsToPixels($shapeRow->getHeight())), 3).'cm'); + $objWriter->endElement(); + + $objWriter->endElement(); + + foreach ($shapeRow->getCells() as $keyCell => $shapeCell) { + // style:style + $objWriter->startElement('style:style'); + $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId.'r'.$keyRow.'c'.$keyCell); + $objWriter->writeAttribute('style:family', 'table-cell'); + + // style:graphic-properties + $objWriter->startElement('style:graphic-properties'); + if ($shapeCell->getFill()->getFillType() == Fill::FILL_SOLID) { + $objWriter->writeAttribute('draw:fill', 'solid'); + $objWriter->writeAttribute('draw:fill-color', '#'.$shapeCell->getFill()->getStartColor()->getRGB()); + } + if ($shapeCell->getFill()->getFillType() == Fill::FILL_GRADIENT_LINEAR) { + $objWriter->writeAttribute('draw:fill', 'gradient'); + $objWriter->writeAttribute('draw:fill-gradient-name', 'gradient_'.$shapeCell->getFill()->getHashCode()); + } + $objWriter->endElement(); + // startElement('style:paragraph-properties'); + if ($shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getTop()->getHashCode() + && $shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getLeft()->getHashCode() + && $shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getRight()->getHashCode()) { + $lineStyle = 'none'; + $lineWidth = String::numberFormat($shapeCell->getBorders()->getBottom()->getLineWidth() / 1.75, 2); + $lineColor = $shapeCell->getBorders()->getBottom()->getColor()->getRGB(); + switch ($shapeCell->getBorders()->getBottom()->getLineStyle()) { + case Border::LINE_SINGLE: + $lineStyle = 'solid'; + } + $objWriter->writeAttribute('fo:border', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); + } else { + $lineStyle = 'none'; + $lineWidth = String::numberFormat($shapeCell->getBorders()->getBottom()->getLineWidth() / 1.75, 2); + $lineColor = $shapeCell->getBorders()->getBottom()->getColor()->getRGB(); + switch ($shapeCell->getBorders()->getBottom()->getLineStyle()) { + case Border::LINE_SINGLE: + $lineStyle = 'solid'; + } + $objWriter->writeAttribute('fo:border-bottom', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); + // TOP + $lineStyle = 'none'; + $lineWidth = String::numberFormat($shapeCell->getBorders()->getTop()->getLineWidth() / 1.75, 2); + $lineColor = $shapeCell->getBorders()->getTop()->getColor()->getRGB(); + switch ($shapeCell->getBorders()->getTop()->getLineStyle()) { + case Border::LINE_SINGLE: + $lineStyle = 'solid'; + } + $objWriter->writeAttribute('fo:border-top', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); + // RIGHT + $lineStyle = 'none'; + $lineWidth = String::numberFormat($shapeCell->getBorders()->getRight()->getLineWidth() / 1.75, 2); + $lineColor = $shapeCell->getBorders()->getRight()->getColor()->getRGB(); + switch ($shapeCell->getBorders()->getRight()->getLineStyle()) { + case Border::LINE_SINGLE: + $lineStyle = 'solid'; + } + $objWriter->writeAttribute('fo:border-right', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); + // LEFT + $lineStyle = 'none'; + $lineWidth = String::numberFormat($shapeCell->getBorders()->getLeft()->getLineWidth() / 1.75, 2); + $lineColor = $shapeCell->getBorders()->getLeft()->getColor()->getRGB(); + switch ($shapeCell->getBorders()->getLeft()->getLineStyle()) { + case Border::LINE_SINGLE: + $lineStyle = 'solid'; + } + $objWriter->writeAttribute('fo:border-left', $lineWidth.'pt '.$lineStyle.' #'.$lineColor); + } + $objWriter->endElement(); + + $objWriter->endElement(); + + foreach ($shapeCell->getParagraphs() as $shapeParagraph) { + foreach ($shapeParagraph->getRichTextElements() as $shapeRichText) { + if ($shapeRichText instanceof Run) { + // Style des font text + if (!isset($this->arrStyleTextFont[$shapeRichText->getFont()->getHashCode()])) { + $this->arrStyleTextFont[$shapeRichText->getFont()->getHashCode()] = $shapeRichText->getFont(); + } + } + } + } + } + } + } + + /** + * Write the slide note + * @param XMLWriter $objWriter + * @param \PhpOffice\PhpPowerpoint\Slide\Note $note + */ + public function writeSlideNote(XMLWriter $objWriter, Note $note) + { + $shapesNote = $note->getShapeCollection(); + if (count($shapesNote) > 0) { + $objWriter->startElement('presentation:notes'); + + foreach ($shapesNote as $shape) { + // Increment $this->shapeId + ++$this->shapeId; + + if ($shape instanceof RichText) { + $this->writeShapeTxt($objWriter, $shape); + } + } + + $objWriter->endElement(); + } + } + + /** + * Write style of a slide + * @param XMLWriter $objWriter + * @param Slide $slide + * @param int $incPage + */ + public function writeStyleSlide(XMLWriter $objWriter, Slide $slide, $incPage) + { + // style:style + $objWriter->startElement('style:style'); + $objWriter->writeAttribute('style:family', 'drawing-page'); + $objWriter->writeAttribute('style:name', 'stylePage'.$incPage); + // style:style/style:drawing-page-properties + $objWriter->startElement('style:drawing-page-properties'); + if (!is_null($oTransition = $slide->getTransition())) { + $objWriter->writeAttribute('presentation:duration', 'PT'.number_format($oTransition->getAdvanceTimeTrigger() / 1000, 6, '.', '').'S'); + if ($oTransition->hasManualTrigger()) { + $objWriter->writeAttribute('presentation:transition-type', 'manual'); + } elseif ($oTransition->hasTimeTrigger()) { + $objWriter->writeAttribute('presentation:transition-type', 'automatic'); + } + switch ($oTransition->getSpeed()) { + case Transition::SPEED_FAST: + $objWriter->writeAttribute('presentation:transition-speed', 'fast'); + break; + case Transition::SPEED_MEDIUM: + $objWriter->writeAttribute('presentation:transition-speed', 'medium'); + break; + case Transition::SPEED_SLOW: + $objWriter->writeAttribute('presentation:transition-speed', 'slow'); + break; + } + + /** + * http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#property-presentation_transition-style + */ + switch ($oTransition->getTransitionType()) { + case Transition::TRANSITION_BLINDS_HORIZONTAL: + $objWriter->writeAttribute('presentation:transition-style', 'horizontal-stripes'); + break; + case Transition::TRANSITION_BLINDS_VERTICAL: + $objWriter->writeAttribute('presentation:transition-style', 'vertical-stripes'); + break; + case Transition::TRANSITION_CHECKER_HORIZONTAL: + $objWriter->writeAttribute('presentation:transition-style', 'horizontal-checkerboard'); + break; + case Transition::TRANSITION_CHECKER_VERTICAL: + $objWriter->writeAttribute('presentation:transition-style', 'vertical-checkerboard'); + break; + case Transition::TRANSITION_CIRCLE_HORIZONTAL: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_CIRCLE_VERTICAL: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_COMB_HORIZONTAL: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_COMB_VERTICAL: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_COVER_DOWN: + $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-bottom'); + break; + case Transition::TRANSITION_COVER_LEFT: + $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-left'); + break; + case Transition::TRANSITION_COVER_LEFT_DOWN: + $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-lowerleft'); + break; + case Transition::TRANSITION_COVER_LEFT_UP: + $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-upperleft'); + break; + case Transition::TRANSITION_COVER_RIGHT: + $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-right'); + break; + case Transition::TRANSITION_COVER_RIGHT_DOWN: + $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-lowerright'); + break; + case Transition::TRANSITION_COVER_RIGHT_UP: + $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-upperright'); + break; + case Transition::TRANSITION_COVER_UP: + $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-top'); + break; + case Transition::TRANSITION_CUT: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_DIAMOND: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_DISSOLVE: + $objWriter->writeAttribute('presentation:transition-style', 'dissolve'); + break; + case Transition::TRANSITION_FADE: + $objWriter->writeAttribute('presentation:transition-style', 'fade-from-center'); + break; + case Transition::TRANSITION_NEWSFLASH: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_PLUS: + $objWriter->writeAttribute('presentation:transition-style', 'close'); + break; + case Transition::TRANSITION_PULL_DOWN: + $objWriter->writeAttribute('presentation:transition-style', 'stretch-from-bottom'); + break; + case Transition::TRANSITION_PULL_LEFT: + $objWriter->writeAttribute('presentation:transition-style', 'stretch-from-left'); + break; + case Transition::TRANSITION_PULL_RIGHT: + $objWriter->writeAttribute('presentation:transition-style', 'stretch-from-right'); + break; + case Transition::TRANSITION_PULL_UP: + $objWriter->writeAttribute('presentation:transition-style', 'stretch-from-top'); + break; + case Transition::TRANSITION_PUSH_DOWN: + $objWriter->writeAttribute('presentation:transition-style', 'roll-from-bottom'); + break; + case Transition::TRANSITION_PUSH_LEFT: + $objWriter->writeAttribute('presentation:transition-style', 'roll-from-left'); + break; + case Transition::TRANSITION_PUSH_RIGHT: + $objWriter->writeAttribute('presentation:transition-style', 'roll-from-right'); + break; + case Transition::TRANSITION_PUSH_UP: + $objWriter->writeAttribute('presentation:transition-style', 'roll-from-top'); + break; + case Transition::TRANSITION_RANDOM: + $objWriter->writeAttribute('presentation:transition-style', 'random'); + break; + case Transition::TRANSITION_RANDOMBAR_HORIZONTAL: + $objWriter->writeAttribute('presentation:transition-style', 'horizontal-lines'); + break; + case Transition::TRANSITION_RANDOMBAR_VERTICAL: + $objWriter->writeAttribute('presentation:transition-style', 'vertical-lines'); + break; + case Transition::TRANSITION_SPLIT_IN_HORIZONTAL: + $objWriter->writeAttribute('presentation:transition-style', 'close-horizontal'); + break; + case Transition::TRANSITION_SPLIT_OUT_HORIZONTAL: + $objWriter->writeAttribute('presentation:transition-style', 'open-horizontal'); + break; + case Transition::TRANSITION_SPLIT_IN_VERTICAL: + $objWriter->writeAttribute('presentation:transition-style', 'close-vertical'); + break; + case Transition::TRANSITION_SPLIT_OUT_VERTICAL: + $objWriter->writeAttribute('presentation:transition-style', 'open-vertical'); + break; + case Transition::TRANSITION_STRIPS_LEFT_DOWN: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_STRIPS_LEFT_UP: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_STRIPS_RIGHT_DOWN: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_STRIPS_RIGHT_UP: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_WEDGE: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_WIPE_DOWN: + $objWriter->writeAttribute('presentation:transition-style', 'fade-from-bottom'); + break; + case Transition::TRANSITION_WIPE_LEFT: + $objWriter->writeAttribute('presentation:transition-style', 'fade-from-left'); + break; + case Transition::TRANSITION_WIPE_RIGHT: + $objWriter->writeAttribute('presentation:transition-style', 'fade-from-right'); + break; + case Transition::TRANSITION_WIPE_UP: + $objWriter->writeAttribute('presentation:transition-style', 'fade-from-top'); + break; + case Transition::TRANSITION_ZOOM_IN: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + case Transition::TRANSITION_ZOOM_OUT: + $objWriter->writeAttribute('presentation:transition-style', 'none'); + break; + } + } + $objWriter->endElement(); + // > style:style + $objWriter->endElement(); + } + + + protected function writeStylePartShadow(XMLWriter $objWriter, Shadow $oShadow) + { + $objWriter->writeAttribute('draw:shadow', 'visible'); + $objWriter->writeAttribute('draw:shadow-color', '#' . $oShadow->getColor()->getRGB()); + if ($oShadow->getDirection() == 0 || $oShadow->getDirection() == 360) { + $objWriter->writeAttribute('draw:shadow-offset-x', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + $objWriter->writeAttribute('draw:shadow-offset-y', '0cm'); + } elseif ($oShadow->getDirection() == 45) { + $objWriter->writeAttribute('draw:shadow-offset-x', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + $objWriter->writeAttribute('draw:shadow-offset-y', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + } elseif ($oShadow->getDirection() == 90) { + $objWriter->writeAttribute('draw:shadow-offset-x', '0cm'); + $objWriter->writeAttribute('draw:shadow-offset-y', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + } elseif ($oShadow->getDirection() == 135) { + $objWriter->writeAttribute('draw:shadow-offset-x', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + $objWriter->writeAttribute('draw:shadow-offset-y', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + } elseif ($oShadow->getDirection() == 180) { + $objWriter->writeAttribute('draw:shadow-offset-x', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + $objWriter->writeAttribute('draw:shadow-offset-y', '0cm'); + } elseif ($oShadow->getDirection() == 225) { + $objWriter->writeAttribute('draw:shadow-offset-x', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + $objWriter->writeAttribute('draw:shadow-offset-y', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + } elseif ($oShadow->getDirection() == 270) { + $objWriter->writeAttribute('draw:shadow-offset-x', '0cm'); + $objWriter->writeAttribute('draw:shadow-offset-y', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + } elseif ($oShadow->getDirection() == 315) { + $objWriter->writeAttribute('draw:shadow-offset-x', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + $objWriter->writeAttribute('draw:shadow-offset-y', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm'); + } + $objWriter->writeAttribute('draw:shadow-opacity', (100 - $oShadow->getAlpha()) . '%'); + $objWriter->writeAttribute('style:mirror', 'none'); + + } } diff --git a/src/PhpPowerpoint/Writer/ODPresentation/Drawing.php b/src/PhpPowerpoint/Writer/ODPresentation/Drawing.php index 77b254456..74f33422c 100644 --- a/src/PhpPowerpoint/Writer/ODPresentation/Drawing.php +++ b/src/PhpPowerpoint/Writer/ODPresentation/Drawing.php @@ -19,6 +19,7 @@ use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\AbstractDrawing; +use PhpOffice\PhpPowerpoint\Shape\Group; use PhpOffice\PhpPowerpoint\Shape\Table; /** @@ -29,11 +30,11 @@ class Drawing extends AbstractPart /** * Get an array of all drawings * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerPoint $pPHPPowerPoint * @return \PhpOffice\PhpPowerpoint\Shape\AbstractDrawing[] All drawings in PHPPowerPoint * @throws \Exception */ - public function allDrawings(PHPPowerPoint $pPHPPowerPoint = null) + public function allDrawings(PhpPowerPoint $pPHPPowerPoint) { // Get an array of all drawings $aDrawings = array(); @@ -46,6 +47,14 @@ public function allDrawings(PHPPowerPoint $pPHPPowerPoint = null) while ($iterator->valid()) { if ($iterator->current() instanceof AbstractDrawing && !($iterator->current() instanceof Table)) { $aDrawings[] = $iterator->current(); + } elseif ($iterator->current() instanceof Group) { + $iterator2 = $iterator->current()->getShapeCollection()->getIterator(); + while ($iterator2->valid()) { + if ($iterator2->current() instanceof AbstractDrawing && !($iterator2->current() instanceof Table)) { + $aDrawings[] = $iterator2->current(); + } + $iterator2->next(); + } } $iterator->next(); diff --git a/src/PhpPowerpoint/Writer/ODPresentation/Manifest.php b/src/PhpPowerpoint/Writer/ODPresentation/Manifest.php index 7f482c051..64c65fda3 100644 --- a/src/PhpPowerpoint/Writer/ODPresentation/Manifest.php +++ b/src/PhpPowerpoint/Writer/ODPresentation/Manifest.php @@ -17,10 +17,10 @@ namespace PhpOffice\PhpPowerpoint\Writer\ODPresentation; +use PhpOffice\Common\File; use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\Drawing as ShapeDrawing; use PhpOffice\PhpPowerpoint\Shape\MemoryDrawing; -use PhpOffice\PhpPowerpoint\Shared\File; use PhpOffice\PhpPowerpoint\Writer\ODPresentation; /** diff --git a/src/PhpPowerpoint/Writer/ODPresentation/ObjectsChart.php b/src/PhpPowerpoint/Writer/ODPresentation/ObjectsChart.php index 4202bbab7..5e78f9715 100644 --- a/src/PhpPowerpoint/Writer/ODPresentation/ObjectsChart.php +++ b/src/PhpPowerpoint/Writer/ODPresentation/ObjectsChart.php @@ -17,15 +17,21 @@ namespace PhpOffice\PhpPowerpoint\Writer\ODPresentation; +use PhpOffice\Common\Drawing as CommonDrawing; +use PhpOffice\Common\String; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\Chart; +use PhpOffice\PhpPowerpoint\Shape\Chart\Title; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\AbstractTypeBar; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\AbstractTypePie; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Area; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar3D; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Line; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie3D; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Scatter; -use PhpOffice\PhpPowerpoint\Shared\Drawing as SharedDrawing; -use PhpOffice\PhpPowerpoint\Shared\String; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; use PhpOffice\PhpPowerpoint\Style\Fill; /** @@ -87,7 +93,7 @@ public function writePart(Chart $chart) private function writeContentPart(Chart $chart) { $chartType = $chart->getPlotArea()->getType(); - if (!($chartType instanceof Bar3D || $chartType instanceof Line || $chartType instanceof Pie3D|| $chartType instanceof Scatter)) { + if (!($chartType instanceof Area || $chartType instanceof AbstractTypeBar || $chartType instanceof Line || $chartType instanceof AbstractTypePie || $chartType instanceof Scatter)) { throw new \Exception('The chart type provided could not be rendered.'); } @@ -159,7 +165,7 @@ private function writeContentPart(Chart $chart) $this->writeChartStyle($chart); // Axis - $this->writeAxisStyle(); + $this->writeAxisStyle($chart); // Series $this->numSeries = 0; @@ -179,7 +185,7 @@ private function writeContentPart(Chart $chart) $this->writePlotAreaStyle($chart); // Title - $this->writeTitleStyle($chart); + $this->writeTitleStyle($chart->getTitle()); // Wall $this->writeWallStyle($chart); @@ -193,23 +199,25 @@ private function writeContentPart(Chart $chart) $this->xmlContent->startElement('office:chart'); // office:chart $this->xmlContent->startElement('chart:chart'); - $this->xmlContent->writeAttribute('svg:width', String::numberFormat(SharedDrawing::pixelsToCentimeters($chart->getWidth()), 3) . 'cm'); - $this->xmlContent->writeAttribute('svg:height', String::numberFormat(SharedDrawing::pixelsToCentimeters($chart->getHeight()), 3) . 'cm'); + $this->xmlContent->writeAttribute('svg:width', String::numberFormat(CommonDrawing::pixelsToCentimeters($chart->getWidth()), 3) . 'cm'); + $this->xmlContent->writeAttribute('svg:height', String::numberFormat(CommonDrawing::pixelsToCentimeters($chart->getHeight()), 3) . 'cm'); $this->xmlContent->writeAttribute('xlink:href', '.'); $this->xmlContent->writeAttribute('xlink:type', 'simple'); $this->xmlContent->writeAttribute('chart:style-name', 'styleChart'); - if ($chartType instanceof Bar3D) { + if ($chartType instanceof Area) { + $this->xmlContent->writeAttribute('chart:class', 'chart:area'); + } elseif ($chartType instanceof AbstractTypeBar) { $this->xmlContent->writeAttribute('chart:class', 'chart:bar'); } elseif ($chartType instanceof Line) { $this->xmlContent->writeAttribute('chart:class', 'chart:line'); - } elseif ($chartType instanceof Pie3D) { + } elseif ($chartType instanceof AbstractTypePie) { $this->xmlContent->writeAttribute('chart:class', 'chart:circle'); } elseif ($chartType instanceof Scatter) { $this->xmlContent->writeAttribute('chart:class', 'chart:scatter'); } //**** Title **** - $this->writeTitle($chart); + $this->writeTitle($chart->getTitle()); //**** Legend **** $this->writeLegend($chart); @@ -267,8 +275,14 @@ private function writeAxis(Chart $chart) } } - private function writeAxisStyle() + /** + * @param Chart $chart + * @todo Set function in \PhpPowerpoint\Shape\Chart\Axis for defining width and color of the axis + */ + private function writeAxisStyle(Chart $chart) { + $chartType = $chart->getPlotArea()->getType(); + // AxisX // style:style $this->xmlContent->startElement('style:style'); @@ -277,8 +291,19 @@ private function writeAxisStyle() // style:chart-properties $this->xmlContent->startElement('style:chart-properties'); $this->xmlContent->writeAttribute('chart:display-label', 'true'); + $this->xmlContent->writeAttribute('chart:tick-marks-major-inner', 'false'); + $this->xmlContent->writeAttribute('chart:tick-marks-major-outer', 'false'); + if ($chartType instanceof AbstractTypePie) { + $this->xmlContent->writeAttribute('chart:reverse-direction', 'true'); + } // > style:chart-properties $this->xmlContent->endElement(); + // style:graphic-properties + $this->xmlContent->startElement('style:graphic-properties'); + $this->xmlContent->writeAttribute('svg:stroke-width', '0.026cm'); + $this->xmlContent->writeAttribute('svg:stroke-color', '#878787'); + // > style:graphic-properties + $this->xmlContent->endElement(); // > style:style $this->xmlContent->endElement(); @@ -290,8 +315,19 @@ private function writeAxisStyle() // style:chart-properties $this->xmlContent->startElement('style:chart-properties'); $this->xmlContent->writeAttribute('chart:display-label', 'true'); + $this->xmlContent->writeAttribute('chart:tick-marks-major-inner', 'false'); + $this->xmlContent->writeAttribute('chart:tick-marks-major-outer', 'false'); + if ($chartType instanceof AbstractTypePie) { + $this->xmlContent->writeAttribute('chart:reverse-direction', 'true'); + } // > style:chart-properties $this->xmlContent->endElement(); + // style:graphic-properties + $this->xmlContent->startElement('style:graphic-properties'); + $this->xmlContent->writeAttribute('svg:stroke-width', '0.026cm'); + $this->xmlContent->writeAttribute('svg:stroke-color', '#878787'); + // > style:graphic-properties + $this->xmlContent->endElement(); // > style:style $this->xmlContent->endElement(); } @@ -351,8 +387,8 @@ private function writeLegend(Chart $chart) // chart:legend $this->xmlContent->startElement('chart:legend'); $this->xmlContent->writeAttribute('chart:legend-position', 'end'); - $this->xmlContent->writeAttribute('svg:x', String::numberFormat(SharedDrawing::pixelsToCentimeters($chart->getLegend()->getOffsetX()), 3) . 'cm'); - $this->xmlContent->writeAttribute('svg:y', String::numberFormat(SharedDrawing::pixelsToCentimeters($chart->getLegend()->getOffsetY()), 3) . 'cm'); + $this->xmlContent->writeAttribute('svg:x', String::numberFormat(CommonDrawing::pixelsToCentimeters($chart->getLegend()->getOffsetX()), 3) . 'cm'); + $this->xmlContent->writeAttribute('svg:y', String::numberFormat(CommonDrawing::pixelsToCentimeters($chart->getLegend()->getOffsetY()), 3) . 'cm'); $this->xmlContent->writeAttribute('style:legend-expansion', 'high'); $this->xmlContent->writeAttribute('chart:style-name', 'styleLegend'); // > chart:legend @@ -397,13 +433,13 @@ private function writePlotArea(Chart $chart) if ($chartType instanceof Bar3D || $chartType instanceof Pie3D) { // dr3d:light $arrayLight = array( - array('#808080', '(0 0 1)', 'false', 'true'), - array('#666666', '(0.2 0.4 1)', 'true', 'false'), - array('#808080', '(0 0 1)', 'false', 'false'), - array('#808080', '(0 0 1)', 'false', 'false'), - array('#808080', '(0 0 1)', 'false', 'false'), - array('#808080', '(0 0 1)', 'false', 'false'), - array('#808080', '(0 0 1)', 'false', 'false'), + array('#808080', '(0 0 1)', 'false', 'true'), + array('#666666', '(0.2 0.4 1)', 'true', 'false'), + array('#808080', '(0 0 1)', 'false', 'false'), + array('#808080', '(0 0 1)', 'false', 'false'), + array('#808080', '(0 0 1)', 'false', 'false'), + array('#808080', '(0 0 1)', 'false', 'false'), + array('#808080', '(0 0 1)', 'false', 'false'), ); foreach ($arrayLight as $light) { $this->xmlContent->startElement('dr3d:light'); @@ -437,6 +473,7 @@ private function writePlotArea(Chart $chart) /** * @param Chart $chart + * @link : http://books.evc-cit.info/odbook/ch08.html#chart-plot-area-section */ private function writePlotAreaStyle(Chart $chart) { @@ -448,11 +485,39 @@ private function writePlotAreaStyle(Chart $chart) $this->xmlContent->writeAttribute('style:family', 'chart'); // style:text-properties $this->xmlContent->startElement('style:chart-properties'); - if ($chartType instanceof Bar3D || $chartType instanceof Pie3D) { + if ($chartType instanceof Bar3D) { + $this->xmlContent->writeAttribute('chart:three-dimensional', 'true'); + $this->xmlContent->writeAttribute('chart:right-angled-axes', 'true'); + } elseif ($chartType instanceof Pie3D) { $this->xmlContent->writeAttribute('chart:three-dimensional', 'true'); $this->xmlContent->writeAttribute('chart:right-angled-axes', 'true'); } - $this->xmlContent->writeAttribute('chart:data-label-number', 'value'); + if ($chartType instanceof AbstractTypeBar) { + if ($chartType->getBarDirection() == AbstractTypeBar::DIRECTION_HORIZONTAL) { + $this->xmlContent->writeAttribute('chart:vertical', 'true'); + } else { + $this->xmlContent->writeAttribute('chart:vertical', 'false'); + } + if ($chartType->getBarGrouping() == Bar::GROUPING_CLUSTERED) { + $this->xmlContent->writeAttribute('chart:stacked', 'false'); + $this->xmlContent->writeAttribute('chart:overlap', '0'); + } elseif ($chartType->getBarGrouping() == Bar::GROUPING_STACKED) { + $this->xmlContent->writeAttribute('chart:stacked', 'true'); + $this->xmlContent->writeAttribute('chart:overlap', '100'); + } elseif ($chartType->getBarGrouping() == Bar::GROUPING_PERCENTSTACKED) { + $this->xmlContent->writeAttribute('chart:stacked', 'true'); + $this->xmlContent->writeAttribute('chart:overlap', '100'); + $this->xmlContent->writeAttribute('chart:percentage', 'true'); + } + } + $labelFormat = 'value'; + if ($chartType instanceof AbstractTypeBar) { + if ($chartType->getBarGrouping() == Bar::GROUPING_PERCENTSTACKED) { + $labelFormat = 'percentage'; + } + } + $this->xmlContent->writeAttribute('chart:data-label-number', $labelFormat); + // > style:text-properties $this->xmlContent->endElement(); // > style:style @@ -473,17 +538,19 @@ private function writeSeries(Chart $chart, Chart\Series $series) $this->xmlContent->startElement('chart:series'); $this->xmlContent->writeAttribute('chart:values-cell-range-address', 'table-local.$'.$this->rangeCol.'$2:.$'.$this->rangeCol.'$'.($numRange+1)); $this->xmlContent->writeAttribute('chart:label-cell-address', 'table-local.$'.$this->rangeCol.'$1'); - if ($chartType instanceof Bar3D) { + if ($chartType instanceof Area) { + $this->xmlContent->writeAttribute('chart:class', 'chart:area'); + } elseif ($chartType instanceof AbstractTypeBar) { $this->xmlContent->writeAttribute('chart:class', 'chart:bar'); } elseif ($chartType instanceof Line) { $this->xmlContent->writeAttribute('chart:class', 'chart:line'); - } elseif ($chartType instanceof Pie3D) { + } elseif ($chartType instanceof AbstractTypePie) { $this->xmlContent->writeAttribute('chart:class', 'chart:circle'); } elseif ($chartType instanceof Scatter) { $this->xmlContent->writeAttribute('chart:class', 'chart:scatter'); } $this->xmlContent->writeAttribute('chart:style-name', 'styleSeries'.$this->numSeries); - if ($chartType instanceof Bar3D || $chartType instanceof Line || $chartType instanceof Scatter) { + if ($chartType instanceof Area || $chartType instanceof AbstractTypeBar || $chartType instanceof Line || $chartType instanceof Scatter) { $dataPointFills = $series->getDataPointFills(); if (empty($dataPointFills)) { $incRepeat = $numRange; @@ -516,7 +583,7 @@ private function writeSeries(Chart $chart, Chart\Series $series) $this->xmlContent->writeAttribute('chart:repeated', $incRepeat); // > chart:data-point $this->xmlContent->endElement(); - } elseif ($chartType instanceof Pie3D) { + } elseif ($chartType instanceof AbstractTypePie) { $count = count($series->getDataPointFills()); for ($inc = 0; $inc < $count; $inc++) { // chart:data-point @@ -546,10 +613,9 @@ private function writeSeriesStyle(Chart $chart, Chart\Series $series) // style:chart-properties $this->xmlContent->startElement('style:chart-properties'); $this->xmlContent->writeAttribute('chart:data-label-number', 'value'); - $this->xmlContent->writeAttribute('chart:label-position', 'right'); - if ($chartType instanceof Pie3D) { - //@todo : Permit edit the offset of a pie - $this->xmlContent->writeAttribute('chart:pie-offset', '20'); + $this->xmlContent->writeAttribute('chart:label-position', 'center'); + if ($chartType instanceof AbstractTypePie) { + $this->xmlContent->writeAttribute('chart:pie-offset', $chartType->getExplosion()); } if ($chartType instanceof Line) { //@todo : Permit edit the symbol of a line @@ -563,12 +629,13 @@ private function writeSeriesStyle(Chart $chart, Chart\Series $series) //@todo : Permit edit the color and width of a line $this->xmlContent->writeAttribute('svg:stroke-width', '0.079cm'); $this->xmlContent->writeAttribute('svg:stroke-color', '#4a7ebb'); - $this->xmlContent->writeAttribute('draw:fill-color', '#4a7ebb'); } else { $this->xmlContent->writeAttribute('draw:stroke', 'none'); - $this->xmlContent->writeAttribute('draw:fill', $series->getFill()->getFillType()); - $this->xmlContent->writeAttribute('draw:fill-color', '#'.$series->getFill()->getStartColor()->getRGB()); + if (!($chartType instanceof Area)) { + $this->xmlContent->writeAttribute('draw:fill', $series->getFill()->getFillType()); + } } + $this->xmlContent->writeAttribute('draw:fill-color', '#'.$series->getFill()->getStartColor()->getRGB()); // > style:graphic-properties $this->xmlContent->endElement(); // style:text-properties @@ -599,7 +666,6 @@ private function writeSeriesStyle(Chart $chart, Chart\Series $series) } /** - * @param Chart $chart */ private function writeTable() { @@ -615,6 +681,19 @@ private function writeTable() $this->xmlContent->endElement(); // > table:table-header-columns $this->xmlContent->endElement(); + + // table:table-columns + $this->xmlContent->startElement('table:table-columns'); + // table:table-column + $this->xmlContent->startElement('table:table-column'); + if (!empty($this->arrayData)) { + $rowFirst = reset($this->arrayData); + $this->xmlContent->writeAttribute('table:number-columns-repeated', count($rowFirst) - 1); + } + // > table:table-column + $this->xmlContent->endElement(); + // > table:table-columns + $this->xmlContent->endElement(); // table:table-header-rows $this->xmlContent->startElement('table:table-header-rows'); @@ -625,7 +704,9 @@ private function writeTable() foreach ($rowFirst as $key => $cell) { // table:table-cell $this->xmlContent->startElement('table:table-cell'); - $this->xmlContent->writeAttribute('office:value', 'string'); + if (isset($this->arrayTitle[$key - 1])) { + $this->xmlContent->writeAttribute('office:value-type', 'string'); + } // text:p $this->xmlContent->startElement('text:p'); if (isset($this->arrayTitle[$key - 1])) { @@ -676,43 +757,47 @@ private function writeTable() } /** - * @param Chart $chart + * @param Title $oTitle */ - private function writeTitle(Chart $chart) + private function writeTitle(Title $oTitle) { - // chart:title - $this->xmlContent->startElement('chart:title'); - $this->xmlContent->writeAttribute('svg:x', String::numberFormat(SharedDrawing::pixelsToCentimeters($chart->getTitle()->getOffsetX()), 3) . 'cm'); - $this->xmlContent->writeAttribute('svg:y', String::numberFormat(SharedDrawing::pixelsToCentimeters($chart->getTitle()->getOffsetY()), 3) . 'cm'); - $this->xmlContent->writeAttribute('chart:style-name', 'styleTitle'); - // > text:p - $this->xmlContent->startElement('text:p'); - $this->xmlContent->text($chart->getTitle()->getText()); - // > text:p - $this->xmlContent->endElement(); - // > chart:title - $this->xmlContent->endElement(); + if ($oTitle->isVisible()) { + // chart:title + $this->xmlContent->startElement('chart:title'); + $this->xmlContent->writeAttribute('svg:x', String::numberFormat(CommonDrawing::pixelsToCentimeters($oTitle->getOffsetX()), 3) . 'cm'); + $this->xmlContent->writeAttribute('svg:y', String::numberFormat(CommonDrawing::pixelsToCentimeters($oTitle->getOffsetY()), 3) . 'cm'); + $this->xmlContent->writeAttribute('chart:style-name', 'styleTitle'); + // > text:p + $this->xmlContent->startElement('text:p'); + $this->xmlContent->text($oTitle->getText()); + // > text:p + $this->xmlContent->endElement(); + // > chart:title + $this->xmlContent->endElement(); + } } /** - * @param Chart $chart + * @param Title $oTitle */ - private function writeTitleStyle(Chart $chart) + private function writeTitleStyle(Title $oTitle) { - // style:style - $this->xmlContent->startElement('style:style'); - $this->xmlContent->writeAttribute('style:name', 'styleTitle'); - $this->xmlContent->writeAttribute('style:family', 'chart'); - // style:text-properties - $this->xmlContent->startElement('style:text-properties'); - $this->xmlContent->writeAttribute('fo:color', '#'.$chart->getTitle()->getFont()->getColor()->getRGB()); - $this->xmlContent->writeAttribute('fo:font-family', $chart->getTitle()->getFont()->getName()); - $this->xmlContent->writeAttribute('fo:font-size', $chart->getTitle()->getFont()->getSize().'pt'); - $this->xmlContent->writeAttribute('fo:font-style', $chart->getTitle()->getFont()->isItalic() ? 'italic' : 'normal'); - // > style:text-properties - $this->xmlContent->endElement(); - // > style:style - $this->xmlContent->endElement(); + if ($oTitle->isVisible()) { + // style:style + $this->xmlContent->startElement('style:style'); + $this->xmlContent->writeAttribute('style:name', 'styleTitle'); + $this->xmlContent->writeAttribute('style:family', 'chart'); + // style:text-properties + $this->xmlContent->startElement('style:text-properties'); + $this->xmlContent->writeAttribute('fo:color', '#'.$oTitle->getFont()->getColor()->getRGB()); + $this->xmlContent->writeAttribute('fo:font-family', $oTitle->getFont()->getName()); + $this->xmlContent->writeAttribute('fo:font-size', $oTitle->getFont()->getSize().'pt'); + $this->xmlContent->writeAttribute('fo:font-style', $oTitle->getFont()->isItalic() ? 'italic' : 'normal'); + // > style:text-properties + $this->xmlContent->endElement(); + // > style:style + $this->xmlContent->endElement(); + } } private function writeWall() diff --git a/src/PhpPowerpoint/Writer/ODPresentation/Styles.php b/src/PhpPowerpoint/Writer/ODPresentation/Styles.php index db9b80401..a607fc9cd 100644 --- a/src/PhpPowerpoint/Writer/ODPresentation/Styles.php +++ b/src/PhpPowerpoint/Writer/ODPresentation/Styles.php @@ -17,17 +17,34 @@ namespace PhpOffice\PhpPowerpoint\Writer\ODPresentation; +use PhpOffice\Common\Drawing as CommonDrawing; +use PhpOffice\Common\String; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\PhpPowerpoint; +use PhpOffice\PhpPowerpoint\Shape\Group; use PhpOffice\PhpPowerpoint\Shape\Table; -use PhpOffice\PhpPowerpoint\Shared\Drawing as SharedDrawing; -use PhpOffice\PhpPowerpoint\Shared\String; use PhpOffice\PhpPowerpoint\Style\Fill; +use PhpOffice\PhpPowerpoint\Shape\RichText; +use PhpOffice\PhpPowerpoint\Style\Border; /** * \PhpOffice\PhpPowerpoint\Writer\ODPresentation\Styles */ class Styles extends AbstractPart { + /** + * Stores font styles draw:gradient nodes + * + * @var array + */ + private $arrayGradient = array(); + /** + * Stores font styles draw:stroke-dash nodes + * + * @var array + */ + private $arrayStrokeDash = array(); + /** * Write Meta file to XML format * @@ -95,31 +112,15 @@ public function writePart(PHPPowerPoint $pPHPPowerPoint) $objWriter->endElement(); // > style:style $objWriter->endElement(); - // draw:gradient - $arrayGradient = array(); + foreach ($pPHPPowerPoint->getAllSlides() as $slide) { foreach ($slide->getShapeCollection() as $shape) { if ($shape instanceof Table) { - foreach ($shape->getRows() as $row) { - foreach ($row->getCells() as $cell) { - if ($cell->getFill()->getFillType() == Fill::FILL_GRADIENT_LINEAR) { - if (!in_array($cell->getFill()->getHashCode(), $arrayGradient)) { - $objWriter->startElement('draw:gradient'); - $objWriter->writeAttribute('draw:name', 'gradient_'.$cell->getFill()->getHashCode()); - $objWriter->writeAttribute('draw:display-name', 'gradient_'.$cell->getFill()->getHashCode()); - $objWriter->writeAttribute('draw:style', 'linear'); - $objWriter->writeAttribute('draw:start-intensity', '100%'); - $objWriter->writeAttribute('draw:end-intensity', '100%'); - $objWriter->writeAttribute('draw:start-color', '#'.$cell->getFill()->getStartColor()->getRGB()); - $objWriter->writeAttribute('draw:end-color', '#'.$cell->getFill()->getEndColor()->getRGB()); - $objWriter->writeAttribute('draw:border', '0%'); - $objWriter->writeAttribute('draw:angle', $cell->getFill()->getRotation() - 90); - $objWriter->endElement(); - $arrayGradient[] = $cell->getFill()->getHashCode(); - } - } - } - } + $this->writeTableStyle($objWriter, $shape); + } elseif ($shape instanceof Group) { + $this->writeGroupStyle($objWriter, $shape); + } elseif ($shape instanceof RichText) { + $this->writeRichTextStyle($objWriter, $shape); } } } @@ -141,8 +142,8 @@ public function writePart(PHPPowerPoint $pPHPPowerPoint) $objWriter->writeAttribute('fo:margin-bottom', '0cm'); $objWriter->writeAttribute('fo:margin-left', '0cm'); $objWriter->writeAttribute('fo:margin-right', '0cm'); - $objWriter->writeAttribute('fo:page-width', String::numberFormat(SharedDrawing::pixelsToCentimeters(SharedDrawing::emuToPixels($pPHPPowerPoint->getLayout()->getCX())), 1) . 'cm'); - $objWriter->writeAttribute('fo:page-height', String::numberFormat(SharedDrawing::pixelsToCentimeters(SharedDrawing::emuToPixels($pPHPPowerPoint->getLayout()->getCY())), 1) . 'cm'); + $objWriter->writeAttribute('fo:page-width', String::numberFormat(CommonDrawing::pixelsToCentimeters(CommonDrawing::emuToPixels($pPHPPowerPoint->getLayout()->getCX())), 1) . 'cm'); + $objWriter->writeAttribute('fo:page-height', String::numberFormat(CommonDrawing::pixelsToCentimeters(CommonDrawing::emuToPixels($pPHPPowerPoint->getLayout()->getCY())), 1) . 'cm'); if ($pPHPPowerPoint->getLayout()->getCX() > $pPHPPowerPoint->getLayout()->getCY()) { $objWriter->writeAttribute('style:print-orientation', 'landscape'); } else { @@ -172,4 +173,148 @@ public function writePart(PHPPowerPoint $pPHPPowerPoint) // Return return $objWriter->getData(); } + + /** + * Write the default style information for a RichText shape + * + * @param XMLWriter $objWriter + * @param RichText $shape + */ + public function writeRichTextStyle(XMLWriter $objWriter, RichText $shape) + { + if ($shape->getFill()->getFillType() == Fill::FILL_GRADIENT_LINEAR || $shape->getFill()->getFillType() == Fill::FILL_GRADIENT_PATH) { + if (!in_array($shape->getFill()->getHashCode(), $this->arrayGradient)) { + $this->writeGradientFill($objWriter, $shape->getFill()); + } + } + if ($shape->getBorder()->getDashStyle() != Border::DASH_SOLID) { + if (!in_array($shape->getBorder()->getDashStyle(), $this->arrayStrokeDash)) { + $objWriter->startElement('draw:stroke-dash'); + $objWriter->writeAttribute('draw:name', 'strokeDash_'.$shape->getBorder()->getDashStyle()); + $objWriter->writeAttribute('draw:style', 'rect'); + switch ($shape->getBorder()->getDashStyle()) { + case Border::DASH_DASH: + $objWriter->writeAttribute('draw:distance', '0.105cm'); + $objWriter->writeAttribute('draw:dots2', '1'); + $objWriter->writeAttribute('draw:dots2-length', '0.14cm'); + break; + case Border::DASH_DASHDOT: + $objWriter->writeAttribute('draw:distance', '0.105cm'); + $objWriter->writeAttribute('draw:dots1', '1'); + $objWriter->writeAttribute('draw:dots1-length', '0.035cm'); + $objWriter->writeAttribute('draw:dots2', '1'); + $objWriter->writeAttribute('draw:dots2-length', '0.14cm'); + break; + case Border::DASH_DOT: + $objWriter->writeAttribute('draw:distance', '0.105cm'); + $objWriter->writeAttribute('draw:dots1', '1'); + $objWriter->writeAttribute('draw:dots1-length', '0.035cm'); + break; + case Border::DASH_LARGEDASH: + $objWriter->writeAttribute('draw:distance', '0.105cm'); + $objWriter->writeAttribute('draw:dots2', '1'); + $objWriter->writeAttribute('draw:dots2-length', '0.28cm'); + break; + case Border::DASH_LARGEDASHDOT: + $objWriter->writeAttribute('draw:distance', '0.105cm'); + $objWriter->writeAttribute('draw:dots1', '1'); + $objWriter->writeAttribute('draw:dots1-length', '0.035cm'); + $objWriter->writeAttribute('draw:dots2', '1'); + $objWriter->writeAttribute('draw:dots2-length', '0.28cm'); + break; + case Border::DASH_LARGEDASHDOTDOT: + $objWriter->writeAttribute('draw:distance', '0.105cm'); + $objWriter->writeAttribute('draw:dots1', '2'); + $objWriter->writeAttribute('draw:dots1-length', '0.035cm'); + $objWriter->writeAttribute('draw:dots2', '1'); + $objWriter->writeAttribute('draw:dots2-length', '0.28cm'); + break; + case Border::DASH_SYSDASH: + $objWriter->writeAttribute('draw:distance', '0.035cm'); + $objWriter->writeAttribute('draw:dots2', '1'); + $objWriter->writeAttribute('draw:dots2-length', '0.105cm'); + break; + case Border::DASH_SYSDASHDOT: + $objWriter->writeAttribute('draw:distance', '0.035cm'); + $objWriter->writeAttribute('draw:dots1', '1'); + $objWriter->writeAttribute('draw:dots1-length', '0.035cm'); + $objWriter->writeAttribute('draw:dots2', '1'); + $objWriter->writeAttribute('draw:dots2-length', '0.105cm'); + break; + case Border::DASH_SYSDASHDOTDOT: + $objWriter->writeAttribute('draw:distance', '0.035cm'); + $objWriter->writeAttribute('draw:dots1', '2'); + $objWriter->writeAttribute('draw:dots1-length', '0.035cm'); + $objWriter->writeAttribute('draw:dots2', '1'); + $objWriter->writeAttribute('draw:dots2-length', '0.105cm'); + break; + case Border::DASH_SYSDOT: + $objWriter->writeAttribute('draw:distance', '0.035cm'); + $objWriter->writeAttribute('draw:dots1', '1'); + $objWriter->writeAttribute('draw:dots1-length', '0.035cm'); + break; + } + $objWriter->endElement(); + $this->arrayStrokeDash[] = $shape->getBorder()->getDashStyle(); + } + } + } + + /** + * Write the default style information for a Table shape + * + * @param XMLWriter $objWriter + * @param Table $shape + */ + public function writeTableStyle(XMLWriter $objWriter, Table $shape) + { + foreach ($shape->getRows() as $row) { + foreach ($row->getCells() as $cell) { + if ($cell->getFill()->getFillType() == Fill::FILL_GRADIENT_LINEAR) { + if (!in_array($cell->getFill()->getHashCode(), $this->arrayGradient)) { + $this->writeGradientFill($objWriter, $cell->getFill()); + } + } + } + } + } + + /** + * Writes the style information for a group of shapes + * + * @param XMLWriter $objWriter + * @param Group $group + */ + public function writeGroupStyle(XMLWriter $objWriter, Group $group) + { + $shapes = $group->getShapeCollection(); + foreach ($shapes as $shape) { + if ($shape instanceof Table) { + $this->writeTableStyle($objWriter, $shape); + } elseif ($shape instanceof Group) { + $this->writeGroupStyle($objWriter, $shape); + } + } + } + + /** + * Write the gradient style + * @param XMLWriter $objWriter + * @param Fill $oFill + */ + protected function writeGradientFill(XMLWriter $objWriter, Fill $oFill) + { + $objWriter->startElement('draw:gradient'); + $objWriter->writeAttribute('draw:name', 'gradient_'.$oFill->getHashCode()); + $objWriter->writeAttribute('draw:display-name', 'gradient_'.$oFill->getHashCode()); + $objWriter->writeAttribute('draw:style', 'linear'); + $objWriter->writeAttribute('draw:start-intensity', '100%'); + $objWriter->writeAttribute('draw:end-intensity', '100%'); + $objWriter->writeAttribute('draw:start-color', '#'.$oFill->getStartColor()->getRGB()); + $objWriter->writeAttribute('draw:end-color', '#'.$oFill->getEndColor()->getRGB()); + $objWriter->writeAttribute('draw:border', '0%'); + $objWriter->writeAttribute('draw:angle', $oFill->getRotation() - 90); + $objWriter->endElement(); + $this->arrayGradient[] = $oFill->getHashCode(); + } } diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007.php b/src/PhpPowerpoint/Writer/PowerPoint2007.php index 950f527b6..d5faa7806 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007.php @@ -56,7 +56,7 @@ class PowerPoint2007 implements WriterInterface /** * Private PHPPowerPoint * - * @var PHPPowerPoint + * @var \PhpOffice\PhpPowerPoint\PhpPowerpoint */ protected $presentation; @@ -91,9 +91,9 @@ class PowerPoint2007 implements WriterInterface /** * Create a new \PhpOffice\PhpPowerpoint\Writer\PowerPoint2007 * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerpoint $pPHPPowerPoint */ - public function __construct(PHPPowerPoint $pPHPPowerPoint = null) + public function __construct(PhpPowerpoint $pPHPPowerPoint = null) { // Assign PHPPowerPoint $this->setPHPPowerPoint($pPHPPowerPoint); @@ -230,7 +230,7 @@ public function save($pFilename) foreach ($masterSlides as $masterSlide) { // Add themes to ZIP file $objZip->addFromString('ppt/theme/_rels/theme' . $masterSlide['masterid'] . '.xml.rels', $wPartRels->writeThemeRelationships($masterSlide['masterid'])); - $objZip->addFromString('ppt/theme/theme' . $masterSlide['masterid'] . '.xml', utf8_encode($wPartTheme->writeTheme($masterSlide['masterid']))); + $objZip->addFromString('ppt/theme/theme' . $masterSlide['masterid'] . '.xml', $wPartTheme->writeTheme($masterSlide['masterid'])); // Add slide masters to ZIP file $objZip->addFromString('ppt/slideMasters/_rels/slideMaster' . $masterSlide['masterid'] . '.xml.rels', $wPartRels->writeSlideMasterRelationships($masterSlide['masterid'])); $objZip->addFromString('ppt/slideMasters/slideMaster' . $masterSlide['masterid'] . '.xml', $masterSlide['body']); @@ -271,6 +271,9 @@ public function save($pFilename) // Add slide $objZip->addFromString('ppt/slides/_rels/slide' . ($i + 1) . '.xml.rels', $wPartRels->writeSlideRelationships($this->presentation->getSlide($i))); $objZip->addFromString('ppt/slides/slide' . ($i + 1) . '.xml', $wPartSlide->writeSlide($this->presentation->getSlide($i))); + if ($this->presentation->getSlide($i)->getNote()->getShapeCollection()->count() > 0) { + $objZip->addFromString('ppt/notesSlides/notesSlide' . ($i + 1) . '.xml', $wPartSlide->writeNote($this->presentation->getSlide($i)->getNote())); + } } // Add media @@ -321,7 +324,9 @@ public function save($pFilename) if (copy($pFilename, $originalFilename) === false) { throw new \Exception("Could not copy temporary zip file $pFilename to $originalFilename."); } - @unlink($pFilename); + if (@unlink($pFilename) === false) { + throw new \Exception('The file '.$pFilename.' could not be removed.'); + } } } else { throw new \Exception("PHPPowerPoint object unassigned."); @@ -346,11 +351,11 @@ public function getPHPPowerPoint() /** * Get PHPPowerPoint object * - * @param PHPPowerPoint $pPHPPowerPoint PHPPowerPoint object + * @param PhpPowerpoint $pPHPPowerPoint PhpPowerpoint object * @throws \Exception * @return \PhpOffice\PhpPowerpoint\Writer\PowerPoint2007 */ - public function setPHPPowerPoint(PHPPowerPoint $pPHPPowerPoint = null) + public function setPHPPowerPoint(PhpPowerpoint $pPHPPowerPoint = null) { $this->presentation = $pPHPPowerPoint; diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/AbstractLayoutPack.php b/src/PhpPowerpoint/Writer/PowerPoint2007/AbstractLayoutPack.php index 0e78dfebb..abfd57ad8 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/AbstractLayoutPack.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/AbstractLayoutPack.php @@ -78,6 +78,7 @@ abstract class AbstractLayoutPack * Array of slide layouts. * * These are all an array consisting of: + * - id (int) * - masterid (int) * - name (string) * - body (string) @@ -186,21 +187,19 @@ public function findLayout($name = '', $masterId = 1) } /** - * Find specific slide layout index. + * Find specific slide layout id. * * @param string $name * @param int $masterId * @return int * @throws \Exception */ - public function findLayoutIndex($name = '', $masterId = 1) + public function findLayoutId($name = '', $masterId = 1) { - $index = 0; - foreach ($this->layouts as $layout) { + foreach ($this->layouts as $layoutId => $layout) { if ($layout['name'] == $name && $layout['masterid'] == $masterId) { - return $index; + return $layoutId; } - ++$index; } throw new \Exception("Could not find slide layout $name in current layout pack."); diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/AbstractPart.php b/src/PhpPowerpoint/Writer/PowerPoint2007/AbstractPart.php index 0114aba29..fe60b7657 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/AbstractPart.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/AbstractPart.php @@ -17,7 +17,7 @@ namespace PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\Writer\WriterInterface; use PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/Chart.php b/src/PhpPowerpoint/Writer/PowerPoint2007/Chart.php index 913a93d38..0ccd8d565 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/Chart.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/Chart.php @@ -21,14 +21,19 @@ use PhpOffice\PhpPowerpoint\Shape\Chart\Legend; use PhpOffice\PhpPowerpoint\Shape\Chart\PlotArea; use PhpOffice\PhpPowerpoint\Shape\Chart\Title; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\AbstractTypeBar; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Area; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar3D; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Line; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie3D; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Scatter; use PhpOffice\PhpPowerpoint\Shape\Chart as ShapeChart; -use PhpOffice\PhpPowerpoint\Shared\Drawing as SharedDrawing; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; +use PhpOffice\Common\Drawing as CommonDrawing; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\Style\Border; +use PhpOffice\PhpPowerpoint\Style\Fill; /** * \PhpOffice\PhpPowerpoint\Writer\PowerPoint2007\Chart @@ -82,7 +87,7 @@ public function writeChart(ShapeChart $chart = null) // c:autoTitleDeleted $objWriter->startElement('c:autoTitleDeleted'); - $objWriter->writeAttribute('val', '0'); + $objWriter->writeAttribute('val', $chart->getTitle()->isVisible() ? '0' : '1'); $objWriter->endElement(); // c:view3D @@ -154,9 +159,9 @@ public function writeChart(ShapeChart $chart = null) // a:outerShdw $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', SharedDrawing::pixelsToEmu($chart->getShadow()->getBlurRadius())); - $objWriter->writeAttribute('dist', SharedDrawing::pixelsToEmu($chart->getShadow()->getDistance())); - $objWriter->writeAttribute('dir', SharedDrawing::degreesToAngle($chart->getShadow()->getDirection())); + $objWriter->writeAttribute('blurRad', CommonDrawing::pixelsToEmu($chart->getShadow()->getBlurRadius())); + $objWriter->writeAttribute('dist', CommonDrawing::pixelsToEmu($chart->getShadow()->getDistance())); + $objWriter->writeAttribute('dir', CommonDrawing::degreesToAngle($chart->getShadow()->getDirection())); $objWriter->writeAttribute('algn', $chart->getShadow()->getAlignment()); $objWriter->writeAttribute('rotWithShape', '0'); @@ -220,7 +225,7 @@ public function writeSpreadsheet(PHPPowerPoint $presentation, $chart, $tempName) } // Create new spreadsheet - $workbook = new PHPExcel(); + $workbook = new \PHPExcel(); // Set properties $title = $chart->getTitle()->getText(); @@ -241,13 +246,15 @@ public function writeSpreadsheet(PHPPowerPoint $presentation, $chart, $tempName) // X-axis $axisXData = array_keys($series->getValues()); - for ($i = 0; $i < count($axisXData); $i++) { + $numAxisXData = count($axisXData); + for ($i = 0; $i < $numAxisXData; $i++) { $sheet->setCellValueByColumnAndRow(0, $i + 2, $axisXData[$i]); } // Y-axis $axisYData = array_values($series->getValues()); - for ($i = 0; $i < count($axisYData); $i++) { + $numAxisYData = count($axisYData); + for ($i = 0; $i < $numAxisYData; $i++) { $sheet->setCellValueByColumnAndRow(1 + $seriesIndex, $i + 2, $axisYData[$i]); } @@ -255,12 +262,14 @@ public function writeSpreadsheet(PHPPowerPoint $presentation, $chart, $tempName) } // Save to string - $writer = PHPExcel_IOFactory::createWriter($workbook, 'Excel2007'); + $writer = \PHPExcel_IOFactory::createWriter($workbook, 'Excel2007'); $writer->save($tempName); // Load file in memory $returnValue = file_get_contents($tempName); - @unlink($tempName); + if (@unlink($tempName) === false) { + throw new \Exception('The file '.$tempName.' could not removed.'); + } return $returnValue; } @@ -268,7 +277,7 @@ public function writeSpreadsheet(PHPPowerPoint $presentation, $chart, $tempName) /** * Write element with value attribute * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param string $elementName * @param string $value */ @@ -282,7 +291,7 @@ protected function writeElementWithValAttribute($objWriter, $elementName, $value /** * Write single value or reference * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param boolean $isReference * @param mixed $value * @param string $reference @@ -313,7 +322,7 @@ protected function writeSingleValueOrReference($objWriter, $isReference, $value, /** * Write series value or reference * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param boolean $isReference * @param mixed $values * @param string $reference @@ -330,6 +339,7 @@ protected function writeMultipleValuesOrReference($objWriter, $isReference, $val } $objWriter->startElement('c:' . $dataType . $referenceType); + $numValues = count($values); if (!$isReference) { // Value @@ -339,7 +349,7 @@ protected function writeMultipleValuesOrReference($objWriter, $isReference, $val $objWriter->endElement(); // Add points - for ($i = 0; $i < count($values); $i++) { + for ($i = 0; $i < $numValues; $i++) { // c:pt $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $i); @@ -357,7 +367,7 @@ protected function writeMultipleValuesOrReference($objWriter, $isReference, $val $objWriter->endElement(); // Add points - for ($i = 0; $i < count($values); $i++) { + for ($i = 0; $i < $numValues; $i++) { // c:pt $objWriter->startElement('c:pt'); $objWriter->writeAttribute('idx', $i); @@ -374,7 +384,7 @@ protected function writeMultipleValuesOrReference($objWriter, $isReference, $val /** * Write Title * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Title $subject * @throws \Exception */ @@ -402,9 +412,9 @@ protected function writeTitle(XMLWriter $objWriter, Title $subject) $objWriter->startElement('a:pPr'); $objWriter->writeAttribute('algn', $subject->getAlignment()->getHorizontal()); $objWriter->writeAttribute('fontAlgn', $subject->getAlignment()->getVertical()); - $objWriter->writeAttribute('marL', SharedDrawing::pixelsToEmu($subject->getAlignment()->getMarginLeft())); - $objWriter->writeAttribute('marR', SharedDrawing::pixelsToEmu($subject->getAlignment()->getMarginRight())); - $objWriter->writeAttribute('indent', SharedDrawing::pixelsToEmu($subject->getAlignment()->getIndent())); + $objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($subject->getAlignment()->getMarginLeft())); + $objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu($subject->getAlignment()->getMarginRight())); + $objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($subject->getAlignment()->getIndent())); $objWriter->writeAttribute('lvl', $subject->getAlignment()->getLevel()); // a:defRPr @@ -482,7 +492,7 @@ protected function writeTitle(XMLWriter $objWriter, Title $subject) /** * Write Plot Area * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\Chart\PlotArea $subject * @param \PhpOffice\PhpPowerpoint\Shape\Chart $chart * @throws \Exception @@ -497,8 +507,14 @@ protected function writePlotArea(XMLWriter $objWriter, PlotArea $subject, ShapeC // Write chart $chartType = $subject->getType(); - if ($chartType instanceof Bar3D) { + if ($chartType instanceof Area) { + $this->writeTypeArea($objWriter, $chartType, $chart->hasIncludedSpreadsheet()); + } elseif ($chartType instanceof Bar) { + $this->writeTypeBar($objWriter, $chartType, $chart->hasIncludedSpreadsheet()); + } elseif ($chartType instanceof Bar3D) { $this->writeTypeBar3D($objWriter, $chartType, $chart->hasIncludedSpreadsheet()); + } elseif ($chartType instanceof Pie) { + $this->writeTypePie($objWriter, $chartType, $chart->hasIncludedSpreadsheet()); } elseif ($chartType instanceof Pie3D) { $this->writeTypePie3D($objWriter, $chartType, $chart->hasIncludedSpreadsheet()); } elseif ($chartType instanceof Line) { @@ -635,6 +651,7 @@ protected function writePlotArea(XMLWriter $objWriter, PlotArea $subject, ShapeC $objWriter->writeAttribute('val', 'minMax'); $objWriter->endElement(); + // ## c:scaling $objWriter->endElement(); // c:axPos @@ -648,10 +665,6 @@ protected function writePlotArea(XMLWriter $objWriter, PlotArea $subject, ShapeC $objWriter->writeAttribute('sourceLinked', '0'); $objWriter->endElement(); - // c:majorGridlines - //$objWriter->startElement('c:majorGridlines'); - //$objWriter->endElement(); - // c:majorTickMark $objWriter->startElement('c:majorTickMark'); $objWriter->writeAttribute('val', 'none'); @@ -680,6 +693,7 @@ protected function writePlotArea(XMLWriter $objWriter, PlotArea $subject, ShapeC // a:defRPr $objWriter->writeElement('a:defRPr', null); + // ## a:pPr $objWriter->endElement(); // a:r @@ -694,6 +708,7 @@ protected function writePlotArea(XMLWriter $objWriter, PlotArea $subject, ShapeC // a:t $objWriter->writeElement('a:t', $subject->getAxisY()->getTitle()); + // ## a:r $objWriter->endElement(); // a:endParaRPr @@ -702,8 +717,10 @@ protected function writePlotArea(XMLWriter $objWriter, PlotArea $subject, ShapeC $objWriter->writeAttribute('dirty', '0'); $objWriter->endElement(); + // ## a:p $objWriter->endElement(); + // ## c:txPr $objWriter->endElement(); // c:crossAx @@ -730,7 +747,7 @@ protected function writePlotArea(XMLWriter $objWriter, PlotArea $subject, ShapeC /** * Write Legend * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Legend $subject * @throws \Exception */ @@ -781,9 +798,9 @@ protected function writeLegend(XMLWriter $objWriter, Legend $subject) $objWriter->startElement('a:pPr'); $objWriter->writeAttribute('algn', $subject->getAlignment()->getHorizontal()); $objWriter->writeAttribute('fontAlgn', $subject->getAlignment()->getVertical()); - $objWriter->writeAttribute('marL', SharedDrawing::pixelsToEmu($subject->getAlignment()->getMarginLeft())); - $objWriter->writeAttribute('marR', SharedDrawing::pixelsToEmu($subject->getAlignment()->getMarginRight())); - $objWriter->writeAttribute('indent', SharedDrawing::pixelsToEmu($subject->getAlignment()->getIndent())); + $objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($subject->getAlignment()->getMarginLeft())); + $objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu($subject->getAlignment()->getMarginRight())); + $objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($subject->getAlignment()->getIndent())); $objWriter->writeAttribute('lvl', $subject->getAlignment()->getLevel()); // a:defRPr @@ -838,7 +855,7 @@ protected function writeLegend(XMLWriter $objWriter, Legend $subject) /** * Write Layout * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param mixed $subject * @throws \Exception */ @@ -892,26 +909,21 @@ protected function writeLayout(XMLWriter $objWriter, $subject) } /** - * Write Type Bar3D + * Write Type Line * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer - * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar3D $subject - * @param boolean $includeSheet + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer + * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Area $subject + * @param boolean $includeSheet * @throws \Exception */ - protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, $includeSheet = false) + protected function writeTypeArea(XMLWriter $objWriter, Area $subject, $includeSheet = false) { - // c:bar3DChart - $objWriter->startElement('c:bar3DChart'); - - // c:barDir - $objWriter->startElement('c:barDir'); - $objWriter->writeAttribute('val', 'col'); - $objWriter->endElement(); + // c:lineChart + $objWriter->startElement('c:areaChart'); // c:grouping $objWriter->startElement('c:grouping'); - $objWriter->writeAttribute('val', 'clustered'); + $objWriter->writeAttribute('val', 'standard'); $objWriter->endElement(); // Write series @@ -932,30 +944,10 @@ protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, $include // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); - // Fills for points? - $dataPointFills = $series->getDataPointFills(); - foreach ($dataPointFills as $key => $value) { - // c:dPt - $objWriter->startElement('c:dPt'); - - // c:idx - $this->writeElementWithValAttribute($objWriter, 'c:idx', $key); - - // c:spPr - $objWriter->startElement('c:spPr'); - - // Write fill - $this->writeFill($objWriter, $value); - - $objWriter->endElement(); - - $objWriter->endElement(); - } - // c:dLbls $objWriter->startElement('c:dLbls'); @@ -1037,13 +1029,14 @@ protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, $include $objWriter->endElement(); - // c:spPr - $objWriter->startElement('c:spPr'); - - // Write fill - $this->writeFill($objWriter, $series->getFill()); - - $objWriter->endElement(); + if ($series->getFill()->getFillType() != Fill::FILL_NONE) { + // c:spPr + $objWriter->startElement('c:spPr'); + // Write fill + $this->writeFill($objWriter, $series->getFill()); + // ## c:spPr + $objWriter->endElement(); + } // Write X axis data $axisXData = array_keys($series->getValues()); @@ -1058,23 +1051,23 @@ protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, $include // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); - + $objWriter->endElement(); ++$seriesIndex; } - // c:gapWidth - $objWriter->startElement('c:gapWidth'); - $objWriter->writeAttribute('val', '75'); + // c:marker + $objWriter->startElement('c:marker'); + $objWriter->writeAttribute('val', '1'); $objWriter->endElement(); - // c:shape - $objWriter->startElement('c:shape'); - $objWriter->writeAttribute('val', 'box'); + // c:smooth + $objWriter->startElement('c:smooth'); + $objWriter->writeAttribute('val', '0'); $objWriter->endElement(); // c:axId @@ -1087,30 +1080,31 @@ protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, $include $objWriter->writeAttribute('val', '52749440'); $objWriter->endElement(); - // c:axId - $objWriter->startElement('c:axId'); - $objWriter->writeAttribute('val', '0'); - $objWriter->endElement(); - $objWriter->endElement(); } + /** - * Write Type Pie3D + * Write Type Bar3D * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer - * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie3D $subject + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer + * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar $subject * @param boolean $includeSheet * @throws \Exception */ - protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, $includeSheet = false) + protected function writeTypeBar(XMLWriter $objWriter, Bar $subject, $includeSheet = false) { - // c:pie3DChart - $objWriter->startElement('c:pie3DChart'); + // c:bar3DChart + $objWriter->startElement('c:barChart'); - // c:varyColors - $objWriter->startElement('c:varyColors'); - $objWriter->writeAttribute('val', '1'); + // c:barDir + $objWriter->startElement('c:barDir'); + $objWriter->writeAttribute('val', $subject->getBarDirection()); + $objWriter->endElement(); + + // c:grouping + $objWriter->startElement('c:grouping'); + $objWriter->writeAttribute('val', $subject->getBarGrouping()); $objWriter->endElement(); // Write series @@ -1131,15 +1125,10 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, $include // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); - // c:explosion - $objWriter->startElement('c:explosion'); - $objWriter->writeAttribute('val', '20'); - $objWriter->endElement(); - // Fills for points? $dataPointFills = $series->getDataPointFills(); foreach ($dataPointFills as $key => $value) { @@ -1149,20 +1138,30 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, $include // c:idx $this->writeElementWithValAttribute($objWriter, 'c:idx', $key); - // c:spPr - $objWriter->startElement('c:spPr'); - - // Write fill - $this->writeFill($objWriter, $value); - - $objWriter->endElement(); + if ($value->getFillType() != Fill::FILL_NONE) { + // c:spPr + $objWriter->startElement('c:spPr'); + // Write fill + $this->writeFill($objWriter, $value); + // ## c:spPr + $objWriter->endElement(); + } + // ## c:dPt $objWriter->endElement(); } // c:dLbls $objWriter->startElement('c:dLbls'); + if ($series->hasDlblNumFormat()) { + //c:numFmt + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', $series->getDlblNumFormat()); + $objWriter->writeAttribute('sourceLinked', '0'); + $objWriter->endElement(); + } + // c:txPr $objWriter->startElement('c:txPr'); @@ -1224,9 +1223,6 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, $include $objWriter->endElement(); - // c:dLblPos - $this->writeElementWithValAttribute($objWriter, 'c:dLblPos', $series->getLabelPosition()); - // c:showVal $this->writeElementWithValAttribute($objWriter, 'c:showVal', $series->hasShowValue() ? '1' : '0'); @@ -1244,6 +1240,16 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, $include $objWriter->endElement(); + // c:spPr + if ($series->getFill()->getFillType() != Fill::FILL_NONE) { + // c:spPr + $objWriter->startElement('c:spPr'); + // Write fill + $this->writeFill($objWriter, $series->getFill()); + // ## c:spPr + $objWriter->endElement(); + } + // Write X axis data $axisXData = array_keys($series->getValues()); @@ -1257,7 +1263,7 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, $include // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); @@ -1266,30 +1272,64 @@ protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, $include ++$seriesIndex; } + // c:overlap + $objWriter->startElement('c:overlap'); + if ($subject->getBarGrouping() == Bar::GROUPING_CLUSTERED) { + $objWriter->writeAttribute('val', '0'); + } elseif ($subject->getBarGrouping() == Bar::GROUPING_STACKED || $subject->getBarGrouping() == Bar::GROUPING_PERCENTSTACKED) { + $objWriter->writeAttribute('val', '100'); + } + $objWriter->endElement(); + + // c:gapWidth + $objWriter->startElement('c:gapWidth'); + $objWriter->writeAttribute('val', '75'); + $objWriter->endElement(); + + // c:shape + $objWriter->startElement('c:shape'); + $objWriter->writeAttribute('val', 'box'); + $objWriter->endElement(); + + // c:axId + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', '52743552'); + $objWriter->endElement(); + + // c:axId + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', '52749440'); + $objWriter->endElement(); + + // c:axId + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', '0'); + $objWriter->endElement(); + $objWriter->endElement(); } /** - * Write Type Line + * Write Type Bar3D * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer - * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Line $subject - * @param boolean $includeSheet + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer + * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar3D $subject + * @param boolean $includeSheet * @throws \Exception */ - protected function writeTypeLine(XMLWriter $objWriter, Line $subject, $includeSheet = false) + protected function writeTypeBar3D(XMLWriter $objWriter, Bar3D $subject, $includeSheet = false) { - // c:lineChart - $objWriter->startElement('c:lineChart'); + // c:bar3DChart + $objWriter->startElement('c:bar3DChart'); - // c:grouping - $objWriter->startElement('c:grouping'); - $objWriter->writeAttribute('val', 'standard'); + // c:barDir + $objWriter->startElement('c:barDir'); + $objWriter->writeAttribute('val', $subject->getBarDirection()); $objWriter->endElement(); - // c:varyColors - $objWriter->startElement('c:varyColors'); - $objWriter->writeAttribute('val', '0'); + // c:grouping + $objWriter->startElement('c:grouping'); + $objWriter->writeAttribute('val', $subject->getBarGrouping()); $objWriter->endElement(); // Write series @@ -1310,10 +1350,32 @@ protected function writeTypeLine(XMLWriter $objWriter, Line $subject, $includeSh // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); + // Fills for points? + $dataPointFills = $series->getDataPointFills(); + foreach ($dataPointFills as $key => $value) { + // c:dPt + $objWriter->startElement('c:dPt'); + + // c:idx + $this->writeElementWithValAttribute($objWriter, 'c:idx', $key); + + if ($value->getFillType() != Fill::FILL_NONE) { + // c:spPr + $objWriter->startElement('c:spPr'); + // Write fill + $this->writeFill($objWriter, $value); + // ## c:spPr + $objWriter->endElement(); + } + + // ## c:dPt + $objWriter->endElement(); + } + // c:dLbls $objWriter->startElement('c:dLbls'); @@ -1395,13 +1457,15 @@ protected function writeTypeLine(XMLWriter $objWriter, Line $subject, $includeSh $objWriter->endElement(); - // c:spPr - $objWriter->startElement('c:spPr'); - - // Write fill - $this->writeFill($objWriter, $series->getFill()); - - $objWriter->endElement(); + // c:spPr + if ($series->getFill()->getFillType() != Fill::FILL_NONE) { + // c:spPr + $objWriter->startElement('c:spPr'); + // Write fill + $this->writeFill($objWriter, $series->getFill()); + // ## c:spPr + $objWriter->endElement(); + } // Write X axis data $axisXData = array_keys($series->getValues()); @@ -1416,23 +1480,23 @@ protected function writeTypeLine(XMLWriter $objWriter, Line $subject, $includeSh // c:val $objWriter->startElement('c:val'); - $coords = ($includeSheet ? 'Sheet1!$' . PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); - + $objWriter->endElement(); ++$seriesIndex; } - // c:marker - $objWriter->startElement('c:marker'); - $objWriter->writeAttribute('val', '1'); + // c:gapWidth + $objWriter->startElement('c:gapWidth'); + $objWriter->writeAttribute('val', '75'); $objWriter->endElement(); - // c:smooth - $objWriter->startElement('c:smooth'); - $objWriter->writeAttribute('val', '0'); + // c:shape + $objWriter->startElement('c:shape'); + $objWriter->writeAttribute('val', 'box'); $objWriter->endElement(); // c:axId @@ -1454,26 +1518,21 @@ protected function writeTypeLine(XMLWriter $objWriter, Line $subject, $includeSh } /** - * Write Type Scatter + * Write Type Pie * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer - * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Scatter $subject - * @param boolean $includeSheet + * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie $subject + * @param boolean $includeSheet * @throws \Exception */ - protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, $includeSheet = false) + protected function writeTypePie(XMLWriter $objWriter, Pie $subject, $includeSheet = false) { - // c:scatterChart - $objWriter->startElement('c:scatterChart'); - - // c:scatterStyle - $objWriter->startElement('c:scatterStyle'); - $objWriter->writeAttribute('val', 'lineMarker'); - $objWriter->endElement(); + // c:pieChart + $objWriter->startElement('c:pieChart'); // c:varyColors $objWriter->startElement('c:varyColors'); - $objWriter->writeAttribute('val', '0'); + $objWriter->writeAttribute('val', '1'); $objWriter->endElement(); // Write series @@ -1494,21 +1553,30 @@ protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, $inc // c:tx $objWriter->startElement('c:tx'); - $coords = ($includeSheet ? 'Sheet1!$' . PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); $objWriter->endElement(); - // c:marker - $objWriter->startElement('c:marker'); + // Fills for points? + $dataPointFills = $series->getDataPointFills(); + foreach ($dataPointFills as $key => $value) { + // c:dPt + $objWriter->startElement('c:dPt'); - // c:marker - $objWriter->startElement('c:symbol'); - $objWriter->writeAttribute('val', 'none'); // Marker style - //$objWriter->writeAttribute('size', '7'); // Marker size - $objWriter->endElement(); + // c:idx + $this->writeElementWithValAttribute($objWriter, 'c:idx', $key); + + // c:spPr + $objWriter->startElement('c:spPr'); + + // Write fill + $this->writeFill($objWriter, $value); + + $objWriter->endElement(); + + $objWriter->endElement(); + } - $objWriter->endElement(); - // c:dLbls $objWriter->startElement('c:dLbls'); @@ -1573,8 +1641,8 @@ protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, $inc $objWriter->endElement(); - // c:showLegendKey - $this->writeElementWithValAttribute($objWriter, 'c:showLegendKey', '0'); + // c:dLblPos + $this->writeElementWithValAttribute($objWriter, 'c:dLblPos', $series->getLabelPosition()); // c:showVal $this->writeElementWithValAttribute($objWriter, 'c:showVal', $series->hasShowValue() ? '1' : '0'); @@ -1592,15 +1660,530 @@ protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, $inc $this->writeElementWithValAttribute($objWriter, 'c:showLeaderLines', $series->hasShowLeaderLines() ? '1' : '0'); $objWriter->endElement(); - /* - // c:spPr - $objWriter->startElement('c:spPr'); - // Write fill - $this->writeFill($objWriter, $series->getFill()); + // Write X axis data + $axisXData = array_keys($series->getValues()); + // c:cat + $objWriter->startElement('c:cat'); + $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisXData, 'Sheet1!$A$2:$A$' . (1 + count($axisXData))); $objWriter->endElement(); - */ + + // Write Y axis data + $axisYData = array_values($series->getValues()); + + // c:val + $objWriter->startElement('c:val'); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); + $objWriter->endElement(); + + $objWriter->endElement(); + + ++$seriesIndex; + } + + $objWriter->endElement(); + } + + /** + * Write Type Pie3D + * + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer + * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie3D $subject + * @param boolean $includeSheet + * @throws \Exception + */ + protected function writeTypePie3D(XMLWriter $objWriter, Pie3D $subject, $includeSheet = false) + { + // c:pie3DChart + $objWriter->startElement('c:pie3DChart'); + + // c:varyColors + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', '1'); + $objWriter->endElement(); + + // Write series + $seriesIndex = 0; + foreach ($subject->getData() as $series) { + // c:ser + $objWriter->startElement('c:ser'); + + // c:idx + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', $seriesIndex); + $objWriter->endElement(); + + // c:order + $objWriter->startElement('c:order'); + $objWriter->writeAttribute('val', $seriesIndex); + $objWriter->endElement(); + + // c:tx + $objWriter->startElement('c:tx'); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); + $objWriter->endElement(); + + // c:explosion + $objWriter->startElement('c:explosion'); + $objWriter->writeAttribute('val', $subject->getExplosion()); + $objWriter->endElement(); + + // Fills for points? + $dataPointFills = $series->getDataPointFills(); + foreach ($dataPointFills as $key => $value) { + // c:dPt + $objWriter->startElement('c:dPt'); + + // c:idx + $this->writeElementWithValAttribute($objWriter, 'c:idx', $key); + + // c:spPr + $objWriter->startElement('c:spPr'); + + // Write fill + $this->writeFill($objWriter, $value); + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + // c:dLbls + $objWriter->startElement('c:dLbls'); + + // c:txPr + $objWriter->startElement('c:txPr'); + + // a:bodyPr + $objWriter->writeElement('a:bodyPr', null); + + // a:lstStyle + $objWriter->writeElement('a:lstStyle', null); + + // a:p + $objWriter->startElement('a:p'); + + // a:pPr + $objWriter->startElement('a:pPr'); + + // a:defRPr + $objWriter->startElement('a:defRPr'); + + $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); + $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); + $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); + $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); + + if ($series->getFont()->isSuperScript() || $series->getFont()->isSubScript()) { + if ($series->getFont()->isSuperScript()) { + $objWriter->writeAttribute('baseline', '30000'); + } elseif ($series->getFont()->isSubScript()) { + $objWriter->writeAttribute('baseline', '-25000'); + } + } + + // Font - a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $series->getFont()->getColor()->getRGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Font - a:latin + $objWriter->startElement('a:latin'); + $objWriter->writeAttribute('typeface', $series->getFont()->getName()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:endParaRPr + $objWriter->startElement('a:endParaRPr'); + $objWriter->writeAttribute('lang', 'en-US'); + $objWriter->writeAttribute('dirty', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // c:dLblPos + $this->writeElementWithValAttribute($objWriter, 'c:dLblPos', $series->getLabelPosition()); + + // c:showVal + $this->writeElementWithValAttribute($objWriter, 'c:showVal', $series->hasShowValue() ? '1' : '0'); + + // c:showCatName + $this->writeElementWithValAttribute($objWriter, 'c:showCatName', $series->hasShowCategoryName() ? '1' : '0'); + + // c:showSerName + $this->writeElementWithValAttribute($objWriter, 'c:showSerName', $series->hasShowSeriesName() ? '1' : '0'); + + // c:showPercent + $this->writeElementWithValAttribute($objWriter, 'c:showPercent', $series->hasShowPercentage() ? '1' : '0'); + + // c:showLeaderLines + $this->writeElementWithValAttribute($objWriter, 'c:showLeaderLines', $series->hasShowLeaderLines() ? '1' : '0'); + + $objWriter->endElement(); + + // Write X axis data + $axisXData = array_keys($series->getValues()); + + // c:cat + $objWriter->startElement('c:cat'); + $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisXData, 'Sheet1!$A$2:$A$' . (1 + count($axisXData))); + $objWriter->endElement(); + + // Write Y axis data + $axisYData = array_values($series->getValues()); + + // c:val + $objWriter->startElement('c:val'); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); + $objWriter->endElement(); + + $objWriter->endElement(); + + ++$seriesIndex; + } + + $objWriter->endElement(); + } + + /** + * Write Type Line + * + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer + * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Line $subject + * @param boolean $includeSheet + * @throws \Exception + */ + protected function writeTypeLine(XMLWriter $objWriter, Line $subject, $includeSheet = false) + { + // c:lineChart + $objWriter->startElement('c:lineChart'); + + // c:grouping + $objWriter->startElement('c:grouping'); + $objWriter->writeAttribute('val', 'standard'); + $objWriter->endElement(); + + // Write series + $seriesIndex = 0; + foreach ($subject->getData() as $series) { + // c:ser + $objWriter->startElement('c:ser'); + + // c:idx + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', $seriesIndex); + $objWriter->endElement(); + + // c:order + $objWriter->startElement('c:order'); + $objWriter->writeAttribute('val', $seriesIndex); + $objWriter->endElement(); + + // c:tx + $objWriter->startElement('c:tx'); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); + $objWriter->endElement(); + + // c:dLbls + $objWriter->startElement('c:dLbls'); + + // c:txPr + $objWriter->startElement('c:txPr'); + + // a:bodyPr + $objWriter->writeElement('a:bodyPr', null); + + // a:lstStyle + $objWriter->writeElement('a:lstStyle', null); + + // a:p + $objWriter->startElement('a:p'); + + // a:pPr + $objWriter->startElement('a:pPr'); + + // a:defRPr + $objWriter->startElement('a:defRPr'); + + $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); + $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); + $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); + $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); + + if ($series->getFont()->isSuperScript() || $series->getFont()->isSubScript()) { + if ($series->getFont()->isSuperScript()) { + $objWriter->writeAttribute('baseline', '30000'); + } elseif ($series->getFont()->isSubScript()) { + $objWriter->writeAttribute('baseline', '-25000'); + } + } + + // Font - a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $series->getFont()->getColor()->getRGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Font - a:latin + $objWriter->startElement('a:latin'); + $objWriter->writeAttribute('typeface', $series->getFont()->getName()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:endParaRPr + $objWriter->startElement('a:endParaRPr'); + $objWriter->writeAttribute('lang', 'en-US'); + $objWriter->writeAttribute('dirty', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // c:showVal + $this->writeElementWithValAttribute($objWriter, 'c:showVal', $series->hasShowValue() ? '1' : '0'); + + // c:showCatName + $this->writeElementWithValAttribute($objWriter, 'c:showCatName', $series->hasShowCategoryName() ? '1' : '0'); + + // c:showSerName + $this->writeElementWithValAttribute($objWriter, 'c:showSerName', $series->hasShowSeriesName() ? '1' : '0'); + + // c:showPercent + $this->writeElementWithValAttribute($objWriter, 'c:showPercent', $series->hasShowPercentage() ? '1' : '0'); + + // c:showLeaderLines + $this->writeElementWithValAttribute($objWriter, 'c:showLeaderLines', $series->hasShowLeaderLines() ? '1' : '0'); + + $objWriter->endElement(); + + if ($series->getFill()->getFillType() != Fill::FILL_NONE) { + // c:spPr + $objWriter->startElement('c:spPr'); + // Write fill + $this->writeFill($objWriter, $series->getFill()); + // ## c:spPr + $objWriter->endElement(); + } + + // Write X axis data + $axisXData = array_keys($series->getValues()); + + // c:cat + $objWriter->startElement('c:cat'); + $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisXData, 'Sheet1!$A$2:$A$' . (1 + count($axisXData))); + $objWriter->endElement(); + + // Write Y axis data + $axisYData = array_values($series->getValues()); + + // c:val + $objWriter->startElement('c:val'); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); + $objWriter->endElement(); + + $objWriter->endElement(); + + ++$seriesIndex; + } + + // c:marker + $objWriter->startElement('c:marker'); + $objWriter->writeAttribute('val', '1'); + $objWriter->endElement(); + + // c:smooth + $objWriter->startElement('c:smooth'); + $objWriter->writeAttribute('val', '0'); + $objWriter->endElement(); + + // c:axId + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', '52743552'); + $objWriter->endElement(); + + // c:axId + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', '52749440'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Type Scatter + * + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer + * @param \PhpOffice\PhpPowerpoint\Shape\Chart\Type\Scatter $subject + * @param boolean $includeSheet + * @throws \Exception + */ + protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, $includeSheet = false) + { + // c:scatterChart + $objWriter->startElement('c:scatterChart'); + + // c:scatterStyle + $objWriter->startElement('c:scatterStyle'); + $objWriter->writeAttribute('val', 'lineMarker'); + $objWriter->endElement(); + + // c:varyColors + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', '0'); + $objWriter->endElement(); + + // Write series + $seriesIndex = 0; + foreach ($subject->getData() as $series) { + // c:ser + $objWriter->startElement('c:ser'); + + // c:idx + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', $seriesIndex); + $objWriter->endElement(); + + // c:order + $objWriter->startElement('c:order'); + $objWriter->writeAttribute('val', $seriesIndex); + $objWriter->endElement(); + + // c:tx + $objWriter->startElement('c:tx'); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex(1 + $seriesIndex) . '$1' : ''); + $this->writeSingleValueOrReference($objWriter, $includeSheet, $series->getTitle(), $coords); + $objWriter->endElement(); + + // c:marker + $objWriter->startElement('c:marker'); + + // c:marker + $objWriter->startElement('c:symbol'); + $objWriter->writeAttribute('val', 'none'); // Marker style + //$objWriter->writeAttribute('size', '7'); // Marker size + $objWriter->endElement(); + + $objWriter->endElement(); + + // c:dLbls + $objWriter->startElement('c:dLbls'); + + // c:txPr + $objWriter->startElement('c:txPr'); + + // a:bodyPr + $objWriter->writeElement('a:bodyPr', null); + + // a:lstStyle + $objWriter->writeElement('a:lstStyle', null); + + // a:p + $objWriter->startElement('a:p'); + + // a:pPr + $objWriter->startElement('a:pPr'); + + // a:defRPr + $objWriter->startElement('a:defRPr'); + + $objWriter->writeAttribute('b', ($series->getFont()->isBold() ? 'true' : 'false')); + $objWriter->writeAttribute('i', ($series->getFont()->isItalic() ? 'true' : 'false')); + $objWriter->writeAttribute('strike', ($series->getFont()->isStrikethrough() ? 'sngStrike' : 'noStrike')); + $objWriter->writeAttribute('sz', ($series->getFont()->getSize() * 100)); + $objWriter->writeAttribute('u', $series->getFont()->getUnderline()); + + if ($series->getFont()->isSuperScript() || $series->getFont()->isSubScript()) { + if ($series->getFont()->isSuperScript()) { + $objWriter->writeAttribute('baseline', '30000'); + } elseif ($series->getFont()->isSubScript()) { + $objWriter->writeAttribute('baseline', '-25000'); + } + } + + // Font - a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $series->getFont()->getColor()->getRGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Font - a:latin + $objWriter->startElement('a:latin'); + $objWriter->writeAttribute('typeface', $series->getFont()->getName()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:endParaRPr + $objWriter->startElement('a:endParaRPr'); + $objWriter->writeAttribute('lang', 'en-US'); + $objWriter->writeAttribute('dirty', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // c:showLegendKey + $this->writeElementWithValAttribute($objWriter, 'c:showLegendKey', '0'); + + // c:showVal + $this->writeElementWithValAttribute($objWriter, 'c:showVal', $series->hasShowValue() ? '1' : '0'); + + // c:showCatName + $this->writeElementWithValAttribute($objWriter, 'c:showCatName', $series->hasShowCategoryName() ? '1' : '0'); + + // c:showSerName + $this->writeElementWithValAttribute($objWriter, 'c:showSerName', $series->hasShowSeriesName() ? '1' : '0'); + + // c:showPercent + $this->writeElementWithValAttribute($objWriter, 'c:showPercent', $series->hasShowPercentage() ? '1' : '0'); + + // c:showLeaderLines + $this->writeElementWithValAttribute($objWriter, 'c:showLeaderLines', $series->hasShowLeaderLines() ? '1' : '0'); + + $objWriter->endElement(); + + if ($series->getFill()->getFillType() != Fill::FILL_NONE) { + // c:spPr + $objWriter->startElement('c:spPr'); + // Write fill + $this->writeFill($objWriter, $series->getFill()); + // ## c:spPr + $objWriter->endElement(); + } + // Write X axis data $axisXData = array_keys($series->getValues()); @@ -1614,7 +2197,7 @@ protected function writeTypeScatter(XMLWriter $objWriter, Scatter $subject, $inc // c:yVal $objWriter->startElement('c:yVal'); - $coords = ($includeSheet ? 'Sheet1!$' . PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); + $coords = ($includeSheet ? 'Sheet1!$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$2:$' . \PHPExcel_Cell::stringFromColumnIndex($seriesIndex + 1) . '$' . (1 + count($axisYData)) : ''); $this->writeMultipleValuesOrReference($objWriter, $includeSheet, $axisYData, $coords); $objWriter->endElement(); diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/ContentTypes.php b/src/PhpPowerpoint/Writer/PowerPoint2007/ContentTypes.php index cd476557a..69f179681 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/ContentTypes.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/ContentTypes.php @@ -21,8 +21,8 @@ use PhpOffice\PhpPowerpoint\Shape\Chart as ShapeChart; use PhpOffice\PhpPowerpoint\Shape\Drawing as ShapeDrawing; use PhpOffice\PhpPowerpoint\Shape\MemoryDrawing; -use PhpOffice\PhpPowerpoint\Shared\File; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; +use PhpOffice\Common\File; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; /** @@ -33,11 +33,11 @@ class ContentTypes extends AbstractPart /** * Write content types to XML format * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerpoint $pPHPPowerPoint * @return string XML Output * @throws \Exception */ - public function writeContentTypes(PHPPowerPoint $pPHPPowerPoint = null) + public function writeContentTypes(PhpPowerpoint $pPHPPowerPoint) { $parentWriter = $this->getParentWriter(); if (!$parentWriter instanceof PowerPoint2007) { @@ -85,7 +85,8 @@ public function writeContentTypes(PHPPowerPoint $pPHPPowerPoint = null) // Slide layouts $slideLayouts = $parentWriter->getLayoutPack()->getLayouts(); - for ($i = 0; $i < count($slideLayouts); ++$i) { + $numSlideLayouts = count($slideLayouts); + for ($i = 0; $i < $numSlideLayouts; ++$i) { $this->writeOverrideContentType($objWriter, '/ppt/slideLayouts/slideLayout' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml'); } @@ -93,6 +94,9 @@ public function writeContentTypes(PHPPowerPoint $pPHPPowerPoint = null) $slideCount = $pPHPPowerPoint->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { $this->writeOverrideContentType($objWriter, '/ppt/slides/slide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml'); + if ($pPHPPowerPoint->getSlide($i)->getNote()->getShapeCollection()->count() > 0) { + $this->writeOverrideContentType($objWriter, '/ppt/notesSlides/notesSlide' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml'); + } } // Add layoutpack content types @@ -196,7 +200,7 @@ private function getImageMimeType($pFile = '') /** * Write Default content type * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param string $pPartname Part name * @param string $pContentType Content type * @throws \Exception @@ -217,7 +221,7 @@ private function writeDefaultContentType(XMLWriter $objWriter, $pPartname = '', /** * Write Override content type * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param string $pPartname Part name * @param string $pContentType Content type * @throws \Exception diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/DocProps.php b/src/PhpPowerpoint/Writer/PowerPoint2007/DocProps.php index fabe96ceb..3cae3cafb 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/DocProps.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/DocProps.php @@ -27,11 +27,11 @@ class DocProps extends AbstractPart /** * Write docProps/app.xml to XML format * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerpoint $pPHPPowerPoint * @return string XML Output * @throws \Exception */ - public function writeDocPropsApp(PHPPowerPoint $pPHPPowerPoint = null) + public function writeDocPropsApp(PhpPowerpoint $pPHPPowerPoint) { // Create XML writer $objWriter = $this->getXMLWriter(); @@ -123,11 +123,11 @@ public function writeDocPropsApp(PHPPowerPoint $pPHPPowerPoint = null) /** * Write docProps/core.xml to XML format * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerpoint $pPHPPowerPoint * @return string XML Output * @throws \Exception */ - public function writeDocPropsCore(PHPPowerPoint $pPHPPowerPoint = null) + public function writeDocPropsCore(PhpPowerpoint $pPHPPowerPoint) { // Create XML writer $objWriter = $this->getXMLWriter(); diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/Drawing.php b/src/PhpPowerpoint/Writer/PowerPoint2007/Drawing.php index fa49339d3..0f59a733d 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/Drawing.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/Drawing.php @@ -19,6 +19,7 @@ use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\AbstractDrawing; +use PhpOffice\PhpPowerpoint\Shape\Group; use PhpOffice\PhpPowerpoint\Shape\Table; /** @@ -29,11 +30,11 @@ class Drawing extends AbstractPart /** * Get an array of all drawings * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerpoint $pPHPPowerPoint * @return \PhpOffice\PhpPowerpoint\Shape\AbstractDrawing[] All drawings in PHPPowerPoint * @throws \Exception */ - public function allDrawings(PHPPowerPoint $pPHPPowerPoint = null) + public function allDrawings(PhpPowerpoint $pPHPPowerPoint) { // Get an array of all drawings $aDrawings = array(); @@ -46,6 +47,14 @@ public function allDrawings(PHPPowerPoint $pPHPPowerPoint = null) while ($iterator->valid()) { if ($iterator->current() instanceof AbstractDrawing && !($iterator->current() instanceof Table)) { $aDrawings[] = $iterator->current(); + } elseif ($iterator->current() instanceof Group) { + $iterator2 = $iterator->current()->getShapeCollection()->getIterator(); + while ($iterator2->valid()) { + if ($iterator2->current() instanceof AbstractDrawing && !($iterator2->current() instanceof Table)) { + $aDrawings[] = $iterator2->current(); + } + $iterator2->next(); + } } $iterator->next(); diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/LayoutPack/PackDefault.php b/src/PhpPowerpoint/Writer/PowerPoint2007/LayoutPack/PackDefault.php index 5e988726d..c37a67964 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/LayoutPack/PackDefault.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/LayoutPack/PackDefault.php @@ -82,7 +82,7 @@ public function __construct() - + Click to edit Master title style @@ -116,35 +116,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -185,7 +185,7 @@ public function __construct() - + 16/04/2009 @@ -263,7 +263,7 @@ public function __construct() - + <#> @@ -593,10 +593,10 @@ public function __construct() - - - - + + + + @@ -627,10 +627,10 @@ public function __construct() - - - - + + + + @@ -876,7 +876,7 @@ public function __construct() - + Click to edit Master title style @@ -995,7 +995,7 @@ public function __construct() - + Click to edit Master subtitle style @@ -1018,7 +1018,7 @@ public function __construct() - + 16/04/2009 @@ -1060,7 +1060,7 @@ public function __construct() - + ?#? @@ -1111,7 +1111,7 @@ public function __construct() - + Click to edit Master title style @@ -1135,35 +1135,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -1186,7 +1186,7 @@ public function __construct() - + 16/04/2009 @@ -1228,7 +1228,7 @@ public function __construct() - + ?#? @@ -1288,7 +1288,7 @@ public function __construct() - + Click to edit Master title style @@ -1408,7 +1408,7 @@ public function __construct() - + Click to edit Master text styles @@ -1430,7 +1430,7 @@ public function __construct() - + 16/04/2009 @@ -1472,7 +1472,7 @@ public function __construct() - + ?#? @@ -1523,7 +1523,7 @@ public function __construct() - + Click to edit Master title style @@ -1580,35 +1580,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -1665,35 +1665,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -1716,7 +1716,7 @@ public function __construct() - + 16/04/2009 @@ -1758,7 +1758,7 @@ public function __construct() - + ?#? @@ -1813,7 +1813,7 @@ public function __construct() - + Click to edit Master title style @@ -1879,7 +1879,7 @@ public function __construct() - + Click to edit Master text styles @@ -1935,35 +1935,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -2029,7 +2029,7 @@ public function __construct() - + Click to edit Master text styles @@ -2085,35 +2085,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -2136,7 +2136,7 @@ public function __construct() - + 16/04/2009 @@ -2178,7 +2178,7 @@ public function __construct() - + ?#? @@ -2229,7 +2229,7 @@ public function __construct() - + Click to edit Master title style @@ -2252,7 +2252,7 @@ public function __construct() - + 16/04/2009 @@ -2294,7 +2294,7 @@ public function __construct() - + ?#? @@ -2345,7 +2345,7 @@ public function __construct() - + 16/04/2009 @@ -2387,7 +2387,7 @@ public function __construct() - + ?#? @@ -2447,7 +2447,7 @@ public function __construct() - + Click to edit Master title style @@ -2504,35 +2504,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -2598,7 +2598,7 @@ public function __construct() - + Click to edit Master text styles @@ -2620,7 +2620,7 @@ public function __construct() - + 16/04/2009 @@ -2662,7 +2662,7 @@ public function __construct() - + ?#? @@ -2722,7 +2722,7 @@ public function __construct() - + Click to edit Master title style @@ -2849,7 +2849,7 @@ public function __construct() - + Click to edit Master text styles @@ -2871,7 +2871,7 @@ public function __construct() - + 16/04/2009 @@ -2913,7 +2913,7 @@ public function __construct() - + ?#? @@ -2964,7 +2964,7 @@ public function __construct() - + Click to edit Master title style @@ -2988,35 +2988,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -3039,7 +3039,7 @@ public function __construct() - + 16/04/2009 @@ -3081,7 +3081,7 @@ public function __construct() - + ?#? @@ -3137,7 +3137,7 @@ public function __construct() - + Click to edit Master title style @@ -3166,35 +3166,35 @@ public function __construct() - + Click to edit Master text styles - + Second level - + Third level - + Fourth level - + Fifth level @@ -3217,7 +3217,7 @@ public function __construct() - + 16/04/2009 @@ -3259,7 +3259,7 @@ public function __construct() - + ?#? diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/LayoutPack/TemplateBased.php b/src/PhpPowerpoint/Writer/PowerPoint2007/LayoutPack/TemplateBased.php index bf370c220..e22d880a6 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/LayoutPack/TemplateBased.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/LayoutPack/TemplateBased.php @@ -97,9 +97,10 @@ public function __construct($fileName = '') // Found slide layout! $layoutId = str_replace('slideLayout', '', basename($masterRel["Target"], '.xml')); $layout = array( - 'masterid' => $slideMasterId, - 'name' => '-unknown-', - 'body' => $package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/" . basename($masterRel["Target"]))) + 'id' => $layoutId, + 'masterid' => $slideMasterId, + 'name' => '-unknown-', + 'body' => $package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($presRel["Target"]) . "/" . dirname($masterRel["Target"]) . "/" . basename($masterRel["Target"]))) ); if (utf8_encode(utf8_decode($layout['body'])) == $layout['body']) { $layoutXml = simplexml_load_string($layout['body']); diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/PptProps.php b/src/PhpPowerpoint/Writer/PowerPoint2007/PptProps.php index bddfa12ce..ad5d268aa 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/PptProps.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/PptProps.php @@ -24,7 +24,6 @@ class PptProps extends AbstractPart /** * Write ppt/presProps.xml to XML format * - * @param PhpPowerpoint $pPHPPowerPoint * @return string XML Output * @throws \Exception */ @@ -81,7 +80,6 @@ public function writePresProps() /** * Write ppt/tableStyles.xml to XML format * - * @param PhpPowerpoint $pPHPPowerPoint * @return string XML Output * @throws \Exception */ @@ -104,7 +102,6 @@ public function writeTableStyles() /** * Write ppt/viewProps.xml to XML format * - * @param PhpPowerpoint $pPHPPowerPoint * @return string XML Output * @throws \Exception */ diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/Presentation.php b/src/PhpPowerpoint/Writer/PowerPoint2007/Presentation.php index 59544f401..746139ee8 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/Presentation.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/Presentation.php @@ -17,9 +17,9 @@ namespace PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\DocumentLayout; use PhpOffice\PhpPowerpoint\PhpPowerpoint; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; use PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; /** @@ -30,11 +30,11 @@ class Presentation extends AbstractPart /** * Write presentation to XML format * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerpoint $pPHPPowerPoint * @return string XML Output * @throws \Exception */ - public function writePresentation(PHPPowerPoint $pPHPPowerPoint = null) + public function writePresentation(PhpPowerpoint $pPHPPowerPoint) { // Create XML writer $objWriter = $this->getXMLWriter(); @@ -82,8 +82,6 @@ public function writePresentation(PHPPowerPoint $pPHPPowerPoint = null) // p:sldSz $objWriter->startElement('p:sldSz'); - //$objWriter->writeAttribute('cx', '9144000'); - //$objWriter->writeAttribute('cy', '6858000'); $objWriter->writeAttribute('cx', $pPHPPowerPoint->getLayout()->getCX()); $objWriter->writeAttribute('cy', $pPHPPowerPoint->getLayout()->getCY()); if ($pPHPPowerPoint->getLayout()->getDocumentLayout() != DocumentLayout::LAYOUT_CUSTOM) { @@ -106,12 +104,12 @@ public function writePresentation(PHPPowerPoint $pPHPPowerPoint = null) /** * Write slides * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer - * @param PHPPowerPoint $pPHPPowerPoint + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer + * @param PhpPowerpoint $pPHPPowerPoint * @param int $startRelationId * @throws \Exception */ - private function writeSlides(XMLWriter $objWriter, PHPPowerPoint $pPHPPowerPoint = null, $startRelationId = 2) + private function writeSlides(XMLWriter $objWriter, PhpPowerpoint $pPHPPowerPoint, $startRelationId = 2) { // Write slides $slideCount = $pPHPPowerPoint->getSlideCount(); @@ -124,7 +122,7 @@ private function writeSlides(XMLWriter $objWriter, PHPPowerPoint $pPHPPowerPoint /** * Write slide * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param int $pSlideId Slide id * @param int $pRelId Relationship ID * @throws \Exception diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/Rels.php b/src/PhpPowerpoint/Writer/PowerPoint2007/Rels.php index 78f205fd6..2452dee6d 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/Rels.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/Rels.php @@ -17,14 +17,16 @@ namespace PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\Chart as ShapeChart; use PhpOffice\PhpPowerpoint\Shape\Drawing as ShapeDrawing; +use PhpOffice\PhpPowerpoint\Shape\Group; use PhpOffice\PhpPowerpoint\Shape\MemoryDrawing; use PhpOffice\PhpPowerpoint\Shape\RichText\Run; use PhpOffice\PhpPowerpoint\Shape\RichText; use PhpOffice\PhpPowerpoint\Shape\RichText\TextElement; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; +use PhpOffice\PhpPowerpoint\Shape\Table as ShapeTable; use PhpOffice\PhpPowerpoint\Slide as SlideElement; use PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; @@ -69,11 +71,11 @@ public function writeRelationships() /** * Write presentation relationships to XML format * - * @param PHPPowerPoint $pPHPPowerPoint + * @param PhpPowerpoint $pPHPPowerPoint * @return string XML Output * @throws \Exception */ - public function writePresentationRelationships(PHPPowerPoint $pPHPPowerPoint = null) + public function writePresentationRelationships(PhpPowerpoint $pPHPPowerPoint) { // Create XML writer $objWriter = $this->getXMLWriter(); @@ -105,9 +107,13 @@ public function writePresentationRelationships(PHPPowerPoint $pPHPPowerPoint = n // Relationships with slides $slideCount = $pPHPPowerPoint->getSlideCount(); for ($i = 0; $i < $slideCount; ++$i) { - $this->writeRelationship($objWriter, ($i + $relationId), 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slides/slide' . ($i + 1) . '.xml'); + $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slides/slide' . ($i + 1) . '.xml'); } + $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps', 'presProps.xml'); + $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps', 'viewProps.xml'); + $this->writeRelationship($objWriter, $relationId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles', 'tableStyles.xml'); + $objWriter->endElement(); // Return @@ -271,14 +277,15 @@ public function writeSlideRelationships(SlideElement $pSlide) // Starting relation id $relId = 1; + $idxSlide = $pSlide->getParent()->getIndex($pSlide); // Write slideLayout relationship $parentWriter = $this->getParentWriter(); if ($parentWriter instanceof PowerPoint2007) { $layoutPack = $parentWriter->getLayoutPack(); - $layoutIndex = $layoutPack->findlayoutIndex($pSlide->getSlideLayout(), $pSlide->getSlideMasterId()); + $layoutId = $layoutPack->findlayoutId($pSlide->getSlideLayout(), $pSlide->getSlideMasterId()); - $this->writeRelationship($objWriter, $relId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout', '../slideLayouts/slideLayout' . ($layoutIndex + 1) . '.xml'); + $this->writeRelationship($objWriter, $relId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout', '../slideLayouts/slideLayout' . $layoutId . '.xml'); } // Write drawing relationships? @@ -300,6 +307,26 @@ public function writeSlideRelationships(SlideElement $pSlide) $iterator->current()->relationId = 'rId' . $relId; ++$relId; + } elseif ($iterator->current() instanceof Group) { + $iterator2 = $iterator->current()->getShapeCollection()->getIterator(); + while ($iterator2->valid()) { + if ($iterator2->current() instanceof ShapeDrawing || $iterator2->current() instanceof MemoryDrawing) { + // Write relationship for image drawing + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . str_replace(' ', '_', $iterator2->current()->getIndexedFilename())); + + $iterator2->current()->relationId = 'rId' . $relId; + + ++$relId; + } elseif ($iterator2->current() instanceof ShapeChart) { + // Write relationship for chart drawing + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', '../charts/' . $iterator2->current()->getIndexedFilename()); + + $iterator2->current()->relationId = 'rId' . $relId; + + ++$relId; + } + $iterator2->next(); + } } $iterator->next(); @@ -348,10 +375,131 @@ public function writeSlideRelationships(SlideElement $pSlide) } } } + + // Hyperlink in table + if ($iterator->current() instanceof ShapeTable) { + // Rows + $countRows = count($iterator->current()->getRows()); + for ($row = 0; $row < $countRows; $row++) { + // Cells in rows + $countCells = count($iterator->current()->getRow($row)->getCells()); + for ($cell = 0; $cell < $countCells; $cell++) { + $currentCell = $iterator->current()->getRow($row)->getCell($cell); + // Paragraphs in cell + foreach ($currentCell->getParagraphs() as $paragraph) { + // RichText in paragraph + foreach ($paragraph->getRichTextElements() as $element) { + // Run or Text in RichText + if ($element instanceof Run || $element instanceof TextElement) { + if ($element->hasHyperlink()) { + // Write relationship for hyperlink + $hyperlink = $element->getHyperlink(); + $hyperlink->relationId = 'rId' . $relId; + + if (!$hyperlink->isInternal()) { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External'); + } else { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml'); + } + + ++$relId; + } + } + } + } + } + } + } + + if ($iterator->current() instanceof Group) { + $iterator2 = $pSlide->getShapeCollection()->getIterator(); + while ($iterator2->valid()) { + // Hyperlink on shape + if ($iterator2->current()->hasHyperlink()) { + // Write relationship for hyperlink + $hyperlink = $iterator2->current()->getHyperlink(); + $hyperlink->relationId = 'rId' . $relId; + + if (!$hyperlink->isInternal()) { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External'); + } else { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml'); + } + + ++$relId; + } + + // Hyperlink on rich text run + if ($iterator2->current() instanceof RichText) { + foreach ($iterator2->current()->getParagraphs() as $paragraph) { + foreach ($paragraph->getRichTextElements() as $element) { + if ($element instanceof Run || $element instanceof TextElement) { + if ($element->hasHyperlink()) { + // Write relationship for hyperlink + $hyperlink = $element->getHyperlink(); + $hyperlink->relationId = 'rId' . $relId; + + if (!$hyperlink->isInternal()) { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External'); + } else { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml'); + } + + ++$relId; + } + } + } + } + } + + // Hyperlink in table + if ($iterator2->current() instanceof ShapeTable) { + // Rows + $countRows = count($iterator2->current()->getRows()); + for ($row = 0; $row < $countRows; $row++) { + // Cells in rows + $countCells = count($iterator2->current()->getRow($row)->getCells()); + for ($cell = 0; $cell < $countCells; $cell++) { + $currentCell = $iterator2->current()->getRow($row)->getCell($cell); + // Paragraphs in cell + foreach ($currentCell->getParagraphs() as $paragraph) { + // RichText in paragraph + foreach ($paragraph->getRichTextElements() as $element) { + // Run or Text in RichText + if ($element instanceof Run || $element instanceof TextElement) { + if ($element->hasHyperlink()) { + // Write relationship for hyperlink + $hyperlink = $element->getHyperlink(); + $hyperlink->relationId = 'rId' . $relId; + + if (!$hyperlink->isInternal()) { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External'); + } else { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml'); + } + + ++$relId; + } + } + } + } + } + } + } + + $iterator2->next(); + } + + } $iterator->next(); } } + + if ($pSlide->getNote()->getShapeCollection()->count() > 0) { + $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide', '../notesSlides/notesSlide'.($idxSlide + 1).'.xml'); + ++$relId; + } $objWriter->endElement(); @@ -392,7 +540,7 @@ public function writeChartRelationships(ShapeChart $pChart) /** * Write relationship * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param int $pId Relationship ID. rId will be prepended! * @param string $pType Relationship type * @param string $pTarget Relationship target diff --git a/src/PhpPowerpoint/Writer/PowerPoint2007/Slide.php b/src/PhpPowerpoint/Writer/PowerPoint2007/Slide.php index 17d9a6d6d..a67395b1b 100644 --- a/src/PhpPowerpoint/Writer/PowerPoint2007/Slide.php +++ b/src/PhpPowerpoint/Writer/PowerPoint2007/Slide.php @@ -17,23 +17,26 @@ namespace PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; +use PhpOffice\Common\Drawing as CommonDrawing; +use PhpOffice\Common\String; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\Shape\AbstractDrawing; use PhpOffice\PhpPowerpoint\Shape\Chart as ShapeChart; +use PhpOffice\PhpPowerpoint\Shape\Group; use PhpOffice\PhpPowerpoint\Shape\Line; use PhpOffice\PhpPowerpoint\Shape\RichText; use PhpOffice\PhpPowerpoint\Shape\RichText\BreakElement; use PhpOffice\PhpPowerpoint\Shape\RichText\Run; use PhpOffice\PhpPowerpoint\Shape\RichText\TextElement; use PhpOffice\PhpPowerpoint\Shape\Table; -use PhpOffice\PhpPowerpoint\Shared\Drawing as SharedDrawing; -use PhpOffice\PhpPowerpoint\Shared\String; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; use PhpOffice\PhpPowerpoint\Slide as SlideElement; +use PhpOffice\PhpPowerpoint\Slide\Note; +use PhpOffice\PhpPowerpoint\Slide\Transition; use PhpOffice\PhpPowerpoint\Style\Alignment; -use PhpOffice\PhpPowerpoint\Style\Borders; use PhpOffice\PhpPowerpoint\Style\Border; use PhpOffice\PhpPowerpoint\Style\Bullet; use PhpOffice\PhpPowerpoint\Style\Fill; +use PhpOffice\PhpPowerpoint\Style\Shadow; /** * Slide writer @@ -97,27 +100,27 @@ public function writeSlide(SlideElement $pSlide = null) // a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', '0'); - $objWriter->writeAttribute('y', '0'); - $objWriter->endElement(); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pSlide->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pSlide->getOffsetY())); + $objWriter->endElement(); // a:off // a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', '0'); - $objWriter->writeAttribute('cy', '0'); - $objWriter->endElement(); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pSlide->getExtentX())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pSlide->getExtentY())); + $objWriter->endElement(); // a:ext // a:chOff $objWriter->startElement('a:chOff'); - $objWriter->writeAttribute('x', '0'); - $objWriter->writeAttribute('y', '0'); - $objWriter->endElement(); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pSlide->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pSlide->getOffsetY())); + $objWriter->endElement(); // a:chOff // a:chExt $objWriter->startElement('a:chExt'); - $objWriter->writeAttribute('cx', '0'); - $objWriter->writeAttribute('cy', '0'); - $objWriter->endElement(); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pSlide->getExtentX())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pSlide->getExtentY())); + $objWriter->endElement(); // a:chExt $objWriter->endElement(); @@ -141,6 +144,8 @@ public function writeSlide(SlideElement $pSlide = null) $this->writeShapeChart($objWriter, $shape, $shapeId); } elseif ($shape instanceof AbstractDrawing) { $this->writeShapePic($objWriter, $shape, $shapeId); + } elseif ($shape instanceof Group) { + $this->writeShapeGroup($objWriter, $shape, $shapeId); } } @@ -153,20 +158,112 @@ public function writeSlide(SlideElement $pSlide = null) $objWriter->startElement('p:clrMapOvr'); // a:masterClrMapping - $objWriter->writeElement('a:masterClrMapping', ''); + $objWriter->writeElement('a:masterClrMapping', null); $objWriter->endElement(); + if (!is_null($pSlide->getTransition())) { + $this->writeTransition($objWriter, $pSlide->getTransition()); + } + $objWriter->endElement(); // Return return $objWriter->getData(); } + /** + * Write group + * + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer + * @param \PhpOffice\PhpPowerpoint\Shape\Group $group + * @param int $shapeId + */ + private function writeShapeGroup(XMLWriter $objWriter, Group $group, &$shapeId) + { + // p:grpSp + $objWriter->startElement('p:grpSp'); + + // p:nvGrpSpPr + $objWriter->startElement('p:nvGrpSpPr'); + + // p:cNvPr + $objWriter->startElement('p:cNvPr'); + $objWriter->writeAttribute('name', 'Group '.$shapeId++); + $objWriter->writeAttribute('id', $shapeId); + $objWriter->endElement(); // p:cNvPr + // NOTE: Re: $shapeId This seems to be how PowerPoint 2010 does business. + + // p:cNvGrpSpPr + $objWriter->writeElement('p:cNvGrpSpPr', null); + + // p:nvPr + $objWriter->writeElement('p:nvPr', null); + + $objWriter->endElement(); // p:nvGrpSpPr + + // p:grpSpPr + $objWriter->startElement('p:grpSpPr'); + + // a:xfrm + $objWriter->startElement('a:xfrm'); + + // a:off + $objWriter->startElement('a:off'); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($group->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($group->getOffsetY())); + $objWriter->endElement(); // a:off + + // a:ext + $objWriter->startElement('a:ext'); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($group->getExtentX())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($group->getExtentY())); + $objWriter->endElement(); // a:ext + + // a:chOff + $objWriter->startElement('a:chOff'); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($group->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($group->getOffsetY())); + $objWriter->endElement(); // a:chOff + + // a:chExt + $objWriter->startElement('a:chExt'); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($group->getExtentX())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($group->getExtentY())); + $objWriter->endElement(); // a:chExt + + $objWriter->endElement(); // a:xfrm + + $objWriter->endElement(); // p:grpSpPr + + $shapes = $group->getShapeCollection(); + foreach ($shapes as $shape) { + // Increment $shapeId + ++$shapeId; + + // Check type + if ($shape instanceof RichText) { + $this->writeShapeText($objWriter, $shape, $shapeId); + } elseif ($shape instanceof Table) { + $this->writeShapeTable($objWriter, $shape, $shapeId); + } elseif ($shape instanceof Line) { + $this->writeShapeLine($objWriter, $shape, $shapeId); + } elseif ($shape instanceof ShapeChart) { + $this->writeShapeChart($objWriter, $shape, $shapeId); + } elseif ($shape instanceof AbstractDrawing) { + $this->writeShapePic($objWriter, $shape, $shapeId); + } elseif ($shape instanceof Group) { + $this->writeShapeGroup($objWriter, $shape, $shapeId); + } + } + + $objWriter->endElement(); // p:grpSp + } + /** * Write chart * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\Chart $shape * @param int $shapeId */ @@ -195,18 +292,18 @@ private function writeShapeChart(XMLWriter $objWriter, ShapeChart $shape, $shape // p:xfrm $objWriter->startElement('p:xfrm'); - $objWriter->writeAttribute('rot', SharedDrawing::degreesToAngle($shape->getRotation())); + $objWriter->writeAttribute('rot', CommonDrawing::degreesToAngle($shape->getRotation())); // a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', SharedDrawing::pixelsToEmu($shape->getOffsetX())); - $objWriter->writeAttribute('y', SharedDrawing::pixelsToEmu($shape->getOffsetY())); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY())); $objWriter->endElement(); // a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', SharedDrawing::pixelsToEmu($shape->getWidth())); - $objWriter->writeAttribute('cy', SharedDrawing::pixelsToEmu($shape->getHeight())); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight())); $objWriter->endElement(); $objWriter->endElement(); @@ -235,7 +332,7 @@ private function writeShapeChart(XMLWriter $objWriter, ShapeChart $shape, $shape /** * Write pic * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\AbstractDrawing $shape * @param int $shapeId * @throws \Exception @@ -254,6 +351,11 @@ private function writeShapePic(XMLWriter $objWriter, AbstractDrawing $shape, $sh $objWriter->writeAttribute('name', $shape->getName()); $objWriter->writeAttribute('descr', $shape->getDescription()); + // a:hlinkClick + if ($shape->hasHyperlink()) { + $this->writeHyperlink($objWriter, $shape); + } + $objWriter->endElement(); // p:cNvPicPr @@ -268,7 +370,6 @@ private function writeShapePic(XMLWriter $objWriter, AbstractDrawing $shape, $sh // p:nvPr $objWriter->writeElement('p:nvPr', null); - $objWriter->endElement(); // p:blipFill @@ -291,18 +392,18 @@ private function writeShapePic(XMLWriter $objWriter, AbstractDrawing $shape, $sh // a:xfrm $objWriter->startElement('a:xfrm'); - $objWriter->writeAttribute('rot', SharedDrawing::degreesToAngle($shape->getRotation())); + $objWriter->writeAttribute('rot', CommonDrawing::degreesToAngle($shape->getRotation())); // a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', SharedDrawing::pixelsToEmu($shape->getOffsetX())); - $objWriter->writeAttribute('y', SharedDrawing::pixelsToEmu($shape->getOffsetY())); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY())); $objWriter->endElement(); // a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', SharedDrawing::pixelsToEmu($shape->getWidth())); - $objWriter->writeAttribute('cy', SharedDrawing::pixelsToEmu($shape->getHeight())); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight())); $objWriter->endElement(); $objWriter->endElement(); @@ -321,31 +422,7 @@ private function writeShapePic(XMLWriter $objWriter, AbstractDrawing $shape, $sh } if ($shape->getShadow()->isVisible()) { - // a:effectLst - $objWriter->startElement('a:effectLst'); - - // a:outerShdw - $objWriter->startElement('a:outerShdw'); - $objWriter->writeAttribute('blurRad', SharedDrawing::pixelsToEmu($shape->getShadow()->getBlurRadius())); - $objWriter->writeAttribute('dist', SharedDrawing::pixelsToEmu($shape->getShadow()->getDistance())); - $objWriter->writeAttribute('dir', SharedDrawing::degreesToAngle($shape->getShadow()->getDirection())); - $objWriter->writeAttribute('algn', $shape->getShadow()->getAlignment()); - $objWriter->writeAttribute('rotWithShape', '0'); - - // a:srgbClr - $objWriter->startElement('a:srgbClr'); - $objWriter->writeAttribute('val', $shape->getShadow()->getColor()->getRGB()); - - // a:alpha - $objWriter->startElement('a:alpha'); - $objWriter->writeAttribute('val', $shape->getShadow()->getAlpha() * 1000); - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); - - $objWriter->endElement(); + $this->writeShadow($objWriter, $shape->getShadow()); } $objWriter->endElement(); @@ -356,7 +433,7 @@ private function writeShapePic(XMLWriter $objWriter, AbstractDrawing $shape, $sh /** * Write txt * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\RichText $shape * @param int $shapeId * @throws \Exception @@ -366,68 +443,90 @@ private function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeId) // p:sp $objWriter->startElement('p:sp'); - // p:nvSpPr + // p:sp\p:nvSpPr $objWriter->startElement('p:nvSpPr'); - // p:cNvPr + // p:sp\p:nvSpPr\p:cNvPr $objWriter->startElement('p:cNvPr'); $objWriter->writeAttribute('id', $shapeId); $objWriter->writeAttribute('name', ''); + // Hyperlink + if ($shape->hasHyperlink()) { + $this->writeHyperlink($objWriter, $shape); + } + // > p:sp\p:nvSpPr $objWriter->endElement(); - // p:cNvSpPr + // p:sp\p:cNvSpPr $objWriter->startElement('p:cNvSpPr'); $objWriter->writeAttribute('txBox', '1'); $objWriter->endElement(); - - // p:nvPr + // p:sp\p:cNvSpPr\p:nvPr $objWriter->writeElement('p:nvPr', null); - + // > p:sp\p:cNvSpPr $objWriter->endElement(); - // p:spPr + // p:sp\p:spPr $objWriter->startElement('p:spPr'); - // a:xfrm + // p:sp\p:spPr\a:xfrm $objWriter->startElement('a:xfrm'); - $objWriter->writeAttribute('rot', SharedDrawing::degreesToAngle($shape->getRotation())); - - // a:off + $objWriter->writeAttribute('rot', CommonDrawing::degreesToAngle($shape->getRotation())); + + // p:sp\p:spPr\a:xfrm\a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', SharedDrawing::pixelsToEmu($shape->getOffsetX())); - $objWriter->writeAttribute('y', SharedDrawing::pixelsToEmu($shape->getOffsetY())); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY())); $objWriter->endElement(); - - // a:ext + + // p:sp\p:spPr\a:xfrm\a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', SharedDrawing::pixelsToEmu($shape->getWidth())); - $objWriter->writeAttribute('cy', SharedDrawing::pixelsToEmu($shape->getHeight())); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight())); $objWriter->endElement(); - + + // > p:sp\p:spPr\a:xfrm $objWriter->endElement(); - // a:prstGeom + // p:sp\p:spPr\a:prstGeom $objWriter->startElement('a:prstGeom'); $objWriter->writeAttribute('prst', 'rect'); $objWriter->endElement(); - + + if ($shape->getFill()) { + $this->writeFill($objWriter, $shape->getFill()); + } + if ($shape->getBorder()->getLineStyle() != Border::LINE_NONE) { + $this->writeBorder($objWriter, $shape->getBorder(), ''); + } + if ($shape->getShadow()->isVisible()) { + $this->writeShadow($objWriter, $shape->getShadow()); + } + // > p:sp\p:spPr $objWriter->endElement(); // p:txBody $objWriter->startElement('p:txBody'); // a:bodyPr + //@link :http://msdn.microsoft.com/en-us/library/documentformat.openxml.drawing.bodyproperties%28v=office.14%29.aspx $objWriter->startElement('a:bodyPr'); $verticalAlign = $shape->getActiveParagraph()->getAlignment()->getVertical(); if ($verticalAlign != Alignment::VERTICAL_BASE && $verticalAlign != Alignment::VERTICAL_AUTO) { $objWriter->writeAttribute('anchor', $verticalAlign); } - $objWriter->writeAttribute('wrap', $shape->getWrap()); + if ($shape->getWrap() != RichText::WRAP_SQUARE) { + $objWriter->writeAttribute('wrap', $shape->getWrap()); + } $objWriter->writeAttribute('rtlCol', '0'); - $objWriter->writeAttribute('horzOverflow', $shape->getHorizontalOverflow()); - $objWriter->writeAttribute('vertOverflow', $shape->getVerticalOverflow()); + if ($shape->getHorizontalOverflow() != RichText::OVERFLOW_OVERFLOW) { + $objWriter->writeAttribute('horzOverflow', $shape->getHorizontalOverflow()); + } + if ($shape->getVerticalOverflow() != RichText::OVERFLOW_OVERFLOW) { + $objWriter->writeAttribute('vertOverflow', $shape->getVerticalOverflow()); + } if ($shape->isUpright()) { $objWriter->writeAttribute('upright', '1'); @@ -436,21 +535,33 @@ private function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeId) $objWriter->writeAttribute('vert', 'vert'); } - $objWriter->writeAttribute('bIns', SharedDrawing::pixelsToEmu($shape->getInsetBottom())); - $objWriter->writeAttribute('lIns', SharedDrawing::pixelsToEmu($shape->getInsetLeft())); - $objWriter->writeAttribute('rIns', SharedDrawing::pixelsToEmu($shape->getInsetRight())); - $objWriter->writeAttribute('tIns', SharedDrawing::pixelsToEmu($shape->getInsetTop())); + $objWriter->writeAttribute('bIns', CommonDrawing::pixelsToEmu($shape->getInsetBottom())); + $objWriter->writeAttribute('lIns', CommonDrawing::pixelsToEmu($shape->getInsetLeft())); + $objWriter->writeAttribute('rIns', CommonDrawing::pixelsToEmu($shape->getInsetRight())); + $objWriter->writeAttribute('tIns', CommonDrawing::pixelsToEmu($shape->getInsetTop())); - $objWriter->writeAttribute('numCol', $shape->getColumns()); + if ($shape->getColumns() <> 1) { + $objWriter->writeAttribute('numCol', $shape->getColumns()); + } // a:spAutoFit - $objWriter->writeElement('a:' . $shape->getAutoFit(), null); + $objWriter->startElement('a:' . $shape->getAutoFit()); + if ($shape->getAutoFit() == RichText::AUTOFIT_NORMAL) { + if (!is_null($shape->getFontScale())) { + $objWriter->writeAttribute('fontScale', (int)($shape->getFontScale() * 1000)); + } + if (!is_null($shape->getLineSpaceReduction())) { + $objWriter->writeAttribute('lnSpcReduction', (int)($shape->getLineSpaceReduction() * 1000)); + } + } + + $objWriter->endElement(); $objWriter->endElement(); // a:lstStyle $objWriter->writeElement('a:lstStyle', null); - + // Write paragraphs $this->writeParagraphs($objWriter, $shape->getParagraphs()); @@ -462,7 +573,7 @@ private function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeId) /** * Write table * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\Table $shape * @param int $shapeId * @throws \Exception @@ -503,14 +614,14 @@ private function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) // a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', SharedDrawing::pixelsToEmu($shape->getOffsetX())); - $objWriter->writeAttribute('y', SharedDrawing::pixelsToEmu($shape->getOffsetY())); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY())); $objWriter->endElement(); // a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', SharedDrawing::pixelsToEmu($shape->getWidth())); - $objWriter->writeAttribute('cy', SharedDrawing::pixelsToEmu($shape->getHeight())); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight())); $objWriter->endElement(); $objWriter->endElement(); @@ -536,7 +647,8 @@ private function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) $objWriter->startElement('a:tblGrid'); // Write cell widths - for ($cell = 0; $cell < count($shape->getRow(0)->getCells()); $cell++) { + $countCells = count($shape->getRow(0)->getCells()); + for ($cell = 0; $cell < $countCells; $cell++) { // a:gridCol $objWriter->startElement('a:gridCol'); @@ -548,7 +660,7 @@ private function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) $width = $totalWidth / $colCount; } - $objWriter->writeAttribute('w', SharedDrawing::pixelsToEmu($width)); + $objWriter->writeAttribute('w', CommonDrawing::pixelsToEmu($width)); $objWriter->endElement(); } @@ -562,13 +674,15 @@ private function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) $defaultBorder = new Border(); // Write rows - for ($row = 0; $row < count($shape->getRows()); $row++) { + $countRows = count($shape->getRows()); + for ($row = 0; $row < $countRows; $row++) { // a:tr $objWriter->startElement('a:tr'); - $objWriter->writeAttribute('h', SharedDrawing::pixelsToEmu($shape->getRow($row)->getHeight())); + $objWriter->writeAttribute('h', CommonDrawing::pixelsToEmu($shape->getRow($row)->getHeight())); // Write cells - for ($cell = 0; $cell < count($shape->getRow($row)->getCells()); $cell++) { + $countCells = count($shape->getRow($row)->getCells()); + for ($cell = 0; $cell < $countCells; $cell++) { // Current cell $currentCell = $shape->getRow($row)->getCell($cell); @@ -679,7 +793,7 @@ private function writeShapeTable(XMLWriter $objWriter, Table $shape, $shapeId) /** * Write paragraphs * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\RichText\Paragraph[] $paragraphs * @throws \Exception */ @@ -694,9 +808,9 @@ private function writeParagraphs(XMLWriter $objWriter, $paragraphs) $objWriter->startElement('a:pPr'); $objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal()); $objWriter->writeAttribute('fontAlgn', $paragraph->getAlignment()->getVertical()); - $objWriter->writeAttribute('marL', SharedDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft())); - $objWriter->writeAttribute('marR', SharedDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginRight())); - $objWriter->writeAttribute('indent', SharedDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent())); + $objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft())); + $objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginRight())); + $objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent())); $objWriter->writeAttribute('lvl', $paragraph->getAlignment()->getLevel()); // Bullet type specified? @@ -802,7 +916,7 @@ private function writeParagraphs(XMLWriter $objWriter, $paragraphs) /** * Write Line Shape * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Shape\Line $shape * @param int $shapeId */ @@ -838,54 +952,54 @@ private function writeShapeLine(XMLWriter $objWriter, Line $shape, $shapeId) if ($shape->getWidth() >= 0 && $shape->getHeight() >= 0) { // a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', SharedDrawing::pixelsToEmu($shape->getOffsetX())); - $objWriter->writeAttribute('y', SharedDrawing::pixelsToEmu($shape->getOffsetY())); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY())); $objWriter->endElement(); // a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', SharedDrawing::pixelsToEmu($shape->getWidth())); - $objWriter->writeAttribute('cy', SharedDrawing::pixelsToEmu($shape->getHeight())); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight())); $objWriter->endElement(); } elseif ($shape->getWidth() < 0 && $shape->getHeight() < 0) { // a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', SharedDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth())); - $objWriter->writeAttribute('y', SharedDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight())); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight())); $objWriter->endElement(); // a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', SharedDrawing::pixelsToEmu(-$shape->getWidth())); - $objWriter->writeAttribute('cy', SharedDrawing::pixelsToEmu(-$shape->getHeight())); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(-$shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(-$shape->getHeight())); $objWriter->endElement(); } elseif ($shape->getHeight() < 0) { $objWriter->writeAttribute('flipV', 1); // a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', SharedDrawing::pixelsToEmu($shape->getOffsetX())); - $objWriter->writeAttribute('y', SharedDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight())); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight())); $objWriter->endElement(); // a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', SharedDrawing::pixelsToEmu($shape->getWidth())); - $objWriter->writeAttribute('cy', SharedDrawing::pixelsToEmu(-$shape->getHeight())); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(-$shape->getHeight())); $objWriter->endElement(); } elseif ($shape->getWidth() < 0) { $objWriter->writeAttribute('flipV', 1); // a:off $objWriter->startElement('a:off'); - $objWriter->writeAttribute('x', SharedDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth())); - $objWriter->writeAttribute('y', SharedDrawing::pixelsToEmu($shape->getOffsetY())); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY())); $objWriter->endElement(); // a:ext $objWriter->startElement('a:ext'); - $objWriter->writeAttribute('cx', SharedDrawing::pixelsToEmu(-$shape->getWidth())); - $objWriter->writeAttribute('cy', SharedDrawing::pixelsToEmu($shape->getHeight())); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(-$shape->getWidth())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight())); $objWriter->endElement(); } @@ -908,7 +1022,7 @@ private function writeShapeLine(XMLWriter $objWriter, Line $shape, $shapeId) /** * Write Border * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Style\Border $pBorder Border * @param string $pElementName Element name * @throws \Exception @@ -975,7 +1089,7 @@ protected function writeBorder(XMLWriter $objWriter, Border $pBorder, $pElementN /** * Write Fill * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Style\Fill $pFill Fill style * @throws \Exception */ @@ -1005,7 +1119,7 @@ protected function writeFill(XMLWriter $objWriter, Fill $pFill) /** * Write Solid Fill * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Style\Fill $pFill Fill style * @throws \Exception */ @@ -1025,7 +1139,7 @@ protected function writeSolidFill(XMLWriter $objWriter, Fill $pFill) /** * Write Gradient Fill * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Style\Fill $pFill Fill style * @throws \Exception */ @@ -1062,7 +1176,7 @@ protected function writeGradientFill(XMLWriter $objWriter, Fill $pFill) // a:lin $objWriter->startElement('a:lin'); - $objWriter->writeAttribute('ang', SharedDrawing::degreesToAngle($pFill->getRotation())); + $objWriter->writeAttribute('ang', CommonDrawing::degreesToAngle($pFill->getRotation())); $objWriter->writeAttribute('scaled', '0'); $objWriter->endElement(); @@ -1072,7 +1186,7 @@ protected function writeGradientFill(XMLWriter $objWriter, Fill $pFill) /** * Write Pattern Fill * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\Style\Fill $pFill Fill style * @throws \Exception */ @@ -1104,10 +1218,39 @@ protected function writePatternFill(XMLWriter $objWriter, Fill $pFill) $objWriter->endElement(); } + protected function writeShadow(XMLWriter $objWriter, Shadow $oShadow) + { + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', CommonDrawing::pixelsToEmu($oShadow->getBlurRadius())); + $objWriter->writeAttribute('dist', CommonDrawing::pixelsToEmu($oShadow->getDistance())); + $objWriter->writeAttribute('dir', CommonDrawing::degreesToAngle($oShadow->getDirection())); + $objWriter->writeAttribute('algn', $oShadow->getAlignment()); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $oShadow->getColor()->getRGB()); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $oShadow->getAlpha() * 1000); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + } + /** * Write hyperlink * - * @param \PhpOffice\PhpPowerpoint\Shared\XMLWriter $objWriter XML Writer + * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer * @param \PhpOffice\PhpPowerpoint\AbstractShape|\PhpOffice\PhpPowerpoint\Shape\RichText\TextElement $shape */ private function writeHyperlink(XMLWriter $objWriter, $shape) @@ -1121,4 +1264,412 @@ private function writeHyperlink(XMLWriter $objWriter, $shape) } $objWriter->endElement(); } + + /** + * Write Note Slide + * @param Note $pNote + * @throws \Exception + */ + public function writeNote(Note $pNote = null) + { + // Check slide + if (is_null($pNote)) { + throw new \Exception("Invalid \PhpOffice\PhpPowerpoint\Slide\Note object passed."); + } + + // Create XML writer + $objWriter = $this->getXMLWriter(); + + // XML header + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); + + // p:notes + $objWriter->startElement('p:notes'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('xmlns:p', 'http://schemas.openxmlformats.org/presentationml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + // p:cSld + $objWriter->startElement('p:cSld'); + + // p:spTree + $objWriter->startElement('p:spTree'); + + // p:nvGrpSpPr + $objWriter->startElement('p:nvGrpSpPr'); + + // p:cNvPr + $objWriter->startElement('p:cNvPr'); + $objWriter->writeAttribute('id', '1'); + $objWriter->writeAttribute('name', ''); + $objWriter->endElement(); + + // p:cNvGrpSpPr + $objWriter->writeElement('p:cNvGrpSpPr', null); + + // p:nvPr + $objWriter->writeElement('p:nvPr', null); + + // ## p:nvGrpSpPr + $objWriter->endElement(); + + // p:grpSpPr + $objWriter->startElement('p:grpSpPr'); + + // a:xfrm + $objWriter->startElement('a:xfrm'); + + // a:off + $objWriter->startElement('a:off'); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pNote->getOffsetY())); + $objWriter->endElement(); // a:off + + // a:ext + $objWriter->startElement('a:ext'); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pNote->getExtentX())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pNote->getExtentY())); + $objWriter->endElement(); // a:ext + + // a:chOff + $objWriter->startElement('a:chOff'); + $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX())); + $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pNote->getOffsetY())); + $objWriter->endElement(); // a:chOff + + // a:chExt + $objWriter->startElement('a:chExt'); + $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pNote->getExtentX())); + $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pNote->getExtentY())); + $objWriter->endElement(); // a:chExt + + // ## a:xfrm + $objWriter->endElement(); + + // ## p:grpSpPr + $objWriter->endElement(); + + // p:sp + $objWriter->startElement('p:sp'); + + // p:nvSpPr + $objWriter->startElement('p:nvSpPr'); + + $objWriter->startElement('p:cNvPr'); + $objWriter->writeAttribute('id', '1'); + $objWriter->writeAttribute('name', 'Notes Placeholder'); + $objWriter->endElement(); + + // p:cNvSpPr + $objWriter->startElement('p:cNvSpPr'); + + //a:spLocks + $objWriter->startElement('a:spLocks'); + $objWriter->writeAttribute('noGrp', '1'); + $objWriter->endElement(); + + // ## p:cNvSpPr + $objWriter->endElement(); + + // p:nvPr + $objWriter->startElement('p:nvPr'); + + $objWriter->startElement('p:ph'); + $objWriter->writeAttribute('type', 'body'); + $objWriter->writeAttribute('idx', '1'); + $objWriter->endElement(); + + // ## p:nvPr + $objWriter->endElement(); + + // ## p:nvSpPr + $objWriter->endElement(); + + $objWriter->writeElement('p:spPr', null); + + // p:txBody + $objWriter->startElement('p:txBody'); + + $objWriter->writeElement('a:bodyPr', null); + $objWriter->writeElement('a:lstStyle', null); + + // Loop shapes + $shapes = $pNote->getShapeCollection(); + foreach ($shapes as $shape) { + // Check type + if ($shape instanceof RichText) { + $paragraphs = $shape->getParagraphs(); + $this->writeParagraphs($objWriter, $paragraphs); + } + } + + // ## p:txBody + $objWriter->endElement(); + + // ## p:sp + $objWriter->endElement(); + + // ## p:spTree + $objWriter->endElement(); + + // ## p:cSld + $objWriter->endElement(); + + // ## p:notes + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Transition Slide + * @link http://officeopenxml.com/prSlide-transitions.php + * @param XMLWriter $objWriter + * @param Transition $transition + */ + public function writeTransition(XMLWriter $objWriter, Transition $transition) + { + $objWriter->startElement('p:transition'); + if (!is_null($transition->getSpeed())) { + $objWriter->writeAttribute('spd', $transition->getSpeed()); + } + $objWriter->writeAttribute('advClick', $transition->hasManualTrigger() ? '1' : '0'); + if ($transition->hasTimeTrigger()) { + $objWriter->writeAttribute('advTm', $transition->getAdvanceTimeTrigger()); + } + + switch ($transition->getTransitionType()) { + case Transition::TRANSITION_BLINDS_HORIZONTAL: + $objWriter->startElement('p:blinds'); + $objWriter->writeAttribute('dir', 'horz'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_BLINDS_VERTICAL: + $objWriter->startElement('p:blinds'); + $objWriter->writeAttribute('dir', 'vert'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_CHECKER_HORIZONTAL: + $objWriter->startElement('p:checker'); + $objWriter->writeAttribute('dir', 'horz'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_CHECKER_VERTICAL: + $objWriter->startElement('p:checker'); + $objWriter->writeAttribute('dir', 'vert'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_CIRCLE_HORIZONTAL: + $objWriter->startElement('p:circle'); + $objWriter->writeAttribute('dir', 'horz'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_CIRCLE_VERTICAL: + $objWriter->startElement('p:circle'); + $objWriter->writeAttribute('dir', 'vert'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COMB_HORIZONTAL: + $objWriter->startElement('p:comb'); + $objWriter->writeAttribute('dir', 'horz'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COMB_VERTICAL: + $objWriter->startElement('p:comb'); + $objWriter->writeAttribute('dir', 'vert'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COVER_DOWN: + $objWriter->startElement('p:cover'); + $objWriter->writeAttribute('dir', 'd'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COVER_LEFT: + $objWriter->startElement('p:cover'); + $objWriter->writeAttribute('dir', 'l'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COVER_LEFT_DOWN: + $objWriter->startElement('p:cover'); + $objWriter->writeAttribute('dir', 'ld'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COVER_LEFT_UP: + $objWriter->startElement('p:cover'); + $objWriter->writeAttribute('dir', 'lu'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COVER_RIGHT: + $objWriter->startElement('p:cover'); + $objWriter->writeAttribute('dir', 'r'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COVER_RIGHT_DOWN: + $objWriter->startElement('p:cover'); + $objWriter->writeAttribute('dir', 'rd'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COVER_RIGHT_UP: + $objWriter->startElement('p:cover'); + $objWriter->writeAttribute('dir', 'ru'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_COVER_UP: + $objWriter->startElement('p:cover'); + $objWriter->writeAttribute('dir', 'u'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_CUT: + $objWriter->writeElement('p:cut'); + break; + case Transition::TRANSITION_DIAMOND: + $objWriter->writeElement('p:diamond'); + break; + case Transition::TRANSITION_DISSOLVE: + $objWriter->writeElement('p:dissolve'); + break; + case Transition::TRANSITION_FADE: + $objWriter->writeElement('p:fade'); + break; + case Transition::TRANSITION_NEWSFLASH: + $objWriter->writeElement('p:newsflash'); + break; + case Transition::TRANSITION_PLUS: + $objWriter->writeElement('p:plus'); + break; + case Transition::TRANSITION_PULL_DOWN: + $objWriter->startElement('p:pull'); + $objWriter->writeAttribute('dir', 'd'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_PULL_LEFT: + $objWriter->startElement('p:pull'); + $objWriter->writeAttribute('dir', 'l'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_PULL_RIGHT: + $objWriter->startElement('p:pull'); + $objWriter->writeAttribute('dir', 'r'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_PULL_UP: + $objWriter->startElement('p:pull'); + $objWriter->writeAttribute('dir', 'u'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_PUSH_DOWN: + $objWriter->startElement('p:push'); + $objWriter->writeAttribute('dir', 'd'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_PUSH_LEFT: + $objWriter->startElement('p:push'); + $objWriter->writeAttribute('dir', 'l'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_PUSH_RIGHT: + $objWriter->startElement('p:push'); + $objWriter->writeAttribute('dir', 'r'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_PUSH_UP: + $objWriter->startElement('p:push'); + $objWriter->writeAttribute('dir', 'u'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_RANDOM: + $objWriter->writeElement('p:random'); + break; + case Transition::TRANSITION_RANDOMBAR_HORIZONTAL: + $objWriter->startElement('p:randomBar'); + $objWriter->writeAttribute('dir', 'horz'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_RANDOMBAR_VERTICAL: + $objWriter->startElement('p:randomBar'); + $objWriter->writeAttribute('dir', 'vert'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_SPLIT_IN_HORIZONTAL: + $objWriter->startElement('p:split'); + $objWriter->writeAttribute('dir', 'in'); + $objWriter->writeAttribute('orient', 'horz'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_SPLIT_OUT_HORIZONTAL: + $objWriter->startElement('p:split'); + $objWriter->writeAttribute('dir', 'out'); + $objWriter->writeAttribute('orient', 'horz'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_SPLIT_IN_VERTICAL: + $objWriter->startElement('p:split'); + $objWriter->writeAttribute('dir', 'in'); + $objWriter->writeAttribute('orient', 'vert'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_SPLIT_OUT_VERTICAL: + $objWriter->startElement('p:split'); + $objWriter->writeAttribute('dir', 'out'); + $objWriter->writeAttribute('orient', 'vert'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_STRIPS_LEFT_DOWN: + $objWriter->startElement('p:strips'); + $objWriter->writeAttribute('dir', 'ld'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_STRIPS_LEFT_UP: + $objWriter->startElement('p:strips'); + $objWriter->writeAttribute('dir', 'lu'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_STRIPS_RIGHT_DOWN: + $objWriter->startElement('p:strips'); + $objWriter->writeAttribute('dir', 'rd'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_STRIPS_RIGHT_UP: + $objWriter->startElement('p:strips'); + $objWriter->writeAttribute('dir', 'ru'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_WEDGE: + $objWriter->writeElement('p:wedge'); + break; + case Transition::TRANSITION_WIPE_DOWN: + $objWriter->startElement('p:wipe'); + $objWriter->writeAttribute('dir', 'd'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_WIPE_LEFT: + $objWriter->startElement('p:wipe'); + $objWriter->writeAttribute('dir', 'l'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_WIPE_RIGHT: + $objWriter->startElement('p:wipe'); + $objWriter->writeAttribute('dir', 'r'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_WIPE_UP: + $objWriter->startElement('p:wipe'); + $objWriter->writeAttribute('dir', 'u'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_ZOOM_IN: + $objWriter->startElement('p:zoom'); + $objWriter->writeAttribute('dir', 'in'); + $objWriter->endElement(); + break; + case Transition::TRANSITION_ZOOM_OUT: + $objWriter->startElement('p:zoom'); + $objWriter->writeAttribute('dir', 'out'); + $objWriter->endElement(); + break; + } + + $objWriter->endElement(); + } } diff --git a/src/PhpPowerpoint/Writer/Serialized.php b/src/PhpPowerpoint/Writer/Serialized.php index 3847fe3be..5211949c1 100644 --- a/src/PhpPowerpoint/Writer/Serialized.php +++ b/src/PhpPowerpoint/Writer/Serialized.php @@ -17,9 +17,9 @@ namespace PhpOffice\PhpPowerpoint\Writer; +use PhpOffice\Common\XMLWriter; use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\AbstractDrawing; -use PhpOffice\PhpPowerpoint\Shared\XMLWriter; /** * \PhpOffice\PhpPowerpoint\Writer\Serialized @@ -38,7 +38,7 @@ class Serialized implements WriterInterface * * @param \PhpOffice\PhpPowerpoint\PhpPowerpoint $pPHPPowerPoint */ - public function __construct (PhpPowerpoint $pPHPPowerPoint = null) + public function __construct(PhpPowerpoint $pPHPPowerPoint = null) { // Assign PHPPowerPoint $this->setPHPPowerPoint($pPHPPowerPoint); @@ -50,7 +50,7 @@ public function __construct (PhpPowerpoint $pPHPPowerPoint = null) * @param string $pFilename * @throws \Exception */ - public function save ($pFilename) + public function save($pFilename) { if (empty($pFilename)) { throw new \Exception("Filename is empty."); @@ -95,7 +95,7 @@ public function save ($pFilename) * @return PHPPowerPoint * @throws \Exception */ - public function getPHPPowerPoint () + public function getPHPPowerPoint() { if (!is_null($this->presentation)) { return $this->presentation; @@ -111,7 +111,7 @@ public function getPHPPowerPoint () * @throws \Exception * @return \PhpOffice\PhpPowerpoint\Writer\Serialized */ - public function setPHPPowerPoint (PhpPowerpoint $pPHPPowerPoint = null) + public function setPHPPowerPoint(PhpPowerpoint $pPHPPowerPoint = null) { $this->presentation = $pPHPPowerPoint; @@ -126,7 +126,7 @@ public function setPHPPowerPoint (PhpPowerpoint $pPHPPowerPoint = null) * @return string XML Output * @throws \Exception */ - private function writeSerialized (PhpPowerpoint $pPHPPowerPoint = null, $pFilename = '') + private function writeSerialized(PhpPowerpoint $pPHPPowerPoint = null, $pFilename = '') { // Clone $pPHPPowerPoint $pPHPPowerPoint = clone $pPHPPowerPoint; diff --git a/tests/PhpPowerpoint/Tests/AbstractShapeTest.php b/tests/PhpPowerpoint/Tests/AbstractShapeTest.php index 93282a2ba..93c26efb9 100644 --- a/tests/PhpPowerpoint/Tests/AbstractShapeTest.php +++ b/tests/PhpPowerpoint/Tests/AbstractShapeTest.php @@ -147,7 +147,7 @@ public function testSlide() /** * @expectedException \Exception - * @expectedExceptionMessage A \PhpOffice\PhpPowerpoint\Slide has already been assigned. Shapes can only exist on one \PhpOffice\PhpPowerpoint\Slide. + * @expectedExceptionMessage A \PhpOffice\PhpPowerpoint\ShapeContainerInterface has already been assigned. Shapes can only exist on one \PhpOffice\PhpPowerpoint\ShapeContainerInterface. */ public function testSlideException() { diff --git a/tests/PhpPowerpoint/Tests/DocumentLayoutTest.php b/tests/PhpPowerpoint/Tests/DocumentLayoutTest.php index 4be7b85a4..b36b2c4bd 100644 --- a/tests/PhpPowerpoint/Tests/DocumentLayoutTest.php +++ b/tests/PhpPowerpoint/Tests/DocumentLayoutTest.php @@ -47,11 +47,60 @@ public function testSetCustomLayout() { $object = new DocumentLayout(); $object->setDocumentLayout(array('cx' => 6858000, 'cy' => 9144000), false); - $object->setLayoutXmilli(6858000 / 36000); - $object->setLayoutYmilli(9144000 / 36000); - - $this->assertEquals('', $object->getDocumentLayout()); + $this->assertEquals(DocumentLayout::LAYOUT_CUSTOM, $object->getDocumentLayout()); + $this->assertEquals(9144000, $object->getCX()); + $this->assertEquals(6858000, $object->getCY()); + $object->setDocumentLayout(array('cx' => 6858000, 'cy' => 9144000), true); + $this->assertEquals(DocumentLayout::LAYOUT_CUSTOM, $object->getDocumentLayout()); $this->assertEquals(6858000, $object->getCX()); $this->assertEquals(9144000, $object->getCY()); } + + public function testCX() + { + $value = rand(1, 100000); + $object = new DocumentLayout(); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCX($value)); + $this->assertEquals($value, $object->getCX()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCX($value, DocumentLayout::UNIT_CENTIMETER)); + $this->assertEquals($value, $object->getCX(DocumentLayout::UNIT_CENTIMETER)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCX($value, DocumentLayout::UNIT_EMU)); + $this->assertEquals($value, $object->getCX(DocumentLayout::UNIT_EMU)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCX($value, DocumentLayout::UNIT_INCH)); + $this->assertEquals($value, $object->getCX(DocumentLayout::UNIT_INCH)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCX($value, DocumentLayout::UNIT_MILLIMETER)); + $this->assertEquals($value, $object->getCX(DocumentLayout::UNIT_MILLIMETER)); + $this->assertEquals($value, $object->getLayoutXmilli()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCX($value, DocumentLayout::UNIT_POINT)); + $this->assertEquals($value, $object->getCX(DocumentLayout::UNIT_POINT)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCX($value, DocumentLayout::UNIT_PIXEL)); + $this->assertEquals($value, $object->getCX(DocumentLayout::UNIT_PIXEL)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setLayoutXmilli($value)); + $this->assertEquals($value, $object->getCX(DocumentLayout::UNIT_MILLIMETER)); + $this->assertEquals($value, $object->getLayoutXmilli()); + } + + public function testCY() + { + $value = rand(1, 100000); + $object = new DocumentLayout(); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCY($value)); + $this->assertEquals($value, $object->getCY()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCY($value, DocumentLayout::UNIT_CENTIMETER)); + $this->assertEquals($value, $object->getCY(DocumentLayout::UNIT_CENTIMETER)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCY($value, DocumentLayout::UNIT_EMU)); + $this->assertEquals($value, $object->getCY(DocumentLayout::UNIT_EMU)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCY($value, DocumentLayout::UNIT_INCH)); + $this->assertEquals($value, $object->getCY(DocumentLayout::UNIT_INCH)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCY($value, DocumentLayout::UNIT_MILLIMETER)); + $this->assertEquals($value, $object->getCY(DocumentLayout::UNIT_MILLIMETER)); + $this->assertEquals($value, $object->getLayoutYmilli()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCY($value, DocumentLayout::UNIT_POINT)); + $this->assertEquals($value, $object->getCY(DocumentLayout::UNIT_POINT)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setCY($value, DocumentLayout::UNIT_PIXEL)); + $this->assertEquals($value, $object->getCY(DocumentLayout::UNIT_PIXEL)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\DocumentLayout', $object->setLayoutYmilli($value)); + $this->assertEquals($value, $object->getCY(DocumentLayout::UNIT_MILLIMETER)); + $this->assertEquals($value, $object->getLayoutYmilli()); + } } diff --git a/tests/PhpPowerpoint/Tests/Reader/PowerPoint97Test.php b/tests/PhpPowerpoint/Tests/Reader/PowerPoint97Test.php index 86d3d13ab..6edb548f8 100644 --- a/tests/PhpPowerpoint/Tests/Reader/PowerPoint97Test.php +++ b/tests/PhpPowerpoint/Tests/Reader/PowerPoint97Test.php @@ -61,7 +61,7 @@ public function testLoadFileNotExists() /** * @expectedException \Exception - * @expectedExceptionMessage Invalid file format for PhpOffice\PhpPowerpoint\Reader\Serialized: + * @expectedExceptionMessage Invalid file format for PhpOffice\PhpPowerpoint\Reader\PowerPoint97: */ public function testLoadFileBadFormat() { diff --git a/tests/PhpPowerpoint/Tests/Reader/SerializedTest.php b/tests/PhpPowerpoint/Tests/Reader/SerializedTest.php index d11e4b08e..ae218b2c4 100644 --- a/tests/PhpPowerpoint/Tests/Reader/SerializedTest.php +++ b/tests/PhpPowerpoint/Tests/Reader/SerializedTest.php @@ -49,7 +49,7 @@ public function testLoadFileNotExists() /** * @expectedException \Exception - * @expectedExceptionMessage Invalid file format for PhpOffice\PhpPowerpoint\Reader\Serialized: + * @expectedExceptionMessage Invalid file format for PhpOffice\PhpPowerpoint\Reader\Serialized: */ public function testLoadFileBadFormat() { diff --git a/tests/PhpPowerpoint/Tests/Shape/Chart/SeriesTest.php b/tests/PhpPowerpoint/Tests/Shape/Chart/SeriesTest.php index 0e548cf62..93e3c8272 100644 --- a/tests/PhpPowerpoint/Tests/Shape/Chart/SeriesTest.php +++ b/tests/PhpPowerpoint/Tests/Shape/Chart/SeriesTest.php @@ -40,6 +40,24 @@ public function testConstruct() $this->assertInternalType('array', $object->getValues()); $this->assertEmpty($object->getValues()); } + + public function testDataLabelNumFormat() + { + $object = new Series(); + + $this->assertEmpty($object->getDlblNumFormat()); + $this->assertFalse($object->hasDlblNumFormat()); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Series', $object->setDlblNumFormat('#%')); + + $this->assertEquals('#%', $object->getDlblNumFormat()); + $this->assertTrue($object->hasDlblNumFormat()); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Series', $object->setDlblNumFormat()); + + $this->assertEmpty($object->getDlblNumFormat()); + $this->assertFalse($object->hasDlblNumFormat()); + } public function testDataPointFills() { @@ -51,6 +69,16 @@ public function testDataPointFills() $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Style\\Fill', $object->getDataPointFill(0)); } + public function testFill() + { + $object = new Series(); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Series', $object->setFill()); + $this->assertNull($object->getFill()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Series', $object->setFill(new Fill())); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Style\\Fill', $object->getFill()); + } + public function testFont() { $object = new Series(); diff --git a/tests/PhpPowerpoint/Tests/Shape/Chart/Type/AreaTest.php b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/AreaTest.php new file mode 100644 index 000000000..db338b273 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/AreaTest.php @@ -0,0 +1,65 @@ +assertInternalType('array', $object->getData()); + $this->assertEmpty($object->getData()); + + $array = array( + new Series(), + new Series(), + ); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Area', $object->setData()); + $this->assertEmpty($object->getData()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Area', $object->setData($array)); + $this->assertCount(count($array), $object->getData()); + } + + public function testSeries() + { + $object = new Area(); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Area', $object->addSeries(new Series())); + $this->assertCount(1, $object->getData()); + } + + public function testHashCode() + { + $oSeries = new Series(); + + $object = new Area(); + $object->addSeries($oSeries); + + $this->assertEquals(md5($oSeries->getHashCode().get_class($object)), $object->getHashCode()); + } +} diff --git a/tests/PhpPowerpoint/Tests/Shape/Chart/Type/Bar3DTest.php b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/Bar3DTest.php index 4e5332c9d..6b51f5f74 100644 --- a/tests/PhpPowerpoint/Tests/Shape/Chart/Type/Bar3DTest.php +++ b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/Bar3DTest.php @@ -45,13 +45,35 @@ public function testData() $this->assertCount(count($array), $object->getData()); } - public function testSerties() + public function testSeries() { $object = new Bar3D(); $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar3D', $object->addSeries(new Series())); $this->assertCount(1, $object->getData()); } + + public function testBarDirection() + { + $object = new Bar3D(); + $this->assertEquals(Bar3D::DIRECTION_VERTICAL, $object->getBarDirection()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar3D', $object->setBarDirection(Bar3D::DIRECTION_HORIZONTAL)); + $this->assertEquals(Bar3D::DIRECTION_HORIZONTAL, $object->getBarDirection()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar3D', $object->setBarDirection(Bar3D::DIRECTION_VERTICAL)); + $this->assertEquals(Bar3D::DIRECTION_VERTICAL, $object->getBarDirection()); + } + + public function testBarGrouping() + { + $object = new Bar3D(); + $this->assertEquals(Bar3D::GROUPING_CLUSTERED, $object->getBarGrouping()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar3D', $object->setBarGrouping(Bar3D::GROUPING_CLUSTERED)); + $this->assertEquals(Bar3D::GROUPING_CLUSTERED, $object->getBarGrouping()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar3D', $object->setBarGrouping(Bar3D::GROUPING_STACKED)); + $this->assertEquals(Bar3D::GROUPING_STACKED, $object->getBarGrouping()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar3D', $object->setBarGrouping(Bar3D::GROUPING_PERCENTSTACKED)); + $this->assertEquals(Bar3D::GROUPING_PERCENTSTACKED, $object->getBarGrouping()); + } public function testHashCode() { diff --git a/tests/PhpPowerpoint/Tests/Shape/Chart/Type/BarTest.php b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/BarTest.php new file mode 100644 index 000000000..6126942e1 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/BarTest.php @@ -0,0 +1,87 @@ +assertInternalType('array', $object->getData()); + $this->assertEmpty($object->getData()); + + $array = array( + new Series(), + new Series(), + ); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar', $object->setData()); + $this->assertEmpty($object->getData()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar', $object->setData($array)); + $this->assertCount(count($array), $object->getData()); + } + + public function testSeries() + { + $object = new Bar(); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar', $object->addSeries(new Series())); + $this->assertCount(1, $object->getData()); + } + + public function testBarDirection() + { + $object = new Bar(); + $this->assertEquals(Bar::DIRECTION_VERTICAL, $object->getBarDirection()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar', $object->setBarDirection(Bar::DIRECTION_HORIZONTAL)); + $this->assertEquals(Bar::DIRECTION_HORIZONTAL, $object->getBarDirection()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar', $object->setBarDirection(Bar::DIRECTION_VERTICAL)); + $this->assertEquals(Bar::DIRECTION_VERTICAL, $object->getBarDirection()); + } + + public function testBarGrouping() + { + $object = new Bar(); + $this->assertEquals(Bar::GROUPING_CLUSTERED, $object->getBarGrouping()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar', $object->setBarGrouping(Bar::GROUPING_CLUSTERED)); + $this->assertEquals(Bar::GROUPING_CLUSTERED, $object->getBarGrouping()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar', $object->setBarGrouping(Bar::GROUPING_STACKED)); + $this->assertEquals(Bar::GROUPING_STACKED, $object->getBarGrouping()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Bar', $object->setBarGrouping(Bar::GROUPING_PERCENTSTACKED)); + $this->assertEquals(Bar::GROUPING_PERCENTSTACKED, $object->getBarGrouping()); + } + + public function testHashCode() + { + $oSeries = new Series(); + + $object = new Bar(); + $object->addSeries($oSeries); + + $this->assertEquals(md5($oSeries->getHashCode().get_class($object)), $object->getHashCode()); + } +} diff --git a/tests/PhpPowerpoint/Tests/Shape/Chart/Type/Pie3DTest.php b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/Pie3DTest.php index 16c0a54ad..2b5895e24 100644 --- a/tests/PhpPowerpoint/Tests/Shape/Chart/Type/Pie3DTest.php +++ b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/Pie3DTest.php @@ -45,7 +45,7 @@ public function testData() $this->assertCount(count($array), $object->getData()); } - public function testSerties() + public function testSeries() { $object = new Pie3D(); @@ -53,6 +53,17 @@ public function testSerties() $this->assertCount(1, $object->getData()); } + public function testExplosion() + { + $value = rand(0, 100); + + $object = new Pie3D(); + + $this->assertEquals(0, $object->getExplosion()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Pie3D', $object->setExplosion($value)); + $this->assertEquals($value, $object->getExplosion()); + } + public function testHashCode() { $oSeries = new Series(); diff --git a/tests/PhpPowerpoint/Tests/Shape/Chart/Type/PieTest.php b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/PieTest.php new file mode 100644 index 000000000..57625978b --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Shape/Chart/Type/PieTest.php @@ -0,0 +1,66 @@ +assertInternalType('array', $object->getData()); + $this->assertEmpty($object->getData()); + + $array = array( + new Series(), + new Series(), + ); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Pie', $object->setData()); + $this->assertEmpty($object->getData()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Pie', $object->setData($array)); + $this->assertCount(count($array), $object->getData()); + } + + public function testSeries() + { + $object = new Pie(); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Type\\Pie', $object->addSeries(new Series())); + $this->assertCount(1, $object->getData()); + } + + + public function testHashCode() + { + $oSeries = new Series(); + + $object = new Pie(); + $object->addSeries($oSeries); + + $this->assertEquals(md5($oSeries->getHashCode().get_class($object)), $object->getHashCode()); + } +} diff --git a/tests/PhpPowerpoint/Tests/Shape/ChartTest.php b/tests/PhpPowerpoint/Tests/Shape/ChartTest.php index 651477d03..fdce9d58b 100644 --- a/tests/PhpPowerpoint/Tests/Shape/ChartTest.php +++ b/tests/PhpPowerpoint/Tests/Shape/ChartTest.php @@ -35,6 +35,20 @@ public function testConstruct() $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\PlotArea', $object->getPlotArea()); $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\View3D', $object->getView3D()); } + + + public function testClone() + { + $object = new Chart(); + + $oClone = clone $object; + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart', $oClone); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Title', $oClone->getTitle()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\Legend', $oClone->getLegend()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\PlotArea', $oClone->getPlotArea()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart\\View3D', $oClone->getView3D()); + } public function testIncludeSpreadsheet() { diff --git a/tests/PhpPowerpoint/Tests/Shape/GroupTest.php b/tests/PhpPowerpoint/Tests/Shape/GroupTest.php new file mode 100644 index 000000000..9f019cdfb --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Shape/GroupTest.php @@ -0,0 +1,147 @@ +assertEquals(0, $object->getOffsetX()); + $this->assertEquals(0, $object->getOffsetY()); + $this->assertEquals(0, $object->getExtentX()); + $this->assertEquals(0, $object->getExtentY()); + $this->assertEquals(0, $object->getShapeCollection()->count()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Group', $object->setWidth(rand(1, 100))); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Group', $object->setHeight(rand(1, 100))); + } + + public function testAdd() + { + $object = new Group(); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Chart', $object->createChartShape()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Drawing', $object->createDrawingShape()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Line', $object->createLineShape(10, 10, 10, 10)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\RichText', $object->createRichTextShape()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Table', $object->createTableShape()); + $this->assertEquals(5, $object->getShapeCollection()->count()); + } + + public function testExtentX() + { + $object = new Group(); + $line1 = new Line(10, 20, 30, 40); + $object->addShape($line1); + + $this->assertEquals(30, $object->getExtentX()); + } + + public function testExtentY() + { + $object = new Group(); + $line1 = new Line(10, 20, 30, 40); + $object->addShape($line1); + + $this->assertEquals(40, $object->getExtentY()); + } + + public function testOffsetX() + { + $object = new Group(); + $line1 = new Line(10, 20, 30, 40); + $object->addShape($line1); + + $this->assertEquals(10, $object->getOffsetX()); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Group', $object->setOffsetX(rand(1, 100))); + $this->assertEquals(10, $object->getOffsetX()); + } + + public function testOffsetY() + { + $object = new Group(); + $line1 = new Line(10, 20, 30, 40); + $object->addShape($line1); + + $this->assertEquals(20, $object->getOffsetY()); + + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Group', $object->setOffsetY(rand(1, 100))); + $this->assertEquals(20, $object->getOffsetY()); + } + + public function testExtentsAndOffsetsForOneShape() + { + // We record initial values here because + // PhpOffice\PhpPowerpoint\Shape\Line subtracts the offsets + // from the extents to produce a raw width and height. + $offsetX = 100; + $offsetY = 100; + $extentX = 1000; + $extentY = 450; + + $object = new Group(); + $line1 = new Line($offsetX, $offsetY, $extentX, $extentY); + $object->addShape($line1); + + $this->assertEquals($offsetX, $object->getOffsetX()); + $this->assertEquals($offsetY, $object->getOffsetY()); + $this->assertEquals($extentX, $object->getExtentX()); + $this->assertEquals($extentY, $object->getExtentY()); + } + + public function testExtentsAndOffsetsForTwoShapes() + { + // Since Groups and Slides cache offsets and extents on first + // calculation, this test is separate from the above. + // Should the calculation be performed every GET, this test can be + // combined with the above. + $offsetX = 100; + $offsetY = 100; + $extentX = 1000; + $extentY = 450; + $increase = 50; + + $line1 = new Line($offsetX, $offsetY, $extentX, $extentY); + $line2 = new Line( + $offsetX+$increase, + $offsetY+$increase, + $extentX+$increase, + $extentY+$increase + ); + + $object = new Group(); + + $object->addShape($line1); + $object->addShape($line2); + + $this->assertEquals($offsetX, $object->getOffsetX()); + $this->assertEquals($offsetY, $object->getOffsetY()); + $this->assertEquals($extentX+$increase, $object->getExtentX()); + $this->assertEquals($extentY+$increase, $object->getExtentY()); + } +} diff --git a/tests/PhpPowerpoint/Tests/Shared/DrawingTest.php b/tests/PhpPowerpoint/Tests/Shared/DrawingTest.php deleted file mode 100644 index 4f7ef947f..000000000 --- a/tests/PhpPowerpoint/Tests/Shared/DrawingTest.php +++ /dev/null @@ -1,76 +0,0 @@ -assertEquals(0, Drawing::pixelsToCentimeters()); - $this->assertEquals($value / Drawing::DPI_96 * 2.54, Drawing::pixelsToCentimeters($value)); - $this->assertEquals(0, Drawing::centimetersToPixels()); - $this->assertEquals($value / 2.54 * Drawing::DPI_96, Drawing::centimetersToPixels($value)); - } - - /** - */ - public function testPixelsEMU() - { - $value = rand(1, 100); - - $this->assertEquals(0, Drawing::pixelsToEmu()); - $this->assertEquals(round($value*9525), Drawing::pixelsToEmu($value)); - $this->assertEquals(0, Drawing::emuToPixels()); - $this->assertEquals(round($value/9525), Drawing::emuToPixels($value)); - } - - /** - */ - public function testPixelsPoints() - { - $value = rand(1, 100); - - $this->assertEquals(0, Drawing::pixelsToPoints()); - $this->assertEquals($value*0.67777777, Drawing::pixelsToPoints($value)); - $this->assertEquals(0, Drawing::pointsToPixels()); - $this->assertEquals($value* 1.333333333, Drawing::pointsToPixels($value)); - } - - /** - */ - public function testDegreesAngle() - { - $value = rand(1, 100); - - $this->assertEquals(0, Drawing::degreesToAngle()); - $this->assertEquals((int) round($value * 60000), Drawing::degreesToAngle($value)); - $this->assertEquals(0, Drawing::angleToDegrees()); - $this->assertEquals(round($value / 60000), Drawing::angleToDegrees($value)); - } -} diff --git a/tests/PhpPowerpoint/Tests/Shared/FileTest.php b/tests/PhpPowerpoint/Tests/Shared/FileTest.php deleted file mode 100644 index 4cb228810..000000000 --- a/tests/PhpPowerpoint/Tests/Shared/FileTest.php +++ /dev/null @@ -1,51 +0,0 @@ -assertTrue(File::fileExists($pathResources.'images'.DIRECTORY_SEPARATOR.'PHPPowerPointLogo.png')); - $this->assertFalse(File::fileExists($pathResources.'images'.DIRECTORY_SEPARATOR.'PHPPowerPointLogo_404.png')); - $this->assertTrue(File::fileExists('zip://'.$pathResources.'files'.DIRECTORY_SEPARATOR.'Sample_01_Simple.pptx#[Content_Types].xml')); - $this->assertFalse(File::fileExists('zip://'.$pathResources.'files'.DIRECTORY_SEPARATOR.'Sample_01_Simple.pptx#404.xml')); - $this->assertFalse(File::fileExists('zip://'.$pathResources.'files'.DIRECTORY_SEPARATOR.'404.pptx#404.xml')); - } - - /** - */ - public function testRealPath() - { - $pathFiles = PHPPOWERPOINT_TESTS_BASE_DIR.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'files'.DIRECTORY_SEPARATOR; - - $this->assertEquals($pathFiles.'Sample_01_Simple.pptx', File::realpath($pathFiles.'Sample_01_Simple.pptx')); - $this->assertEquals('zip://'.$pathFiles.'Sample_01_Simple.pptx#[Content_Types].xml', File::realpath('zip://'.$pathFiles.'Sample_01_Simple.pptx#[Content_Types].xml')); - $this->assertEquals('zip://'.$pathFiles.'Sample_01_Simple.pptx#/[Content_Types].xml', File::realpath('zip://'.$pathFiles.'Sample_01_Simple.pptx#/rels/../[Content_Types].xml')); - } -} diff --git a/tests/PhpPowerpoint/Tests/Shared/FontTest.php b/tests/PhpPowerpoint/Tests/Shared/FontTest.php deleted file mode 100644 index b9b307e1b..000000000 --- a/tests/PhpPowerpoint/Tests/Shared/FontTest.php +++ /dev/null @@ -1,41 +0,0 @@ -assertEquals(16, Font::fontSizeToPixels()); - $this->assertEquals((16 / 12) * $value, Font::fontSizeToPixels($value)); - $this->assertEquals(96, Font::inchSizeToPixels()); - $this->assertEquals(96 * $value, Font::inchSizeToPixels($value)); - $this->assertEquals(37.795275591, Font::centimeterSizeToPixels()); - $this->assertEquals(37.795275591 * $value, Font::centimeterSizeToPixels($value)); - } -} diff --git a/tests/PhpPowerpoint/Tests/Shared/StringTest.php b/tests/PhpPowerpoint/Tests/Shared/StringTest.php deleted file mode 100644 index 50445bf4e..000000000 --- a/tests/PhpPowerpoint/Tests/Shared/StringTest.php +++ /dev/null @@ -1,47 +0,0 @@ -assertEquals('', String::controlCharacterPHP2OOXML()); - $this->assertEquals('aeiou', String::controlCharacterPHP2OOXML('aeiou')); - $this->assertEquals('àéîöù', String::controlCharacterPHP2OOXML('àéîöù')); - - $value = rand(0, 8); - $this->assertEquals('_x'.sprintf('%04s', strtoupper(dechex($value))).'_', String::controlCharacterPHP2OOXML(chr($value))); - } - - public function testNumberFormat() - { - $this->assertEquals('2.1', String::numberFormat('2.06', 1)); - $this->assertEquals('2.1', String::numberFormat('2.12', 1)); - $this->assertEquals('1234', String::numberFormat(1234, 1)); - } -} diff --git a/tests/PhpPowerpoint/Tests/Shared/XMLWriterTest.php b/tests/PhpPowerpoint/Tests/Shared/XMLWriterTest.php deleted file mode 100644 index 94eaa5e16..000000000 --- a/tests/PhpPowerpoint/Tests/Shared/XMLWriterTest.php +++ /dev/null @@ -1,47 +0,0 @@ -startElement('element'); - $object->text('AAA'); - $object->endElement(); - $this->assertEquals('AAA'.chr(10), $object->getData()); - - // Disk - $object = new XMLWriter(XMLWriter::STORAGE_DISK); - $object->startElement('element'); - $object->text('BBB'); - $object->endElement(); - $this->assertEquals('BBB'.chr(10), $object->getData()); - } -} diff --git a/tests/PhpPowerpoint/Tests/Slide/NoteTest.php b/tests/PhpPowerpoint/Tests/Slide/NoteTest.php new file mode 100644 index 000000000..ede2bed16 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Slide/NoteTest.php @@ -0,0 +1,89 @@ +assertNull($object->getParent()); + + $oPhpPowerpoint = new PhpPowerpoint(); + $oSlide = $oPhpPowerpoint->createSlide(); + $oSlide->setNote($object); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide', $object->getParent()); + } + + public function testExtent() + { + $object = new Note(); + $this->assertNotNull($object->getExtentX()); + + $object = new Note(); + $this->assertNotNull($object->getExtentY()); + } + + public function testHashCode() + { + $object = new Note(); + $this->assertInternalType('string', $object->getHashCode()); + } + + public function testOffset() + { + $object = new Note(); + $this->assertNotNull($object->getOffsetX()); + + $object = new Note(); + $this->assertNotNull($object->getOffsetY()); + } + + public function testShape() + { + $object = new Note(); + $this->assertEquals(0, $object->getShapeCollection()->count()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\RichText', $object->createRichTextShape()); + $this->assertEquals(1, $object->getShapeCollection()->count()); + + $oRichText = new RichText(); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\RichText', $object->addShape($oRichText)); + $this->assertEquals(2, $object->getShapeCollection()->count()); + } + + /** + * Test get/set hash index + */ + public function testSetGetHashIndex() + { + $object = new Note(); + $value = rand(1, 100); + $this->assertNull($object->getHashIndex()); + $object->setHashIndex($value); + $this->assertEquals($value, $object->getHashIndex()); + } +} diff --git a/tests/PhpPowerpoint/Tests/Slide/TransitionTest.php b/tests/PhpPowerpoint/Tests/Slide/TransitionTest.php new file mode 100644 index 000000000..531aadc4a --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Slide/TransitionTest.php @@ -0,0 +1,93 @@ +assertNull($object->getSpeed()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setSpeed()); + $this->assertEquals(Transition::SPEED_MEDIUM, $object->getSpeed()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setSpeed(Transition::SPEED_FAST)); + $this->assertEquals(Transition::SPEED_FAST, $object->getSpeed()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setSpeed(rand(1, 1000))); + $this->assertNull($object->getSpeed()); + } + + public function testManualTrigger() + { + $object = new Transition(); + $this->assertFalse($object->hasManualTrigger()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setManualTrigger()); + $this->assertFalse($object->hasManualTrigger()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setManualTrigger(true)); + $this->assertTrue($object->hasManualTrigger()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setManualTrigger(null)); + $this->assertTrue($object->hasManualTrigger()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setManualTrigger(false)); + $this->assertFalse($object->hasManualTrigger()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setManualTrigger(null)); + $this->assertFalse($object->hasManualTrigger()); + } + + public function testTimeTrigger() + { + $object = new Transition(); + $this->assertFalse($object->hasTimeTrigger()); + $this->assertNull($object->getAdvanceTimeTrigger()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setTimeTrigger()); + $this->assertFalse($object->hasTimeTrigger()); + $this->assertNull($object->getAdvanceTimeTrigger()); + $value = rand(1, 1000); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setTimeTrigger(true, $value)); + $this->assertTrue($object->hasTimeTrigger()); + $this->assertEquals($value, $object->getAdvanceTimeTrigger()); + $value = rand(1, 1000); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setTimeTrigger(null, $value)); + $this->assertTrue($object->hasTimeTrigger()); + $this->assertEquals($value, $object->getAdvanceTimeTrigger()); + $value = rand(1, 1000); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setTimeTrigger(false, $value)); + $this->assertFalse($object->hasTimeTrigger()); + $this->assertNull($object->getAdvanceTimeTrigger()); + $value = rand(1, 1000); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setTimeTrigger(null, $value)); + $this->assertFalse($object->hasTimeTrigger()); + $this->assertNull($object->getAdvanceTimeTrigger()); + } + + public function testTransitionType() + { + $object = new Transition(); + $this->assertNull($object->getTransitionType()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setTransitionType()); + $this->assertNull($object->getTransitionType()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->setTransitionType(Transition::TRANSITION_RANDOM)); + $this->assertEquals(Transition::TRANSITION_RANDOM, $object->getTransitionType()); + + } +} diff --git a/tests/PhpPowerpoint/Tests/SlideTest.php b/tests/PhpPowerpoint/Tests/SlideTest.php index 7af850a2d..6dd0783bd 100644 --- a/tests/PhpPowerpoint/Tests/SlideTest.php +++ b/tests/PhpPowerpoint/Tests/SlideTest.php @@ -18,6 +18,7 @@ namespace PhpOffice\PhpPowerpoint\Tests; use PhpOffice\PhpPowerpoint\Slide; +use PhpOffice\PhpPowerpoint\Slide\Transition; use PhpOffice\PhpPowerpoint\PhpPowerpoint; /** @@ -27,6 +28,24 @@ */ class SlideTest extends \PHPUnit_Framework_TestCase { + public function testExtents() + { + $object = new Slide(); + $this->assertNotNull($object->getExtentX()); + + $object = new Slide(); + $this->assertNotNull($object->getExtentY()); + } + + public function testOffset() + { + $object = new Slide(); + $this->assertNotNull($object->getOffsetX()); + + $object = new Slide(); + $this->assertNotNull($object->getOffsetY()); + } + public function testParent() { $object = new Slide(); @@ -58,4 +77,23 @@ public function testSlideMasterId() $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide', $object->setSlideMasterId($value)); $this->assertEquals($value, $object->getSlideMasterId()); } + + public function testGroup() + { + $object = new Slide(); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Shape\\Group', $object->createGroup()); + } + + public function testTransition() + { + $object = new Slide(); + $oTransition = new Transition(); + $this->assertNull($object->getTransition()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide', $object->setTransition()); + $this->assertNull($object->getTransition()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide', $object->setTransition($oTransition)); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide\\Transition', $object->getTransition()); + $this->assertInstanceOf('PhpOffice\\PhpPowerpoint\\Slide', $object->setTransition(null)); + $this->assertNull($object->getTransition()); + } } diff --git a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/AbstractPartTest.php b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/AbstractPartTest.php new file mode 100644 index 000000000..c0f9ca7d0 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/AbstractPartTest.php @@ -0,0 +1,89 @@ +setAccessible(true); + return $method->invokeArgs($obj, $args); + } + + /** + * Executed before each method of the class + */ + public function tearDown() + { + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage No parent \PhpOffice\PhpPowerpoint\Writer\WriterInterface assigned. + */ + public function testParentException() + { + $oDrawing = new Drawing(); + $oDrawing->getParentWriter(); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation + */ + public function testWriterException() + { + $oManifest = new Manifest(); + $oManifest->setParentWriter(new PowerPoint2007()); + $oManifest->writePart(); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\ODPresentation + */ + public function testXMLWriterException() + { + $oManifest = new Manifest(); + $oManifest->setParentWriter(new PowerPoint2007()); + $this->runProtectedMethod($oManifest, 'getXMLWriter'); + } + + public function testXMLWriterWithDiskCaching() + { + $oODPresentation = new ODPresentation(); + $oODPresentation->setUseDiskCaching(true); + $oManifest = new Manifest(); + $oManifest->setParentWriter($oODPresentation); + + $this->assertNotEmpty(\PHPUnit_Framework_Assert::readAttribute($this->runProtectedMethod($oManifest, 'getXMLWriter'), 'tempFileName')); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartAreaTest.php b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartAreaTest.php new file mode 100644 index 000000000..d8609e489 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartAreaTest.php @@ -0,0 +1,76 @@ + 1, 'Feb' => 5, 'Mar' => 2)); + $oSeries->getFill()->setStartColor(new Color('FF93A9CE')); + + $oArea = new Area(); + $oArea->addSeries($oSeries); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oChart = $oSlide->createChartShape(); + $oChart->getPlotArea()->setType($oArea); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:chart/chart:chart'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('chart:area', $pres->getElementAttribute($element, 'chart:class', 'Object 1/content.xml')); + + $element = '/office:document-content/office:body/office:chart/chart:chart/chart:plot-area/chart:series'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('chart:area', $pres->getElementAttribute($element, 'chart:class', 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleSeries0\']/style:graphic-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'draw:fill', 'Object 1/content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:fill-color', 'Object 1/content.xml')); + $this->assertEquals('#93A9CE', $pres->getElementAttribute($element, 'draw:fill-color', 'Object 1/content.xml')); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartBarTest.php b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartBarTest.php new file mode 100644 index 000000000..43cec308e --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartBarTest.php @@ -0,0 +1,104 @@ + 1, 'Feb' => 5, 'Mar' => 2)); + $oSeries->setShowSeriesName(true); + $oSeries->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4672A8')); + $oSeries->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFAB4744')); + $oSeries->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF8AA64F')); + + $oBar = new Bar(); + $oBar->addSeries($oSeries); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oChart = $oSlide->createChartShape(); + $oChart->getPlotArea()->setType($oBar); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:chart/chart:chart'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('chart:bar', $pres->getElementAttribute($element, 'chart:class', 'Object 1/content.xml')); + + $element = '/office:document-content/office:body/office:chart/chart:chart/chart:plot-area/chart:series/chart:data-point'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'stylePlotArea\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('false', $pres->getElementAttribute($element, 'chart:vertical', 'Object 1/content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'chart:three-dimensional', 'Object 1/content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'chart:right-angled-axes', 'Object 1/content.xml')); + } + + public function testChartBarHorizontal() + { + $oSeries = new Series('Series', array('Jan' => 1, 'Feb' => 5, 'Mar' => 2)); + $oSeries->setShowSeriesName(true); + $oSeries->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4672A8')); + $oSeries->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFAB4744')); + $oSeries->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF8AA64F')); + + $oBar = new Bar(); + $oBar->setBarDirection(Bar::DIRECTION_HORIZONTAL); + $oBar->addSeries($oSeries); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oChart = $oSlide->createChartShape(); + $oChart->getPlotArea()->setType($oBar); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:chart/chart:chart'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('chart:bar', $pres->getElementAttribute($element, 'chart:class', 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'stylePlotArea\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:vertical', 'Object 1/content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'chart:three-dimensional', 'Object 1/content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'chart:right-angled-axes', 'Object 1/content.xml')); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartsTest.php b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartsTest.php index 44345d7a5..9fc5e55ff 100644 --- a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartsTest.php +++ b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ChartsTest.php @@ -21,6 +21,7 @@ use PhpOffice\PhpPowerpoint\Shape\Chart\Series; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar3D; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Line; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie3D; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Scatter; use PhpOffice\PhpPowerpoint\Style\Color; @@ -58,6 +59,30 @@ public function testNoChart() TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); } + + public function testTitleVisibility() + { + + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oShape = $oSlide->createChartShape(); + $oLine = new Line(); + $oShape->getPlotArea()->setType($oLine); + + $elementTitle = '/office:document-content/office:body/office:chart/chart:chart/chart:title'; + $elementStyle = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleTitle\']'; + + $this->assertTrue($oShape->getTitle()->isVisible()); + $this->assertInstanceOf('PhpOffice\PhpPowerpoint\Shape\Chart\Title', $oShape->getTitle()->setVisible(true)); + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'ODPresentation'); + $this->assertTrue($oXMLDoc->elementExists($elementTitle, 'Object 1/content.xml')); + $this->assertTrue($oXMLDoc->elementExists($elementStyle, 'Object 1/content.xml')); + + $this->assertInstanceOf('PhpOffice\PhpPowerpoint\Shape\Chart\Title', $oShape->getTitle()->setVisible(false)); + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'ODPresentation'); + $this->assertFalse($oXMLDoc->elementExists($elementTitle, 'Object 1/content.xml')); + $this->assertFalse($oXMLDoc->elementExists($elementStyle, 'Object 1/content.xml')); + } public function testChartBar3D() { @@ -83,6 +108,46 @@ public function testChartBar3D() $element = '/office:document-content/office:body/office:chart/chart:chart/chart:plot-area/chart:series/chart:data-point'; $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'stylePlotArea\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('false', $pres->getElementAttribute($element, 'chart:vertical', 'Object 1/content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'chart:three-dimensional', 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:three-dimensional', 'Object 1/content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'chart:right-angled-axes', 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:right-angled-axes', 'Object 1/content.xml')); + } + + public function testChartBar3DHorizontal() + { + $oSeries = new Series('Series', array('Jan' => 1, 'Feb' => 5, 'Mar' => 2)); + $oSeries->setShowSeriesName(true); + $oSeries->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4672A8')); + $oSeries->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFAB4744')); + $oSeries->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF8AA64F')); + + $oBar3D = new Bar3D(); + $oBar3D->setBarDirection(Bar3D::DIRECTION_HORIZONTAL); + $oBar3D->addSeries($oSeries); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oChart = $oSlide->createChartShape(); + $oChart->getPlotArea()->setType($oBar3D); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:chart/chart:chart'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('chart:bar', $pres->getElementAttribute($element, 'chart:class', 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'stylePlotArea\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:vertical', 'Object 1/content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'chart:three-dimensional', 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:three-dimensional', 'Object 1/content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'chart:right-angled-axes', 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:right-angled-axes', 'Object 1/content.xml')); } public function testChartLine() @@ -103,9 +168,25 @@ public function testChartLine() $element = '/office:document-content/office:body/office:chart/chart:chart'; $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); $this->assertEquals('chart:line', $pres->getElementAttribute($element, 'chart:class', 'Object 1/content.xml')); + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleAxisX\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('false', $pres->getElementAttribute($element, 'chart:tick-marks-major-inner', 'Object 1/content.xml')); + $this->assertEquals('false', $pres->getElementAttribute($element, 'chart:tick-marks-major-outer', 'Object 1/content.xml')); + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleAxisX\']/style:graphic-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('0.026cm', $pres->getElementAttribute($element, 'svg:stroke-width', 'Object 1/content.xml')); + $this->assertEquals('#878787', $pres->getElementAttribute($element, 'svg:stroke-color', 'Object 1/content.xml')); + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleAxisY\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('false', $pres->getElementAttribute($element, 'chart:tick-marks-major-inner', 'Object 1/content.xml')); + $this->assertEquals('false', $pres->getElementAttribute($element, 'chart:tick-marks-major-outer', 'Object 1/content.xml')); + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleAxisY\']/style:graphic-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('0.026cm', $pres->getElementAttribute($element, 'svg:stroke-width', 'Object 1/content.xml')); + $this->assertEquals('#878787', $pres->getElementAttribute($element, 'svg:stroke-color', 'Object 1/content.xml')); } - public function testChartPie3D() + public function testChartPie() { $oSeries = new Series('Series', array('Jan' => 1, 'Feb' => 5, 'Mar' => 2)); $oSeries->setShowSeriesName(true); @@ -113,13 +194,13 @@ public function testChartPie3D() $oSeries->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFAB4744')); $oSeries->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF8AA64F')); - $oPie3D = new Pie3D(); - $oPie3D->addSeries($oSeries); + $oPie = new Pie(); + $oPie->addSeries($oSeries); $phpPowerPoint = new PhpPowerpoint(); $oSlide = $phpPowerPoint->getActiveSlide(); $oChart = $oSlide->createChartShape(); - $oChart->getPlotArea()->setType($oPie3D); + $oChart->getPlotArea()->setType($oPie); $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); @@ -129,6 +210,71 @@ public function testChartPie3D() $element = '/office:document-content/office:body/office:chart/chart:chart/chart:plot-area/chart:series/chart:data-point'; $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleAxisX\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:reverse-direction', 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleAxisY\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:reverse-direction', 'Object 1/content.xml')); + } + + public function testChartPie3D() + { + $oSeries = new Series('Series', array('Jan' => 1, 'Feb' => 5, 'Mar' => 2)); + $oSeries->setShowSeriesName(true); + $oSeries->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF4672A8')); + $oSeries->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFAB4744')); + $oSeries->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF8AA64F')); + + $oPie3D = new Pie3D(); + $oPie3D->addSeries($oSeries); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oChart = $oSlide->createChartShape(); + $oChart->getPlotArea()->setType($oPie3D); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:chart/chart:chart'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('chart:circle', $pres->getElementAttribute($element, 'chart:class', 'Object 1/content.xml')); + + $element = '/office:document-content/office:body/office:chart/chart:chart/chart:plot-area/chart:series/chart:data-point'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleAxisX\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:reverse-direction', 'Object 1/content.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleAxisY\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals('true', $pres->getElementAttribute($element, 'chart:reverse-direction', 'Object 1/content.xml')); + } + + public function testChartPie3DExplosion() + { + $value = rand(0, 100); + + $oSeries = new Series('Series', array('Jan' => 1, 'Feb' => 5, 'Mar' => 2)); + $oSeries->setShowSeriesName(true); + + $oPie3D = new Pie3D(); + $oPie3D->setExplosion($value); + $oPie3D->addSeries($oSeries); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oChart = $oSlide->createChartShape(); + $oChart->getPlotArea()->setType($oPie3D); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'styleSeries0\'][@style:family=\'chart\']/style:chart-properties'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $this->assertEquals($value, $pres->getElementAttribute($element, 'chart:pie-offset', 'Object 1/content.xml')); } public function testChartScatter() @@ -150,4 +296,31 @@ public function testChartScatter() $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); $this->assertEquals('chart:scatter', $pres->getElementAttribute($element, 'chart:class', 'Object 1/content.xml')); } + + public function testLegend() + { + $oSeries = new Series('Series', array('Jan' => 1, 'Feb' => 5, 'Mar' => 2)); + $oSeries->setShowSeriesName(true); + + $oLine = new Line(); + $oLine->addSeries($oSeries); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oChart = $oSlide->createChartShape(); + $oChart->getPlotArea()->setType($oLine); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:chart/chart:chart/chart:legend'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $element = '/office:document-content/office:body/office:chart/chart:chart/table:table/table:table-header-rows'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $element = '/office:document-content/office:body/office:chart/chart:chart/table:table/table:table-header-rows/table:table-row'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $element = '/office:document-content/office:body/office:chart/chart:chart/table:table/table:table-header-rows/table:table-row/table:table-cell'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + $element = '/office:document-content/office:body/office:chart/chart:chart/table:table/table:table-header-rows/table:table-row/table:table-cell[@office:value-type=\'string\']'; + $this->assertTrue($pres->elementExists($element, 'Object 1/content.xml')); + } } diff --git a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ContentTest.php b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ContentTest.php index d4acceaad..4af9d7aca 100644 --- a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ContentTest.php +++ b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/ContentTest.php @@ -17,12 +17,19 @@ namespace PhpOffice\PhpPowerpoint\Tests\Writer\ODPresentation; +use PhpOffice\Common\Drawing as CommonDrawing; use PhpOffice\PhpPowerpoint\PhpPowerpoint; use PhpOffice\PhpPowerpoint\Shape\RichText\Run; +use PhpOffice\PhpPowerpoint\Slide\Transition; use PhpOffice\PhpPowerpoint\Style\Alignment; +use PhpOffice\PhpPowerpoint\Style\Border; use PhpOffice\PhpPowerpoint\Style\Bullet; +use PhpOffice\PhpPowerpoint\Style\Color; use PhpOffice\PhpPowerpoint\Writer\ODPresentation; use PhpOffice\PhpPowerpoint\Tests\TestHelperDOCX; +use PhpOffice\Common\Drawing; +use PhpOffice\PhpPowerpoint\Style\Fill; +use PhpOffice\PhpPowerpoint\Style\PhpOffice\PhpPowerpoint\Style; /** * Test class for PhpOffice\PhpPowerpoint\Writer\ODPresentation\Manifest @@ -39,6 +46,38 @@ public function tearDown() TestHelperDOCX::clear(); } + public function testDrawingWithHyperlink() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createDrawingShape(); + $oShape->setPath(PHPPOWERPOINT_TESTS_BASE_DIR.'/resources/images/PHPPowerPointLogo.png'); + $oShape->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPowerPoint/'); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:presentation/draw:page/draw:frame/office:event-listeners/presentation:event-listener'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertEquals('https://github.com/PHPOffice/PHPPowerPoint/', $pres->getElementAttribute($element, 'xlink:href', 'content.xml')); + } + + public function testGroup() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShapeGroup = $oSlide->createGroup(); + $oShape = $oShapeGroup->createDrawingShape(); + $oShape->setPath(PHPPOWERPOINT_TESTS_BASE_DIR.'/resources/images/PHPPowerPointLogo.png'); + $oShape->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPowerPoint/'); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:presentation/draw:page/draw:g'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $element = '/office:document-content/office:body/office:presentation/draw:page/draw:g/draw:frame/office:event-listeners/presentation:event-listener'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + } + public function testList() { $phpPowerPoint = new PhpPowerpoint(); @@ -137,7 +176,22 @@ public function testListWithRichText() $this->assertTrue($pres->elementExists($element, 'content.xml')); } - public function testRichtextAutoShrink() + public function testNote() + { + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oNote = $oSlide->getNote(); + $oRichText = $oNote->createRichTextShape()->setHeight(300)->setWidth(600); + $oRichText->createTextRun('testNote'); + + $pres = TestHelperDOCX::getDocument($oPHPPowerPoint, 'ODPresentation'); + $element = '/office:document-content/office:body/office:presentation/draw:page/presentation:notes'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $element = '/office:document-content/office:body/office:presentation/draw:page/presentation:notes/draw:frame/draw:text-box/text:p/text:span'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + } + + public function testRichTextAutoShrink() { $phpPowerPoint = new PhpPowerpoint(); $oSlide = $phpPowerPoint->getActiveSlide(); @@ -167,6 +221,90 @@ public function testRichtextAutoShrink() $this->assertEquals('false', $pres->getElementAttribute($element, 'draw:auto-grow-height', 'content.xml')); $this->assertEquals('true', $pres->getElementAttribute($element, 'draw:auto-grow-width', 'content.xml')); } + + public function testRichTextBorder() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oRichText1 = $oSlide->createRichTextShape(); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'gr1\']/style:graphic-properties'; + + $oRichText1->getBorder()->setColor(new Color('FF4672A8'))->setDashStyle(Border::DASH_SOLID)->setLineStyle(Border::LINE_NONE); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'svg:stroke-color', 'content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'svg:stroke-width', 'content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:stroke', 'content.xml')); + $this->assertEquals('none', $pres->getElementAttribute($element, 'draw:stroke', 'content.xml')); + + $oRichText1->getBorder()->setColor(new Color('FF4672A8'))->setDashStyle(Border::DASH_SOLID)->setLineStyle(Border::LINE_SINGLE); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'svg:stroke-color', 'content.xml')); + $this->assertEquals('#'.$oRichText1->getBorder()->getColor()->getRGB(), $pres->getElementAttribute($element, 'svg:stroke-color', 'content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'svg:stroke-width', 'content.xml')); + $this->assertStringEndsWith('cm', $pres->getElementAttribute($element, 'svg:stroke-width', 'content.xml')); + $this->assertStringStartsWith((string) number_format(CommonDrawing::pointsToCentimeters($oRichText1->getBorder()->getLineWidth()), 3, '.', ''), $pres->getElementAttribute($element, 'svg:stroke-width', 'content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:stroke', 'content.xml')); + $this->assertEquals('solid', $pres->getElementAttribute($element, 'draw:stroke', 'content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'draw:stroke-dash', 'content.xml')); + + $oRichText1->getBorder()->setColor(new Color('FF4672A8'))->setDashStyle(Border::DASH_DASH); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'gr1\']/style:graphic-properties'; + $this->assertEquals('dash', $pres->getElementAttribute($element, 'draw:stroke', 'content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:stroke-dash', 'content.xml')); + $this->assertStringStartsWith('strokeDash_', $pres->getElementAttribute($element, 'draw:stroke-dash', 'content.xml')); + $this->assertStringEndsWith($oRichText1->getBorder()->getDashStyle(), $pres->getElementAttribute($element, 'draw:stroke-dash', 'content.xml')); + } + + public function testRichTextShadow() + { + $randAlpha = rand(0, 100); + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRichText->createTextRun('AAA'); + $oRichText->getShadow()->setVisible(true)->setAlpha($randAlpha)->setBlurRadius(2); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'gr1\']/style:graphic-properties'; + for ($inc = 0; $inc <= 360; $inc += 45) { + $randDistance = rand(0, 100); + $oRichText->getShadow()->setDirection($inc)->setDistance($randDistance); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertEquals('visible', $pres->getElementAttribute($element, 'draw:shadow', 'content.xml')); + $this->assertEquals('none', $pres->getElementAttribute($element, 'style:mirror', 'content.xml')); + // Opacity + $this->assertStringStartsWith((string)(100 - $randAlpha), $pres->getElementAttribute($element, 'draw:shadow-opacity', 'content.xml')); + $this->assertStringEndsWith('%', $pres->getElementAttribute($element, 'draw:shadow-opacity', 'content.xml')); + // Color + $this->assertStringStartsWith('#', $pres->getElementAttribute($element, 'draw:shadow-color', 'content.xml')); + // X + $xOffset = $pres->getElementAttribute($element, 'draw:shadow-offset-x', 'content.xml'); + if ($inc == 90 || $inc == 270) { + $this->assertEquals('0cm', $xOffset); + } else { + if ($inc > 90 && $inc < 270) { + $this->assertEquals('-'.Drawing::pixelsToCentimeters($randDistance).'cm', $xOffset); + } else { + $this->assertEquals(Drawing::pixelsToCentimeters($randDistance).'cm', $xOffset); + } + } + // Y + $yOffset = $pres->getElementAttribute($element, 'draw:shadow-offset-y', 'content.xml'); + if ($inc == 0 || $inc == 180 || $inc == 360) { + $this->assertEquals('0cm', $yOffset); + } else { + if (($inc > 0 && $inc < 180) || $inc == 360) { + $this->assertEquals(Drawing::pixelsToCentimeters($randDistance).'cm', $yOffset); + } else { + $this->assertEquals('-'.Drawing::pixelsToCentimeters($randDistance).'cm', $yOffset); + } + } + } + } public function testStyleAlignment() { @@ -257,6 +395,32 @@ public function testTable() $this->assertTrue($pres->elementExists($element, 'content.xml')); } + public function testTableCellFill() + { + $oColor = new Color(); + $oColor->setRGB(Color::COLOR_BLUE); + + $oFill = new Fill(); + $oFill->setFillType(Fill::FILL_SOLID)->setStartColor($oColor); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createTableShape(); + $oRow = $oShape->createRow(); + $oCell = $oRow->getCell(); + $oCell->setFill($oFill); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'gr1r0c0\']'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertEquals('table-cell', $pres->getElementAttribute($element, 'style:family', 'content.xml')); + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'gr1r0c0\']/style:graphic-properties'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertEquals('solid', $pres->getElementAttribute($element, 'draw:fill', 'content.xml')); + $this->assertStringStartsWith('#', $pres->getElementAttribute($element, 'draw:fill-color', 'content.xml')); + $this->assertStringEndsWith($oColor->getRGB(), $pres->getElementAttribute($element, 'draw:fill-color', 'content.xml')); + } + public function testTableWithColspan() { $value = rand(2, 100); @@ -274,6 +438,28 @@ public function testTableWithColspan() $this->assertEquals($value, $pres->getElementAttribute($element, 'table:number-columns-spanned', 'content.xml')); } + /** + * @link : https://github.com/PHPOffice/PHPPowerPoint/issues/70 + */ + public function testTableWithHyperlink() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createTableShape(4); + $oShape->setHeight(200)->setWidth(600)->setOffsetX(150)->setOffsetY(300); + $oRow = $oShape->createRow(); + $oCell = $oRow->getCell(); + $oTextRun = $oCell->createTextRun('AAA'); + $oHyperlink = $oTextRun->getHyperlink(); + $oHyperlink->setUrl('https://github.com/PHPOffice/PHPPowerPoint/'); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + + $element = '/office:document-content/office:body/office:presentation/draw:page/draw:frame/table:table/table:table-row/table:table-cell/text:p/text:span/text:a'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertEquals('https://github.com/PHPOffice/PHPPowerPoint/', $pres->getElementAttribute($element, 'xlink:href', 'content.xml')); + } + public function testTableWithText() { $oRun = new Run(); @@ -285,10 +471,214 @@ public function testTableWithText() $oRow = $oShape->createRow(); $oCell = $oRow->getCell(); $oCell->addText($oRun); + $oCell->createBreak(); $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); $element = '/office:document-content/office:body/office:presentation/draw:page/draw:frame/table:table/table:table-row/table:table-cell/text:p/text:span'; $this->assertTrue($pres->elementExists($element, 'content.xml')); $this->assertEquals('Test', $pres->getElement($element, 'content.xml')->nodeValue); + $element = '/office:document-content/office:body/office:presentation/draw:page/draw:frame/table:table/table:table-row/table:table-cell/text:p/text:span/text:line-break'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + } + + public function testTransition() + { + $value = rand(1000, 5000); + + $oTransition = new Transition(); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'stylePage0\']/style:drawing-page-properties'; + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertFalse($pres->attributeElementExists($element, 'presentation:duration', 'content.xml')); + + $oTransition->setTimeTrigger(true, $value); + $oSlide->setTransition($oTransition); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'presentation:duration', 'content.xml')); + $this->assertStringStartsWith('PT', $pres->getElementAttribute($element, 'presentation:duration', 'content.xml')); + $this->assertStringEndsWith('S', $pres->getElementAttribute($element, 'presentation:duration', 'content.xml')); + $this->assertContains(number_format($value / 1000, 6, '.', ''), $pres->getElementAttribute($element, 'presentation:duration', 'content.xml')); + $this->assertContains('automatic', $pres->getElementAttribute($element, 'presentation:transition-type', 'content.xml')); + + $oTransition->setSpeed(Transition::SPEED_FAST); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertContains('fast', $pres->getElementAttribute($element, 'presentation:transition-speed', 'content.xml')); + + $oTransition->setSpeed(Transition::SPEED_MEDIUM); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertContains('medium', $pres->getElementAttribute($element, 'presentation:transition-speed', 'content.xml')); + + $oTransition->setSpeed(Transition::SPEED_SLOW); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertContains('slow', $pres->getElementAttribute($element, 'presentation:transition-speed', 'content.xml')); + + $rcTransition = new \ReflectionClass('PhpOffice\PhpPowerpoint\Slide\Transition'); + $arrayConstants = $rcTransition->getConstants(); + foreach ($arrayConstants as $key => $value) { + if (strpos($key, 'TRANSITION_') !== 0) { + continue; + } + + $oTransition->setTransitionType($rcTransition->getConstant($key)); + $oSlide->setTransition($oTransition); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + switch ($key) { + case 'TRANSITION_BLINDS_HORIZONTAL': + $this->assertContains('horizontal-stripes', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_BLINDS_VERTICAL': + $this->assertContains('vertical-stripes', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_CHECKER_HORIZONTAL': + $this->assertContains('horizontal-checkerboard', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_CHECKER_VERTICAL': + $this->assertContains('vertical-checkerboard', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_CIRCLE_HORIZONTAL': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_CIRCLE_VERTICAL': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COMB_HORIZONTAL': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COMB_VERTICAL': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COVER_DOWN': + $this->assertContains('uncover-to-bottom', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COVER_LEFT': + $this->assertContains('uncover-to-left', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COVER_LEFT_DOWN': + $this->assertContains('uncover-to-lowerleft', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COVER_LEFT_UP': + $this->assertContains('uncover-to-upperleft', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COVER_RIGHT': + $this->assertContains('uncover-to-right', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COVER_RIGHT_DOWN': + $this->assertContains('uncover-to-lowerright', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COVER_RIGHT_UP': + $this->assertContains('uncover-to-upperright', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_COVER_UP': + $this->assertContains('uncover-to-top', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_CUT': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_DIAMOND': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_DISSOLVE': + $this->assertContains('dissolve', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_FADE': + $this->assertContains('fade-from-center', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_NEWSFLASH': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PLUS': + $this->assertContains('close', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PULL_DOWN': + $this->assertContains('stretch-from-bottom', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PULL_LEFT': + $this->assertContains('stretch-from-left', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PULL_RIGHT': + $this->assertContains('stretch-from-right', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PULL_UP': + $this->assertContains('stretch-from-top', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PUSH_DOWN': + $this->assertContains('roll-from-bottom', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PUSH_LEFT': + $this->assertContains('roll-from-left', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PUSH_RIGHT': + $this->assertContains('roll-from-right', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_PUSH_UP': + $this->assertContains('roll-from-top', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_RANDOM': + $this->assertContains('random', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_RANDOMBAR_HORIZONTAL': + $this->assertContains('horizontal-lines', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_RANDOMBAR_VERTICAL': + $this->assertContains('vertical-lines', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_SPLIT_IN_HORIZONTAL': + $this->assertContains('close-horizontal', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_SPLIT_OUT_HORIZONTAL': + $this->assertContains('open-horizontal', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_SPLIT_IN_VERTICAL': + $this->assertContains('close-vertical', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_SPLIT_OUT_VERTICAL': + $this->assertContains('open-vertical', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_STRIPS_LEFT_DOWN': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_STRIPS_LEFT_UP': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_STRIPS_RIGHT_DOWN': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_STRIPS_RIGHT_UP': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_WEDGE': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_WIPE_DOWN': + $this->assertContains('fade-from-bottom', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_WIPE_LEFT': + $this->assertContains('fade-from-left', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_WIPE_RIGHT': + $this->assertContains('fade-from-right', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_WIPE_UP': + $this->assertContains('fade-from-top', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_ZOOM_IN': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + case 'TRANSITION_ZOOM_OUT': + $this->assertContains('none', $pres->getElementAttribute($element, 'presentation:transition-style', 'content.xml')); + break; + } + } + + $oTransition->setManualTrigger(true); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $this->assertContains('manual', $pres->getElementAttribute($element, 'presentation:transition-type', 'content.xml')); } } diff --git a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/DrawingTest.php b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/DrawingTest.php new file mode 100644 index 000000000..67065889a --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/DrawingTest.php @@ -0,0 +1,55 @@ +getActiveSlide(); + $oGroup = $oSlide->createGroup(); + + $oDrawing = new Drawing(); + $this->assertInternalType('array', $oDrawing->allDrawings($oPhpPowerPoint)); + $this->assertEmpty($oDrawing->allDrawings($oPhpPowerPoint)); + + $oGroup->createDrawingShape(); + $oGroup->createDrawingShape(); + $oGroup->createDrawingShape(); + + $this->assertInternalType('array', $oDrawing->allDrawings($oPhpPowerPoint)); + $this->assertCount(3, $oDrawing->allDrawings($oPhpPowerPoint)); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/StylesTest.php b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/StylesTest.php index 1eeda5220..83f62b797 100644 --- a/tests/PhpPowerpoint/Tests/Writer/ODPresentation/StylesTest.php +++ b/tests/PhpPowerpoint/Tests/Writer/ODPresentation/StylesTest.php @@ -19,6 +19,7 @@ use PhpOffice\PhpPowerpoint\DocumentLayout; use PhpOffice\PhpPowerpoint\PhpPowerpoint; +use PhpOffice\PhpPowerpoint\Style\Border; use PhpOffice\PhpPowerpoint\Style\Color; use PhpOffice\PhpPowerpoint\Style\Fill; use PhpOffice\PhpPowerpoint\Writer\ODPresentation; @@ -39,20 +40,6 @@ public function tearDown() TestHelperDOCX::clear(); } - public function testGradient() - { - $phpPowerPoint = new PhpPowerpoint(); - $oSlide = $phpPowerPoint->getActiveSlide(); - $oShape = $oSlide->createTableShape(); - $oRow = $oShape->createRow(); - $oCell = $oRow->getCell(); - $oCell->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR)->setStartColor(new Color('FFFF7700'))->setEndColor(new Color('FFFFFFFF')); - - $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); - $element = "/office:document-styles/office:styles/draw:gradient"; - $this->assertEquals('gradient_'.$oCell->getFill()->getHashCode(), $pres->getElementAttribute($element, 'draw:name', 'styles.xml')); - } - public function testDocumentLayout() { $element = "/office:document-styles/office:automatic-styles/style:page-layout/style:page-layout-properties"; @@ -89,4 +76,104 @@ public function testCustomDocumentLayout() $this->assertTrue($pres->elementExists($element, 'styles.xml')); $this->assertEquals('sPL0', $pres->getElementAttribute($element, 'style:page-layout-name', 'styles.xml')); } + + public function testFillGradientLinearRichText() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createRichTextShape(); + $oShape->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR)->setStartColor(new Color('FFFF7700'))->setEndColor(new Color('FFFFFFFF')); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $element = '/office:document-styles/office:styles/draw:gradient'; + $this->assertEquals('gradient_'.$oShape->getFill()->getHashCode(), $pres->getElementAttribute($element, 'draw:name', 'styles.xml')); + + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'gr1\']/style:graphic-properties'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertEquals('gradient', $pres->getElementAttribute($element, 'draw:fill', 'content.xml')); + $this->assertEquals('gradient_'.$oShape->getFill()->getHashCode(), $pres->getElementAttribute($element, 'draw:fill-gradient-name', 'content.xml')); + } + + public function testFillSolidRichText() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createRichTextShape(); + $oShape->getFill()->setFillType(Fill::FILL_SOLID)->setRotation(90)->setStartColor(new Color('FF4672A8'))->setEndColor(new Color('FF4672A8')); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $element = '/office:document-content/office:automatic-styles/style:style[@style:name=\'gr1\']/style:graphic-properties'; + $this->assertTrue($pres->elementExists($element, 'content.xml')); + $this->assertEquals('solid', $pres->getElementAttribute($element, 'draw:fill', 'content.xml')); + $this->assertEquals('#'.$oShape->getFill()->getStartColor()->getRGB(), $pres->getElementAttribute($element, 'draw:fill-color', 'content.xml')); + $this->assertEquals('#'.$oShape->getFill()->getEndColor()->getRGB(), $pres->getElementAttribute($element, 'draw:fill-color', 'content.xml')); + } + + public function testGradientTable() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createTableShape(); + $oRow = $oShape->createRow(); + $oCell = $oRow->getCell(); + $oCell->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR)->setStartColor(new Color('FFFF7700'))->setEndColor(new Color('FFFFFFFF')); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $element = "/office:document-styles/office:styles/draw:gradient"; + $this->assertEquals('gradient_'.$oCell->getFill()->getHashCode(), $pres->getElementAttribute($element, 'draw:name', 'styles.xml')); + } + + public function testStrokeDash() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oRichText1 = $oSlide->createRichTextShape(); + $oRichText1->getBorder()->setColor(new Color('FF4672A8'))->setLineStyle(Border::LINE_SINGLE); + $arrayDashStyle = array( + Border::DASH_DASH, + Border::DASH_DASHDOT, + Border::DASH_DOT, + Border::DASH_LARGEDASH, + Border::DASH_LARGEDASHDOT, + Border::DASH_LARGEDASHDOTDOT, + Border::DASH_SYSDASH, + Border::DASH_SYSDASHDOT, + Border::DASH_SYSDASHDOTDOT, + Border::DASH_SYSDOT, + ); + + foreach ($arrayDashStyle as $style) { + $oRichText1->getBorder()->setDashStyle($style); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'ODPresentation'); + $element = '/office:document-styles/office:styles/draw:stroke-dash[@draw:name=\'strokeDash_'.$style.'\']'; + $this->assertTrue($pres->elementExists($element, 'styles.xml')); + $this->assertEquals('rect', $pres->getElementAttribute($element, 'draw:style', 'styles.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:distance', 'styles.xml')); + + switch ($style) { + case Border::DASH_DOT: + case Border::DASH_SYSDOT: + $this->assertTrue($pres->attributeElementExists($element, 'draw:dots1', 'styles.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:dots1-length', 'styles.xml')); + break; + case Border::DASH_DASH: + case Border::DASH_LARGEDASH: + case Border::DASH_SYSDASH: + $this->assertTrue($pres->attributeElementExists($element, 'draw:dots2', 'styles.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:dots2-length', 'styles.xml')); + break; + case Border::DASH_DASHDOT: + case Border::DASH_LARGEDASHDOT: + case Border::DASH_LARGEDASHDOTDOT: + case Border::DASH_SYSDASHDOT: + case Border::DASH_SYSDASHDOTDOT: + $this->assertTrue($pres->attributeElementExists($element, 'draw:dots1', 'styles.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:dots1-length', 'styles.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:dots2', 'styles.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'draw:dots2-length', 'styles.xml')); + break; + } + } + } } diff --git a/tests/PhpPowerpoint/Tests/Writer/ODPresentationTest.php b/tests/PhpPowerpoint/Tests/Writer/ODPresentationTest.php index c13fac296..62a25f7a5 100644 --- a/tests/PhpPowerpoint/Tests/Writer/ODPresentationTest.php +++ b/tests/PhpPowerpoint/Tests/Writer/ODPresentationTest.php @@ -78,6 +78,18 @@ public function testSave() unlink($filename); } + /** + * Test get PHPPowerPoint exception + * + * @expectedException Exception + * @expectedExceptionMessage Filename is empty + */ + public function testSaveEmpty() + { + $object = new ODPresentation(); + $object->save(''); + } + /** * Test get writer part null */ diff --git a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/AbstractPartTest.php b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/AbstractPartTest.php new file mode 100644 index 000000000..73f251a29 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/AbstractPartTest.php @@ -0,0 +1,77 @@ +setAccessible(true); + return $method->invokeArgs($obj, $args); + } + + /** + * Executed before each method of the class + */ + public function tearDown() + { + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage No parent \PhpOffice\PhpPowerpoint\Writer\WriterInterface assigned. + */ + public function testParentException() + { + $oDrawing = new Drawing(); + $oDrawing->getParentWriter(); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage The $parentWriter is not an instance of \PhpOffice\PhpPowerpoint\Writer\PowerPoint2007 + */ + public function testWriterException() + { + $oManifest = new Rels(); + $oManifest->setParentWriter(new ODPresentation()); + $oManifest->writeRelationships(); + } + + public function testXMLWriterWithDiskCaching() + { + $oPowerPoint2007 = new PowerPoint2007(); + $oPowerPoint2007->setUseDiskCaching(true); + $oRels = new Rels(); + $oRels->setParentWriter($oPowerPoint2007); + + $this->assertNotEmpty(\PHPUnit_Framework_Assert::readAttribute($this->runProtectedMethod($oRels, 'getXMLWriter'), 'tempFileName')); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartAreaTest.php b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartAreaTest.php new file mode 100644 index 000000000..afb6edb59 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartAreaTest.php @@ -0,0 +1,73 @@ + 1, + 'B' => 2, + 'C' => 4, + 'D' => 3, + 'E' => 2, + ); + + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oShape = $oSlide->createChartShape(); + $oShape->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80); + $oArea = new Area(); + $oSeries = new Series('Downloads', $seriesData); + $oSeries->getFill()->setStartColor(new Color('FFAABBCC')); + $oArea->addSeries($oSeries); + $oShape->getPlotArea()->setType($oArea); + + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:graphicFrame/a:graphic/a:graphicData'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/slides/slide1.xml')); + $element = '/c:chartSpace/c:chart/c:plotArea/c:areaChart'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $element = '/c:chartSpace/c:chart/c:plotArea/c:areaChart/c:ser'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartBarTest.php b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartBarTest.php new file mode 100644 index 000000000..6d7d06e93 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartBarTest.php @@ -0,0 +1,81 @@ + 1, + 'B' => 2, + 'C' => 4, + 'D' => 3, + 'E' => 2, + ); + + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oShape = $oSlide->createChartShape(); + $oShape->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80); + $oBar = new Bar(); + $oSeries = new Series('Downloads', $seriesData); + $oSeries->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_BLUE)); + $oSeries->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKBLUE)); + $oSeries->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKGREEN)); + $oSeries->getDataPointFill(3)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKRED)); + $oSeries->getDataPointFill(4)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKYELLOW)); + $oBar->addSeries($oSeries); + $oShape->getPlotArea()->setType($oBar); + + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:graphicFrame/a:graphic/a:graphicData'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/slides/slide1.xml')); + $element = '/c:chartSpace/c:chart/c:plotArea/c:barChart'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $element = '/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $element = '/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser/c:dPt/c:spPr'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $element = '/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser/c:tx/c:v'; + $this->assertEquals($oSeries->getTitle(), $oXMLDoc->getElement($element, 'ppt/charts/'.$oShape->getIndexedFilename())->nodeValue); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartTest.php b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartTest.php index 016be9d21..c83346bd3 100644 --- a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartTest.php +++ b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ChartTest.php @@ -21,6 +21,7 @@ use PhpOffice\PhpPowerpoint\Shape\Chart\Series; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Bar3D; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Line; +use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Pie3D; use PhpOffice\PhpPowerpoint\Shape\Chart\Type\Scatter; use PhpOffice\PhpPowerpoint\Style\Color; @@ -70,6 +71,28 @@ public function testPlotAreaBadType() TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); } + public function testTitleVisibility() + { + $element = '/c:chartSpace/c:chart/c:autoTitleDeleted'; + + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oShape = $oSlide->createChartShape(); + $oLine = new Line(); + $oShape->getPlotArea()->setType($oLine); + + $this->assertTrue($oShape->getTitle()->isVisible()); + $this->assertInstanceOf('PhpOffice\PhpPowerpoint\Shape\Chart\Title', $oShape->getTitle()->setVisible(true)); + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $this->assertEquals('0', $oXMLDoc->getElementAttribute($element, 'val', 'ppt/charts/'.$oShape->getIndexedFilename())); + + $this->assertInstanceOf('PhpOffice\PhpPowerpoint\Shape\Chart\Title', $oShape->getTitle()->setVisible(false)); + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $this->assertEquals('1', $oXMLDoc->getElementAttribute($element, 'val', 'ppt/charts/'.$oShape->getIndexedFilename())); + } + public function testTypeBar3D() { $seriesData = array( @@ -162,6 +185,33 @@ public function testTypeBar3DSuperScript() $this->assertEquals('30000', $oXMLDoc->getElementAttribute($element, 'baseline', 'ppt/charts/'.$oShape->getIndexedFilename())); } + public function testTypeBar3DBarDirection() + { + $seriesData = array( + 'A' => 1, + 'B' => 2, + 'C' => 4, + 'D' => 3, + 'E' => 2, + ); + + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oShape = $oSlide->createChartShape(); + $oShape->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80); + $oBar3D = new Bar3D(); + $oBar3D->setBarDirection(Bar3D::DIRECTION_HORIZONTAL); + $oSeries = new Series('Downloads', $seriesData); + $oBar3D->addSeries($oSeries); + $oShape->getPlotArea()->setType($oBar3D); + + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); + + $element = '/c:chartSpace/c:chart/c:plotArea/c:bar3DChart/c:barDir'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $this->assertEquals(Bar3D::DIRECTION_HORIZONTAL, $oXMLDoc->getElementAttribute($element, 'val', 'ppt/charts/'.$oShape->getIndexedFilename())); + } + public function testTypeLine() { $seriesData = array( @@ -247,7 +297,7 @@ public function testTypeLineSuperScript() $this->assertEquals('30000', $oXMLDoc->getElementAttribute($element, 'baseline', 'ppt/charts/'.$oShape->getIndexedFilename())); } - public function testTypePie3D() + public function testTypePie() { $seriesData = array( 'A' => 1, @@ -257,6 +307,43 @@ public function testTypePie3D() 'E' => 2, ); + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oShape = $oSlide->createChartShape(); + $oShape->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80); + $oPie = new Pie(); + $oSeries = new Series('Downloads', $seriesData); + $oSeries->getDataPointFill(0)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_BLUE)); + $oSeries->getDataPointFill(1)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKBLUE)); + $oSeries->getDataPointFill(2)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKGREEN)); + $oSeries->getDataPointFill(3)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKRED)); + $oSeries->getDataPointFill(4)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKYELLOW)); + $oPie->addSeries($oSeries); + $oShape->getPlotArea()->setType($oPie); + + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:graphicFrame/a:graphic/a:graphicData'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/slides/slide1.xml')); + $element = '/c:chartSpace/c:chart/c:plotArea/c:pieChart'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $element = '/c:chartSpace/c:chart/c:plotArea/c:pieChart/c:ser'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $element = '/c:chartSpace/c:chart/c:plotArea/c:pieChart/c:ser/c:dPt/c:spPr'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $element = '/c:chartSpace/c:chart/c:plotArea/c:pieChart/c:ser/c:tx/c:v'; + $this->assertEquals($oSeries->getTitle(), $oXMLDoc->getElement($element, 'ppt/charts/'.$oShape->getIndexedFilename())->nodeValue); + } + public function testTypePie3D() + { + $seriesData = array( + 'A' => 1, + 'B' => 2, + 'C' => 4, + 'D' => 3, + 'E' => 2, + ); + $oPHPPowerPoint = new PhpPowerpoint(); $oSlide = $oPHPPowerPoint->getActiveSlide(); $oShape = $oSlide->createChartShape(); @@ -270,9 +357,9 @@ public function testTypePie3D() $oSeries->getDataPointFill(4)->setFillType(Fill::FILL_SOLID)->setStartColor(new Color(Color::COLOR_DARKYELLOW)); $oPie3D->addSeries($oSeries); $oShape->getPlotArea()->setType($oPie3D); - + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); - + $element = '/p:sld/p:cSld/p:spTree/p:graphicFrame/a:graphic/a:graphicData'; $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/slides/slide1.xml')); $element = '/c:chartSpace/c:chart/c:plotArea/c:pie3DChart'; @@ -285,6 +372,34 @@ public function testTypePie3D() $this->assertEquals($oSeries->getTitle(), $oXMLDoc->getElement($element, 'ppt/charts/'.$oShape->getIndexedFilename())->nodeValue); } + public function testTypePie3DExplosion() + { + $value = rand(1, 100); + $seriesData = array( + 'A' => 1, + 'B' => 2, + 'C' => 4, + 'D' => 3, + 'E' => 2, + ); + + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oShape = $oSlide->createChartShape(); + $oShape->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80); + $oPie3D = new Pie3D(); + $oPie3D->setExplosion($value); + $oSeries = new Series('Downloads', $seriesData); + $oPie3D->addSeries($oSeries); + $oShape->getPlotArea()->setType($oPie3D); + + $oXMLDoc = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); + + $element = '/c:chartSpace/c:chart/c:plotArea/c:pie3DChart/c:ser/c:explosion'; + $this->assertTrue($oXMLDoc->elementExists($element, 'ppt/charts/'.$oShape->getIndexedFilename())); + $this->assertEquals($value, $oXMLDoc->getElementAttribute($element, 'val', 'ppt/charts/'.$oShape->getIndexedFilename())); + } + public function testTypePie3DSubScript() { $seriesData = array( diff --git a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ContenTypesTest.php b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ContenTypesTest.php new file mode 100644 index 000000000..672fb28a2 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/ContenTypesTest.php @@ -0,0 +1,50 @@ +setParentWriter(new ODPresentation()); + $oContentTypes->writeContentTypes(new PhpPowerpoint()); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/DrawingTest.php b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/DrawingTest.php new file mode 100644 index 000000000..a85c220d4 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/DrawingTest.php @@ -0,0 +1,55 @@ +getActiveSlide(); + $oGroup = $oSlide->createGroup(); + + $oDrawing = new Drawing(); + $this->assertInternalType('array', $oDrawing->allDrawings($oPhpPowerPoint)); + $this->assertEmpty($oDrawing->allDrawings($oPhpPowerPoint)); + + $oGroup->createDrawingShape(); + $oGroup->createDrawingShape(); + $oGroup->createDrawingShape(); + + $this->assertInternalType('array', $oDrawing->allDrawings($oPhpPowerPoint)); + $this->assertCount(3, $oDrawing->allDrawings($oPhpPowerPoint)); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/LayoutPack/TemplateBasedTest.php b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/LayoutPack/TemplateBasedTest.php new file mode 100644 index 000000000..d632d3e46 --- /dev/null +++ b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/LayoutPack/TemplateBasedTest.php @@ -0,0 +1,74 @@ +getLayouts(); + + foreach ($layouts as $layout) { + $foundLayout = $templateBased->findLayout($layout['name']); + $this->assertEquals($layout, $foundLayout); + } + } + + /** + * @expectedException \Exception + */ + public function testFindLayoutException() + { + $file = PHPPOWERPOINT_TESTS_BASE_DIR . '/resources/files/Sample_00_01.pptx'; + $templateBased = new TemplateBased($file); + $name = 'Invalid'; + $templateBased->findLayout($name); + } + + public function testFindLayoutId() + { + $file = PHPPOWERPOINT_TESTS_BASE_DIR . '/resources/files/Sample_00_01.pptx'; + $templateBased = new TemplateBased($file); + $layouts = $templateBased->getLayouts(); + + foreach ($layouts as $layout) { + $foundLayoutId = $templateBased->findLayoutId($layout['name']); + $this->assertEquals($layout['id'], $foundLayoutId); + } + } + + /** + * @expectedException \Exception + */ + public function testFindLayoutIdException() + { + $file = PHPPOWERPOINT_TESTS_BASE_DIR . '/resources/files/Sample_00_01.pptx'; + $templateBased = new TemplateBased($file); + $name = 'Invalid'; + $templateBased->findLayoutId($name); + } +} diff --git a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/SlideTest.php b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/SlideTest.php index 926d9ce73..7dfaedcf4 100644 --- a/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/SlideTest.php +++ b/tests/PhpPowerpoint/Tests/Writer/PowerPoint2007/SlideTest.php @@ -17,16 +17,17 @@ namespace PhpOffice\PhpPowerpoint\Tests\Writer\PowerPoint2007; +use PhpOffice\Common\Drawing; +use PhpOffice\PhpPowerpoint\Tests\TestHelperDOCX; use PhpOffice\PhpPowerpoint\PhpPowerpoint; -use PhpOffice\PhpPowerpoint\Shared\Drawing; +use PhpOffice\PhpPowerpoint\Shape\RichText; use PhpOffice\PhpPowerpoint\Style\Alignment; use PhpOffice\PhpPowerpoint\Style\Bullet; use PhpOffice\PhpPowerpoint\Style\Color; use PhpOffice\PhpPowerpoint\Style\Fill; -use PhpOffice\PhpPowerpoint\Tests\TestHelperDOCX; -use PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; +use PhpOffice\PhpPowerpoint\Slide\Transition; use PhpOffice\PhpPowerpoint\Style\Border; -use PhpOffice\PhpPowerpoint\Shape\Hyperlink; +use PhpOffice\PhpPowerpoint\Writer\PowerPoint2007; use PhpOffice\PhpPowerpoint\Writer\PowerPoint2007\Slide; /** @@ -139,6 +140,21 @@ public function testAlignmentShapeTop() $this->assertEquals(Alignment::VERTICAL_TOP, $pres->getElementAttribute($element, 'anchor', 'ppt/slides/slide1.xml')); } + public function testDrawingWithHyperlink() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createDrawingShape(); + $oShape->setPath(PHPPOWERPOINT_TESTS_BASE_DIR.'/resources/images/PHPPowerPointLogo.png'); + $oShape->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPowerPoint/'); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:pic/p:nvPicPr/p:cNvPr/a:hlinkClick'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertEquals('rId3', $pres->getElementAttribute($element, 'r:id', 'ppt/slides/slide1.xml')); + } + public function testDrawingShapeBorder() { $phpPowerPoint = new PhpPowerpoint(); @@ -168,7 +184,7 @@ public function testDrawingShapeShadow() $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); } - public function testFillGradientLinear() + public function testFillGradientLinearTable() { $expected1 = 'E06B20'; $expected2 = strrev($expected1); @@ -193,11 +209,36 @@ public function testFillGradientLinear() $this->assertEquals($expected2, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); } - public function testFillGradientPath() + /** + * @link : https://github.com/PHPOffice/PHPPowerPoint/issues/61 + */ + public function testFillGradientLinearRichText() { $expected1 = 'E06B20'; $expected2 = strrev($expected1); - + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createRichTextShape(); + $oShape->setHeight(200)->setWidth(600)->setOffsetX(150)->setOffsetY(300); + $oFill = $oShape->getFill(); + $oFill->setFillType(Fill::FILL_GRADIENT_LINEAR)->setStartColor(new Color('FF'.$expected1))->setEndColor(new Color('FF'.$expected2)); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:gradFill/a:gsLst/a:gs[@pos="0"]/a:srgbClr'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertEquals($expected1, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:gradFill/a:gsLst/a:gs[@pos="100000"]/a:srgbClr'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertEquals($expected2, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); + } + + public function testFillGradientPathTable() + { + $expected1 = 'E06B20'; + $expected2 = strrev($expected1); + $phpPowerPoint = new PhpPowerpoint(); $oSlide = $phpPowerPoint->getActiveSlide(); $oShape = $oSlide->createTableShape(1); @@ -207,9 +248,9 @@ public function testFillGradientPath() $oCell->createTextRun('R1C1'); $oFill = $oCell->getFill(); $oFill->setFillType(Fill::FILL_GRADIENT_PATH)->setStartColor(new Color('FF'.$expected1))->setEndColor(new Color('FF'.$expected2)); - + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); - + $element = '/p:sld/p:cSld/p:spTree/p:graphicFrame/a:graphic/a:graphicData/a:tbl/a:tr/a:tc/a:tcPr/a:gradFill/a:gsLst/a:gs[@pos="0"]/a:srgbClr'; $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); $this->assertEquals($expected1, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); @@ -218,7 +259,32 @@ public function testFillGradientPath() $this->assertEquals($expected2, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); } - public function testFillPattern() + /** + * @link : https://github.com/PHPOffice/PHPPowerPoint/issues/61 + */ + public function testFillGradientPathText() + { + $expected1 = 'E06B20'; + $expected2 = strrev($expected1); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createRichTextShape(); + $oShape->setHeight(200)->setWidth(600)->setOffsetX(150)->setOffsetY(300); + $oFill = $oShape->getFill(); + $oFill->setFillType(Fill::FILL_GRADIENT_PATH)->setStartColor(new Color('FF'.$expected1))->setEndColor(new Color('FF'.$expected2)); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:gradFill/a:gsLst/a:gs[@pos="0"]/a:srgbClr'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertEquals($expected1, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:gradFill/a:gsLst/a:gs[@pos="100000"]/a:srgbClr'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertEquals($expected2, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); + } + + public function testFillPatternTable() { $expected1 = 'E06B20'; $expected2 = strrev($expected1); @@ -243,7 +309,7 @@ public function testFillPattern() $this->assertEquals($expected2, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); } - public function testFillSolid() + public function testFillSolidTable() { $expected = 'E06B20'; @@ -263,6 +329,27 @@ public function testFillSolid() $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); $this->assertEquals($expected, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); } + + /** + * @link : https://github.com/PHPOffice/PHPPowerPoint/issues/61 + */ + public function testFillSolidText() + { + $expected = 'E06B20'; + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createRichTextShape(); + $oShape->setHeight(200)->setWidth(600)->setOffsetX(150)->setOffsetY(300); + $oFill = $oShape->getFill(); + $oFill->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FF'.$expected)); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:solidFill/a:srgbClr'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertEquals($expected, $pres->getElementAttribute($element, 'val', 'ppt/slides/slide1.xml')); + } public function testHyperlink() { @@ -369,6 +456,43 @@ public function testLine() $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); } + public function testNote() + { + $oPHPPowerPoint = new PhpPowerpoint(); + $oSlide = $oPHPPowerPoint->getActiveSlide(); + $oNote = $oSlide->getNote(); + $oRichText = $oNote->createRichTextShape()->setHeight(300)->setWidth(600); + $oRichText->createTextRun('testNote'); + + $pres = TestHelperDOCX::getDocument($oPHPPowerPoint, 'PowerPoint2007'); + // Content Types + // $element = '/Types/Override[@PartName="/ppt/notesSlides/notesSlide1.xml"][@ContentType="application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml"]'; + // $this->assertTrue($pres->elementExists($element, '[Content_Types].xml')); + // Rels + // $element = '/Relationships/Relationship[@Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide"][@Target="../notesSlides/notesSlide1.xml"]'; + // $this->assertTrue($pres->elementExists($element, 'ppt/slides/_rels/slide1.xml.rels')); + // Slide + $element = '/p:notes'; + $this->assertTrue($pres->elementExists($element, 'ppt/notesSlides/notesSlide1.xml')); + $element = '/p:notes/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t'; + $this->assertTrue($pres->elementExists($element, 'ppt/notesSlides/notesSlide1.xml')); + } + + public function testRichTextAutoFitNormal() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRichText->setAutoFit(RichText::AUTOFIT_NORMAL, 47.5, 20); + $oRichText->createTextRun('This is my text for the test.'); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:bodyPr/a:normAutofit'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertEquals(47500, $pres->getElementAttribute($element, 'fontScale', 'ppt/slides/slide1.xml')); + $this->assertEquals(20000, $pres->getElementAttribute($element, 'lnSpcReduction', 'ppt/slides/slide1.xml')); + } + public function testRichTextBreak() { $phpPowerPoint = new PhpPowerpoint(); @@ -382,6 +506,33 @@ public function testRichTextBreak() $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); } + public function testRichTextHyperlink() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRichText->getHyperLink()->setUrl('http://www.google.fr'); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:sp//a:hlinkClick'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + } + + public function testRichTextShadow() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oRichText = $oSlide->createRichTextShape(); + $oRichText->createTextRun('AAA'); + $oRichText->getShadow()->setVisible(true)->setAlpha(75)->setBlurRadius(2)->setDirection(45); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:effectLst/a:outerShdw'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + } + public function testRichTextUpright() { $phpPowerPoint = new PhpPowerpoint(); @@ -539,4 +690,224 @@ public function testTableWithRowspan() $this->assertTrue($pres->elementExists($element.'[@rowSpan="2"]', 'ppt/slides/slide1.xml')); $this->assertTrue($pres->elementExists($element.'[@vMerge="1"]', 'ppt/slides/slide1.xml')); } + + /** + * @link : https://github.com/PHPOffice/PHPPowerPoint/issues/70 + */ + public function testTableWithHyperlink() + { + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + $oShape = $oSlide->createTableShape(4); + $oShape->setHeight(200)->setWidth(600)->setOffsetX(150)->setOffsetY(300); + $oRow = $oShape->createRow(); + $oCell = $oRow->getCell(); + $oTextRun = $oCell->createTextRun('AAA'); + $oHyperlink = $oTextRun->getHyperlink(); + $oHyperlink->setUrl('https://github.com/PHPOffice/PHPPowerPoint/'); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + + $element = '/p:sld/p:cSld/p:spTree/p:graphicFrame/a:graphic/a:graphicData/a:tbl/a:tr/a:tc/a:txBody/a:p/a:r/a:rPr/a:hlinkClick'; + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertEquals('rId2', $pres->getElementAttribute($element, 'r:id', 'ppt/slides/slide1.xml')); + } + + public function testTransition() + { + $value = rand(1000, 5000); + + $oTransition = new Transition(); + + $phpPowerPoint = new PhpPowerpoint(); + $oSlide = $phpPowerPoint->getActiveSlide(); + + $element = '/p:sld/p:transition'; + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + $this->assertFalse($pres->elementExists($element, 'ppt/slides/slide1.xml')); + + $oTransition->setTimeTrigger(true, $value); + $oSlide->setTransition($oTransition); + + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + $this->assertTrue($pres->elementExists($element, 'ppt/slides/slide1.xml')); + $this->assertTrue($pres->attributeElementExists($element, 'advTm', 'ppt/slides/slide1.xml')); + $this->assertEquals($value, $pres->getElementAttribute($element, 'advTm', 'ppt/slides/slide1.xml')); + $this->assertContains('0', $pres->getElementAttribute($element, 'advClick', 'ppt/slides/slide1.xml')); + + $oTransition->setSpeed(Transition::SPEED_FAST); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + $this->assertContains('fast', $pres->getElementAttribute($element, 'spd', 'ppt/slides/slide1.xml')); + + $oTransition->setSpeed(Transition::SPEED_MEDIUM); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + $this->assertContains('med', $pres->getElementAttribute($element, 'spd', 'ppt/slides/slide1.xml')); + + $oTransition->setSpeed(Transition::SPEED_SLOW); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + $this->assertContains('slow', $pres->getElementAttribute($element, 'spd', 'ppt/slides/slide1.xml')); + + $rcTransition = new \ReflectionClass('PhpOffice\PhpPowerpoint\Slide\Transition'); + $arrayConstants = $rcTransition->getConstants(); + foreach ($arrayConstants as $key => $value) { + if (strpos($key, 'TRANSITION_') !== 0) { + continue; + } + + $oTransition->setTransitionType($rcTransition->getConstant($key)); + $oSlide->setTransition($oTransition); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + switch ($key) { + case 'TRANSITION_BLINDS_HORIZONTAL': + $this->assertTrue($pres->elementExists($element.'/p:blinds[@dir=\'horz\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_BLINDS_VERTICAL': + $this->assertTrue($pres->elementExists($element.'/p:blinds[@dir=\'vert\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_CHECKER_HORIZONTAL': + $this->assertTrue($pres->elementExists($element.'/p:checker[@dir=\'horz\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_CHECKER_VERTICAL': + $this->assertTrue($pres->elementExists($element.'/p:checker[@dir=\'vert\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_CIRCLE_HORIZONTAL': + $this->assertTrue($pres->elementExists($element.'/p:circle[@dir=\'horz\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_CIRCLE_VERTICAL': + $this->assertTrue($pres->elementExists($element.'/p:circle[@dir=\'vert\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COMB_HORIZONTAL': + $this->assertTrue($pres->elementExists($element.'/p:comb[@dir=\'horz\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COMB_VERTICAL': + $this->assertTrue($pres->elementExists($element.'/p:comb[@dir=\'vert\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COVER_DOWN': + $this->assertTrue($pres->elementExists($element.'/p:cover[@dir=\'d\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COVER_LEFT': + $this->assertTrue($pres->elementExists($element.'/p:cover[@dir=\'l\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COVER_LEFT_DOWN': + $this->assertTrue($pres->elementExists($element.'/p:cover[@dir=\'ld\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COVER_LEFT_UP': + $this->assertTrue($pres->elementExists($element.'/p:cover[@dir=\'lu\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COVER_RIGHT': + $this->assertTrue($pres->elementExists($element.'/p:cover[@dir=\'r\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COVER_RIGHT_DOWN': + $this->assertTrue($pres->elementExists($element.'/p:cover[@dir=\'rd\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COVER_RIGHT_UP': + $this->assertTrue($pres->elementExists($element.'/p:cover[@dir=\'ru\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_COVER_UP': + $this->assertTrue($pres->elementExists($element.'/p:cover[@dir=\'u\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_CUT': + $this->assertTrue($pres->elementExists($element.'/p:cut', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_DIAMOND': + $this->assertTrue($pres->elementExists($element.'/p:diamond', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_DISSOLVE': + $this->assertTrue($pres->elementExists($element.'/p:dissolve', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_FADE': + $this->assertTrue($pres->elementExists($element.'/p:fade', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_NEWSFLASH': + $this->assertTrue($pres->elementExists($element.'/p:newsflash', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PLUS': + $this->assertTrue($pres->elementExists($element.'/p:plus', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PULL_DOWN': + $this->assertTrue($pres->elementExists($element.'/p:pull[@dir=\'d\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PULL_LEFT': + $this->assertTrue($pres->elementExists($element.'/p:pull[@dir=\'l\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PULL_RIGHT': + $this->assertTrue($pres->elementExists($element.'/p:pull[@dir=\'r\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PULL_UP': + $this->assertTrue($pres->elementExists($element.'/p:pull[@dir=\'u\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PUSH_DOWN': + $this->assertTrue($pres->elementExists($element.'/p:push[@dir=\'d\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PUSH_LEFT': + $this->assertTrue($pres->elementExists($element.'/p:push[@dir=\'l\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PUSH_RIGHT': + $this->assertTrue($pres->elementExists($element.'/p:push[@dir=\'r\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_PUSH_UP': + $this->assertTrue($pres->elementExists($element.'/p:push[@dir=\'u\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_RANDOM': + $this->assertTrue($pres->elementExists($element.'/p:random', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_RANDOMBAR_HORIZONTAL': + $this->assertTrue($pres->elementExists($element.'/p:randomBar[@dir=\'horz\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_RANDOMBAR_VERTICAL': + $this->assertTrue($pres->elementExists($element.'/p:randomBar[@dir=\'vert\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_SPLIT_IN_HORIZONTAL': + $this->assertTrue($pres->elementExists($element.'/p:split[@dir=\'in\'][@orient=\'horz\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_SPLIT_OUT_HORIZONTAL': + $this->assertTrue($pres->elementExists($element.'/p:split[@dir=\'out\'][@orient=\'horz\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_SPLIT_IN_VERTICAL': + $this->assertTrue($pres->elementExists($element.'/p:split[@dir=\'in\'][@orient=\'vert\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_SPLIT_OUT_VERTICAL': + $this->assertTrue($pres->elementExists($element.'/p:split[@dir=\'out\'][@orient=\'vert\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_STRIPS_LEFT_DOWN': + $this->assertTrue($pres->elementExists($element.'/p:strips[@dir=\'ld\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_STRIPS_LEFT_UP': + $this->assertTrue($pres->elementExists($element.'/p:strips[@dir=\'lu\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_STRIPS_RIGHT_DOWN': + $this->assertTrue($pres->elementExists($element.'/p:strips[@dir=\'rd\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_STRIPS_RIGHT_UP': + $this->assertTrue($pres->elementExists($element.'/p:strips[@dir=\'ru\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_WEDGE': + $this->assertTrue($pres->elementExists($element.'/p:wedge', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_WIPE_DOWN': + $this->assertTrue($pres->elementExists($element.'/p:wipe[@dir=\'d\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_WIPE_LEFT': + $this->assertTrue($pres->elementExists($element.'/p:wipe[@dir=\'l\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_WIPE_RIGHT': + $this->assertTrue($pres->elementExists($element.'/p:wipe[@dir=\'r\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_WIPE_UP': + $this->assertTrue($pres->elementExists($element.'/p:wipe[@dir=\'u\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_ZOOM_IN': + $this->assertTrue($pres->elementExists($element.'/p:zoom[@dir=\'in\']', 'ppt/slides/slide1.xml')); + break; + case 'TRANSITION_ZOOM_OUT': + $this->assertTrue($pres->elementExists($element.'/p:zoom[@dir=\'out\']', 'ppt/slides/slide1.xml')); + break; + } + } + + $oTransition->setManualTrigger(true); + $pres = TestHelperDOCX::getDocument($phpPowerPoint, 'PowerPoint2007'); + $this->assertContains('1', $pres->getElementAttribute($element, 'advClick', 'ppt/slides/slide1.xml')); + } } diff --git a/tests/PhpPowerpoint/Tests/Writer/SerializedTest.php b/tests/PhpPowerpoint/Tests/Writer/SerializedTest.php index 80fbee62a..233c086ae 100644 --- a/tests/PhpPowerpoint/Tests/Writer/SerializedTest.php +++ b/tests/PhpPowerpoint/Tests/Writer/SerializedTest.php @@ -78,7 +78,7 @@ public function testSave() /** * @expectedException \Exception - * @expectedExceptionMessage Could not open + * @expectedExceptionMessage Could not open */ public function testSaveNotExistingDir() { diff --git a/tests/resources/files/Sample_00_01.pptx b/tests/resources/files/Sample_00_01.pptx new file mode 100644 index 000000000..604b76a94 Binary files /dev/null and b/tests/resources/files/Sample_00_01.pptx differ