Completed
Pull Request — develop (#230)
by Franck
08:28
created

PptSlides::writeSlideRelationships()   F

Complexity

Conditions 61
Paths 224

Size

Total Lines 284
Code Lines 151

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 97
CRAP Score 195.9409

Importance

Changes 7
Bugs 1 Features 0
Metric Value
dl 0
loc 284
ccs 97
cts 145
cp 0.669
rs 3.68
c 7
b 1
f 0
cc 61
eloc 151
nc 224
nop 1
crap 195.9409

How to fix   Long Method    Complexity   

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