Completed
Pull Request — develop (#207)
by Franck
09:22
created

PptSlides::render()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.0582

Importance

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