SchemaTe 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. <?php
  2. namespace PhpOffice\PhpPresentation\Tests\Writer\PowerPoint2007;
  3. use PhpOffice\PhpPresentation\PhpPresentation;
  4. use PhpOffice\PhpPresentation\Shape\Chart\Series;
  5. use PhpOffice\PhpPresentation\Shape\Chart\Type\Line;
  6. use PhpOffice\PhpPresentation\Shape\Comment;
  7. use PhpOffice\PhpPresentation\Shape\Placeholder;
  8. use PhpOffice\PhpPresentation\Shape\RichText;
  9. use PhpOffice\PhpPresentation\Slide;
  10. use PhpOffice\PhpPresentation\Slide\Animation;
  11. use PhpOffice\PhpPresentation\Slide\Transition;
  12. use PhpOffice\PhpPresentation\Style\Alignment;
  13. use PhpOffice\PhpPresentation\Style\Border;
  14. use PhpOffice\PhpPresentation\Style\Color;
  15. use PhpOffice\PhpPresentation\Style\Fill;
  16. use PhpOffice\PhpPresentation\Style\Shadow;
  17. use PhpOffice\PhpPresentation\Tests\PhpPresentationTestCase;
  18. use PhpOffice\PhpPresentation\Shape\Drawing;
  19. use PhpOffice\PhpPresentation\Shape\Media;
  20. use Symfony\Component\Finder\SplFileInfo;
  21. class SchemaTest extends PhpPresentationTestCase
  22. {
  23. private $internalErrors;
  24. public function setUp()
  25. {
  26. parent::setUp();
  27. libxml_clear_errors();
  28. $this->internalErrors = libxml_use_internal_errors(true);
  29. }
  30. public function tearDown()
  31. {
  32. parent::tearDown();
  33. libxml_use_internal_errors($this->internalErrors);
  34. }
  35. /**
  36. * Test whether the generated XML validates against the Office Open XML File Formats schema
  37. *
  38. * @see http://www.ecma-international.org/publications/standards/Ecma-376.htm
  39. * @dataProvider pptProvider
  40. */
  41. public function testSchema(PhpPresentation $presentation)
  42. {
  43. $this->writePresentationFile($presentation, 'PowerPoint2007');
  44. // validate all XML files
  45. $path = realpath($this->workDirectory . '/ppt');
  46. $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
  47. foreach ($iterator as $file) {
  48. /** @var SplFileInfo $file */
  49. if ($file->getExtension() !== "xml") {
  50. continue;
  51. }
  52. $fileName = str_replace('\\', '/', substr($file->getRealPath(), strlen($path) + 1));
  53. $dom = $this->getXmlDom('ppt/' . $fileName);
  54. $xmlSource = $dom->saveXML();
  55. // In the ISO/ECMA standard the namespace has changed from
  56. // http://schemas.openxmlformats.org/ to http://purl.oclc.org/ooxml/
  57. // We need to use the http://purl.oclc.org/ooxml/ namespace to validate
  58. // the xml against the current schema
  59. $xmlSource = str_replace(array(
  60. "http://schemas.openxmlformats.org/drawingml/2006/main",
  61. "http://schemas.openxmlformats.org/drawingml/2006/chart",
  62. "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
  63. "http://schemas.openxmlformats.org/presentationml/2006/main",
  64. ), array(
  65. "http://purl.oclc.org/ooxml/drawingml/main",
  66. "http://purl.oclc.org/ooxml/drawingml/chart",
  67. "http://purl.oclc.org/ooxml/officeDocument/relationships",
  68. "http://purl.oclc.org/ooxml/presentationml/main",
  69. ), $xmlSource);
  70. $dom->loadXML($xmlSource);
  71. $dom->schemaValidate(__DIR__ . '/../../../../resources/schema/ooxml/pml.xsd');
  72. $error = libxml_get_last_error();
  73. if ($error) {
  74. $this->fail(sprintf("Validation error: %s in file %s on line %s\n%s", $error->message, $file, $error->line, $dom->saveXML()));
  75. }
  76. }
  77. }
  78. public function pptProvider()
  79. {
  80. return array(
  81. array($this->generatePresentation01()),
  82. array($this->generatePresentation02()),
  83. );
  84. }
  85. /**
  86. * Generates a ppt which contains different elements per slide i.e. shape, table, etc.
  87. *
  88. * @return PhpPresentation
  89. */
  90. private function generatePresentation01()
  91. {
  92. $objPHPPresentation = new PhpPresentation();
  93. $objPHPPresentation->getDocumentProperties()
  94. ->setCreator('PHPOffice')
  95. ->setLastModifiedBy('PHPPresentation Team')
  96. ->setTitle('Sample 02 Title')
  97. ->setSubject('Sample 02 Subject')
  98. ->setDescription('Sample 02 Description')
  99. ->setKeywords('office 2007 openxml libreoffice odt php')
  100. ->setCategory('Sample Category');
  101. $currentSlide = $objPHPPresentation->getActiveSlide();
  102. // text shape
  103. $shape = $currentSlide->createRichTextShape()
  104. ->setHeight(300)
  105. ->setWidth(600)
  106. ->setOffsetX(170)
  107. ->setOffsetY(180);
  108. $shape->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
  109. $textRun = $shape->createTextRun('Thank you for using PHPPresentation!');
  110. $textRun->getFont()->setBold(true)
  111. ->setSize(60)
  112. ->setColor(new Color('FFE06B20'));
  113. // image
  114. $currentSlide = $objPHPPresentation->createSlide();
  115. $gdImage = @imagecreatetruecolor(140, 20);
  116. $textColor = imagecolorallocate($gdImage, 255, 255, 255);
  117. imagestring($gdImage, 1, 5, 5, 'Created with PHPPresentation', $textColor);
  118. $shape = new Drawing\Gd();
  119. $shape->setName('Sample image')
  120. ->setDescription('Sample image')
  121. ->setImageResource($gdImage)
  122. ->setRenderingFunction(Drawing\Gd::RENDERING_JPEG)
  123. ->setMimeType(Drawing\Gd::MIMETYPE_DEFAULT)
  124. ->setHeight(36)
  125. ->setOffsetX(10)
  126. ->setOffsetY(10);
  127. $currentSlide->addShape($shape);
  128. // table
  129. $currentSlide = $objPHPPresentation->createSlide();
  130. $shape = $currentSlide->createTableShape(3);
  131. $shape->setHeight(200);
  132. $shape->setWidth(600);
  133. $shape->setOffsetX(150);
  134. $shape->setOffsetY(300);
  135. $row = $shape->createRow();
  136. $row->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR)
  137. ->setRotation(90)
  138. ->setStartColor(new Color('FFE06B20'))
  139. ->setEndColor(new Color('FFFFFFFF'));
  140. $cell = $row->nextCell();
  141. $cell->setColSpan(3);
  142. $cell->createTextRun('Title row')->getFont()->setBold(true)->setSize(16);
  143. $cell->getBorders()->getBottom()->setLineWidth(4)
  144. ->setLineStyle(Border::LINE_SINGLE)
  145. ->setDashStyle(Border::DASH_DASH);
  146. $row = $shape->createRow();
  147. $row->setHeight(20);
  148. $row->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR)
  149. ->setRotation(90)
  150. ->setStartColor(new Color('FFE06B20'))
  151. ->setEndColor(new Color('FFFFFFFF'));
  152. $row->nextCell()->createTextRun('R1C1')->getFont()->setBold(true);
  153. $row->nextCell()->createTextRun('R1C2')->getFont()->setBold(true);
  154. $row->nextCell()->createTextRun('R1C3')->getFont()->setBold(true);
  155. foreach ($row->getCells() as $cell) {
  156. $cell->getBorders()->getTop()->setLineWidth(4)
  157. ->setLineStyle(Border::LINE_SINGLE)
  158. ->setDashStyle(Border::DASH_DASH);
  159. }
  160. // chart
  161. $currentSlide = $objPHPPresentation->createSlide();
  162. $oFill = new Fill();
  163. $oFill->setFillType(Fill::FILL_SOLID)->setStartColor(new Color('FFE06B20'));
  164. $oShadow = new Shadow();
  165. $oShadow->setVisible(true)->setDirection(45)->setDistance(10);
  166. $seriesData = array(
  167. 'Monday' => 12,
  168. 'Tuesday' => 15,
  169. 'Wednesday' => 13,
  170. 'Thursday' => 17,
  171. 'Friday' => 14,
  172. 'Saturday' => 9,
  173. 'Sunday' => 7
  174. );
  175. $lineChart = new Line();
  176. $series = new Series('Downloads', $seriesData);
  177. $series->setShowSeriesName(true);
  178. $series->setShowValue(true);
  179. $lineChart->addSeries($series);
  180. $shape = $currentSlide->createChartShape();
  181. $shape->setName('PHPPresentation Daily Downloads')->setResizeProportional(false)->setHeight(550)->setWidth(700)->setOffsetX(120)->setOffsetY(80);
  182. $shape->setShadow($oShadow);
  183. $shape->setFill($oFill);
  184. $shape->getBorder()->setLineStyle(Border::LINE_SINGLE);
  185. $shape->getTitle()->setText('PHPPresentation Daily Downloads');
  186. $shape->getTitle()->getFont()->setItalic(true);
  187. $shape->getPlotArea()->setType($lineChart);
  188. $shape->getView3D()->setRotationX(30);
  189. $shape->getView3D()->setPerspective(30);
  190. $shape->getLegend()->getBorder()->setLineStyle(Border::LINE_SINGLE);
  191. $shape->getLegend()->getFont()->setItalic(true);
  192. // fill
  193. $currentSlide = $objPHPPresentation->createSlide();
  194. for ($inc = 1; $inc <= 4; $inc++) {
  195. // Create a shape (text)
  196. $shape = $currentSlide->createRichTextShape()
  197. ->setHeight(200)
  198. ->setWidth(300);
  199. if ($inc == 1 || $inc == 3) {
  200. $shape->setOffsetX(10);
  201. } else {
  202. $shape->setOffsetX(320);
  203. }
  204. if ($inc == 1 || $inc == 2) {
  205. $shape->setOffsetY(10);
  206. } else {
  207. $shape->setOffsetY(220);
  208. }
  209. $shape->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
  210. switch ($inc) {
  211. case 1:
  212. $shape->getFill()->setFillType(Fill::FILL_NONE);
  213. break;
  214. case 2:
  215. $shape->getFill()->setFillType(Fill::FILL_GRADIENT_LINEAR)->setRotation(90)->setStartColor(new Color('FF4672A8'))->setEndColor(new Color('FF000000'));
  216. break;
  217. case 3:
  218. $shape->getFill()->setFillType(Fill::FILL_GRADIENT_PATH)->setRotation(90)->setStartColor(new Color('FF4672A8'))->setEndColor(new Color('FF000000'));
  219. break;
  220. case 4:
  221. $shape->getFill()->setFillType(Fill::FILL_SOLID)->setRotation(90)->setStartColor(new Color('FF4672A8'))->setEndColor(new Color('FF4672A8'));
  222. break;
  223. }
  224. $textRun = $shape->createTextRun('Use PHPPresentation!');
  225. $textRun->getFont()->setBold(true)
  226. ->setSize(30)
  227. ->setColor(new Color('FFE06B20'));
  228. }
  229. // slide note
  230. $currentSlide = $objPHPPresentation->createSlide();
  231. $shape = $currentSlide->createDrawingShape();
  232. $shape->setName('PHPPresentation logo')
  233. ->setDescription('PHPPresentation logo')
  234. ->setPath(__DIR__ . '/../../../../../samples/resources/phppowerpoint_logo.gif')
  235. ->setHeight(36)
  236. ->setOffsetX(10)
  237. ->setOffsetY(10);
  238. $shape->getShadow()->setVisible(true)
  239. ->setDirection(45)
  240. ->setDistance(10);
  241. $shape->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPresentation/')->setTooltip('PHPPresentation');
  242. $shape = $currentSlide->createRichTextShape()
  243. ->setHeight(300)
  244. ->setWidth(600)
  245. ->setOffsetX(170)
  246. ->setOffsetY(180);
  247. $shape->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
  248. $textRun = $shape->createTextRun('Thank you for using PHPPresentation!');
  249. $textRun->getFont()->setBold(true)
  250. ->setSize(60)
  251. ->setColor(new Color('FFE06B20'));
  252. $oNote = $currentSlide->getNote();
  253. $oLayout = $objPHPPresentation->getLayout();
  254. $oRichText = $oNote->createRichTextShape()
  255. ->setHeight($oLayout->getCY($oLayout::UNIT_PIXEL))
  256. ->setWidth($oLayout->getCX($oLayout::UNIT_PIXEL))
  257. ->setOffsetX(170)
  258. ->setOffsetY(180);
  259. $oRichText->createTextRun('A class library');
  260. $oRichText->createParagraph()->createTextRun('Written in PHP');
  261. $oRichText->createParagraph()->createTextRun('Representing a presentation');
  262. $oRichText->createParagraph()->createTextRun('Supports writing to different file formats');
  263. // transition
  264. $currentSlide = $objPHPPresentation->createSlide();
  265. $shapeDrawing = $currentSlide->createDrawingShape();
  266. $shapeDrawing->setName('PHPPresentation logo')
  267. ->setDescription('PHPPresentation logo')
  268. ->setPath(__DIR__ . '/../../../../../samples/resources/phppowerpoint_logo.gif')
  269. ->setHeight(36)
  270. ->setOffsetX(10)
  271. ->setOffsetY(10);
  272. $shapeDrawing->getShadow()->setVisible(true)
  273. ->setDirection(45)
  274. ->setDistance(10);
  275. $shapeDrawing->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPresentation/')->setTooltip('PHPPresentation');
  276. $shapeRichText = $currentSlide->createRichTextShape()
  277. ->setHeight(300)
  278. ->setWidth(600)
  279. ->setOffsetX(170)
  280. ->setOffsetY(180);
  281. $shapeRichText->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
  282. $textRun = $shapeRichText->createTextRun('Thank you for using PHPPresentation!');
  283. $textRun->getFont()->setBold(true)
  284. ->setSize(60)
  285. ->setColor(new Color('FFE06B20'));
  286. $oTransition = new Transition();
  287. $oTransition->setManualTrigger(false);
  288. $oTransition->setTimeTrigger(true, 4000);
  289. $oTransition->setTransitionType(Transition::TRANSITION_SPLIT_IN_VERTICAL);
  290. $currentSlide->setTransition($oTransition);
  291. // comment
  292. $currentSlide = $objPHPPresentation->createSlide();
  293. $oShapeDrawing = new Drawing\File();
  294. $oShapeDrawing->setName('PHPPresentation logo')
  295. ->setDescription('PHPPresentation logo')
  296. ->setPath(__DIR__ . '/../../../../../samples/resources/phppowerpoint_logo.gif')
  297. ->setHeight(36)
  298. ->setOffsetX(10)
  299. ->setOffsetY(10);
  300. $oShapeDrawing->getShadow()->setVisible(true)
  301. ->setDirection(45)
  302. ->setDistance(10);
  303. $oShapeDrawing->getHyperlink()->setUrl('https://github.com/PHPOffice/PHPPresentation/')->setTooltip('PHPPresentation');
  304. $oShapeRichText = new RichText();
  305. $oShapeRichText->setHeight(300)
  306. ->setWidth(600)
  307. ->setOffsetX(170)
  308. ->setOffsetY(180);
  309. $oShapeRichText->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
  310. $textRun = $oShapeRichText->createTextRun('Thank you for using PHPPresentation!');
  311. $textRun->getFont()->setBold(true)
  312. ->setSize(60)
  313. ->setColor(new Color('FFE06B20'));
  314. $currentSlide->addShape(clone $oShapeDrawing);
  315. $currentSlide->addShape(clone $oShapeRichText);
  316. $oAuthor = new \PhpOffice\PhpPresentation\Shape\Comment\Author();
  317. $oAuthor->setName('Progi1984');
  318. $oAuthor->setInitials('P');
  319. $oComment1 = new \PhpOffice\PhpPresentation\Shape\Comment();
  320. $oComment1->setText('Text A');
  321. $oComment1->setOffsetX(10);
  322. $oComment1->setOffsetY(55);
  323. $oComment1->setDate(time());
  324. $oComment1->setAuthor($oAuthor);
  325. $currentSlide->addShape($oComment1);
  326. $oComment2 = new \PhpOffice\PhpPresentation\Shape\Comment();
  327. $oComment2->setText('Text B');
  328. $oComment2->setOffsetX(170);
  329. $oComment2->setOffsetY(180);
  330. $oComment2->setDate(time());
  331. $oComment2->setAuthor($oAuthor);
  332. $currentSlide->addShape($oComment2);
  333. // animation
  334. $currentSlide = $objPHPPresentation->createSlide();
  335. $oDrawing1 = clone $oShapeDrawing;
  336. $oRichText1 = clone $oShapeRichText;
  337. $oSlide1 = $objPHPPresentation->getActiveSlide();
  338. $oSlide1->addShape($oDrawing1);
  339. $oSlide1->addShape($oRichText1);
  340. $oAnimation1 = new Animation();
  341. $oAnimation1->addShape($oDrawing1);
  342. $oSlide1->addAnimation($oAnimation1);
  343. $oAnimation2 = new Animation();
  344. $oAnimation2->addShape($oRichText1);
  345. $oSlide1->addAnimation($oAnimation2);
  346. $oDrawing2 = clone $oShapeDrawing;
  347. $oRichText2 = clone $oShapeRichText;
  348. $oSlide2 = $objPHPPresentation->createSlide();
  349. $oSlide2->addShape($oDrawing2);
  350. $oSlide2->addShape($oRichText2);
  351. $oAnimation4 = new Animation();
  352. $oAnimation4->addShape($oRichText2);
  353. $oSlide2->addAnimation($oAnimation4);
  354. $oAnimation3 = new Animation();
  355. $oAnimation3->addShape($oDrawing2);
  356. $oSlide2->addAnimation($oAnimation3);
  357. $oDrawing3 = clone $oShapeDrawing;
  358. $oRichText3 = clone $oShapeRichText;
  359. $currentSlide->addShape($oDrawing3);
  360. $currentSlide->addShape($oRichText3);
  361. $oAnimation5 = new Animation();
  362. $oAnimation5->addShape($oRichText3);
  363. $oAnimation5->addShape($oDrawing3);
  364. $currentSlide->addAnimation($oAnimation5);
  365. // @TODO add more complex elements
  366. return $objPHPPresentation;
  367. }
  368. /**
  369. * Generates a ppt containing placeholder in the master and the slide
  370. *
  371. * @return PhpPresentation
  372. */
  373. private function generatePresentation02()
  374. {
  375. $objPHPPresentation = new PhpPresentation();
  376. $objPHPPresentation->getDocumentProperties()
  377. ->setCreator('PHPOffice')
  378. ->setLastModifiedBy('PHPPresentation Team')
  379. ->setTitle('Sample 02 Title')
  380. ->setSubject('Sample 02 Subject')
  381. ->setDescription('Sample 02 Description')
  382. ->setKeywords('office 2007 openxml libreoffice odt php')
  383. ->setCategory('Sample Category');
  384. // master slide
  385. $masterSlides = $objPHPPresentation->getAllMasterSlides();
  386. /** @var Slide $objMaster */
  387. $objMaster = reset($masterSlides);
  388. $objShape = $objMaster->createRichTextShape();
  389. $objShape->setWidthAndHeight(270, 30)->setOffsetX(600)->setOffsetY(655);
  390. $objShape->createTextRun("Footer")
  391. ->getFont()
  392. ->setName("Arial")
  393. ->setSize(7);
  394. $objShape->getActiveParagraph()->getAlignment()->setHorizontal(Alignment::HORIZONTAL_RIGHT);
  395. $objShape = $objMaster->createRichTextShape();
  396. $objShape->setWidthAndHeight(50, 30)->setOffsetX(870)->setOffsetY(655);
  397. $objShape->createTextRun("")
  398. ->getFont()
  399. ->setName("Arial")
  400. ->setSize(7);
  401. $objShape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_SLIDENUM));
  402. // slide with placeholder
  403. $currentSlide = $objPHPPresentation->getActiveSlide();
  404. $objShape = $currentSlide->createRichTextShape();
  405. $objShape->setWidthAndHeight(50, 30)->setOffsetX(870)->setOffsetY(655);
  406. $objShape->createTextRun("")
  407. ->getFont()
  408. ->setName("Arial")
  409. ->setSize(7);
  410. $objShape->setPlaceHolder(new Placeholder(Placeholder::PH_TYPE_SLIDENUM));
  411. return $objPHPPresentation;
  412. }
  413. }