Completed
Pull Request — develop (#322)
by Thomas
08:13 queued 03:00
created

PptSlides::writeSlideRelationships()   F

Complexity

Conditions 61
Paths 224

Size

Total Lines 290
Code Lines 157

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 132
CRAP Score 207.2501

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 290
ccs 132
cts 200
cp 0.66
rs 3.68
c 1
b 0
f 0
cc 61
eloc 157
nc 224
nop 1
crap 207.2501

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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