Completed
Pull Request — develop (#207)
by Franck
16:14 queued 07:46
created

PptSlides   F

Complexity

Total Complexity 206

Size/Duplication

Total Lines 1954
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 31

Test Coverage

Coverage 91.04%

Importance

Changes 10
Bugs 0 Features 1
Metric Value
wmc 206
c 10
b 0
f 1
lcom 1
cbo 31
dl 0
loc 1954
ccs 1067
cts 1172
cp 0.9104
rs 0.5217

14 Methods

Rating   Name   Duplication   Size   Complexity  
A render() 0 21 4
D writeSlideRelationships() 0 275 58
C writeSlide() 0 169 12
C writeShapeGroup() 0 80 8
A writeShapeChart() 0 61 1
B writeShapeDrawing() 0 113 3
F writeShapeText() 0 128 14
F writeShapeTable() 0 211 18
D writeParagraphs() 0 118 20
C writeShapeLine() 0 98 8
B writeShadow() 0 36 3
A writeHyperlink() 0 11 2
B writeNote() 0 280 3
D writeTransition() 0 244 52

How to fix   Complexity   

Complex Class

Complex classes like PptSlides often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PptSlides, and based on these observations, apply Extract Interface, too.

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

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

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

function doesNotAcceptNull(stdClass $x) { }

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

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

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