Completed
Pull Request — develop (#207)
by Franck
12:42 queued 05:23
created

PptSlides::writeShadow()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

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