Completed
Pull Request — develop (#588)
by
unknown
06:25
created

PptSlides   F

Complexity

Total Complexity 83

Size/Duplication

Total Lines 925
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Test Coverage

Coverage 81.72%

Importance

Changes 0
Metric Value
wmc 83
lcom 1
cbo 13
dl 0
loc 925
ccs 304
cts 372
cp 0.8172
rs 1.675
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A render() 0 22 5
F writeSlideRelationships() 0 290 61
B writeSlide() 0 146 4
C writeSlideAnimations() 0 314 9
B writeShapeDrawing() 0 115 4

How to fix   Complexity   

Complex Class

Complex classes like PptSlides often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PptSlides, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PhpOffice\PhpPresentation\Writer\PowerPoint2007;
4
5
use PhpOffice\Common\Drawing as CommonDrawing;
6
use PhpOffice\Common\XMLWriter;
7
use PhpOffice\PhpPresentation\Shape\Chart as ShapeChart;
8
use PhpOffice\PhpPresentation\Shape\Comment;
9
use PhpOffice\PhpPresentation\Shape\Drawing as ShapeDrawing;
10
use PhpOffice\PhpPresentation\Shape\Group;
11
use PhpOffice\PhpPresentation\Shape\Media;
12
use PhpOffice\PhpPresentation\Shape\RichText;
13
use PhpOffice\PhpPresentation\Shape\RichText\Run;
14
use PhpOffice\PhpPresentation\Shape\RichText\TextElement;
15
use PhpOffice\PhpPresentation\Shape\Table as ShapeTable;
16
use PhpOffice\PhpPresentation\Slide;
17
use PhpOffice\PhpPresentation\Slide\Background\Image;
18
use PhpOffice\PhpPresentation\Slide\Note;
19
20
class PptSlides extends AbstractSlide
21
{
22
    /**
23
     * Add slides (drawings, ...) and slide relationships (drawings, ...)
24
     * @return \PhpOffice\Common\Adapter\Zip\ZipInterface
25
     * @throws \Exception
26
     */
27 112
    public function render()
28
    {
29 112
        foreach ($this->oPresentation->getAllSlides() as $idx => $oSlide) {
30 112
            $this->oZip->addFromString('ppt/slides/_rels/slide' . ($idx + 1) . '.xml.rels', $this->writeSlideRelationships($oSlide));
31 112
            $this->oZip->addFromString('ppt/slides/slide' . ($idx + 1) . '.xml', $this->writeSlide($oSlide));
32
33
            // Add note slide
34 112
            if ($oSlide->getNote() instanceof Note) {
35 112
                if ($oSlide->getNote()->getShapeCollection()->count() > 0) {
36 1
                    $this->oZip->addFromString('ppt/notesSlides/notesSlide' . ($idx + 1) . '.xml', $this->writeNote($oSlide->getNote()));
37
                }
38
            }
39
40
            // Add background image slide
41 112
            $oBkgImage = $oSlide->getBackground();
42 112
            if ($oBkgImage instanceof Image) {
43 112
                $this->oZip->addFromString('ppt/media/'.$oBkgImage->getIndexedFilename($idx), file_get_contents($oBkgImage->getPath()));
44
            }
45
        }
46
47 112
        return $this->oZip;
48
    }
49
50
    /**
51
     * Write slide relationships to XML format
52
     *
53
     * @param  \PhpOffice\PhpPresentation\Slide $pSlide
54
     * @return string              XML Output
55
     * @throws \Exception
56
     */
57 112
    protected function writeSlideRelationships(Slide $pSlide)
58
    {
59
        //@todo Group all getShapeCollection()->getIterator
60
61
        // Create XML writer
62 112
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
63
64
        // XML header
65 112
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
66
67
        // Relationships
68 112
        $objWriter->startElement('Relationships');
69 112
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
70
71
        // Starting relation id
72 112
        $relId = 1;
73 112
        $idxSlide = $pSlide->getParent()->getIndex($pSlide);
74
75
        // Write slideLayout relationship
76 112
        $layoutId = 1;
77 112
        if ($pSlide->getSlideLayout()) {
78 112
            $layoutId = $pSlide->getSlideLayout()->layoutNr;
79
        }
80 112
        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout', '../slideLayouts/slideLayout' . $layoutId . '.xml');
81 112
        ++$relId;
82
83
        // Write drawing relationships?
84 112
        if ($pSlide->getShapeCollection()->count() > 0) {
85
            // Loop trough images and write relationships
86 85
            $iterator = $pSlide->getShapeCollection()->getIterator();
87 85
            while ($iterator->valid()) {
88 85
                if ($iterator->current() instanceof Media) {
89
                    // Write relationship for image drawing
90 1
                    $iterator->current()->relationId = 'rId' . $relId;
91 1
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/video', '../media/' . $iterator->current()->getIndexedFilename());
92 1
                    ++$relId;
93 1
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.microsoft.com/office/2007/relationships/media', '../media/' . $iterator->current()->getIndexedFilename());
94 1
                    ++$relId;
95 84
                } elseif ($iterator->current() instanceof ShapeDrawing\AbstractDrawingAdapter) {
96
                    // Write relationship for image drawing
97 8
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $iterator->current()->getIndexedFilename());
98 8
                    $iterator->current()->relationId = 'rId' . $relId;
99 8
                    ++$relId;
100 76
                } elseif ($iterator->current() instanceof ShapeChart) {
101
                    // Write relationship for chart drawing
102 34
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', '../charts/' . $iterator->current()->getIndexedFilename());
103
104 34
                    $iterator->current()->relationId = 'rId' . $relId;
105
106 34
                    ++$relId;
107 42
                } elseif ($iterator->current() instanceof Group) {
108 1
                    $iterator2 = $iterator->current()->getShapeCollection()->getIterator();
109 1
                    while ($iterator2->valid()) {
110 1
                        if ($iterator2->current() instanceof Media) {
111
                            // Write relationship for image drawing
112
                            $iterator2->current()->relationId = 'rId' . $relId;
113
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/video', '../media/' . $iterator->current()->getIndexedFilename());
114
                            ++$relId;
115
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.microsoft.com/office/2007/relationships/media', '../media/' . $iterator->current()->getIndexedFilename());
116
                            ++$relId;
117 1
                        } elseif ($iterator2->current() instanceof ShapeDrawing\AbstractDrawingAdapter) {
118
                            // Write relationship for image drawing
119
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $iterator2->current()->getIndexedFilename());
120
                            $iterator2->current()->relationId = 'rId' . $relId;
121
122
                            ++$relId;
123 1
                        } elseif ($iterator2->current() instanceof ShapeChart) {
124
                            // Write relationship for chart drawing
125
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', '../charts/' . $iterator2->current()->getIndexedFilename());
126
                            $iterator2->current()->relationId = 'rId' . $relId;
127
128
                            ++$relId;
129
                        }
130 1
                        $iterator2->next();
131
                    }
132
                }
133
134 85
                $iterator->next();
135
            }
136
        }
137
138
        // Write background relationships?
139 112
        $oBackground = $pSlide->getBackground();
140 112
        if ($oBackground instanceof Image) {
141
            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $oBackground->getIndexedFilename($idxSlide));
142
            $oBackground->relationId = 'rId' . $relId;
143
            ++$relId;
144
        }
145
146
        // Write hyperlink relationships?
147 112
        if ($pSlide->getShapeCollection()->count() > 0) {
148
            // Loop trough hyperlinks and write relationships
149 85
            $iterator = $pSlide->getShapeCollection()->getIterator();
150 85
            while ($iterator->valid()) {
151
                // Hyperlink on shape
152 85
                if ($iterator->current()->hasHyperlink()) {
153
                    // Write relationship for hyperlink
154 2
                    $hyperlink               = $iterator->current()->getHyperlink();
155 2
                    $hyperlink->relationId = 'rId' . $relId;
156
157 2
                    if (!$hyperlink->isInternal()) {
158 2
                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
159
                    } else {
160
                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
161
                    }
162
163 2
                    ++$relId;
164
                }
165
166
                // Hyperlink on rich text run
167 85
                if ($iterator->current() instanceof RichText) {
168 24
                    foreach ($iterator->current()->getParagraphs() as $paragraph) {
169 24
                        foreach ($paragraph->getRichTextElements() as $element) {
170 19
                            if ($element instanceof Run || $element instanceof TextElement) {
171 18
                                if ($element->hasHyperlink()) {
172
                                    // Write relationship for hyperlink
173 2
                                    $hyperlink               = $element->getHyperlink();
174 2
                                    $hyperlink->relationId = 'rId' . $relId;
175
176 2
                                    if (!$hyperlink->isInternal()) {
177 1
                                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
178
                                    } else {
179 1
                                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
180
                                    }
181
182 24
                                    ++$relId;
183
                                }
184
                            }
185
                        }
186
                    }
187
                }
188
189
                // Hyperlink in table
190 85
                if ($iterator->current() instanceof ShapeTable) {
191
                    // Rows
192 10
                    $countRows = count($iterator->current()->getRows());
193 10
                    for ($row = 0; $row < $countRows; $row++) {
194
                        // Cells in rows
195 10
                        $countCells = count($iterator->current()->getRow($row)->getCells());
196 10
                        for ($cell = 0; $cell < $countCells; $cell++) {
197 10
                            $currentCell = $iterator->current()->getRow($row)->getCell($cell);
198
                            // Paragraphs in cell
199 10
                            foreach ($currentCell->getParagraphs() as $paragraph) {
200
                                // RichText in paragraph
201 10
                                foreach ($paragraph->getRichTextElements() as $element) {
202
                                    // Run or Text in RichText
203 10
                                    if ($element instanceof Run || $element instanceof TextElement) {
204 10
                                        if ($element->hasHyperlink()) {
205
                                            // Write relationship for hyperlink
206 1
                                            $hyperlink               = $element->getHyperlink();
207 1
                                            $hyperlink->relationId = 'rId' . $relId;
208
209 1
                                            if (!$hyperlink->isInternal()) {
210 1
                                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
211
                                            } else {
212
                                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
213
                                            }
214
215 10
                                            ++$relId;
216
                                        }
217
                                    }
218
                                }
219
                            }
220
                        }
221
                    }
222
                }
223
224 85
                if ($iterator->current() instanceof Group) {
225 1
                    $iterator2 = $pSlide->getShapeCollection()->getIterator();
226 1
                    while ($iterator2->valid()) {
227
                        // Hyperlink on shape
228 1
                        if ($iterator2->current()->hasHyperlink()) {
229
                            // Write relationship for hyperlink
230
                            $hyperlink             = $iterator2->current()->getHyperlink();
231
                            $hyperlink->relationId = 'rId' . $relId;
232
233
                            if (!$hyperlink->isInternal()) {
234
                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
235
                            } else {
236
                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
237
                            }
238
239
                            ++$relId;
240
                        }
241
242
                        // Hyperlink on rich text run
243 1
                        if ($iterator2->current() instanceof RichText) {
244
                            foreach ($iterator2->current()->getParagraphs() as $paragraph) {
245
                                foreach ($paragraph->getRichTextElements() as $element) {
246
                                    if ($element instanceof Run || $element instanceof TextElement) {
247
                                        if ($element->hasHyperlink()) {
248
                                            // Write relationship for hyperlink
249
                                            $hyperlink              = $element->getHyperlink();
250
                                            $hyperlink->relationId = 'rId' . $relId;
251
252
                                            if (!$hyperlink->isInternal()) {
253
                                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
254
                                            } else {
255
                                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
256
                                            }
257
258
                                            ++$relId;
259
                                        }
260
                                    }
261
                                }
262
                            }
263
                        }
264
265
                        // Hyperlink in table
266 1
                        if ($iterator2->current() instanceof ShapeTable) {
267
                            // Rows
268
                            $countRows = count($iterator2->current()->getRows());
269
                            for ($row = 0; $row < $countRows; $row++) {
270
                                // Cells in rows
271
                                $countCells = count($iterator2->current()->getRow($row)->getCells());
272
                                for ($cell = 0; $cell < $countCells; $cell++) {
273
                                    $currentCell = $iterator2->current()->getRow($row)->getCell($cell);
274
                                    // Paragraphs in cell
275
                                    foreach ($currentCell->getParagraphs() as $paragraph) {
276
                                        // RichText in paragraph
277
                                        foreach ($paragraph->getRichTextElements() as $element) {
278
                                            // Run or Text in RichText
279
                                            if ($element instanceof Run || $element instanceof TextElement) {
280
                                                if ($element->hasHyperlink()) {
281
                                                    // Write relationship for hyperlink
282
                                                    $hyperlink               = $element->getHyperlink();
283
                                                    $hyperlink->relationId = 'rId' . $relId;
284
285
                                                    if (!$hyperlink->isInternal()) {
286
                                                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
287
                                                    } else {
288
                                                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
289
                                                    }
290
291
                                                    ++$relId;
292
                                                }
293
                                            }
294
                                        }
295
                                    }
296
                                }
297
                            }
298
                        }
299
300 1
                        $iterator2->next();
301
                    }
302
                }
303
304 85
                $iterator->next();
305
            }
306
        }
307
308
        // Write comment relationships
309 112
        if ($pSlide->getShapeCollection()->count() > 0) {
310 85
            $hasSlideComment = false;
311
312
            // Loop trough images and write relationships
313 85
            $iterator = $pSlide->getShapeCollection()->getIterator();
314 85
            while ($iterator->valid()) {
315 85
                if ($iterator->current() instanceof Comment) {
316 6
                    $hasSlideComment = true;
317 6
                    break;
318 79
                } elseif ($iterator->current() instanceof Group) {
319 1
                    $iterator2 = $iterator->current()->getShapeCollection()->getIterator();
320 1
                    while ($iterator2->valid()) {
321 1
                        if ($iterator2->current() instanceof Comment) {
322 1
                            $hasSlideComment = true;
323 1
                            break 2;
324
                        }
325
                        $iterator2->next();
326
                    }
327
                }
328
329 78
                $iterator->next();
330
            }
331
332 85
            if ($hasSlideComment) {
333 7
                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', '../comments/comment'.($idxSlide + 1).'.xml');
334 7
                ++$relId;
335
            }
336
        }
337
338 112
        if ($pSlide->getNote()->getShapeCollection()->count() > 0) {
339 1
            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide', '../notesSlides/notesSlide'.($idxSlide + 1).'.xml');
340
        }
341
342 112
        $objWriter->endElement();
343
344
        // Return
345 112
        return $objWriter->getData();
346
    }
347
348
    /**
349
     * Write slide to XML format
350
     *
351
     * @param  \PhpOffice\PhpPresentation\Slide $pSlide
352
     * @return string              XML Output
353
     * @throws \Exception
354
     */
355 112
    public function writeSlide(Slide $pSlide)
356
    {
357
        // Create XML writer
358 112
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
359
360
        // XML header
361 112
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
362
363
        // p:sld
364 112
        $objWriter->startElement('p:sld');
365 112
        $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
366 112
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
367 112
        $objWriter->writeAttribute('xmlns:p', 'http://schemas.openxmlformats.org/presentationml/2006/main');
368 112
        $objWriter->writeAttributeIf(!$pSlide->isVisible(), 'show', 0);
369
370
        // p:sld/p:cSld
371 112
        $objWriter->startElement('p:cSld');
372
373
        // Background
374 112
        if ($pSlide->getBackground() instanceof Slide\AbstractBackground) {
375
            $oBackground = $pSlide->getBackground();
376
            // p:bg
377
            $objWriter->startElement('p:bg');
378
379
            // p:bgPr
380
            $objWriter->startElement('p:bgPr');
381
382
            if ($oBackground instanceof Slide\Background\Color) {
383
                // a:solidFill
384
                $objWriter->startElement('a:solidFill');
385
386
                $this->writeColor($objWriter, $oBackground->getColor());
387
388
                // > a:solidFill
389
                $objWriter->endElement();
390
            }
391
392
            if ($oBackground instanceof Slide\Background\Image) {
393
                // a:blipFill
394
                $objWriter->startElement('a:blipFill');
395
396
                // a:blip
397
                $objWriter->startElement('a:blip');
398
                $objWriter->writeAttribute('r:embed', $oBackground->relationId);
399
400
                // > a:blipFill
401
                $objWriter->endElement();
402
403
                // a:stretch
404
                $objWriter->startElement('a:stretch');
405
406
                // a:fillRect
407
                $objWriter->writeElement('a:fillRect');
408
409
                // > a:stretch
410
                $objWriter->endElement();
411
412
                // > a:blipFill
413
                $objWriter->endElement();
414
            }
415
416
            // > p:bgPr
417
            $objWriter->endElement();
418
419
            // > p:bg
420
            $objWriter->endElement();
421
        }
422
423
        // p:spTree
424 112
        $objWriter->startElement('p:spTree');
425
426
        // p:nvGrpSpPr
427 112
        $objWriter->startElement('p:nvGrpSpPr');
428
429
        // p:cNvPr
430 112
        $objWriter->startElement('p:cNvPr');
431 112
        $objWriter->writeAttribute('id', '1');
432 112
        $objWriter->writeAttribute('name', '');
433 112
        $objWriter->endElement();
434
435
        // p:cNvGrpSpPr
436 112
        $objWriter->writeElement('p:cNvGrpSpPr', null);
437
438
        // p:nvPr
439 112
        $objWriter->writeElement('p:nvPr', null);
440
441 112
        $objWriter->endElement();
442
443
        // p:grpSpPr
444 112
        $objWriter->startElement('p:grpSpPr');
445
446
        // a:xfrm
447 112
        $objWriter->startElement('a:xfrm');
448
449
        // a:off
450 112
        $objWriter->startElement('a:off');
451 112
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pSlide->getOffsetX()));
452 112
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pSlide->getOffsetY()));
453 112
        $objWriter->endElement(); // a:off
454
455
        // a:ext
456 112
        $objWriter->startElement('a:ext');
457 112
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pSlide->getExtentX()));
458 112
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pSlide->getExtentY()));
459 112
        $objWriter->endElement(); // a:ext
460
461
        // a:chOff
462 112
        $objWriter->startElement('a:chOff');
463 112
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pSlide->getOffsetX()));
464 112
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pSlide->getOffsetY()));
465 112
        $objWriter->endElement(); // a:chOff
466
467
        // a:chExt
468 112
        $objWriter->startElement('a:chExt');
469 112
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pSlide->getExtentX()));
470 112
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pSlide->getExtentY()));
471 112
        $objWriter->endElement(); // a:chExt
472
473 112
        $objWriter->endElement();
474
475 112
        $objWriter->endElement();
476
477
        // Loop shapes
478 112
        $this->writeShapeCollection($objWriter, $pSlide->getShapeCollection());
479
480
        // TODO
481 112
        $objWriter->endElement();
482
483 112
        $objWriter->endElement();
484
485
        // p:clrMapOvr
486 112
        $objWriter->startElement('p:clrMapOvr');
487
        // p:clrMapOvr\a:masterClrMapping
488 112
        $objWriter->writeElement('a:masterClrMapping', null);
489
        // ##p:clrMapOvr
490 112
        $objWriter->endElement();
491
492 112
        $this->writeSlideTransition($objWriter, $pSlide->getTransition());
493
494 112
        $this->writeSlideAnimations($objWriter, $pSlide);
495
496 112
        $objWriter->endElement();
497
498
        // Return
499 112
        return $objWriter->getData();
500
    }
501
502
    /**
503
     * @param XMLWriter $objWriter
504
     * @param Slide $oSlide
505
     */
506 112
    protected function writeSlideAnimations(XMLWriter $objWriter, Slide $oSlide)
507
    {
508 112
        $arrayAnimations = $oSlide->getAnimations();
509 112
        if (empty($arrayAnimations)) {
510 111
            return;
511
        }
512
513
        // Variables
514 1
        $shapeId = 0;
515 1
        $idCount = 1;
516 1
        $hashToIdMap = array();
517 1
        $arrayAnimationIds = array();
518
519 1
        foreach ($oSlide->getShapeCollection() as $shape) {
520 1
            $hashToIdMap[$shape->getHashCode()] = ++$shapeId;
521
        }
522
523 1
        foreach ($arrayAnimations as $oAnimation) {
524 1
            foreach ($oAnimation->getShapeCollection() as $oShape) {
525 1
                $arrayAnimationIds[] = $hashToIdMap[$oShape->getHashCode()];
526
            }
527
        }
528
529
        // p:timing
530 1
        $objWriter->startElement('p:timing');
531
        
532
        // p:timing/p:tnLst
533 1
        $objWriter->startElement('p:tnLst');
534
        
535
        // p:timing/p:tnLst/p:par
536 1
        $objWriter->startElement('p:par');
537
        
538
        // p:timing/p:tnLst/p:par/p:cTn
539 1
        $objWriter->startElement('p:cTn');
540 1
        $objWriter->writeAttribute('id', $idCount++);
541 1
        $objWriter->writeAttribute('dur', 'indefinite');
542 1
        $objWriter->writeAttribute('restart', 'never');
543 1
        $objWriter->writeAttribute('nodeType', 'tmRoot');
544
        
545
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst
546 1
        $objWriter->startElement('p:childTnLst');
547
        
548
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq
549 1
        $objWriter->startElement('p:seq');
550 1
        $objWriter->writeAttribute('concurrent', '1');
551 1
        $objWriter->writeAttribute('nextAc', 'seek');
552
        
553
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn
554 1
        $objWriter->startElement('p:cTn');
555 1
        $objWriter->writeAttribute('id', $idCount++);
556 1
        $objWriter->writeAttribute('dur', 'indefinite');
557 1
        $objWriter->writeAttribute('nodeType', 'mainSeq');
558
        
559
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst
560 1
        $objWriter->startElement('p:childTnLst');
561
562
        // Each animation has multiple shapes
563 1
        foreach ($arrayAnimations as $oAnimation) {
564
            
565
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par
566 1
            $objWriter->startElement('p:par');
567
            
568
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn
569 1
            $objWriter->startElement('p:cTn');
570 1
            $objWriter->writeAttribute('id', $idCount++);
571 1
            $objWriter->writeAttribute('fill', 'hold');
572
            
573
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:stCondLst
574 1
            $objWriter->startElement('p:stCondLst');
575
            
576
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:stCondLst/p:cond
577 1
            $objWriter->startElement('p:cond');
578 1
            $objWriter->writeAttribute('delay', 'indefinite');
579 1
            $objWriter->endElement();
580
            
581
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn\##p:stCondLst
582 1
            $objWriter->endElement();
583
            
584
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst
585 1
            $objWriter->startElement('p:childTnLst');
586
            
587
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par
588 1
            $objWriter->startElement('p:par');
589
            
590
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn
591 1
            $objWriter->startElement('p:cTn');
592 1
            $objWriter->writeAttribute('id', $idCount++);
593 1
            $objWriter->writeAttribute('fill', 'hold');
594
            
595
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn/p:stCondLst
596 1
            $objWriter->startElement('p:stCondLst');
597
            
598
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn/p:stCondLst/p:cond
599 1
            $objWriter->startElement('p:cond');
600 1
            $objWriter->writeAttribute('delay', '0');
601 1
            $objWriter->endElement();
602
            
603
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn\##p:stCondLst
604 1
            $objWriter->endElement();
605
            
606
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst
607 1
            $objWriter->startElement('p:childTnLst');
608
609 1
            $firstAnimation = true;
610 1
            foreach ($oAnimation->getShapeCollection() as $oShape) {
611 1
                $nodeType = $firstAnimation ? 'clickEffect' : 'withEffect';
612 1
                $shapeId = $hashToIdMap[$oShape->getHashCode()];
613
                // p:par
614 1
                $objWriter->startElement('p:par');
615
                
616
                // p:par/p:cTn
617 1
                $objWriter->startElement('p:cTn');
618 1
                $objWriter->writeAttribute('id', $idCount++);
619 1
                $objWriter->writeAttribute('presetID', '1');
620 1
                $objWriter->writeAttribute('presetClass', 'entr');
621 1
                $objWriter->writeAttribute('fill', 'hold');
622 1
                $objWriter->writeAttribute('presetSubtype', '0');
623 1
                $objWriter->writeAttribute('grpId', '0');
624 1
                $objWriter->writeAttribute('nodeType', $nodeType);
625
                
626
                // p:par/p:cTn/p:stCondLst
627 1
                $objWriter->startElement('p:stCondLst');
628
                
629
                // p:par/p:cTn/p:stCondLst/p:cond
630 1
                $objWriter->startElement('p:cond');
631 1
                $objWriter->writeAttribute('delay', '0');
632 1
                $objWriter->endElement();
633
                
634
                // p:par/p:cTn\##p:stCondLst
635 1
                $objWriter->endElement();
636
                
637
                // p:par/p:cTn/p:childTnLst
638 1
                $objWriter->startElement('p:childTnLst');
639
                
640
                // p:par/p:cTn/p:childTnLst/p:set
641 1
                $objWriter->startElement('p:set');
642
                
643
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr
644 1
                $objWriter->startElement('p:cBhvr');
645
                
646
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:cTn
647 1
                $objWriter->startElement('p:cTn');
648 1
                $objWriter->writeAttribute('id', $idCount++);
649 1
                $objWriter->writeAttribute('dur', '1');
650 1
                $objWriter->writeAttribute('fill', 'hold');
651
                
652
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:cTn/p:stCondLst
653 1
                $objWriter->startElement('p:stCondLst');
654
                
655
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:cTn/p:stCondLst/p:cond
656 1
                $objWriter->startElement('p:cond');
657 1
                $objWriter->writeAttribute('delay', '0');
658 1
                $objWriter->endElement();
659
                
660
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:cTn\##p:stCondLst
661 1
                $objWriter->endElement();
662
                
663
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr\##p:cTn
664 1
                $objWriter->endElement();
665
                
666
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:tgtEl
667 1
                $objWriter->startElement('p:tgtEl');
668
                
669
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:tgtEl/p:spTgt
670 1
                $objWriter->startElement('p:spTgt');
671 1
                $objWriter->writeAttribute('spid', $shapeId);
672 1
                $objWriter->endElement();
673
                
674
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr\##p:tgtEl
675 1
                $objWriter->endElement();
676
                
677
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:attrNameLst
678 1
                $objWriter->startElement('p:attrNameLst');
679
                
680
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:attrNameLst/p:attrName
681 1
                $objWriter->writeElement('p:attrName', 'style.visibility');
682
                
683
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr\##p:attrNameLst
684 1
                $objWriter->endElement();
685
                
686
                // p:par/p:cTn/p:childTnLst/p:set\##p:cBhvr
687 1
                $objWriter->endElement();
688
                
689
                // p:par/p:cTn/p:childTnLst/p:set/p:to
690 1
                $objWriter->startElement('p:to');
691
                
692
                // p:par/p:cTn/p:childTnLst/p:set/p:to/p:strVal
693 1
                $objWriter->startElement('p:strVal');
694 1
                $objWriter->writeAttribute('val', 'visible');
695 1
                $objWriter->endElement();
696
                
697
                // p:par/p:cTn/p:childTnLst/p:set\##p:to
698 1
                $objWriter->endElement();
699
                
700
                // p:par/p:cTn/p:childTnLst\##p:set
701 1
                $objWriter->endElement();
702
                
703
                // p:par/p:cTn\##p:childTnLst
704 1
                $objWriter->endElement();
705
                
706
                // p:par\##p:cTn
707 1
                $objWriter->endElement();
708
                
709
                // ##p:par
710 1
                $objWriter->endElement();
711
712 1
                $firstAnimation = false;
713
            }
714
715
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par/p:cTn\##p:childTnLst
716 1
            $objWriter->endElement();
717
            
718
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par\##p:cTn
719 1
            $objWriter->endElement();
720
            
721
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst\##p:par
722 1
            $objWriter->endElement();
723
            
724
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn\##p:childTnLst
725 1
            $objWriter->endElement();
726
            
727
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par\##p:cTn
728 1
            $objWriter->endElement();
729
            
730
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst\##p:par
731 1
            $objWriter->endElement();
732
        }
733
734
        
735
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn\##p:childTnLst
736 1
        $objWriter->endElement();
737
        
738
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq\##p:cTn
739 1
        $objWriter->endElement();
740
        
741
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst
742 1
        $objWriter->startElement('p:prevCondLst');
743
        
744
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst/p:cond
745 1
        $objWriter->startElement('p:cond');
746 1
        $objWriter->writeAttribute('evt', 'onPrev');
747 1
        $objWriter->writeAttribute('delay', '0');
748
        
749
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst/p:cond/p:tgtEl
750 1
        $objWriter->startElement('p:tgtEl');
751
        
752
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst/p:cond/p:tgtEl/p:sldTgt
753 1
        $objWriter->writeElement('p:sldTgt', null);
754
        
755
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst/p:cond\##p:tgtEl
756 1
        $objWriter->endElement();
757
        
758
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst\##p:cond
759 1
        $objWriter->endElement();
760
        
761
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq\##p:prevCondLst
762 1
        $objWriter->endElement();
763
        
764
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst
765 1
        $objWriter->startElement('p:nextCondLst');
766
        
767
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst/p:cond
768 1
        $objWriter->startElement('p:cond');
769 1
        $objWriter->writeAttribute('evt', 'onNext');
770 1
        $objWriter->writeAttribute('delay', '0');
771
        
772
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst/p:cond/p:tgtEl
773 1
        $objWriter->startElement('p:tgtEl');
774
        
775
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst/p:cond/p:tgtEl/p:sldTgt
776 1
        $objWriter->writeElement('p:sldTgt', null);
777
        
778
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst/p:cond\##p:tgtEl
779 1
        $objWriter->endElement();
780
        
781
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst\##p:cond
782 1
        $objWriter->endElement();
783
        
784
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq\##p:nextCondLst
785 1
        $objWriter->endElement();
786
        
787
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst\##p:seq
788 1
        $objWriter->endElement();
789
        
790
        // p:timing/p:tnLst/p:par/p:cTn\##p:childTnLst
791 1
        $objWriter->endElement();
792
        
793
        // p:timing/p:tnLst/p:par\##p:cTn
794 1
        $objWriter->endElement();
795
        
796
        // p:timing/p:tnLst\##p:par
797 1
        $objWriter->endElement();
798
        
799
        // p:timing\##p:tnLst
800 1
        $objWriter->endElement();
801
802
        // p:timing/p:bldLst
803 1
        $objWriter->startElement('p:bldLst');
804
805
        // Add in ids of all shapes in this slides animations
806 1
        foreach ($arrayAnimationIds as $id) {
807
            // p:timing/p:bldLst/p:bldP
808 1
            $objWriter->startElement('p:bldP');
809 1
            $objWriter->writeAttribute('spid', $id);
810 1
            $objWriter->writeAttribute('grpId', 0);
811 1
            $objWriter->endELement();
812
        }
813
814
        // p:timing\##p:bldLst
815 1
        $objWriter->endElement();
816
817
        // ##p:timing
818 1
        $objWriter->endElement();
819 1
    }
820
821
    /**
822
     * Write pic
823
     *
824
     * @param  \PhpOffice\Common\XMLWriter  $objWriter XML Writer
825
     * @param  \PhpOffice\PhpPresentation\Shape\Drawing\AbstractDrawingAdapter $shape
826
     * @param  int $shapeId
827
     * @throws \Exception
828
     */
829
    protected function writeShapeDrawing(XMLWriter $objWriter, ShapeDrawing\AbstractDrawingAdapter $shape, $shapeId)
0 ignored issues
show
Unused Code introduced by
The parameter $objWriter is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $shape is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $shapeId is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
830
    {
831
        exit( 'eyah');
832
        // p:pic
833
        $objWriter->startElement('p:pic');
0 ignored issues
show
Unused Code introduced by
$objWriter->startElement('p:pic'); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
834
835
        // p:nvPicPr
836
        $objWriter->startElement('p:nvPicPr');
837
838
        // p:cNvPr
839
        $objWriter->startElement('p:cNvPr');
840
        $objWriter->writeAttribute('id', $shapeId);
841
        $objWriter->writeAttribute('name', $shape->getName());
842
        $objWriter->writeAttribute('descr', $shape->getDescription());
843
844
        // a:hlinkClick
845
        if ($shape->hasHyperlink()) {
846
            $this->writeHyperlink($objWriter, $shape);
847
        }
848
849
        $objWriter->endElement();
850
851
        // p:cNvPicPr
852
        $objWriter->startElement('p:cNvPicPr');
853
854
        // a:picLocks
855
        $objWriter->startElement('a:picLocks');
856
        $objWriter->writeAttribute('noChangeAspect', '1');
857
        $objWriter->endElement();
858
859
        $objWriter->endElement();
860
861
        // p:nvPr
862
        $objWriter->startElement('p:nvPr');
863
        // PlaceHolder
864
        if ($shape->isPlaceholder()) {
865
            $objWriter->startElement('p:ph');
866
            $objWriter->writeAttribute('type', $shape->getPlaceholder()->getType());
867
            $objWriter->endElement();
868
        }
869
        /**
870
         * @link : https://github.com/stefslon/exportToPPTX/blob/master/exportToPPTX.m#L2128
871
         */
872
        if ($shape instanceof Media) {
873
            // p:nvPr > a:videoFile
874
            $objWriter->startElement('a:videoFile');
875
            $objWriter->writeAttribute('r:link', $shape->relationId);
876
            $objWriter->endElement();
877
            // p:nvPr > p:extLst
878
            $objWriter->startElement('p:extLst');
879
            // p:nvPr > p:extLst > p:ext
880
            $objWriter->startElement('p:ext');
881
            $objWriter->writeAttribute('uri', '{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}');
882
            // p:nvPr > p:extLst > p:ext > p14:media
883
            $objWriter->startElement('p14:media');
884
            $objWriter->writeAttribute('r:embed', ($shape->relationId + 1));
885
            $objWriter->writeAttribute('xmlns:p14', 'http://schemas.microsoft.com/office/powerpoint/2010/main');
886
            // p:nvPr > p:extLst > p:ext > ##p14:media
887
            $objWriter->endElement();
888
            // p:nvPr > p:extLst > ##p:ext
889
            $objWriter->endElement();
890
            // p:nvPr > ##p:extLst
891
            $objWriter->endElement();
892
        }
893
        // ##p:nvPr
894
        $objWriter->endElement();
895
        $objWriter->endElement();
896
897
        // p:blipFill
898
        $objWriter->startElement('p:blipFill');
899
900
        // a:blip
901
        $objWriter->startElement('a:blip');
902
        $objWriter->writeAttribute('r:embed', $shape->relationId);
903
        $objWriter->endElement();
904
905
        // a:stretch
906
        $objWriter->startElement('a:stretch');
907
        $objWriter->writeElement('a:fillRect');
908
        $objWriter->endElement();
909
910
        $objWriter->endElement();
911
912
        // p:spPr
913
        $objWriter->startElement('p:spPr');
914
        // a:xfrm
915
        $objWriter->startElement('a:xfrm');
916
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
917
918
        // a:off
919
        $objWriter->startElement('a:off');
920
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
921
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
922
        $objWriter->endElement();
923
924
        // a:ext
925
        $objWriter->startElement('a:ext');
926
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
927
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
928
        $objWriter->endElement();
929
930
        $objWriter->endElement();
931
932
        // a:prstGeom
933
        $objWriter->startElement('a:prstGeom');
934
        $objWriter->writeAttribute('prst', 'rect');
935
        // // a:prstGeom/a:avLst
936
        $objWriter->writeElement('a:avLst', null);
937
        // ##a:prstGeom
938
        $objWriter->endElement();
939
940
        $objWriter->endElement();
941
942
        $objWriter->endElement();
943
    }
944
}
945