Completed
Pull Request — develop (#215)
by Franck
08:29
created

PptSlides::render()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.0582

Importance

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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

This error could be the result of:

1. Missing dependencies

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

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

2. Missing use statement

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

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

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

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