Completed
Pull Request — develop (#301)
by Franck
23:29 queued 20:54
created

PptSlides   F

Complexity

Total Complexity 203

Size/Duplication

Total Lines 2165
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 31

Test Coverage

Coverage 86.12%

Importance

Changes 7
Bugs 0 Features 1
Metric Value
wmc 203
lcom 1
cbo 31
dl 0
loc 2165
ccs 1129
cts 1311
cp 0.8612
rs 0.5217
c 7
b 0
f 1

14 Methods

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

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