Completed
Pull Request — develop (#207)
by Franck
06:53
created

PptSlides::writeSlideRelationships()   D

Complexity

Conditions 60
Paths 112

Size

Total Lines 284
Code Lines 151

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 99
CRAP Score 174.8952

Importance

Changes 5
Bugs 1 Features 0
Metric Value
c 5
b 1
f 0
dl 0
loc 284
ccs 99
cts 145
cp 0.6828
rs 4.0689
cc 60
eloc 151
nc 112
nop 1
crap 174.8952

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
45
            }
46
47
            // Add background image slide
48 94
            $oBkgImage = $oSlide->getBackground();
49 94
            if ($oBkgImage instanceof Image) {
50 94
                $this->oZip->addFromString('ppt/media/'.$oBkgImage->getIndexedFilename($idx), file_get_contents($oBkgImage->getPath()));
51
            }
52
        }
53
54 94
        return $this->oZip;
55
    }
56
57
    /**
58
     * Write slide relationships to XML format
59
     *
60
     * @param  \PhpOffice\PhpPresentation\Slide $pSlide
61
     * @return string              XML Output
62
     * @throws \Exception
63
     */
64 94
    protected function writeSlideRelationships(Slide $pSlide)
65
    {
66
        //@todo Group all getShapeCollection()->getIterator
67
68
        // Create XML writer
69 94
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
70
71
        // XML header
72 94
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
73
74
        // Relationships
75 94
        $objWriter->startElement('Relationships');
76 94
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
77
78
        // Starting relation id
79 94
        $relId = 1;
80 94
        $idxSlide = $pSlide->getParent()->getIndex($pSlide);
81
82
        // Write slideLayout relationship
83 94
        $oLayoutPack  = new PackDefault();
84 94
        $layoutId = $oLayoutPack->findlayoutId($pSlide->getSlideLayout(), $pSlide->getSlideMasterId());
85
86 94
        $this->writeRelationship($objWriter, $relId++, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout', '../slideLayouts/slideLayout' . $layoutId . '.xml');
87
88
        // Write drawing relationships?
89 94
        if ($pSlide->getShapeCollection()->count() > 0) {
90
            // Loop trough images and write relationships
91 70
            $iterator = $pSlide->getShapeCollection()->getIterator();
92 70
            while ($iterator->valid()) {
93 70
                if ($iterator->current() instanceof Media) {
94
                    // Write relationship for image drawing
95 1
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.microsoft.com/office/2007/relationships/media', '../media/' . $iterator->current()->getIndexedFilename());
96 1
                    $iterator->current()->relationId = 'rId' . $relId;
97 1
                    ++$relId;
98 69
                } elseif ($iterator->current() instanceof ShapeDrawing\AbstractDrawingAdapter) {
99
                    // Write relationship for image drawing
100 7
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $iterator->current()->getIndexedFilename());
101 7
                    $iterator->current()->relationId = 'rId' . $relId;
102 7
                    ++$relId;
103 62
                } elseif ($iterator->current() instanceof ShapeChart) {
104
                    // Write relationship for chart drawing
105 24
                    $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', '../charts/' . $iterator->current()->getIndexedFilename());
106
107 24
                    $iterator->current()->relationId = 'rId' . $relId;
108
109 24
                    ++$relId;
110 38
                } elseif ($iterator->current() instanceof Group) {
111 1
                    $iterator2 = $iterator->current()->getShapeCollection()->getIterator();
112 1
                    while ($iterator2->valid()) {
113 1
                        if ($iterator->current() instanceof Media) {
114
                            // Write relationship for image drawing
115
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.microsoft.com/office/2007/relationships/media', '../media/' . $iterator->current()->getIndexedFilename());
116
                            $iterator->current()->relationId = 'rId' . $relId;
117
                            ++$relId;
118 1
                        } elseif ($iterator->current() instanceof ShapeDrawing\AbstractDrawingAdapter) {
119
                            // Write relationship for image drawing
120
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $iterator2->current()->getIndexedFilename());
121
                            $iterator2->current()->relationId = 'rId' . $relId;
122
123
                            ++$relId;
124 1
                        } elseif ($iterator2->current() instanceof ShapeChart) {
125
                            // Write relationship for chart drawing
126
                            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', '../charts/' . $iterator2->current()->getIndexedFilename());
127
                            $iterator2->current()->relationId = 'rId' . $relId;
128
129
                            ++$relId;
130
                        }
131 1
                        $iterator2->next();
132
                    }
133
                }
134
135 70
                $iterator->next();
136
            }
137
        }
138
139
        // Write background relationships?
140 94
        $oBackground = $pSlide->getBackground();
141 94
        if ($oBackground instanceof Image) {
142
            $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', '../media/' . $oBackground->getIndexedFilename($idxSlide));
143
            $oBackground->relationId = 'rId' . $relId;
144
            ++$relId;
145
        }
146
147
        // Write hyperlink relationships?
148 94
        if ($pSlide->getShapeCollection()->count() > 0) {
149
            // Loop trough hyperlinks and write relationships
150 70
            $iterator = $pSlide->getShapeCollection()->getIterator();
151 70
            while ($iterator->valid()) {
152
                // Hyperlink on shape
153 70
                if ($iterator->current()->hasHyperlink()) {
154
                    // Write relationship for hyperlink
155 2
                    $hyperlink               = $iterator->current()->getHyperlink();
156 2
                    $hyperlink->relationId = 'rId' . $relId;
157
158 2
                    if (!$hyperlink->isInternal()) {
159 2
                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', $hyperlink->getUrl(), 'External');
160
                    } else {
161
                        $this->writeRelationship($objWriter, $relId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide', 'slide' . $hyperlink->getSlideNumber() . '.xml');
162
                    }
163
164 2
                    ++$relId;
165
                }
166
167
                // Hyperlink on rich text run
168 70
                if ($iterator->current() instanceof RichText) {
169 21
                    foreach ($iterator->current()->getParagraphs() as $paragraph) {
170 21
                        foreach ($paragraph->getRichTextElements() as $element) {
171 17
                            if ($element instanceof Run || $element instanceof RunTextElement) {
0 ignored issues
show
Bug introduced by
The class PhpOffice\PhpPresentatio...oint2007\RunTextElement does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

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