Completed
Pull Request — develop (#207)
by Franck
24:36 queued 20:39
created

PptSlides::writeSlideRelationships()   D

Complexity

Conditions 58
Paths 112

Size

Total Lines 275
Code Lines 143

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 120
CRAP Score 195.2988

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 275
ccs 120
cts 183
cp 0.6556
rs 4.0689
cc 58
eloc 143
nc 112
nop 1
crap 195.2988

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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