Completed
Pull Request — develop (#304)
by Franck
07:14
created

PptSlides::writeShapeChart()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 67
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 36
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 67
ccs 36
cts 36
cp 1
rs 9.2815
c 0
b 0
f 0
cc 2
eloc 38
nc 2
nop 3
crap 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace PhpOffice\PhpPresentation\Writer\PowerPoint2007;
4
5
use PhpOffice\Common\Drawing as CommonDrawing;
6
use PhpOffice\Common\Text;
7
use PhpOffice\Common\XMLWriter;
8
use PhpOffice\PhpPresentation\Shape\AbstractDrawing;
9
use PhpOffice\PhpPresentation\Shape\Chart as ShapeChart;
10
use PhpOffice\PhpPresentation\Shape\Comment;
11
use PhpOffice\PhpPresentation\Shape\Drawing as ShapeDrawing;
12
use PhpOffice\PhpPresentation\Shape\Group;
13
use PhpOffice\PhpPresentation\Shape\Line;
14
use PhpOffice\PhpPresentation\Shape\Media;
15
use PhpOffice\PhpPresentation\Shape\RichText;
16
use PhpOffice\PhpPresentation\Shape\RichText\BreakElement;
17
use PhpOffice\PhpPresentation\Shape\RichText\Run;
18
use PhpOffice\PhpPresentation\Shape\RichText\TextElement;
19
use PhpOffice\PhpPresentation\Shape\Table as ShapeTable;
20
use PhpOffice\PhpPresentation\Slide;
21
use PhpOffice\PhpPresentation\Slide\Background\Image;
22
use PhpOffice\PhpPresentation\Slide\Note;
23
use PhpOffice\PhpPresentation\Slide\Transition;
24
use PhpOffice\PhpPresentation\Style\Alignment;
25
use PhpOffice\PhpPresentation\Style\Bullet;
26
use PhpOffice\PhpPresentation\Style\Border;
27
use PhpOffice\PhpPresentation\Style\Color;
28
29
class PptSlides extends AbstractSlide
30
{
31
    /**
32
     * Add slides (drawings, ...) and slide relationships (drawings, ...)
33
     * @return \PhpOffice\Common\Adapter\Zip\ZipInterface
34
     */
35 52
    public function render()
36
    {
37 52
        foreach ($this->oPresentation->getAllSlides() as $idx => $oSlide) {
38 52
            $this->oZip->addFromString('ppt/slides/_rels/slide' . ($idx + 1) . '.xml.rels', $this->writeSlideRelationships($oSlide));
39 52
            $this->oZip->addFromString('ppt/slides/slide' . ($idx + 1) . '.xml', $this->writeSlide($oSlide));
40
41
            // Add note slide
42 52
            if ($oSlide->getNote()->getShapeCollection()->count() > 0) {
43
                $this->oZip->addFromString('ppt/notesSlides/notesSlide' . ($idx + 1) . '.xml', $this->writeNote($oSlide->getNote()));
0 ignored issues
show
Bug introduced by
It seems like $oSlide->getNote() can be null; however, writeNote() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
44
            }
45
46
            // Add background image slide
47 52
            $oBkgImage = $oSlide->getBackground();
48 52
            if ($oBkgImage instanceof Image) {
49 52
                $this->oZip->addFromString('ppt/media/'.$oBkgImage->getIndexedFilename($idx), file_get_contents($oBkgImage->getPath()));
50
            }
51
        }
52
53 52
        return $this->oZip;
54
    }
55
56
    /**
57
     * Write slide relationships to XML format
58
     *
59
     * @param  \PhpOffice\PhpPresentation\Slide $pSlide
60
     * @return string              XML Output
61
     * @throws \Exception
62
     */
63 52
    protected function writeSlideRelationships(Slide $pSlide)
64
    {
65
        //@todo Group all getShapeCollection()->getIterator
66
67
        // Create XML writer
68 52
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
69
70
        // XML header
71 52
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
72
73
        // Relationships
74 52
        $objWriter->startElement('Relationships');
75 52
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
76
77
        // Starting relation id
78 52
        $relId = 1;
79 52
        $idxSlide = $pSlide->getParent()->getIndex($pSlide);
80
81
        // Write slideLayout relationship
82 52
        $layoutId = 1;
83 52
        if ($pSlide->getSlideLayout()) {
84 52
            $layoutId = $pSlide->getSlideLayout()->layoutNr;
85
        }
86 52
        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout', '../slideLayouts/slideLayout' . $layoutId . '.xml');
87 52
        ++$relId;
88
89
        // Write drawing relationships?
90 52
        if ($pSlide->getShapeCollection()->count() > 0) {
91
            // Loop trough images and write relationships
92 33
            $iterator = $pSlide->getShapeCollection()->getIterator();
93 33
            while ($iterator->valid()) {
94 33
                if ($iterator->current() instanceof Media) {
95
                    // Write relationship for image drawing
96
                    $iterator->current()->relationId = 'rId' . $relId;
97
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/video', '../media/' . $iterator->current()->getIndexedFilename());
98
                    ++$relId;
99
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.microsoft.com/office/2007/relationships/media', '../media/' . $iterator->current()->getIndexedFilename());
100
                    ++$relId;
101 33
                } elseif ($iterator->current() instanceof ShapeDrawing\AbstractDrawingAdapter) {
102
                    // Write relationship for image drawing
103 4
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $iterator->current()->getIndexedFilename());
104 4
                    $iterator->current()->relationId = 'rId' . $relId;
105 4
                    ++$relId;
106 29
                } elseif ($iterator->current() instanceof ShapeChart) {
107
                    // Write relationship for chart drawing
108 24
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', '../charts/' . $iterator->current()->getIndexedFilename());
109
110 24
                    $iterator->current()->relationId = 'rId' . $relId;
111
112 24
                    ++$relId;
113 5
                } elseif ($iterator->current() instanceof Group) {
114
                    $iterator2 = $iterator->current()->getShapeCollection()->getIterator();
115
                    while ($iterator2->valid()) {
116
                        if ($iterator2->current() instanceof Media) {
117
                            // Write relationship for image drawing
118
                            $iterator2->current()->relationId = 'rId' . $relId;
119
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/video', '../media/' . $iterator->current()->getIndexedFilename());
120
                            ++$relId;
121
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.microsoft.com/office/2007/relationships/media', '../media/' . $iterator->current()->getIndexedFilename());
122
                            ++$relId;
123
                        } elseif ($iterator2->current() instanceof ShapeDrawing\AbstractDrawingAdapter) {
124
                            // Write relationship for image drawing
125
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $iterator2->current()->getIndexedFilename());
126
                            $iterator2->current()->relationId = 'rId' . $relId;
127
128
                            ++$relId;
129
                        } elseif ($iterator2->current() instanceof ShapeChart) {
130
                            // Write relationship for chart drawing
131
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', '../charts/' . $iterator2->current()->getIndexedFilename());
132
                            $iterator2->current()->relationId = 'rId' . $relId;
133
134
                            ++$relId;
135
                        }
136
                        $iterator2->next();
137
                    }
138
                }
139
140 33
                $iterator->next();
141
            }
142
        }
143
144
        // Write background relationships?
145 52
        $oBackground = $pSlide->getBackground();
146 52
        if ($oBackground instanceof Image) {
147
            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $oBackground->getIndexedFilename($idxSlide));
148
            $oBackground->relationId = 'rId' . $relId;
149
            ++$relId;
150
        }
151
152
        // Write hyperlink relationships?
153 52
        if ($pSlide->getShapeCollection()->count() > 0) {
154
            // Loop trough hyperlinks and write relationships
155 33
            $iterator = $pSlide->getShapeCollection()->getIterator();
156 33
            while ($iterator->valid()) {
157
                // Hyperlink on shape
158 33
                if ($iterator->current()->hasHyperlink()) {
159
                    // Write relationship for hyperlink
160
                    $hyperlink               = $iterator->current()->getHyperlink();
161
                    $hyperlink->relationId = 'rId' . $relId;
162
163
                    if (!$hyperlink->isInternal()) {
164
                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
165
                    } else {
166
                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
167
                    }
168
169
                    ++$relId;
170
                }
171
172
                // Hyperlink on rich text run
173 33
                if ($iterator->current() instanceof RichText) {
174
                    foreach ($iterator->current()->getParagraphs() as $paragraph) {
175
                        foreach ($paragraph->getRichTextElements() as $element) {
176
                            if ($element instanceof Run || $element instanceof RunTextElement) {
0 ignored issues
show
Bug introduced by
The class PhpOffice\PhpPresentatio...oint2007\RunTextElement does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
177
                                if ($element->hasHyperlink()) {
178
                                    // Write relationship for hyperlink
179
                                    $hyperlink               = $element->getHyperlink();
180
                                    $hyperlink->relationId = 'rId' . $relId;
181
182
                                    if (!$hyperlink->isInternal()) {
183
                                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
184
                                    } else {
185
                                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
186
                                    }
187
188
                                    ++$relId;
189
                                }
190
                            }
191
                        }
192
                    }
193
                }
194
195
                // Hyperlink in table
196 33
                if ($iterator->current() instanceof ShapeTable) {
197
                    // Rows
198
                    $countRows = count($iterator->current()->getRows());
199
                    for ($row = 0; $row < $countRows; $row++) {
200
                        // Cells in rows
201
                        $countCells = count($iterator->current()->getRow($row)->getCells());
202
                        for ($cell = 0; $cell < $countCells; $cell++) {
203
                            $currentCell = $iterator->current()->getRow($row)->getCell($cell);
204
                            // Paragraphs in cell
205
                            foreach ($currentCell->getParagraphs() as $paragraph) {
206
                                // RichText in paragraph
207
                                foreach ($paragraph->getRichTextElements() as $element) {
208
                                    // Run or Text in RichText
209
                                    if ($element instanceof Run || $element instanceof TextElement) {
210
                                        if ($element->hasHyperlink()) {
211
                                            // Write relationship for hyperlink
212
                                            $hyperlink               = $element->getHyperlink();
213
                                            $hyperlink->relationId = 'rId' . $relId;
214
215
                                            if (!$hyperlink->isInternal()) {
216
                                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
217
                                            } else {
218
                                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
219
                                            }
220
221
                                            ++$relId;
222
                                        }
223
                                    }
224
                                }
225
                            }
226
                        }
227
                    }
228
                }
229
230 33
                if ($iterator->current() instanceof Group) {
231
                    $iterator2 = $pSlide->getShapeCollection()->getIterator();
232
                    while ($iterator2->valid()) {
233
                        // Hyperlink on shape
234
                        if ($iterator2->current()->hasHyperlink()) {
235
                            // Write relationship for hyperlink
236
                            $hyperlink             = $iterator2->current()->getHyperlink();
237
                            $hyperlink->relationId = 'rId' . $relId;
238
239
                            if (!$hyperlink->isInternal()) {
240
                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
241
                            } else {
242
                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
243
                            }
244
245
                            ++$relId;
246
                        }
247
248
                        // Hyperlink on rich text run
249
                        if ($iterator2->current() instanceof RichText) {
250
                            foreach ($iterator2->current()->getParagraphs() as $paragraph) {
251
                                foreach ($paragraph->getRichTextElements() as $element) {
252
                                    if ($element instanceof Run || $element instanceof TextElement) {
253
                                        if ($element->hasHyperlink()) {
254
                                            // Write relationship for hyperlink
255
                                            $hyperlink              = $element->getHyperlink();
256
                                            $hyperlink->relationId = 'rId' . $relId;
257
258
                                            if (!$hyperlink->isInternal()) {
259
                                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
260
                                            } else {
261
                                                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
262
                                            }
263
264
                                            ++$relId;
265
                                        }
266
                                    }
267
                                }
268
                            }
269
                        }
270
271
                        // Hyperlink in table
272
                        if ($iterator2->current() instanceof ShapeTable) {
273
                            // Rows
274
                            $countRows = count($iterator2->current()->getRows());
275
                            for ($row = 0; $row < $countRows; $row++) {
276
                                // Cells in rows
277
                                $countCells = count($iterator2->current()->getRow($row)->getCells());
278
                                for ($cell = 0; $cell < $countCells; $cell++) {
279
                                    $currentCell = $iterator2->current()->getRow($row)->getCell($cell);
280
                                    // Paragraphs in cell
281
                                    foreach ($currentCell->getParagraphs() as $paragraph) {
282
                                        // RichText in paragraph
283
                                        foreach ($paragraph->getRichTextElements() as $element) {
284
                                            // Run or Text in RichText
285
                                            if ($element instanceof Run || $element instanceof TextElement) {
286
                                                if ($element->hasHyperlink()) {
287
                                                    // Write relationship for hyperlink
288
                                                    $hyperlink               = $element->getHyperlink();
289
                                                    $hyperlink->relationId = 'rId' . $relId;
290
291
                                                    if (!$hyperlink->isInternal()) {
292
                                                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
293
                                                    } else {
294
                                                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
295
                                                    }
296
297
                                                    ++$relId;
298
                                                }
299
                                            }
300
                                        }
301
                                    }
302
                                }
303
                            }
304
                        }
305
306
                        $iterator2->next();
307
                    }
308
                }
309
310 33
                $iterator->next();
311
            }
312
        }
313
314
        // Write comment relationships
315 52
        if ($pSlide->getShapeCollection()->count() > 0) {
316 33
            $hasSlideComment = false;
317
318
            // Loop trough images and write relationships
319 33
            $iterator = $pSlide->getShapeCollection()->getIterator();
320 33
            while ($iterator->valid()) {
321 33
                if ($iterator->current() instanceof Comment) {
322 5
                    $hasSlideComment = true;
323 5
                    break;
324 28
                } elseif ($iterator->current() instanceof Group) {
325
                    $iterator2 = $iterator->current()->getShapeCollection()->getIterator();
326
                    while ($iterator2->valid()) {
327
                        if ($iterator2->current() instanceof Comment) {
328
                            $hasSlideComment = true;
329
                            break 2;
330
                        }
331
                        $iterator2->next();
332
                    }
333
                }
334
335 28
                $iterator->next();
336
            }
337
338 33
            if ($hasSlideComment) {
339 5
                $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', '../comments/comment'.($idxSlide + 1).'.xml');
340 5
                ++$relId;
341
            }
342
        }
343
344 52
        if ($pSlide->getNote()->getShapeCollection()->count() > 0) {
345
            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide', '../notesSlides/notesSlide'.($idxSlide + 1).'.xml');
346
        }
347
348 52
        $objWriter->endElement();
349
350
        // Return
351 52
        return $objWriter->getData();
352
    }
353
354
    /**
355
     * Write slide to XML format
356
     *
357
     * @param  \PhpOffice\PhpPresentation\Slide $pSlide
358
     * @return string              XML Output
359
     * @throws \Exception
360
     */
361 52
    public function writeSlide(Slide $pSlide)
362
    {
363
        // Create XML writer
364 52
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
365
366
        // XML header
367 52
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
368
369
        // p:sld
370 52
        $objWriter->startElement('p:sld');
371 52
        $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
372 52
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
373 52
        $objWriter->writeAttribute('xmlns:p', 'http://schemas.openxmlformats.org/presentationml/2006/main');
374 52
        $objWriter->writeAttributeIf(!$pSlide->isVisible(), 'show', 0);
375
376
        // p:sld/p:cSld
377 52
        $objWriter->startElement('p:cSld');
378
379
        // Background
380 52
        if ($pSlide->getBackground() instanceof Slide\AbstractBackground) {
381
            $oBackground = $pSlide->getBackground();
382
            // p:bg
383
            $objWriter->startElement('p:bg');
384
385
            // p:bgPr
386
            $objWriter->startElement('p:bgPr');
387
388
            if ($oBackground instanceof Slide\Background\Color) {
389
                // a:solidFill
390
                $objWriter->startElement('a:solidFill');
391
392
                $this->writeColor($objWriter, $oBackground->getColor());
393
394
                // > a:solidFill
395
                $objWriter->endElement();
396
            }
397
398
            if ($oBackground instanceof Slide\Background\Image) {
399
                // a:blipFill
400
                $objWriter->startElement('a:blipFill');
401
402
                // a:blip
403
                $objWriter->startElement('a:blip');
404
                $objWriter->writeAttribute('r:embed', $oBackground->relationId);
405
406
                // > a:blipFill
407
                $objWriter->endElement();
408
409
                // a:stretch
410
                $objWriter->startElement('a:stretch');
411
412
                // a:fillRect
413
                $objWriter->writeElement('a:fillRect');
414
415
                // > a:stretch
416
                $objWriter->endElement();
417
418
                // > a:blipFill
419
                $objWriter->endElement();
420
            }
421
422
            // > p:bgPr
423
            $objWriter->endElement();
424
425
            // > p:bg
426
            $objWriter->endElement();
427
        }
428
429
        // p:spTree
430 52
        $objWriter->startElement('p:spTree');
431
432
        // p:nvGrpSpPr
433 52
        $objWriter->startElement('p:nvGrpSpPr');
434
435
        // p:cNvPr
436 52
        $objWriter->startElement('p:cNvPr');
437 52
        $objWriter->writeAttribute('id', '1');
438 52
        $objWriter->writeAttribute('name', '');
439 52
        $objWriter->endElement();
440
441
        // p:cNvGrpSpPr
442 52
        $objWriter->writeElement('p:cNvGrpSpPr', null);
443
444
        // p:nvPr
445 52
        $objWriter->writeElement('p:nvPr', null);
446
447 52
        $objWriter->endElement();
448
449
        // p:grpSpPr
450 52
        $objWriter->startElement('p:grpSpPr');
451
452
        // a:xfrm
453 52
        $objWriter->startElement('a:xfrm');
454
455
        // a:off
456 52
        $objWriter->startElement('a:off');
457 52
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pSlide->getOffsetX()));
458 52
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pSlide->getOffsetY()));
459 52
        $objWriter->endElement(); // a:off
460
461
        // a:ext
462 52
        $objWriter->startElement('a:ext');
463 52
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pSlide->getExtentX()));
464 52
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pSlide->getExtentY()));
465 52
        $objWriter->endElement(); // a:ext
466
467
        // a:chOff
468 52
        $objWriter->startElement('a:chOff');
469 52
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pSlide->getOffsetX()));
470 52
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pSlide->getOffsetY()));
471 52
        $objWriter->endElement(); // a:chOff
472
473
        // a:chExt
474 52
        $objWriter->startElement('a:chExt');
475 52
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pSlide->getExtentX()));
476 52
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pSlide->getExtentY()));
477 52
        $objWriter->endElement(); // a:chExt
478
479 52
        $objWriter->endElement();
480
481 52
        $objWriter->endElement();
482
483
        // Loop shapes
484 52
        $this->writeShapeCollection($objWriter, $pSlide->getShapeCollection());
485
486
        // TODO
487 52
        $objWriter->endElement();
488
489 52
        $objWriter->endElement();
490
491
        // p:clrMapOvr
492 52
        $objWriter->startElement('p:clrMapOvr');
493
        // p:clrMapOvr\a:masterClrMapping
494 52
        $objWriter->writeElement('a:masterClrMapping', null);
495
        // ##p:clrMapOvr
496 52
        $objWriter->endElement();
497
498 52
        $this->writeSlideTransition($objWriter, $pSlide->getTransition());
499
500 52
        $this->writeSlideAnimations($objWriter, $pSlide);
501
502 52
        $objWriter->endElement();
503
504
        // Return
505 52
        return $objWriter->getData();
506
    }
507
508
    /**
509
     * @param XMLWriter $objWriter
510
     * @param Slide $oSlide
511
     */
512 52
    protected function writeSlideAnimations(XMLWriter $objWriter, Slide $oSlide)
513
    {
514 52
        $arrayAnimations = $oSlide->getAnimations();
515 52
        if (empty($arrayAnimations)) {
516 52
            return;
517
        }
518
519
        // Variables
520
        $shapeId = 1;
521
        $idCount = 1;
522
        $hashToIdMap = array();
523
        $arrayAnimationIds = array();
524
525
        foreach ($oSlide->getShapeCollection() as $shape) {
526
            $hashToIdMap[$shape->getHashCode()] = ++$shapeId;
527
        }
528
        foreach ($arrayAnimations as $oAnimation) {
529
            foreach ($oAnimation->getShapeCollection() as $oShape) {
530
                $arrayAnimationIds[] = $hashToIdMap[$oShape->getHashCode()];
531
            }
532
        }
533
534
        // p:timing
535
        $objWriter->startElement('p:timing');
536
        // p:timing/p:tnLst
537
        $objWriter->startElement('p:tnLst');
538
        // p:timing/p:tnLst/p:par
539
        $objWriter->startElement('p:par');
540
        // p:timing/p:tnLst/p:par/p:cTn
541
        $objWriter->startElement('p:cTn');
542
        $objWriter->writeAttribute('id', $idCount++);
543
        $objWriter->writeAttribute('dur', 'indefinite');
544
        $objWriter->writeAttribute('restart', 'never');
545
        $objWriter->writeAttribute('nodeType', 'tmRoot');
546
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst
547
        $objWriter->startElement('p:childTnLst');
548
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq
549
        $objWriter->startElement('p:seq');
550
        $objWriter->writeAttribute('concurrent', '1');
551
        $objWriter->writeAttribute('nextAc', 'seek');
552
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn
553
        $objWriter->startElement('p:cTn');
554
        $objWriter->writeAttribute('id', $idCount++);
555
        $objWriter->writeAttribute('dur', 'indefinite');
556
        $objWriter->writeAttribute('nodeType', 'mainSeq');
557
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst
558
        $objWriter->startElement('p:childTnLst');
559
560
        // Each animation has multiple shapes
561
        foreach ($arrayAnimations as $oAnimation) {
562
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par
563
            $objWriter->startElement('p:par');
564
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn
565
            $objWriter->startElement('p:cTn');
566
            $objWriter->writeAttribute('id', $idCount++);
567
            $objWriter->writeAttribute('fill', 'hold');
568
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:stCondLst
569
            $objWriter->startElement('p:stCondLst');
570
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:stCondLst/p:cond
571
            $objWriter->startElement('p:cond');
572
            $objWriter->writeAttribute('delay', 'indefinite');
573
            $objWriter->endElement();
574
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn\##p:stCondLst
575
            $objWriter->endElement();
576
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst
577
            $objWriter->startElement('p:childTnLst');
578
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst/p:par
579
            $objWriter->startElement('p:par');
580
            // 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
581
            $objWriter->startElement('p:cTn');
582
            $objWriter->writeAttribute('id', $idCount++);
583
            $objWriter->writeAttribute('fill', 'hold');
584
            // 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
585
            $objWriter->startElement('p:stCondLst');
586
            // 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
587
            $objWriter->startElement('p:cond');
588
            $objWriter->writeAttribute('delay', '0');
589
            $objWriter->endElement();
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\##p:stCondLst
591
            $objWriter->endElement();
592
            // 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
593
            $objWriter->startElement('p:childTnLst');
594
595
            $firstAnimation = true;
596
            foreach ($oAnimation->getShapeCollection() as $oShape) {
597
                $nodeType = $firstAnimation ? 'clickEffect' : 'withEffect';
598
                $shapeId = $hashToIdMap[$oShape->getHashCode()];
599
600
                // p:par
601
                $objWriter->startElement('p:par');
602
                // p:par/p:cTn
603
                $objWriter->startElement('p:cTn');
604
                $objWriter->writeAttribute('id', $idCount++);
605
                $objWriter->writeAttribute('presetID', '1');
606
                $objWriter->writeAttribute('presetClass', 'entr');
607
                $objWriter->writeAttribute('fill', 'hold');
608
                $objWriter->writeAttribute('presetSubtype', '0');
609
                $objWriter->writeAttribute('grpId', '0');
610
                $objWriter->writeAttribute('nodeType', $nodeType);
611
                // p:par/p:cTn/p:stCondLst
612
                $objWriter->startElement('p:stCondLst');
613
                // p:par/p:cTn/p:stCondLst/p:cond
614
                $objWriter->startElement('p:cond');
615
                $objWriter->writeAttribute('delay', '0');
616
                $objWriter->endElement();
617
                // p:par/p:cTn\##p:stCondLst
618
                $objWriter->endElement();
619
                // p:par/p:cTn/p:childTnLst
620
                $objWriter->startElement('p:childTnLst');
621
                // p:par/p:cTn/p:childTnLst/p:set
622
                $objWriter->startElement('p:set');
623
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr
624
                $objWriter->startElement('p:cBhvr');
625
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:cTn
626
                $objWriter->startElement('p:cTn');
627
                $objWriter->writeAttribute('id', $idCount++);
628
                $objWriter->writeAttribute('dur', '1');
629
                $objWriter->writeAttribute('fill', 'hold');
630
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:cTn/p:stCondLst
631
                $objWriter->startElement('p:stCondLst');
632
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:cTn/p:stCondLst/p:cond
633
                $objWriter->startElement('p:cond');
634
                $objWriter->writeAttribute('delay', '0');
635
                $objWriter->endElement();
636
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:cTn\##p:stCondLst
637
                $objWriter->endElement();
638
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr\##p:cTn
639
                $objWriter->endElement();
640
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:tgtEl
641
                $objWriter->startElement('p:tgtEl');
642
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:tgtEl/p:spTgt
643
                $objWriter->startElement('p:spTgt');
644
                $objWriter->writeAttribute('spid', $shapeId);
645
                $objWriter->endElement();
646
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr\##p:tgtEl
647
                $objWriter->endElement();
648
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:attrNameLst
649
                $objWriter->startElement('p:attrNameLst');
650
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr/p:attrNameLst/p:attrName
651
                $objWriter->writeElement('p:attrName', 'style.visibility');
652
                // p:par/p:cTn/p:childTnLst/p:set/p:cBhvr\##p:attrNameLst
653
                $objWriter->endElement();
654
                // p:par/p:cTn/p:childTnLst/p:set\##p:cBhvr
655
                $objWriter->endElement();
656
                // p:par/p:cTn/p:childTnLst/p:set/p:to
657
                $objWriter->startElement('p:to');
658
                // p:par/p:cTn/p:childTnLst/p:set/p:to/p:strVal
659
                $objWriter->startElement('p:strVal');
660
                $objWriter->writeAttribute('val', 'visible');
661
                $objWriter->endElement();
662
                // p:par/p:cTn/p:childTnLst/p:set\##p:to
663
                $objWriter->endElement();
664
                // p:par/p:cTn/p:childTnLst\##p:set
665
                $objWriter->endElement();
666
                // p:par/p:cTn\##p:childTnLst
667
                $objWriter->endElement();
668
                // p:par\##p:cTn
669
                $objWriter->endElement();
670
                // ##p:par
671
                $objWriter->endElement();
672
673
                $firstAnimation = false;
674
            }
675
676
            // 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
677
            $objWriter->endElement();
678
            // 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
679
            $objWriter->endElement();
680
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn/p:childTnLst\##p:par
681
            $objWriter->endElement();
682
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par/p:cTn\##p:childTnLst
683
            $objWriter->endElement();
684
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst/p:par\##p:cTn
685
            $objWriter->endElement();
686
            // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn/p:childTnLst\##p:par
687
            $objWriter->endElement();
688
        }
689
690
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:cTn\##p:childTnLst
691
        $objWriter->endElement();
692
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq\##p:cTn
693
        $objWriter->endElement();
694
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst
695
        $objWriter->startElement('p:prevCondLst');
696
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst/p:cond
697
        $objWriter->startElement('p:cond');
698
        $objWriter->writeAttribute('evt', 'onPrev');
699
        $objWriter->writeAttribute('delay', '0');
700
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst/p:cond/p:tgtEl
701
        $objWriter->startElement('p:tgtEl');
702
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst/p:cond/p:tgtEl/p:sldTgt
703
        $objWriter->writeElement('p:sldTgt', null);
704
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst/p:cond\##p:tgtEl
705
        $objWriter->endElement();
706
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:prevCondLst\##p:cond
707
        $objWriter->endElement();
708
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq\##p:prevCondLst
709
        $objWriter->endElement();
710
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst
711
        $objWriter->startElement('p:nextCondLst');
712
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst/p:cond
713
        $objWriter->startElement('p:cond');
714
        $objWriter->writeAttribute('evt', 'onNext');
715
        $objWriter->writeAttribute('delay', '0');
716
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst/p:cond/p:tgtEl
717
        $objWriter->startElement('p:tgtEl');
718
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst/p:cond/p:tgtEl/p:sldTgt
719
        $objWriter->writeElement('p:sldTgt', null);
720
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst/p:cond\##p:tgtEl
721
        $objWriter->endElement();
722
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq/p:nextCondLst\##p:cond
723
        $objWriter->endElement();
724
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst/p:seq\##p:nextCondLst
725
        $objWriter->endElement();
726
        // p:timing/p:tnLst/p:par/p:cTn/p:childTnLst\##p:seq
727
        $objWriter->endElement();
728
        // p:timing/p:tnLst/p:par/p:cTn\##p:childTnLst
729
        $objWriter->endElement();
730
        // p:timing/p:tnLst/p:par\##p:cTn
731
        $objWriter->endElement();
732
        // p:timing/p:tnLst\##p:par
733
        $objWriter->endElement();
734
        // p:timing\##p:tnLst
735
        $objWriter->endElement();
736
737
        // p:timing/p:bldLst
738
        $objWriter->startElement('p:bldLst');
739
740
        // Add in ids of all shapes in this slides animations
741
        foreach ($arrayAnimationIds as $id) {
742
            // p:timing/p:bldLst/p:bldP
743
            $objWriter->startElement('p:bldP');
744
            $objWriter->writeAttribute('spid', $id);
745
            $objWriter->writeAttribute('grpId', 0);
746
            $objWriter->endELement();
747
        }
748
749
        // p:timing\##p:bldLst
750
        $objWriter->endElement();
751
752
        // ##p:timing
753
        $objWriter->endElement();
754
    }
755
756
    /**
757
     * Write group
758
     *
759
     * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
760
     * @param \PhpOffice\PhpPresentation\Shape\Group $group
761
     * @param  int $shapeId
762
     */
763
    protected function writeShapeGroup(XMLWriter $objWriter, Group $group, &$shapeId)
764
    {
765
        // p:grpSp
766
        $objWriter->startElement('p:grpSp');
767
768
        // p:nvGrpSpPr
769
        $objWriter->startElement('p:nvGrpSpPr');
770
771
        // p:cNvPr
772
        $objWriter->startElement('p:cNvPr');
773
        $objWriter->writeAttribute('name', 'Group '.$shapeId++);
774
        $objWriter->writeAttribute('id', $shapeId);
775
        $objWriter->endElement(); // p:cNvPr
776
        // NOTE: Re: $shapeId This seems to be how PowerPoint 2010 does business.
777
778
        // p:cNvGrpSpPr
779
        $objWriter->writeElement('p:cNvGrpSpPr', null);
780
781
        // p:nvPr
782
        $objWriter->writeElement('p:nvPr', null);
783
784
        $objWriter->endElement(); // p:nvGrpSpPr
785
786
        // p:grpSpPr
787
        $objWriter->startElement('p:grpSpPr');
788
789
        // a:xfrm
790
        $objWriter->startElement('a:xfrm');
791
792
        // a:off
793
        $objWriter->startElement('a:off');
794
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($group->getOffsetX()));
795
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($group->getOffsetY()));
796
        $objWriter->endElement(); // a:off
797
798
        // a:ext
799
        $objWriter->startElement('a:ext');
800
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($group->getExtentX()));
801
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($group->getExtentY()));
802
        $objWriter->endElement(); // a:ext
803
804
        // a:chOff
805
        $objWriter->startElement('a:chOff');
806
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($group->getOffsetX()));
807
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($group->getOffsetY()));
808
        $objWriter->endElement(); // a:chOff
809
810
        // a:chExt
811
        $objWriter->startElement('a:chExt');
812
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($group->getExtentX()));
813
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($group->getExtentY()));
814
        $objWriter->endElement(); // a:chExt
815
816
        $objWriter->endElement(); // a:xfrm
817
818
        $objWriter->endElement(); // p:grpSpPr
819
820
        $this->writeShapeCollection($objWriter, $group->getShapeCollection(), $shapeId);
821
        $objWriter->endElement(); // p:grpSp
822
    }
823
824
    /**
825
     * Write chart
826
     *
827
     * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
828
     * @param \PhpOffice\PhpPresentation\Shape\Chart $shape
829
     * @param  int $shapeId
830
     */
831 24
    protected function writeShapeChart(XMLWriter $objWriter, ShapeChart $shape, $shapeId)
832
    {
833
        // p:graphicFrame
834 24
        $objWriter->startElement('p:graphicFrame');
835
836
        // p:nvGraphicFramePr
837 24
        $objWriter->startElement('p:nvGraphicFramePr');
838
839
        // p:cNvPr
840 24
        $objWriter->startElement('p:cNvPr');
841 24
        $objWriter->writeAttribute('id', $shapeId);
842 24
        $objWriter->writeAttribute('name', $shape->getName());
843 24
        $objWriter->writeAttribute('descr', $shape->getDescription());
844 24
        $objWriter->endElement();
845
846
        // p:cNvGraphicFramePr
847 24
        $objWriter->writeElement('p:cNvGraphicFramePr', null);
848
849
        // p:nvPr
850 24
        $objWriter->startElement('p:nvPr');
851 24
        if ($shape->isPlaceholder()) {
852
            $objWriter->startElement('p:ph');
853
            $objWriter->writeAttribute('type', $shape->getPlaceholder()->getType());
854
            $objWriter->endElement();
855
        }
856 24
        $objWriter->endElement();
857
858 24
        $objWriter->endElement();
859
860
        // p:xfrm
861 24
        $objWriter->startElement('p:xfrm');
862 24
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
863
864
        // a:off
865 24
        $objWriter->startElement('a:off');
866 24
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
867 24
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
868 24
        $objWriter->endElement();
869
870
        // a:ext
871 24
        $objWriter->startElement('a:ext');
872 24
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
873 24
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
874 24
        $objWriter->endElement();
875
876 24
        $objWriter->endElement();
877
878
        // a:graphic
879 24
        $objWriter->startElement('a:graphic');
880
881
        // a:graphicData
882 24
        $objWriter->startElement('a:graphicData');
883 24
        $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
884
885
        // c:chart
886 24
        $objWriter->startElement('c:chart');
887 24
        $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
888 24
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
889 24
        $objWriter->writeAttribute('r:id', $shape->relationId);
890 24
        $objWriter->endElement();
891
892 24
        $objWriter->endElement();
893
894 24
        $objWriter->endElement();
895
896 24
        $objWriter->endElement();
897 24
    }
898
899
    /**
900
     * Write pic
901
     *
902
     * @param  \PhpOffice\Common\XMLWriter  $objWriter XML Writer
903
     * @param  \PhpOffice\PhpPresentation\Shape\Drawing\AbstractDrawingAdapter $shape
904
     * @param  int $shapeId
905
     * @throws \Exception
906
     */
907
    protected function writeShapeDrawing(XMLWriter $objWriter, ShapeDrawing\AbstractDrawingAdapter $shape, $shapeId)
908
    {
909
        // p:pic
910
        $objWriter->startElement('p:pic');
911
912
        // p:nvPicPr
913
        $objWriter->startElement('p:nvPicPr');
914
915
        // p:cNvPr
916
        $objWriter->startElement('p:cNvPr');
917
        $objWriter->writeAttribute('id', $shapeId);
918
        $objWriter->writeAttribute('name', $shape->getName());
919
        $objWriter->writeAttribute('descr', $shape->getDescription());
920
921
        // a:hlinkClick
922
        if ($shape->hasHyperlink()) {
923
            $this->writeHyperlink($objWriter, $shape);
924
        }
925
926
        $objWriter->endElement();
927
928
        // p:cNvPicPr
929
        $objWriter->startElement('p:cNvPicPr');
930
931
        // a:picLocks
932
        $objWriter->startElement('a:picLocks');
933
        $objWriter->writeAttribute('noChangeAspect', '1');
934
        $objWriter->endElement();
935
936
        $objWriter->endElement();
937
938
        // p:nvPr
939
        $objWriter->startElement('p:nvPr');
940
        // PlaceHolder
941
        if ($shape->isPlaceholder()) {
942
            $objWriter->startElement('p:ph');
943
            $objWriter->writeAttribute('type', $shape->getPlaceholder()->getType());
944
            $objWriter->endElement();
945
        }
946
        /**
947
         * @link : https://github.com/stefslon/exportToPPTX/blob/master/exportToPPTX.m#L2128
948
         */
949
        if ($shape instanceof Media) {
950
            // p:nvPr > a:videoFile
951
            $objWriter->startElement('a:videoFile');
952
            $objWriter->writeAttribute('r:link', $shape->relationId);
953
            $objWriter->endElement();
954
            // p:nvPr > p:extLst
955
            $objWriter->startElement('p:extLst');
956
            // p:nvPr > p:extLst > p:ext
957
            $objWriter->startElement('p:ext');
958
            $objWriter->writeAttribute('uri', '{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}');
959
            // p:nvPr > p:extLst > p:ext > p14:media
960
            $objWriter->startElement('p14:media');
961
            $objWriter->writeAttribute('r:embed', ($shape->relationId + 1));
962
            $objWriter->writeAttribute('xmlns:p14', 'http://schemas.microsoft.com/office/powerpoint/2010/main');
963
            // p:nvPr > p:extLst > p:ext > ##p14:media
964
            $objWriter->endElement();
965
            // p:nvPr > p:extLst > ##p:ext
966
            $objWriter->endElement();
967
            // p:nvPr > ##p:extLst
968
            $objWriter->endElement();
969
        }
970
        // ##p:nvPr
971
        $objWriter->endElement();
972
        $objWriter->endElement();
973
974
        // p:blipFill
975
        $objWriter->startElement('p:blipFill');
976
977
        // a:blip
978
        $objWriter->startElement('a:blip');
979
        $objWriter->writeAttribute('r:embed', $shape->relationId);
980
        $objWriter->endElement();
981
982
        // a:stretch
983
        $objWriter->startElement('a:stretch');
984
        $objWriter->writeElement('a:fillRect', null);
985
        $objWriter->endElement();
986
987
        $objWriter->endElement();
988
989
        // p:spPr
990
        $objWriter->startElement('p:spPr');
991
        // a:xfrm
992
        $objWriter->startElement('a:xfrm');
993
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
994
995
        // a:off
996
        $objWriter->startElement('a:off');
997
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
998
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
999
        $objWriter->endElement();
1000
1001
        // a:ext
1002
        $objWriter->startElement('a:ext');
1003
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
1004
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
1005
        $objWriter->endElement();
1006
1007
        $objWriter->endElement();
1008
1009
        // a:prstGeom
1010
        $objWriter->startElement('a:prstGeom');
1011
        $objWriter->writeAttribute('prst', 'rect');
1012
1013
        // a:avLst
1014
        $objWriter->writeElement('a:avLst', null);
1015
1016
        $objWriter->endElement();
1017
1018
        $this->writeBorder($objWriter, $shape->getBorder(), '');
1019
1020
        $this->writeShadow($objWriter, $shape->getShadow());
1021
1022
        $objWriter->endElement();
1023
1024
        $objWriter->endElement();
1025
    }
1026
1027
    /**
1028
     * Write txt
1029
     *
1030
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
1031
     * @param  \PhpOffice\PhpPresentation\Shape\RichText   $shape
1032
     * @param  int                            $shapeId
1033
     * @throws \Exception
1034
     */
1035
    protected function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeId)
1036
    {
1037
        // p:sp
1038
        $objWriter->startElement('p:sp');
1039
1040
        // p:sp/p:nvSpPr
1041
        $objWriter->startElement('p:nvSpPr');
1042
1043
        // p:sp/p:nvSpPr/p:cNvPr
1044
        $objWriter->startElement('p:cNvPr');
1045
        $objWriter->writeAttribute('id', $shapeId);
1046
        $objWriter->writeAttribute('name', '');
1047
1048
        // Hyperlink
1049
        if ($shape->hasHyperlink()) {
1050
            $this->writeHyperlink($objWriter, $shape);
1051
        }
1052
        // > p:sp/p:nvSpPr
1053
        $objWriter->endElement();
1054
1055
        // p:sp/p:cNvSpPr
1056
        $objWriter->startElement('p:cNvSpPr');
1057
        $objWriter->writeAttribute('txBox', '1');
1058
        $objWriter->endElement();
1059
        // p:sp/p:cNvSpPr/p:nvPr
1060
        $objWriter->startElement('p:nvPr');
1061
        if ($shape->isPlaceholder()) {
1062
            $objWriter->startElement('p:ph');
1063
            $objWriter->writeAttribute('type', $shape->getPlaceholder()->getType());
1064
            $objWriter->endElement();
1065
        }
1066
        $objWriter->endElement();
1067
1068
        // > p:sp/p:cNvSpPr
1069
        $objWriter->endElement();
1070
1071
        // p:sp/p:spPr
1072
        $objWriter->startElement('p:spPr');
1073
1074
        if (!$shape->isPlaceholder()) {
1075
            // p:sp/p:spPr\a:xfrm
1076
            $objWriter->startElement('a:xfrm');
1077
            $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
1078
1079
            // p:sp/p:spPr\a:xfrm\a:off
1080
            $objWriter->startElement('a:off');
1081
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
1082
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
1083
            $objWriter->endElement();
1084
1085
            // p:sp/p:spPr\a:xfrm\a:ext
1086
            $objWriter->startElement('a:ext');
1087
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
1088
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
1089
            $objWriter->endElement();
1090
1091
            // > p:sp/p:spPr\a:xfrm
1092
            $objWriter->endElement();
1093
1094
            // p:sp/p:spPr\a:prstGeom
1095
            $objWriter->startElement('a:prstGeom');
1096
            $objWriter->writeAttribute('prst', 'rect');
1097
            $objWriter->endElement();
1098
        }
1099
1100
        $this->writeFill($objWriter, $shape->getFill());
1101
        $this->writeBorder($objWriter, $shape->getBorder(), '');
1102
        $this->writeShadow($objWriter, $shape->getShadow());
1103
1104
        // > p:sp/p:spPr
1105
        $objWriter->endElement();
1106
1107
        // p:txBody
1108
        $objWriter->startElement('p:txBody');
1109
1110
        // a:bodyPr
1111
        //@link :http://msdn.microsoft.com/en-us/library/documentformat.openxml.drawing.bodyproperties%28v=office.14%29.aspx
1112
        $objWriter->startElement('a:bodyPr');
1113
        if (!$shape->isPlaceholder()) {
1114
            $verticalAlign = $shape->getActiveParagraph()->getAlignment()->getVertical();
1115
            if ($verticalAlign != Alignment::VERTICAL_BASE && $verticalAlign != Alignment::VERTICAL_AUTO) {
1116
                $objWriter->writeAttribute('anchor', $verticalAlign);
1117
            }
1118
            if ($shape->getWrap() != RichText::WRAP_SQUARE) {
1119
                $objWriter->writeAttribute('wrap', $shape->getWrap());
1120
            }
1121
            $objWriter->writeAttribute('rtlCol', '0');
1122
1123
            if ($shape->getHorizontalOverflow() != RichText::OVERFLOW_OVERFLOW) {
1124
                $objWriter->writeAttribute('horzOverflow', $shape->getHorizontalOverflow());
1125
            }
1126
            if ($shape->getVerticalOverflow() != RichText::OVERFLOW_OVERFLOW) {
1127
                $objWriter->writeAttribute('vertOverflow', $shape->getVerticalOverflow());
1128
            }
1129
1130
            if ($shape->isUpright()) {
1131
                $objWriter->writeAttribute('upright', '1');
1132
            }
1133
            if ($shape->isVertical()) {
1134
                $objWriter->writeAttribute('vert', 'vert');
1135
            }
1136
1137
            $objWriter->writeAttribute('bIns', CommonDrawing::pixelsToEmu($shape->getInsetBottom()));
1138
            $objWriter->writeAttribute('lIns', CommonDrawing::pixelsToEmu($shape->getInsetLeft()));
1139
            $objWriter->writeAttribute('rIns', CommonDrawing::pixelsToEmu($shape->getInsetRight()));
1140
            $objWriter->writeAttribute('tIns', CommonDrawing::pixelsToEmu($shape->getInsetTop()));
1141
1142
            if ($shape->getColumns() <> 1) {
1143
                $objWriter->writeAttribute('numCol', $shape->getColumns());
1144
            }
1145
1146
            // a:spAutoFit
1147
            $objWriter->startElement('a:' . $shape->getAutoFit());
1148
            if ($shape->getAutoFit() == RichText::AUTOFIT_NORMAL) {
1149
                if (!is_null($shape->getFontScale())) {
1150
                    $objWriter->writeAttribute('fontScale', (int)($shape->getFontScale() * 1000));
1151
                }
1152
                if (!is_null($shape->getLineSpaceReduction())) {
1153
                    $objWriter->writeAttribute('lnSpcReduction', (int)($shape->getLineSpaceReduction() * 1000));
1154
                }
1155
            }
1156
1157
            $objWriter->endElement();
1158
        }
1159
        $objWriter->endElement();
1160
1161
        // a:lstStyle
1162
        $objWriter->startElement('a:lstStyle');
1163
        $objWriter->endElement();
1164
1165
        // Write paragraphs
1166
        $this->writeParagraphs($objWriter, $shape->getParagraphs(), $shape->isPlaceholder());
1167
1168
        $objWriter->endElement();
1169
1170
        $objWriter->endElement();
1171
    }
1172
1173
    /**
1174
     * Write table
1175
     *
1176
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
1177
     * @param  \PhpOffice\PhpPresentation\Shape\Table      $shape
1178
     * @param  int                            $shapeId
1179
     * @throws \Exception
1180
     */
1181
    protected function writeShapeTable(XMLWriter $objWriter, ShapeTable $shape, $shapeId)
1182
    {
1183
        // p:graphicFrame
1184
        $objWriter->startElement('p:graphicFrame');
1185
1186
        // p:nvGraphicFramePr
1187
        $objWriter->startElement('p:nvGraphicFramePr');
1188
1189
        // p:cNvPr
1190
        $objWriter->startElement('p:cNvPr');
1191
        $objWriter->writeAttribute('id', $shapeId);
1192
        $objWriter->writeAttribute('name', $shape->getName());
1193
        $objWriter->writeAttribute('descr', $shape->getDescription());
1194
1195
        $objWriter->endElement();
1196
1197
        // p:cNvGraphicFramePr
1198
        $objWriter->startElement('p:cNvGraphicFramePr');
1199
1200
        // a:graphicFrameLocks
1201
        $objWriter->startElement('a:graphicFrameLocks');
1202
        $objWriter->writeAttribute('noGrp', '1');
1203
        $objWriter->endElement();
1204
1205
        $objWriter->endElement();
1206
1207
        // p:nvPr
1208
        $objWriter->startElement('p:nvPr');
1209
        if ($shape->isPlaceholder()) {
1210
            $objWriter->startElement('p:ph');
1211
            $objWriter->writeAttribute('type', $shape->getPlaceholder()->getType());
1212
            $objWriter->endElement();
1213
        }
1214
        $objWriter->endElement();
1215
1216
        $objWriter->endElement();
1217
1218
        // p:xfrm
1219
        $objWriter->startElement('p:xfrm');
1220
1221
        // a:off
1222
        $objWriter->startElement('a:off');
1223
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
1224
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
1225
        $objWriter->endElement();
1226
1227
        // a:ext
1228
        $objWriter->startElement('a:ext');
1229
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
1230
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
1231
        $objWriter->endElement();
1232
1233
        $objWriter->endElement();
1234
1235
        // a:graphic
1236
        $objWriter->startElement('a:graphic');
1237
1238
        // a:graphicData
1239
        $objWriter->startElement('a:graphicData');
1240
        $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/table');
1241
1242
        // a:tbl
1243
        $objWriter->startElement('a:tbl');
1244
1245
        // a:tblPr
1246
        $objWriter->startElement('a:tblPr');
1247
        $objWriter->writeAttribute('firstRow', '1');
1248
        $objWriter->writeAttribute('bandRow', '1');
1249
1250
        $objWriter->endElement();
1251
1252
        // a:tblGrid
1253
        $objWriter->startElement('a:tblGrid');
1254
1255
        // Write cell widths
1256
        $countCells = count($shape->getRow(0)->getCells());
1257
        for ($cell = 0; $cell < $countCells; $cell++) {
1258
            // a:gridCol
1259
            $objWriter->startElement('a:gridCol');
1260
1261
            // Calculate column width
1262
            $width = $shape->getRow(0)->getCell($cell)->getWidth();
1263
            if ($width == 0) {
1264
                $colCount   = count($shape->getRow(0)->getCells());
1265
                $totalWidth = $shape->getWidth();
1266
                $width      = $totalWidth / $colCount;
1267
            }
1268
1269
            $objWriter->writeAttribute('w', CommonDrawing::pixelsToEmu($width));
1270
            $objWriter->endElement();
1271
        }
1272
1273
        $objWriter->endElement();
1274
1275
        // Colspan / rowspan containers
1276
        $colSpan = array();
1277
        $rowSpan = array();
1278
1279
        // Default border style
1280
        $defaultBorder = new Border();
1281
1282
        // Write rows
1283
        $countRows = count($shape->getRows());
1284
        for ($row = 0; $row < $countRows; $row++) {
1285
            // a:tr
1286
            $objWriter->startElement('a:tr');
1287
            $objWriter->writeAttribute('h', CommonDrawing::pixelsToEmu($shape->getRow($row)->getHeight()));
1288
1289
            // Write cells
1290
            $countCells = count($shape->getRow($row)->getCells());
1291
            for ($cell = 0; $cell < $countCells; $cell++) {
1292
                // Current cell
1293
                $currentCell = $shape->getRow($row)->getCell($cell);
1294
1295
                // Next cell right
1296
                $nextCellRight = $shape->getRow($row)->getCell($cell + 1, true);
1297
1298
                // Next cell below
1299
                $nextRowBelow  = $shape->getRow($row + 1, true);
1300
                $nextCellBelow = null;
1301
                if ($nextRowBelow != null) {
1302
                    $nextCellBelow = $nextRowBelow->getCell($cell, true);
1303
                }
1304
1305
                // a:tc
1306
                $objWriter->startElement('a:tc');
1307
                // Colspan
1308
                if ($currentCell->getColSpan() > 1) {
1309
                    $objWriter->writeAttribute('gridSpan', $currentCell->getColSpan());
1310
                    $colSpan[$row] = $currentCell->getColSpan() - 1;
1311
                } elseif (isset($colSpan[$row]) && $colSpan[$row] > 0) {
1312
                    $colSpan[$row]--;
1313
                    $objWriter->writeAttribute('hMerge', '1');
1314
                }
1315
1316
                // Rowspan
1317
                if ($currentCell->getRowSpan() > 1) {
1318
                    $objWriter->writeAttribute('rowSpan', $currentCell->getRowSpan());
1319
                    $rowSpan[$cell] = $currentCell->getRowSpan() - 1;
1320
                } elseif (isset($rowSpan[$cell]) && $rowSpan[$cell] > 0) {
1321
                    $rowSpan[$cell]--;
1322
                    $objWriter->writeAttribute('vMerge', '1');
1323
                }
1324
1325
                // a:txBody
1326
                $objWriter->startElement('a:txBody');
1327
1328
                // a:bodyPr
1329
                $objWriter->startElement('a:bodyPr');
1330
                $objWriter->writeAttribute('wrap', 'square');
1331
                $objWriter->writeAttribute('rtlCol', '0');
1332
1333
                // a:spAutoFit
1334
                $objWriter->writeElement('a:spAutoFit', null);
1335
1336
                $objWriter->endElement();
1337
1338
                // a:lstStyle
1339
                $objWriter->writeElement('a:lstStyle', null);
1340
1341
                // Write paragraphs
1342
                $this->writeParagraphs($objWriter, $currentCell->getParagraphs());
1343
1344
                $objWriter->endElement();
1345
1346
                // a:tcPr
1347
                $objWriter->startElement('a:tcPr');
1348
                // Alignment (horizontal)
1349
                $firstParagraph  = $currentCell->getParagraph(0);
1350
                $verticalAlign = $firstParagraph->getAlignment()->getVertical();
1351
                if ($verticalAlign != Alignment::VERTICAL_BASE && $verticalAlign != Alignment::VERTICAL_AUTO) {
1352
                    $objWriter->writeAttribute('anchor', $verticalAlign);
1353
                }
1354
1355
                // Margins
1356
                $alignment = $firstParagraph->getAlignment();
1357
                $objWriter->writeAttribute('marL', $alignment->getMarginLeft());
1358
                $objWriter->writeAttribute('marR', $alignment->getMarginRight());
1359
                $objWriter->writeAttribute('marT', $alignment->getMarginTop());
1360
                $objWriter->writeAttribute('marB', $alignment->getMarginBottom());
1361
1362
                // Determine borders
1363
                $borderLeft         = $currentCell->getBorders()->getLeft();
1364
                $borderRight        = $currentCell->getBorders()->getRight();
1365
                $borderTop          = $currentCell->getBorders()->getTop();
1366
                $borderBottom       = $currentCell->getBorders()->getBottom();
1367
                $borderDiagonalDown = $currentCell->getBorders()->getDiagonalDown();
1368
                $borderDiagonalUp   = $currentCell->getBorders()->getDiagonalUp();
1369
1370
                // Fix PowerPoint implementation
1371
                if (!is_null($nextCellRight) && $nextCellRight->getBorders()->getRight()->getHashCode() != $defaultBorder->getHashCode()) {
1372
                    $borderRight = $nextCellRight->getBorders()->getLeft();
1373
                }
1374
                if (!is_null($nextCellBelow) && $nextCellBelow->getBorders()->getBottom()->getHashCode() != $defaultBorder->getHashCode()) {
1375
                    $borderBottom = $nextCellBelow->getBorders()->getTop();
1376
                }
1377
1378
                // Write borders
1379
                $this->writeBorder($objWriter, $borderLeft, 'L');
1380
                $this->writeBorder($objWriter, $borderRight, 'R');
1381
                $this->writeBorder($objWriter, $borderTop, 'T');
1382
                $this->writeBorder($objWriter, $borderBottom, 'B');
1383
                $this->writeBorder($objWriter, $borderDiagonalDown, 'TlToBr');
1384
                $this->writeBorder($objWriter, $borderDiagonalUp, 'BlToTr');
1385
1386
                // Fill
1387
                $this->writeFill($objWriter, $currentCell->getFill());
1388
1389
                $objWriter->endElement();
1390
1391
                $objWriter->endElement();
1392
            }
1393
1394
            $objWriter->endElement();
1395
        }
1396
1397
        $objWriter->endElement();
1398
1399
        $objWriter->endElement();
1400
1401
        $objWriter->endElement();
1402
1403
        $objWriter->endElement();
1404
    }
1405
1406
    /**
1407
     * Write paragraphs
1408
     *
1409
     * @param  \PhpOffice\Common\XMLWriter           $objWriter  XML Writer
1410
     * @param  \PhpOffice\PhpPresentation\Shape\RichText\Paragraph[] $paragraphs
1411
     * @param  bool $bIsPlaceholder
1412
     * @throws \Exception
1413
     */
1414
    protected function writeParagraphs(XMLWriter $objWriter, $paragraphs, $bIsPlaceholder = false)
1415
    {
1416
        // Loop trough paragraphs
1417
        foreach ($paragraphs as $paragraph) {
1418
            // a:p
1419
            $objWriter->startElement('a:p');
1420
1421
            // a:pPr
1422
            if (!$bIsPlaceholder) {
1423
                $objWriter->startElement('a:pPr');
1424
                $objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal());
1425
                $objWriter->writeAttribute('fontAlgn', $paragraph->getAlignment()->getVertical());
1426
                $objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft()));
1427
                $objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginRight()));
1428
                $objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent()));
1429
                $objWriter->writeAttribute('lvl', $paragraph->getAlignment()->getLevel());
1430
1431
                $objWriter->startElement('a:lnSpc');
1432
                $objWriter->startElement('a:spcPct');
1433
                $objWriter->writeAttribute('val', $paragraph->getLineSpacing() * 1000);
1434
                $objWriter->endElement();
1435
                $objWriter->endElement();
1436
1437
                // Bullet type specified?
1438
                if ($paragraph->getBulletStyle()->getBulletType() != Bullet::TYPE_NONE) {
1439
                    // Color
1440
                    // a:buClr must be before a:buFont (else PowerPoint crashes at launch)
1441
                    if ($paragraph->getBulletStyle()->getBulletColor() instanceof Color) {
1442
                        $objWriter->startElement('a:buClr');
1443
                        $this->writeColor($objWriter, $paragraph->getBulletStyle()->getBulletColor());
1444
                        $objWriter->endElement();
1445
                    }
1446
1447
                    // a:buFont
1448
                    $objWriter->startElement('a:buFont');
1449
                    $objWriter->writeAttribute('typeface', $paragraph->getBulletStyle()->getBulletFont());
1450
                    $objWriter->endElement();
1451
1452
                    if ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_BULLET) {
1453
                        // a:buChar
1454
                        $objWriter->startElement('a:buChar');
1455
                        $objWriter->writeAttribute('char', $paragraph->getBulletStyle()->getBulletChar());
1456
                        $objWriter->endElement();
1457
                    } elseif ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_NUMERIC) {
1458
                        // a:buAutoNum
1459
                        $objWriter->startElement('a:buAutoNum');
1460
                        $objWriter->writeAttribute('type', $paragraph->getBulletStyle()->getBulletNumericStyle());
1461
                        if ($paragraph->getBulletStyle()->getBulletNumericStartAt() != 1) {
1462
                            $objWriter->writeAttribute('startAt', $paragraph->getBulletStyle()->getBulletNumericStartAt());
1463
                        }
1464
                        $objWriter->endElement();
1465
                    }
1466
                }
1467
1468
                $objWriter->endElement();
1469
            }
1470
1471
            // Loop trough rich text elements
1472
            $elements = $paragraph->getRichTextElements();
1473
            foreach ($elements as $element) {
1474
                if ($element instanceof BreakElement) {
1475
                    // a:br
1476
                    $objWriter->writeElement('a:br', null);
1477
                } elseif ($element instanceof Run || $element instanceof TextElement) {
1478
                    // a:r
1479
                    $objWriter->startElement('a:r');
1480
1481
                    // a:rPr
1482
                    if ($element instanceof Run && !$bIsPlaceholder) {
1483
                        // a:rPr
1484
                        $objWriter->startElement('a:rPr');
1485
1486
                        // Lang
1487
                        $objWriter->writeAttribute('lang', ($element->getLanguage() ? $element->getLanguage() : 'en-US'));
1488
1489
                        $objWriter->writeAttributeIf($element->getFont()->isBold(), 'b', '1');
1490
                        $objWriter->writeAttributeIf($element->getFont()->isItalic(), 'i', '1');
1491
                        $objWriter->writeAttributeIf($element->getFont()->isStrikethrough(), 'strike', 'sngStrike');
1492
1493
                        // Size
1494
                        $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100));
1495
1496
                        // Character spacing
1497
                        $objWriter->writeAttribute('spc', $element->getFont()->getCharacterSpacing());
1498
1499
                        // Underline
1500
                        $objWriter->writeAttribute('u', $element->getFont()->getUnderline());
1501
1502
                        // Superscript / subscript
1503
                        $objWriter->writeAttributeIf($element->getFont()->isSuperScript(), 'baseline', '30000');
1504
                        $objWriter->writeAttributeIf($element->getFont()->isSubScript(), 'baseline', '-25000');
1505
1506
                        // Color - a:solidFill
1507
                        $objWriter->startElement('a:solidFill');
1508
                        $this->writeColor($objWriter, $element->getFont()->getColor());
1509
                        $objWriter->endElement();
1510
1511
                        // Font - a:latin
1512
                        $objWriter->startElement('a:latin');
1513
                        $objWriter->writeAttribute('typeface', $element->getFont()->getName());
1514
                        $objWriter->endElement();
1515
1516
                        // a:hlinkClick
1517
                        $this->writeHyperlink($objWriter, $element);
1518
1519
                        $objWriter->endElement();
1520
                    }
1521
1522
                    // t
1523
                    $objWriter->startElement('a:t');
1524
                    $objWriter->writeCData(Text::controlCharacterPHP2OOXML($element->getText()));
1525
                    $objWriter->endElement();
1526
1527
                    $objWriter->endElement();
1528
                }
1529
            }
1530
1531
            $objWriter->endElement();
1532
        }
1533
    }
1534
1535
    /**
1536
     * Write Line Shape
1537
     *
1538
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
1539
     * @param \PhpOffice\PhpPresentation\Shape\Line $shape
1540
     * @param  int $shapeId
1541
     */
1542
    protected function writeShapeLine(XMLWriter $objWriter, Line $shape, $shapeId)
1543
    {
1544
        // p:sp
1545
        $objWriter->startElement('p:cxnSp');
1546
1547
        // p:nvSpPr
1548
        $objWriter->startElement('p:nvCxnSpPr');
1549
1550
        // p:cNvPr
1551
        $objWriter->startElement('p:cNvPr');
1552
        $objWriter->writeAttribute('id', $shapeId);
1553
        $objWriter->writeAttribute('name', '');
1554
1555
        $objWriter->endElement();
1556
1557
        // p:cNvCxnSpPr
1558
        $objWriter->writeElement('p:cNvCxnSpPr', null);
1559
1560
        // p:nvPr
1561
        $objWriter->startElement('p:nvPr');
1562
        if ($shape->isPlaceholder()) {
1563
            $objWriter->startElement('p:ph');
1564
            $objWriter->writeAttribute('type', $shape->getPlaceholder()->getType());
1565
            $objWriter->endElement();
1566
        }
1567
        $objWriter->endElement();
1568
1569
        $objWriter->endElement();
1570
1571
        // p:spPr
1572
        $objWriter->startElement('p:spPr');
1573
1574
        // a:xfrm
1575
        $objWriter->startElement('a:xfrm');
1576
1577
        if ($shape->getWidth() >= 0 && $shape->getHeight() >= 0) {
1578
            // a:off
1579
            $objWriter->startElement('a:off');
1580
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
1581
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
1582
            $objWriter->endElement();
1583
1584
            // a:ext
1585
            $objWriter->startElement('a:ext');
1586
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
1587
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
1588
            $objWriter->endElement();
1589
        } elseif ($shape->getWidth() < 0 && $shape->getHeight() < 0) {
1590
            // a:off
1591
            $objWriter->startElement('a:off');
1592
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth()));
1593
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight()));
1594
            $objWriter->endElement();
1595
1596
            // a:ext
1597
            $objWriter->startElement('a:ext');
1598
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(-$shape->getWidth()));
1599
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(-$shape->getHeight()));
1600
            $objWriter->endElement();
1601
        } elseif ($shape->getHeight() < 0) {
1602
            $objWriter->writeAttribute('flipV', 1);
1603
1604
            // a:off
1605
            $objWriter->startElement('a:off');
1606
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
1607
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight()));
1608
            $objWriter->endElement();
1609
1610
            // a:ext
1611
            $objWriter->startElement('a:ext');
1612
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
1613
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(-$shape->getHeight()));
1614
            $objWriter->endElement();
1615
        } elseif ($shape->getWidth() < 0) {
1616
            $objWriter->writeAttribute('flipV', 1);
1617
1618
            // a:off
1619
            $objWriter->startElement('a:off');
1620
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth()));
1621
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
1622
            $objWriter->endElement();
1623
1624
            // a:ext
1625
            $objWriter->startElement('a:ext');
1626
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(-$shape->getWidth()));
1627
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
1628
            $objWriter->endElement();
1629
        }
1630
1631
        $objWriter->endElement();
1632
1633
        // a:prstGeom
1634
        $objWriter->startElement('a:prstGeom');
1635
        $objWriter->writeAttribute('prst', 'line');
1636
        $objWriter->endElement();
1637
1638
        if ($shape->getBorder()->getLineStyle() != Border::LINE_NONE) {
1639
            $this->writeBorder($objWriter, $shape->getBorder(), '');
1640
        }
1641
1642
        $objWriter->endElement();
1643
1644
        $objWriter->endElement();
1645
    }
1646
1647
    /**
1648
     * Write hyperlink
1649
     *
1650
     * @param \PhpOffice\Common\XMLWriter                               $objWriter XML Writer
1651
     * @param \PhpOffice\PhpPresentation\AbstractShape|\PhpOffice\PhpPresentation\Shape\RichText\TextElement $shape
1652
     */
1653
    protected function writeHyperlink(XMLWriter $objWriter, $shape)
1654
    {
1655
        if (!$shape->hasHyperlink()) {
1656
            return;
1657
        }
1658
        // a:hlinkClick
1659
        $objWriter->startElement('a:hlinkClick');
1660
        $objWriter->writeAttribute('r:id', $shape->getHyperlink()->relationId);
1661
        $objWriter->writeAttribute('tooltip', $shape->getHyperlink()->getTooltip());
1662
        if ($shape->getHyperlink()->isInternal()) {
1663
            $objWriter->writeAttribute('action', $shape->getHyperlink()->getUrl());
1664
        }
1665
        $objWriter->endElement();
1666
    }
1667
1668
    /**
1669
     * Write Note Slide
1670
     * @param Note $pNote
1671
     * @throws \Exception
1672
     * @return  string
1673
     */
1674
    protected function writeNote(Note $pNote)
1675
    {
1676
        // Create XML writer
1677
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
1678
1679
        // XML header
1680
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
1681
1682
        // p:notes
1683
        $objWriter->startElement('p:notes');
1684
        $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
1685
        $objWriter->writeAttribute('xmlns:p', 'http://schemas.openxmlformats.org/presentationml/2006/main');
1686
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
1687
1688
        // p:notes/p:cSld
1689
        $objWriter->startElement('p:cSld');
1690
1691
        // p:notes/p:cSld/p:spTree
1692
        $objWriter->startElement('p:spTree');
1693
1694
        // p:notes/p:cSld/p:spTree/p:nvGrpSpPr
1695
        $objWriter->startElement('p:nvGrpSpPr');
1696
1697
        // p:notes/p:cSld/p:spTree/p:nvGrpSpPr/p:cNvPr
1698
        $objWriter->startElement('p:cNvPr');
1699
        $objWriter->writeAttribute('id', '1');
1700
        $objWriter->writeAttribute('name', '');
1701
        $objWriter->endElement();
1702
1703
        // p:notes/p:cSld/p:spTree/p:nvGrpSpPr/p:cNvGrpSpPr
1704
        $objWriter->writeElement('p:cNvGrpSpPr', null);
1705
1706
        // p:notes/p:cSld/p:spTree/p:nvGrpSpPr/p:nvPr
1707
        $objWriter->writeElement('p:nvPr', null);
1708
1709
        // p:notes/p:cSld/p:spTree/p:nvGrpSpPr
1710
        $objWriter->endElement();
1711
1712
        // p:notes/p:cSld/p:spTree/p:grpSpPr
1713
        $objWriter->startElement('p:grpSpPr');
1714
1715
        // p:notes/p:cSld/p:spTree/p:grpSpPr/a:xfrm
1716
        $objWriter->startElement('a:xfrm');
1717
1718
        // p:notes/p:cSld/p:spTree/p:grpSpPr/a:xfrm/a:off
1719
        $objWriter->startElement('a:off');
1720
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX()));
1721
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pNote->getOffsetY()));
1722
        $objWriter->endElement(); // a:off
1723
1724
        // p:notes/p:cSld/p:spTree/p:grpSpPr/a:xfrm/a:ext
1725
        $objWriter->startElement('a:ext');
1726
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pNote->getExtentX()));
1727
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pNote->getExtentY()));
1728
        $objWriter->endElement(); // a:ext
1729
1730
        // p:notes/p:cSld/p:spTree/p:grpSpPr/a:xfrm/a:chOff
1731
        $objWriter->startElement('a:chOff');
1732
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX()));
1733
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pNote->getOffsetY()));
1734
        $objWriter->endElement(); // a:chOff
1735
1736
        // p:notes/p:cSld/p:spTree/p:grpSpPr/a:xfrm/a:chExt
1737
        $objWriter->startElement('a:chExt');
1738
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pNote->getExtentX()));
1739
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pNote->getExtentY()));
1740
        $objWriter->endElement(); // a:chExt
1741
1742
        // p:notes/p:cSld/p:spTree/p:grpSpPr/a:xfrm
1743
        $objWriter->endElement();
1744
1745
        // p:notes/p:cSld/p:spTree/p:grpSpPr
1746
        $objWriter->endElement();
1747
1748
        // p:notes/p:cSld/p:spTree/p:sp[1]
1749
        $objWriter->startElement('p:sp');
1750
1751
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr
1752
        $objWriter->startElement('p:nvSpPr');
1753
1754
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr/p:cNvPr
1755
        $objWriter->startElement('p:cNvPr');
1756
        $objWriter->writeAttribute('id', '2');
1757
        $objWriter->writeAttribute('name', 'Slide Image Placeholder 1');
1758
        $objWriter->endElement();
1759
1760
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr/p:cNvSpPr
1761
        $objWriter->startElement('p:cNvSpPr');
1762
1763
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr/p:cNvSpPr/a:spLocks
1764
        $objWriter->startElement('a:spLocks');
1765
        $objWriter->writeAttribute('noGrp', '1');
1766
        $objWriter->writeAttribute('noRot', '1');
1767
        $objWriter->writeAttribute('noChangeAspect', '1');
1768
        $objWriter->endElement();
1769
1770
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr/p:cNvSpPr
1771
        $objWriter->endElement();
1772
1773
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr/p:nvPr
1774
        $objWriter->startElement('p:nvPr');
1775
1776
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr/p:nvPr/p:ph
1777
        $objWriter->startElement('p:ph');
1778
        $objWriter->writeAttribute('type', 'sldImg');
1779
        $objWriter->endElement();
1780
1781
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr/p:nvPr
1782
        $objWriter->endElement();
1783
1784
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:nvSpPr
1785
        $objWriter->endElement();
1786
1787
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr
1788
        $objWriter->startElement('p:spPr');
1789
1790
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:xfrm
1791
        $objWriter->startElement('a:xfrm');
1792
1793
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:xfrm/a:off
1794
        $objWriter->startElement('a:off');
1795
        $objWriter->writeAttribute('x', 0);
1796
        $objWriter->writeAttribute('y', 0);
1797
        $objWriter->endElement();
1798
1799
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:xfrm/a:ext
1800
        $objWriter->startElement('a:ext');
1801
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(round($pNote->getExtentX() / 2)));
1802
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(round($pNote->getExtentY() / 2)));
1803
        $objWriter->endElement();
1804
1805
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:xfrm
1806
        $objWriter->endElement();
1807
1808
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:prstGeom
1809
        $objWriter->startElement('a:prstGeom');
1810
        $objWriter->writeAttribute('prst', 'rect');
1811
1812
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:prstGeom/a:avLst
1813
        $objWriter->writeElement('a:avLst', null);
1814
1815
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:prstGeom
1816
        $objWriter->endElement();
1817
1818
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:noFill
1819
        $objWriter->writeElement('a:noFill', null);
1820
1821
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:ln
1822
        $objWriter->startElement('a:ln');
1823
        $objWriter->writeAttribute('w', '12700');
1824
1825
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:ln/a:solidFill
1826
        $objWriter->startElement('a:solidFill');
1827
1828
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:ln/a:solidFill/a:prstClr
1829
        $objWriter->startElement('a:prstClr');
1830
        $objWriter->writeAttribute('val', 'black');
1831
        $objWriter->endElement();
1832
1833
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:ln/a:solidFill
1834
        $objWriter->endElement();
1835
1836
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr/a:ln
1837
        $objWriter->endElement();
1838
1839
        // p:notes/p:cSld/p:spTree/p:sp[1]/p:spPr
1840
        $objWriter->endElement();
1841
1842
        // p:notes/p:cSld/p:spTree/p:sp[1]
1843
        $objWriter->endElement();
1844
1845
        // p:notes/p:cSld/p:spTree/p:sp[2]
1846
        $objWriter->startElement('p:sp');
1847
1848
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr
1849
        $objWriter->startElement('p:nvSpPr');
1850
1851
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr/p:cNvPr
1852
        $objWriter->startElement('p:cNvPr');
1853
        $objWriter->writeAttribute('id', '3');
1854
        $objWriter->writeAttribute('name', 'Notes Placeholder');
1855
        $objWriter->endElement();
1856
1857
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr/p:cNvSpPr
1858
        $objWriter->startElement('p:cNvSpPr');
1859
1860
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr/p:cNvSpPr/a:spLocks
1861
        $objWriter->startElement('a:spLocks');
1862
        $objWriter->writeAttribute('noGrp', '1');
1863
        $objWriter->endElement();
1864
1865
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr/p:cNvSpPr
1866
        $objWriter->endElement();
1867
1868
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr/p:nvPr
1869
        $objWriter->startElement('p:nvPr');
1870
1871
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr/p:nvPr/p:ph
1872
        $objWriter->startElement('p:ph');
1873
        $objWriter->writeAttribute('type', 'body');
1874
        $objWriter->writeAttribute('idx', '1');
1875
        $objWriter->endElement();
1876
1877
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr/p:nvPr
1878
        $objWriter->endElement();
1879
1880
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:nvSpPr
1881
        $objWriter->endElement();
1882
1883
        // START notes print below rectangle section
1884
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr
1885
        $objWriter->startElement('p:spPr');
1886
1887
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr/a:xfrm
1888
        $objWriter->startElement('a:xfrm');
1889
1890
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr/a:xfrm/a:off
1891
        $objWriter->startElement('a:off');
1892
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX()));
1893
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu(round($pNote->getExtentY() / 2) + $pNote->getOffsetY()));
1894
        $objWriter->endElement();
1895
1896
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr/a:xfrm/a:ext
1897
        $objWriter->startElement('a:ext');
1898
        $objWriter->writeAttribute('cx', '5486400');
1899
        $objWriter->writeAttribute('cy', '3600450');
1900
        $objWriter->endElement();
1901
1902
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr/a:xfrm
1903
        $objWriter->endElement();
1904
1905
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr/a:prstGeom
1906
        $objWriter->startElement('a:prstGeom');
1907
        $objWriter->writeAttribute('prst', 'rect');
1908
1909
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr/a:prstGeom/a:avLst
1910
        $objWriter->writeElement('a:avLst', null);
1911
1912
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr/a:prstGeom
1913
        $objWriter->endElement();
1914
1915
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:spPr
1916
        $objWriter->endElement();
1917
1918
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:txBody
1919
        $objWriter->startElement('p:txBody');
1920
1921
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:txBody/a:bodyPr
1922
        $objWriter->writeElement('a:bodyPr', null);
1923
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:txBody/a:lstStyle
1924
        $objWriter->writeElement('a:lstStyle', null);
1925
1926
        // Loop shapes
1927
        $shapes  = $pNote->getShapeCollection();
1928
        foreach ($shapes as $shape) {
1929
            // Check type
1930
            if ($shape instanceof RichText) {
1931
                $paragraphs = $shape->getParagraphs();
1932
                $this->writeParagraphs($objWriter, $paragraphs);
1933
            }
1934
        }
1935
1936
        // p:notes/p:cSld/p:spTree/p:sp[2]/p:txBody
1937
        $objWriter->endElement();
1938
1939
        // p:notes/p:cSld/p:spTree/p:sp[2]
1940
        $objWriter->endElement();
1941
1942
        // p:notes/p:cSld/p:spTree
1943
        $objWriter->endElement();
1944
1945
        // p:notes/p:cSld
1946
        $objWriter->endElement();
1947
1948
        // p:notes
1949
        $objWriter->endElement();
1950
1951
        // Return
1952
        return $objWriter->getData();
1953
    }
1954
1955
    /**
1956
     * Write Transition Slide
1957
     * @link http://officeopenxml.com/prSlide-transitions.php
1958
     * @param XMLWriter $objWriter
1959
     * @param Transition $transition
1960
     */
1961 52
    protected function writeSlideTransition(XMLWriter $objWriter, $transition)
1962
    {
1963 52
        if (!$transition instanceof Transition) {
1964 52
            return;
1965
        }
1966
        $objWriter->startElement('p:transition');
1967
        if (!is_null($transition->getSpeed())) {
1968
            $objWriter->writeAttribute('spd', $transition->getSpeed());
1969
        }
1970
        $objWriter->writeAttribute('advClick', $transition->hasManualTrigger() ? '1' : '0');
1971
        if ($transition->hasTimeTrigger()) {
1972
            $objWriter->writeAttribute('advTm', $transition->getAdvanceTimeTrigger());
1973
        }
1974
1975
        switch ($transition->getTransitionType()) {
1976
            case Transition::TRANSITION_BLINDS_HORIZONTAL:
1977
                $objWriter->startElement('p:blinds');
1978
                $objWriter->writeAttribute('dir', 'horz');
1979
                $objWriter->endElement();
1980
                break;
1981
            case Transition::TRANSITION_BLINDS_VERTICAL:
1982
                $objWriter->startElement('p:blinds');
1983
                $objWriter->writeAttribute('dir', 'vert');
1984
                $objWriter->endElement();
1985
                break;
1986
            case Transition::TRANSITION_CHECKER_HORIZONTAL:
1987
                $objWriter->startElement('p:checker');
1988
                $objWriter->writeAttribute('dir', 'horz');
1989
                $objWriter->endElement();
1990
                break;
1991
            case Transition::TRANSITION_CHECKER_VERTICAL:
1992
                $objWriter->startElement('p:checker');
1993
                $objWriter->writeAttribute('dir', 'vert');
1994
                $objWriter->endElement();
1995
                break;
1996
            case Transition::TRANSITION_CIRCLE_HORIZONTAL:
1997
                $objWriter->startElement('p:circle');
1998
                $objWriter->writeAttribute('dir', 'horz');
1999
                $objWriter->endElement();
2000
                break;
2001
            case Transition::TRANSITION_CIRCLE_VERTICAL:
2002
                $objWriter->startElement('p:circle');
2003
                $objWriter->writeAttribute('dir', 'vert');
2004
                $objWriter->endElement();
2005
                break;
2006
            case Transition::TRANSITION_COMB_HORIZONTAL:
2007
                $objWriter->startElement('p:comb');
2008
                $objWriter->writeAttribute('dir', 'horz');
2009
                $objWriter->endElement();
2010
                break;
2011
            case Transition::TRANSITION_COMB_VERTICAL:
2012
                $objWriter->startElement('p:comb');
2013
                $objWriter->writeAttribute('dir', 'vert');
2014
                $objWriter->endElement();
2015
                break;
2016
            case Transition::TRANSITION_COVER_DOWN:
2017
                $objWriter->startElement('p:cover');
2018
                $objWriter->writeAttribute('dir', 'd');
2019
                $objWriter->endElement();
2020
                break;
2021
            case Transition::TRANSITION_COVER_LEFT:
2022
                $objWriter->startElement('p:cover');
2023
                $objWriter->writeAttribute('dir', 'l');
2024
                $objWriter->endElement();
2025
                break;
2026
            case Transition::TRANSITION_COVER_LEFT_DOWN:
2027
                $objWriter->startElement('p:cover');
2028
                $objWriter->writeAttribute('dir', 'ld');
2029
                $objWriter->endElement();
2030
                break;
2031
            case Transition::TRANSITION_COVER_LEFT_UP:
2032
                $objWriter->startElement('p:cover');
2033
                $objWriter->writeAttribute('dir', 'lu');
2034
                $objWriter->endElement();
2035
                break;
2036
            case Transition::TRANSITION_COVER_RIGHT:
2037
                $objWriter->startElement('p:cover');
2038
                $objWriter->writeAttribute('dir', 'r');
2039
                $objWriter->endElement();
2040
                break;
2041
            case Transition::TRANSITION_COVER_RIGHT_DOWN:
2042
                $objWriter->startElement('p:cover');
2043
                $objWriter->writeAttribute('dir', 'rd');
2044
                $objWriter->endElement();
2045
                break;
2046
            case Transition::TRANSITION_COVER_RIGHT_UP:
2047
                $objWriter->startElement('p:cover');
2048
                $objWriter->writeAttribute('dir', 'ru');
2049
                $objWriter->endElement();
2050
                break;
2051
            case Transition::TRANSITION_COVER_UP:
2052
                $objWriter->startElement('p:cover');
2053
                $objWriter->writeAttribute('dir', 'u');
2054
                $objWriter->endElement();
2055
                break;
2056
            case Transition::TRANSITION_CUT:
2057
                $objWriter->writeElement('p:cut');
2058
                break;
2059
            case Transition::TRANSITION_DIAMOND:
2060
                $objWriter->writeElement('p:diamond');
2061
                break;
2062
            case Transition::TRANSITION_DISSOLVE:
2063
                $objWriter->writeElement('p:dissolve');
2064
                break;
2065
            case Transition::TRANSITION_FADE:
2066
                $objWriter->writeElement('p:fade');
2067
                break;
2068
            case Transition::TRANSITION_NEWSFLASH:
2069
                $objWriter->writeElement('p:newsflash');
2070
                break;
2071
            case Transition::TRANSITION_PLUS:
2072
                $objWriter->writeElement('p:plus');
2073
                break;
2074
            case Transition::TRANSITION_PULL_DOWN:
2075
                $objWriter->startElement('p:pull');
2076
                $objWriter->writeAttribute('dir', 'd');
2077
                $objWriter->endElement();
2078
                break;
2079
            case Transition::TRANSITION_PULL_LEFT:
2080
                $objWriter->startElement('p:pull');
2081
                $objWriter->writeAttribute('dir', 'l');
2082
                $objWriter->endElement();
2083
                break;
2084
            case Transition::TRANSITION_PULL_RIGHT:
2085
                $objWriter->startElement('p:pull');
2086
                $objWriter->writeAttribute('dir', 'r');
2087
                $objWriter->endElement();
2088
                break;
2089
            case Transition::TRANSITION_PULL_UP:
2090
                $objWriter->startElement('p:pull');
2091
                $objWriter->writeAttribute('dir', 'u');
2092
                $objWriter->endElement();
2093
                break;
2094
            case Transition::TRANSITION_PUSH_DOWN:
2095
                $objWriter->startElement('p:push');
2096
                $objWriter->writeAttribute('dir', 'd');
2097
                $objWriter->endElement();
2098
                break;
2099
            case Transition::TRANSITION_PUSH_LEFT:
2100
                $objWriter->startElement('p:push');
2101
                $objWriter->writeAttribute('dir', 'l');
2102
                $objWriter->endElement();
2103
                break;
2104
            case Transition::TRANSITION_PUSH_RIGHT:
2105
                $objWriter->startElement('p:push');
2106
                $objWriter->writeAttribute('dir', 'r');
2107
                $objWriter->endElement();
2108
                break;
2109
            case Transition::TRANSITION_PUSH_UP:
2110
                $objWriter->startElement('p:push');
2111
                $objWriter->writeAttribute('dir', 'u');
2112
                $objWriter->endElement();
2113
                break;
2114
            case Transition::TRANSITION_RANDOM:
2115
                $objWriter->writeElement('p:random');
2116
                break;
2117
            case Transition::TRANSITION_RANDOMBAR_HORIZONTAL:
2118
                $objWriter->startElement('p:randomBar');
2119
                $objWriter->writeAttribute('dir', 'horz');
2120
                $objWriter->endElement();
2121
                break;
2122
            case Transition::TRANSITION_RANDOMBAR_VERTICAL:
2123
                $objWriter->startElement('p:randomBar');
2124
                $objWriter->writeAttribute('dir', 'vert');
2125
                $objWriter->endElement();
2126
                break;
2127
            case Transition::TRANSITION_SPLIT_IN_HORIZONTAL:
2128
                $objWriter->startElement('p:split');
2129
                $objWriter->writeAttribute('dir', 'in');
2130
                $objWriter->writeAttribute('orient', 'horz');
2131
                $objWriter->endElement();
2132
                break;
2133
            case Transition::TRANSITION_SPLIT_OUT_HORIZONTAL:
2134
                $objWriter->startElement('p:split');
2135
                $objWriter->writeAttribute('dir', 'out');
2136
                $objWriter->writeAttribute('orient', 'horz');
2137
                $objWriter->endElement();
2138
                break;
2139
            case Transition::TRANSITION_SPLIT_IN_VERTICAL:
2140
                $objWriter->startElement('p:split');
2141
                $objWriter->writeAttribute('dir', 'in');
2142
                $objWriter->writeAttribute('orient', 'vert');
2143
                $objWriter->endElement();
2144
                break;
2145
            case Transition::TRANSITION_SPLIT_OUT_VERTICAL:
2146
                $objWriter->startElement('p:split');
2147
                $objWriter->writeAttribute('dir', 'out');
2148
                $objWriter->writeAttribute('orient', 'vert');
2149
                $objWriter->endElement();
2150
                break;
2151
            case Transition::TRANSITION_STRIPS_LEFT_DOWN:
2152
                $objWriter->startElement('p:strips');
2153
                $objWriter->writeAttribute('dir', 'ld');
2154
                $objWriter->endElement();
2155
                break;
2156
            case Transition::TRANSITION_STRIPS_LEFT_UP:
2157
                $objWriter->startElement('p:strips');
2158
                $objWriter->writeAttribute('dir', 'lu');
2159
                $objWriter->endElement();
2160
                break;
2161
            case Transition::TRANSITION_STRIPS_RIGHT_DOWN:
2162
                $objWriter->startElement('p:strips');
2163
                $objWriter->writeAttribute('dir', 'rd');
2164
                $objWriter->endElement();
2165
                break;
2166
            case Transition::TRANSITION_STRIPS_RIGHT_UP:
2167
                $objWriter->startElement('p:strips');
2168
                $objWriter->writeAttribute('dir', 'ru');
2169
                $objWriter->endElement();
2170
                break;
2171
            case Transition::TRANSITION_WEDGE:
2172
                $objWriter->writeElement('p:wedge');
2173
                break;
2174
            case Transition::TRANSITION_WIPE_DOWN:
2175
                $objWriter->startElement('p:wipe');
2176
                $objWriter->writeAttribute('dir', 'd');
2177
                $objWriter->endElement();
2178
                break;
2179
            case Transition::TRANSITION_WIPE_LEFT:
2180
                $objWriter->startElement('p:wipe');
2181
                $objWriter->writeAttribute('dir', 'l');
2182
                $objWriter->endElement();
2183
                break;
2184
            case Transition::TRANSITION_WIPE_RIGHT:
2185
                $objWriter->startElement('p:wipe');
2186
                $objWriter->writeAttribute('dir', 'r');
2187
                $objWriter->endElement();
2188
                break;
2189
            case Transition::TRANSITION_WIPE_UP:
2190
                $objWriter->startElement('p:wipe');
2191
                $objWriter->writeAttribute('dir', 'u');
2192
                $objWriter->endElement();
2193
                break;
2194
            case Transition::TRANSITION_ZOOM_IN:
2195
                $objWriter->startElement('p:zoom');
2196
                $objWriter->writeAttribute('dir', 'in');
2197
                $objWriter->endElement();
2198
                break;
2199
            case Transition::TRANSITION_ZOOM_OUT:
2200
                $objWriter->startElement('p:zoom');
2201
                $objWriter->writeAttribute('dir', 'out');
2202
                $objWriter->endElement();
2203
                break;
2204
        }
2205
2206
        $objWriter->endElement();
2207
    }
2208
}
2209