Completed
Pull Request — develop (#294)
by
unknown
12:02
created

PptSlides   F

Complexity

Total Complexity 203

Size/Duplication

Total Lines 2163
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 31

Test Coverage

Coverage 94.12%

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 203
c 5
b 0
f 1
lcom 1
cbo 31
dl 0
loc 2163
ccs 1057
cts 1123
cp 0.9412
rs 0.5217

14 Methods

Rating   Name   Duplication   Size   Complexity  
A render() 0 20 4
F writeSlideRelationships() 0 286 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 writeShapeText() 0 137 16
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

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 97
    public function render()
36
    {
37 97
        foreach ($this->oPresentation->getAllSlides() as $idx => $oSlide) {
38 97
            $this->oZip->addFromString('ppt/slides/_rels/slide' . ($idx + 1) . '.xml.rels', $this->writeSlideRelationships($oSlide));
39 97
            $this->oZip->addFromString('ppt/slides/slide' . ($idx + 1) . '.xml', $this->writeSlide($oSlide));
40
41
            // Add note slide
42 97
            if ($oSlide->getNote()->getShapeCollection()->count() > 0) {
43 1
                $this->oZip->addFromString('ppt/notesSlides/notesSlide' . ($idx + 1) . '.xml', $this->writeNote($oSlide->getNote()));
0 ignored issues
show
Bug introduced by
It seems like $oSlide->getNote() can be null; however, writeNote() does not accept null, maybe add an additional type check?

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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