Completed
Pull Request — develop (#208)
by Franck
07:39
created

PptSlides   F

Complexity

Total Complexity 217

Size/Duplication

Total Lines 2198
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 32

Test Coverage

Coverage 94.24%

Importance

Changes 17
Bugs 1 Features 4
Metric Value
wmc 217
c 17
b 1
f 4
lcom 1
cbo 32
dl 0
loc 2198
ccs 1128
cts 1197
cp 0.9424
rs 0.5217

15 Methods

Rating   Name   Duplication   Size   Complexity  
A render() 0 20 4
D writeSlideRelationships() 0 284 60
C writeSlide() 0 166 11
D writeSlideAnimations() 0 243 9
C writeShapeGroup() 0 80 8
A writeShapeChart() 0 61 1
B writeShapeDrawing() 0 113 3
F writeShapeText() 0 128 14
F writeShapeTable() 0 211 18
D writeParagraphs() 0 115 20
C writeShapeLine() 0 98 8
B writeShadow() 0 27 3
A writeHyperlink() 0 11 2
B writeNote() 0 280 3
D writeSlideTransition() 0 247 53

How to fix   Complexity   

Complex Class

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

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

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

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