Completed
Pull Request — develop (#307)
by Franck
55:08 queued 52:20
created

PptSlides   F

Complexity

Total Complexity 203

Size/Duplication

Total Lines 2171
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 31

Test Coverage

Coverage 86.54%

Importance

Changes 7
Bugs 0 Features 1
Metric Value
wmc 203
c 7
b 0
f 1
lcom 1
cbo 31
dl 0
loc 2171
ccs 1138
cts 1315
cp 0.8654
rs 0.5217

14 Methods

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

How to fix   Complexity   

Complex Class

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

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

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

1
<?php
2
3
namespace PhpOffice\PhpPresentation\Writer\PowerPoint2007;
4
5
use PhpOffice\Common\Drawing as CommonDrawing;
6
use PhpOffice\Common\Text;
7
use PhpOffice\Common\XMLWriter;
8
use PhpOffice\PhpPresentation\Shape\AbstractDrawing;
9
use PhpOffice\PhpPresentation\Shape\Chart as ShapeChart;
10
use PhpOffice\PhpPresentation\Shape\Comment;
11
use PhpOffice\PhpPresentation\Shape\Drawing as ShapeDrawing;
12
use PhpOffice\PhpPresentation\Shape\Group;
13
use PhpOffice\PhpPresentation\Shape\Line;
14
use PhpOffice\PhpPresentation\Shape\Media;
15
use PhpOffice\PhpPresentation\Shape\RichText;
16
use PhpOffice\PhpPresentation\Shape\RichText\BreakElement;
17
use PhpOffice\PhpPresentation\Shape\RichText\Run;
18
use PhpOffice\PhpPresentation\Shape\RichText\TextElement;
19
use PhpOffice\PhpPresentation\Shape\Table as ShapeTable;
20
use PhpOffice\PhpPresentation\Slide;
21
use PhpOffice\PhpPresentation\Slide\Background\Image;
22
use PhpOffice\PhpPresentation\Slide\Note;
23
use PhpOffice\PhpPresentation\Slide\Transition;
24
use PhpOffice\PhpPresentation\Style\Alignment;
25
use PhpOffice\PhpPresentation\Style\Bullet;
26
use PhpOffice\PhpPresentation\Style\Border;
27
use PhpOffice\PhpPresentation\Style\Color;
28
29
class PptSlides extends AbstractSlide
30
{
31
    /**
32
     * Add slides (drawings, ...) and slide relationships (drawings, ...)
33
     * @return \PhpOffice\Common\Adapter\Zip\ZipInterface
34
     */
35 100
    public function render()
36
    {
37 100
        foreach ($this->oPresentation->getAllSlides() as $idx => $oSlide) {
38 100
            $this->oZip->addFromString('ppt/slides/_rels/slide' . ($idx + 1) . '.xml.rels', $this->writeSlideRelationships($oSlide));
39 100
            $this->oZip->addFromString('ppt/slides/slide' . ($idx + 1) . '.xml', $this->writeSlide($oSlide));
40
41
            // Add note slide
42 100
            if ($oSlide->getNote()->getShapeCollection()->count() > 0) {
43 2
                $this->oZip->addFromString('ppt/notesSlides/notesSlide' . ($idx + 1) . '.xml', $this->writeNote($oSlide->getNote()));
0 ignored issues
show
Bug introduced by
It seems like $oSlide->getNote() can be null; however, writeNote() does not accept null, maybe add an additional type check?

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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