Completed
Pull Request — develop (#209)
by Franck
07:39
created

PptSlides::writeShapeChart()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 61
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 61
ccs 34
cts 34
cp 1
rs 9.5147
cc 1
eloc 33
nc 1
nop 3
crap 1

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

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