Completed
Pull Request — develop (#307)
by
unknown
12:20
created

PptSlides   F

Complexity

Total Complexity 203

Size/Duplication

Total Lines 2162
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 31

Test Coverage

Coverage 94.14%

Importance

Changes 6
Bugs 0 Features 1
Metric Value
wmc 203
lcom 1
cbo 31
dl 0
loc 2162
ccs 1060
cts 1126
cp 0.9414
rs 0.5217
c 6
b 0
f 1

14 Methods

Rating   Name   Duplication   Size   Complexity  
A render() 0 20 4
F writeSlideRelationships() 0 285 61
B writeSlide() 0 146 4
D writeSlideAnimations() 0 243 9
A writeShapeGroup() 0 60 1
A writeShapeChart() 0 67 2
B writeShapeDrawing() 0 119 4
F writeShapeTable() 0 217 19
D writeParagraphs() 0 114 15
D writeShapeLine() 0 104 9
A writeHyperlink() 0 14 3
B writeNote() 0 280 3
D writeSlideTransition() 0 247 53
F writeShapeText() 0 137 16

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\Color;
28
29
class PptSlides extends AbstractSlide
30
{
31
    /**
32
     * Add slides (drawings, ...) and slide relationships (drawings, ...)
33
     * @return \PhpOffice\Common\Adapter\Zip\ZipInterface
34
     */
35 99
    public function render()
36
    {
37 99
        foreach ($this->oPresentation->getAllSlides() as $idx => $oSlide) {
38 99
            $this->oZip->addFromString('ppt/slides/_rels/slide' . ($idx + 1) . '.xml.rels', $this->writeSlideRelationships($oSlide));
39 99
            $this->oZip->addFromString('ppt/slides/slide' . ($idx + 1) . '.xml', $this->writeSlide($oSlide));
40
41
            // Add note slide
42 99
            if ($oSlide->getNote()->getShapeCollection()->count() > 0) {
43 2
                $this->oZip->addFromString('ppt/notesSlides/notesSlide' . ($idx + 1) . '.xml', $this->writeNote($oSlide->getNote()));
0 ignored issues
show
Bug introduced by
It seems like $oSlide->getNote() can be null; however, writeNote() does not accept null, maybe add an additional type check?

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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