Completed
Pull Request — develop (#304)
by Franck
08:25
created

AbstractSlide::writeSlideTransition()   D

Complexity

Conditions 53
Paths 197

Size

Total Lines 247
Code Lines 239

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 2025.9244

Importance

Changes 0
Metric Value
dl 0
loc 247
ccs 1
cts 9
cp 0.1111
rs 4
c 0
b 0
f 0
cc 53
eloc 239
nc 197
nop 2
crap 2025.9244

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
 * This file is part of PHPPresentation - A pure PHP library for reading and writing
4
 * presentations documents.
5
 *
6
 * PHPPresentation is free software distributed under the terms of the GNU Lesser
7
 * General Public License version 3 as published by the Free Software Foundation.
8
 *
9
 * For the full copyright and license information, please read the LICENSE
10
 * file that was distributed with this source code. For the full list of
11
 * contributors, visit https://github.com/PHPOffice/PHPPresentation/contributors.
12
 *
13
 * @link        https://github.com/PHPOffice/PHPPresentation
14
 * @copyright   2009-2015 PHPPresentation contributors
15
 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16
 */
17
namespace PhpOffice\PhpPresentation\Writer\PowerPoint2007;
18
19
use PhpOffice\Common\Drawing as CommonDrawing;
20
use PhpOffice\Common\Text;
21
use PhpOffice\Common\XMLWriter;
22
use PhpOffice\PhpPresentation\Shape\AbstractGraphic;
23
use PhpOffice\PhpPresentation\Shape\Chart as ShapeChart;
24
use PhpOffice\PhpPresentation\Shape\Comment;
25
use PhpOffice\PhpPresentation\Shape\Drawing\Gd as ShapeDrawingGd;
26
use PhpOffice\PhpPresentation\Shape\Drawing\File as ShapeDrawingFile;
27
use PhpOffice\PhpPresentation\Shape\Group;
28
use PhpOffice\PhpPresentation\Shape\Line;
29
use PhpOffice\PhpPresentation\Shape\Media;
30
use PhpOffice\PhpPresentation\Shape\Placeholder;
31
use PhpOffice\PhpPresentation\Shape\RichText;
32
use PhpOffice\PhpPresentation\Shape\RichText\BreakElement;
33
use PhpOffice\PhpPresentation\Shape\RichText\Run;
34
use PhpOffice\PhpPresentation\Shape\RichText\TextElement;
35
use PhpOffice\PhpPresentation\Shape\Table as ShapeTable;
36
use PhpOffice\PhpPresentation\Slide;
37
use PhpOffice\PhpPresentation\Slide\Note;
38
use PhpOffice\PhpPresentation\Style\Alignment;
39
use PhpOffice\PhpPresentation\Style\Bullet;
40
use PhpOffice\PhpPresentation\Style\Border;
41
use PhpOffice\PhpPresentation\Style\Shadow;
42
use PhpOffice\PhpPresentation\Slide\AbstractSlide as AbstractSlideAlias;
43
use PhpOffice\PhpPresentation\Slide\SlideMaster;
44
use PhpOffice\PhpPresentation\Slide\Background;
45
use PhpOffice\PhpPresentation\Slide\Transition;
46
47
abstract class AbstractSlide extends AbstractDecoratorWriter
0 ignored issues
show
Complexity introduced by
The class AbstractSlide has a coupling between objects value of 31. Consider to reduce the number of dependencies under 31.
Loading history...
48
{
49
    /**
50
     * @param SlideMaster $pSlideMaster
51
     * @param $objWriter
52
     * @param $relId
53
     * @throws \Exception
54 99
     */
55
    protected function writeDrawingRelations(AbstractSlideAlias $pSlideMaster, $objWriter, $relId)
56 99
    {
57
        if ($pSlideMaster->getShapeCollection()->count() > 0) {
58
            // Loop trough images and write relationships
59
            $iterator = $pSlideMaster->getShapeCollection()->getIterator();
60
            while ($iterator->valid()) {
61
                if ($iterator->current() instanceof ShapeDrawingFile || $iterator->current() instanceof ShapeDrawingGd) {
62
                    // Write relationship for image drawing
63
                    $this->writeRelationship(
64
                        $objWriter,
65
                        $relId,
66
                        'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
67
                        '../media/' . str_replace(' ', '_', $iterator->current()->getIndexedFilename())
68
                    );
69
                    $iterator->current()->relationId = 'rId' . $relId;
70
                    ++$relId;
71
                } elseif ($iterator->current() instanceof ShapeChart) {
72
                    // Write relationship for chart drawing
73
                    $this->writeRelationship(
74
                        $objWriter,
75
                        $relId,
76
                        'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
77
                        '../charts/' . $iterator->current()->getIndexedFilename()
78
                    );
79
                    $iterator->current()->relationId = 'rId' . $relId;
80
                    ++$relId;
81
                } elseif ($iterator->current() instanceof Group) {
82
                    $iterator2 = $iterator->current()->getShapeCollection()->getIterator();
83
                    while ($iterator2->valid()) {
84
                        if ($iterator2->current() instanceof ShapeDrawingFile ||
85
                            $iterator2->current() instanceof ShapeDrawingGd
86
                        ) {
87
                            // Write relationship for image drawing
88
                            $this->writeRelationship(
89
                                $objWriter,
90
                                $relId,
91
                                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
92
                                '../media/' . str_replace(' ', '_', $iterator2->current()->getIndexedFilename())
93
                            );
94
                            $iterator2->current()->relationId = 'rId' . $relId;
95
                            ++$relId;
96
                        } elseif ($iterator2->current() instanceof ShapeChart) {
97
                            // Write relationship for chart drawing
98
                            $this->writeRelationship(
99
                                $objWriter,
100
                                $relId,
101
                                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
102
                                '../charts/' . $iterator2->current()->getIndexedFilename()
103
                            );
104
                            $iterator2->current()->relationId = 'rId' . $relId;
105
                            ++$relId;
106
                        }
107
                        $iterator2->next();
108
                    }
109
                }
110
                $iterator->next();
111
            }
112 99
        }
113
    }
114
115
    /**
116
     * @param XMLWriter $objWriter
117
     * @param \ArrayObject|\PhpOffice\PhpPresentation\AbstractShape[] $shapes
118
     * @param int $shapeId
119
     * @throws \Exception
120 99
     */
121
    protected function writeShapeCollection(XMLWriter $objWriter, $shapes = array(), &$shapeId = 0)
122 99
    {
123 99
        if (count($shapes) == 0) {
124
            return;
125 74
        }
126
        foreach ($shapes as $shape) {
127 74
            // Increment $shapeId
128
            ++$shapeId;
129 74
            // Check type
130 24
            if ($shape instanceof RichText) {
131 74
                $this->writeShapeText($objWriter, $shape, $shapeId);
132 10
            } elseif ($shape instanceof ShapeTable) {
133 50
                $this->writeShapeTable($objWriter, $shape, $shapeId);
134 1
            } elseif ($shape instanceof Line) {
135 40
                $this->writeShapeLine($objWriter, $shape, $shapeId);
136 24
            } elseif ($shape instanceof ShapeChart) {
137 39
                $this->writeShapeChart($objWriter, $shape, $shapeId);
138 8
            } elseif ($shape instanceof AbstractGraphic) {
139 15
                $this->writeShapePic($objWriter, $shape, $shapeId);
140 1
            } elseif ($shape instanceof Group) {
141 7
                $this->writeShapeGroup($objWriter, $shape, $shapeId);
142 7
            } elseif ($shape instanceof Comment) {
143
            } else {
144
                throw new \Exception("Unknown Shape type: {get_class($shape)}");
145 74
            }
146 74
        }
147
    }
148
149
    /**
150
     * Write txt
151
     *
152
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
153
     * @param  \PhpOffice\PhpPresentation\Shape\RichText $shape
154
     * @param  int $shapeId
155
     * @throws \Exception
156
     */
157
    protected function writeShapeText(XMLWriter $objWriter, RichText $shape, $shapeId)
158
    {
159
        // p:sp
160
        $objWriter->startElement('p:sp');
161
        // p:sp\p:nvSpPr
162
        $objWriter->startElement('p:nvSpPr');
163
        // p:sp\p:nvSpPr\p:cNvPr
164
        $objWriter->startElement('p:cNvPr');
165
        $objWriter->writeAttribute('id', $shapeId);
166
        if ($shape->isPlaceholder()) {
167
            $objWriter->writeAttribute('name', 'Placeholder for ' . $shape->getPlaceholder()->getType());
168
        } else {
169
            $objWriter->writeAttribute('name', '');
170
        }
171
        // Hyperlink
172
        if ($shape->hasHyperlink()) {
173
            $this->writeHyperlink($objWriter, $shape);
174
        }
175
        // > p:sp\p:nvSpPr
176
        $objWriter->endElement();
177
        // p:sp\p:cNvSpPr
178
        $objWriter->startElement('p:cNvSpPr');
179
        $objWriter->writeAttribute('txBox', '1');
180
        $objWriter->endElement();
181
        // p:sp\p:cNvSpPr\p:nvPr
182
        if ($shape->isPlaceholder()) {
183
            $objWriter->startElement('p:nvPr');
184
            $objWriter->startElement('p:ph');
185
            $objWriter->writeAttribute('type', $shape->getPlaceholder()->getType());
186
            if (!is_null($shape->getPlaceholder()->getIdx())) {
187
                $objWriter->writeAttribute('idx', $shape->getPlaceholder()->getIdx());
188
            }
189
            $objWriter->endElement();
190
            $objWriter->endElement();
191
        } else {
192
            $objWriter->writeElement('p:nvPr', null);
193
        }
194
        // > p:sp\p:cNvSpPr
195
        $objWriter->endElement();
196
        // p:sp\p:spPr
197
        $objWriter->startElement('p:spPr');
198
        // p:sp\p:spPr\a:xfrm
199
        $objWriter->startElement('a:xfrm');
200
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
201
        // p:sp\p:spPr\a:xfrm\a:off
202
        $objWriter->startElement('a:off');
203
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
204
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
205
        $objWriter->endElement();
206
        // p:sp\p:spPr\a:xfrm\a:ext
207
        $objWriter->startElement('a:ext');
208
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
209
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
210
        $objWriter->endElement();
211
        // > p:sp\p:spPr\a:xfrm
212
        $objWriter->endElement();
213
        // p:sp\p:spPr\a:prstGeom
214
        $objWriter->startElement('a:prstGeom');
215
        $objWriter->writeAttribute('prst', 'rect');
216
217
        // p:sp\p:spPr\a:prstGeom\a:avLst
218
        $objWriter->writeElement('a:avLst');
219
220
        $objWriter->endElement();
221
        $this->writeFill($objWriter, $shape->getFill());
222
        if ($shape->getBorder()->getLineStyle() != Border::LINE_NONE) {
223
            $this->writeBorder($objWriter, $shape->getBorder(), '');
224
        }
225
        if ($shape->getShadow()->isVisible()) {
226
            $this->writeShadow($objWriter, $shape->getShadow());
227
        }
228
        // > p:sp\p:spPr
229
        $objWriter->endElement();
230
        // p:txBody
231
        $objWriter->startElement('p:txBody');
232
        // a:bodyPr
233
        //@link :http://msdn.microsoft.com/en-us/library/documentformat.openxml.drawing.bodyproperties%28v=office.14%29.aspx
234
        $objWriter->startElement('a:bodyPr');
235
        $verticalAlign = $shape->getActiveParagraph()->getAlignment()->getVertical();
236
        if ($verticalAlign != Alignment::VERTICAL_BASE && $verticalAlign != Alignment::VERTICAL_AUTO) {
237
            $objWriter->writeAttribute('anchor', $verticalAlign);
238
        }
239
        if ($shape->getWrap() != RichText::WRAP_SQUARE) {
240
            $objWriter->writeAttribute('wrap', $shape->getWrap());
241
        }
242
        $objWriter->writeAttribute('rtlCol', '0');
243
        if ($shape->getHorizontalOverflow() != RichText::OVERFLOW_OVERFLOW) {
244
            $objWriter->writeAttribute('horzOverflow', $shape->getHorizontalOverflow());
245
        }
246
        if ($shape->getVerticalOverflow() != RichText::OVERFLOW_OVERFLOW) {
247
            $objWriter->writeAttribute('vertOverflow', $shape->getVerticalOverflow());
248
        }
249
        if ($shape->isUpright()) {
250
            $objWriter->writeAttribute('upright', '1');
251
        }
252
        if ($shape->isVertical()) {
253
            $objWriter->writeAttribute('vert', 'vert');
254
        }
255
        $objWriter->writeAttribute('bIns', CommonDrawing::pixelsToEmu($shape->getInsetBottom()));
256
        $objWriter->writeAttribute('lIns', CommonDrawing::pixelsToEmu($shape->getInsetLeft()));
257
        $objWriter->writeAttribute('rIns', CommonDrawing::pixelsToEmu($shape->getInsetRight()));
258
        $objWriter->writeAttribute('tIns', CommonDrawing::pixelsToEmu($shape->getInsetTop()));
259
        if ($shape->getColumns() <> 1) {
260
            $objWriter->writeAttribute('numCol', $shape->getColumns());
261
        }
262
        // a:spAutoFit
263
        $objWriter->startElement('a:' . $shape->getAutoFit());
264
        if ($shape->getAutoFit() == RichText::AUTOFIT_NORMAL) {
265
            if (!is_null($shape->getFontScale())) {
266
                $objWriter->writeAttribute('fontScale', (int)($shape->getFontScale() * 1000));
267
            }
268
            if (!is_null($shape->getLineSpaceReduction())) {
269
                $objWriter->writeAttribute('lnSpcReduction', (int)($shape->getLineSpaceReduction() * 1000));
270
            }
271
        }
272
        $objWriter->endElement();
273
        $objWriter->endElement();
274
        // a:lstStyle
275
        $objWriter->writeElement('a:lstStyle', null);
276
        if ($shape->isPlaceholder() &&
277
            ($shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_SLIDENUM ||
278
                $shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_DATETIME)
279
        ) {
280
            $objWriter->startElement('a:p');
281
            $objWriter->startElement('a:fld');
282
            $objWriter->writeAttribute('id', $this->getGUID());
283
            $objWriter->writeAttribute('type', (
284
            $shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_SLIDENUM ? 'slidenum' : 'datetime'));
285
            $objWriter->writeElement('a:t', (
286
            $shape->getPlaceholder()->getType() == Placeholder::PH_TYPE_SLIDENUM ? '<nr.>' : '03-04-05'));
287
            $objWriter->endElement();
288
            $objWriter->endElement();
289
        } else {
290
            // Write paragraphs
291
            $this->writeParagraphs($objWriter, $shape->getParagraphs());
292
        }
293
        $objWriter->endElement();
294
        $objWriter->endElement();
295
    }
296
297
    /**
298
     * Write table
299
     *
300
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
301
     * @param  \PhpOffice\PhpPresentation\Shape\Table $shape
302
     * @param  int $shapeId
303
     * @throws \Exception
304
     */
305
    protected function writeShapeTable(XMLWriter $objWriter, ShapeTable $shape, $shapeId)
306
    {
307
        // p:graphicFrame
308
        $objWriter->startElement('p:graphicFrame');
309
        // p:nvGraphicFramePr
310
        $objWriter->startElement('p:nvGraphicFramePr');
311
        // p:cNvPr
312
        $objWriter->startElement('p:cNvPr');
313
        $objWriter->writeAttribute('id', $shapeId);
314
        $objWriter->writeAttribute('name', $shape->getName());
315
        $objWriter->writeAttribute('descr', $shape->getDescription());
316
        $objWriter->endElement();
317
        // p:cNvGraphicFramePr
318
        $objWriter->startElement('p:cNvGraphicFramePr');
319
        // a:graphicFrameLocks
320
        $objWriter->startElement('a:graphicFrameLocks');
321
        $objWriter->writeAttribute('noGrp', '1');
322
        $objWriter->endElement();
323
        $objWriter->endElement();
324
        // p:nvPr
325
        $objWriter->writeElement('p:nvPr', null);
326
        $objWriter->endElement();
327
        // p:xfrm
328
        $objWriter->startElement('p:xfrm');
329
        // a:off
330
        $objWriter->startElement('a:off');
331
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
332
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
333
        $objWriter->endElement();
334
        // a:ext
335
        $objWriter->startElement('a:ext');
336
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
337
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
338
        $objWriter->endElement();
339
        $objWriter->endElement();
340
        // a:graphic
341
        $objWriter->startElement('a:graphic');
342
        // a:graphicData
343
        $objWriter->startElement('a:graphicData');
344
        $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/table');
345
        // a:tbl
346
        $objWriter->startElement('a:tbl');
347
        // a:tblPr
348
        $objWriter->startElement('a:tblPr');
349
        $objWriter->writeAttribute('firstRow', '1');
350
        $objWriter->writeAttribute('bandRow', '1');
351
        $objWriter->endElement();
352
        // a:tblGrid
353
        $objWriter->startElement('a:tblGrid');
354
        // Write cell widths
355
        $countCells = count($shape->getRow(0)->getCells());
356
        for ($cell = 0; $cell < $countCells; $cell++) {
357
            // a:gridCol
358
            $objWriter->startElement('a:gridCol');
359
            // Calculate column width
360
            $width = $shape->getRow(0)->getCell($cell)->getWidth();
361
            if ($width == 0) {
362
                $colCount = count($shape->getRow(0)->getCells());
363
                $totalWidth = $shape->getWidth();
364
                $width = $totalWidth / $colCount;
365
            }
366
            $objWriter->writeAttribute('w', CommonDrawing::pixelsToEmu($width));
367
            $objWriter->endElement();
368
        }
369
        $objWriter->endElement();
370
        // Colspan / rowspan containers
371
        $colSpan = array();
372
        $rowSpan = array();
373
        // Default border style
374
        $defaultBorder = new Border();
375
        // Write rows
376
        $countRows = count($shape->getRows());
377
        for ($row = 0; $row < $countRows; $row++) {
378
            // a:tr
379
            $objWriter->startElement('a:tr');
380
            $objWriter->writeAttribute('h', CommonDrawing::pixelsToEmu($shape->getRow($row)->getHeight()));
381
            // Write cells
382
            $countCells = count($shape->getRow($row)->getCells());
383
            for ($cell = 0; $cell < $countCells; $cell++) {
384
                // Current cell
385
                $currentCell = $shape->getRow($row)->getCell($cell);
386
                // Next cell right
387
                $nextCellRight = $shape->getRow($row)->getCell($cell + 1, true);
388
                // Next cell below
389
                $nextRowBelow = $shape->getRow($row + 1, true);
390
                $nextCellBelow = null;
391
                if ($nextRowBelow != null) {
392
                    $nextCellBelow = $nextRowBelow->getCell($cell, true);
393
                }
394
                // a:tc
395
                $objWriter->startElement('a:tc');
396
                // Colspan
397
                if ($currentCell->getColSpan() > 1) {
398
                    $objWriter->writeAttribute('gridSpan', $currentCell->getColSpan());
399
                    $colSpan[$row] = $currentCell->getColSpan() - 1;
400
                } elseif (isset($colSpan[$row]) && $colSpan[$row] > 0) {
401
                    $colSpan[$row]--;
402
                    $objWriter->writeAttribute('hMerge', '1');
403
                }
404
                // Rowspan
405
                if ($currentCell->getRowSpan() > 1) {
406
                    $objWriter->writeAttribute('rowSpan', $currentCell->getRowSpan());
407
                    $rowSpan[$cell] = $currentCell->getRowSpan() - 1;
408
                } elseif (isset($rowSpan[$cell]) && $rowSpan[$cell] > 0) {
409
                    $rowSpan[$cell]--;
410
                    $objWriter->writeAttribute('vMerge', '1');
411
                }
412
                // a:txBody
413
                $objWriter->startElement('a:txBody');
414
                // a:bodyPr
415
                $objWriter->startElement('a:bodyPr');
416
                $objWriter->writeAttribute('wrap', 'square');
417
                $objWriter->writeAttribute('rtlCol', '0');
418
                // a:spAutoFit
419
                $objWriter->writeElement('a:spAutoFit', null);
420
                $objWriter->endElement();
421
                // a:lstStyle
422
                $objWriter->writeElement('a:lstStyle', null);
423
                // Write paragraphs
424
                $this->writeParagraphs($objWriter, $currentCell->getParagraphs());
425
                $objWriter->endElement();
426
                // a:tcPr
427
                $objWriter->startElement('a:tcPr');
428
                // Alignment (horizontal)
429
                $firstParagraph = $currentCell->getParagraph(0);
430
                $verticalAlign = $firstParagraph->getAlignment()->getVertical();
431
                if ($verticalAlign != Alignment::VERTICAL_BASE && $verticalAlign != Alignment::VERTICAL_AUTO) {
432
                    $objWriter->writeAttribute('anchor', $verticalAlign);
433
                }
434
                // Determine borders
435
                $borderLeft = $currentCell->getBorders()->getLeft();
436
                $borderRight = $currentCell->getBorders()->getRight();
437
                $borderTop = $currentCell->getBorders()->getTop();
438
                $borderBottom = $currentCell->getBorders()->getBottom();
439
                $borderDiagonalDown = $currentCell->getBorders()->getDiagonalDown();
440
                $borderDiagonalUp = $currentCell->getBorders()->getDiagonalUp();
441
                // Fix PowerPoint implementation
442
                if (!is_null($nextCellRight)
443
                    && $nextCellRight->getBorders()->getRight()->getHashCode() != $defaultBorder->getHashCode()
444
                ) {
445
                    $borderRight = $nextCellRight->getBorders()->getLeft();
446
                }
447
                if (!is_null($nextCellBelow)
448
                    && $nextCellBelow->getBorders()->getBottom()->getHashCode() != $defaultBorder->getHashCode()
449
                ) {
450
                    $borderBottom = $nextCellBelow->getBorders()->getTop();
451
                }
452
                // Write borders
453
                $this->writeBorder($objWriter, $borderLeft, 'L');
454
                $this->writeBorder($objWriter, $borderRight, 'R');
455
                $this->writeBorder($objWriter, $borderTop, 'T');
456
                $this->writeBorder($objWriter, $borderBottom, 'B');
457
                $this->writeBorder($objWriter, $borderDiagonalDown, 'TlToBr');
458
                $this->writeBorder($objWriter, $borderDiagonalUp, 'BlToTr');
459
                // Fill
460
                $this->writeFill($objWriter, $currentCell->getFill());
461
                $objWriter->endElement();
462
                $objWriter->endElement();
463
            }
464
            $objWriter->endElement();
465
        }
466
        $objWriter->endElement();
467
        $objWriter->endElement();
468
        $objWriter->endElement();
469
        $objWriter->endElement();
470
    }
471
472
    /**
473
     * Write paragraphs
474
     *
475
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
476
     * @param  \PhpOffice\PhpPresentation\Shape\RichText\Paragraph[] $paragraphs
477
     * @throws \Exception
478
     */
479
    protected function writeParagraphs(XMLWriter $objWriter, $paragraphs)
480
    {
481
        // Loop trough paragraphs
482
        foreach ($paragraphs as $paragraph) {
483
            // a:p
484
            $objWriter->startElement('a:p');
485
            // a:pPr
486
            $objWriter->startElement('a:pPr');
487
            $objWriter->writeAttribute('algn', $paragraph->getAlignment()->getHorizontal());
488
            $objWriter->writeAttribute('fontAlgn', $paragraph->getAlignment()->getVertical());
489
            $objWriter->writeAttribute('marL', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getMarginLeft()));
490
            $objWriter->writeAttribute('marR', CommonDrawing::pixelsToEmu(
491
                $paragraph->getAlignment()->getMarginRight()
492
            ));
493
            $objWriter->writeAttribute('indent', CommonDrawing::pixelsToEmu($paragraph->getAlignment()->getIndent()));
494
            $objWriter->writeAttribute('lvl', $paragraph->getAlignment()->getLevel());
495
            // Bullet type specified?
496
            if ($paragraph->getBulletStyle()->getBulletType() != Bullet::TYPE_NONE) {
497
                // a:buFont
498
                $objWriter->startElement('a:buFont');
499
                $objWriter->writeAttribute('typeface', $paragraph->getBulletStyle()->getBulletFont());
500
                $objWriter->endElement();
501
                if ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_BULLET) {
502
                    // a:buChar
503
                    $objWriter->startElement('a:buChar');
504
                    $objWriter->writeAttribute('char', $paragraph->getBulletStyle()->getBulletChar());
505
                    $objWriter->endElement();
506
                } elseif ($paragraph->getBulletStyle()->getBulletType() == Bullet::TYPE_NUMERIC) {
507
                    // a:buAutoNum
508
                    $objWriter->startElement('a:buAutoNum');
509
                    $objWriter->writeAttribute('type', $paragraph->getBulletStyle()->getBulletNumericStyle());
510
                    if ($paragraph->getBulletStyle()->getBulletNumericStartAt() != 1) {
511
                        $objWriter->writeAttribute('startAt', $paragraph->getBulletStyle()->getBulletNumericStartAt());
512
                    }
513
                    $objWriter->endElement();
514
                }
515
            }
516
            $objWriter->endElement();
517
            // Loop trough rich text elements
518
            $elements = $paragraph->getRichTextElements();
519
            foreach ($elements as $element) {
520
                if ($element instanceof BreakElement) {
521
                    // a:br
522
                    $objWriter->writeElement('a:br', null);
523
                } elseif ($element instanceof Run || $element instanceof TextElement) {
524
                    // a:r
525
                    $objWriter->startElement('a:r');
526
                    // a:rPr
527
                    if ($element instanceof Run) {
528
                        // a:rPr
529
                        $objWriter->startElement('a:rPr');
530
                        // Lang
531
                        $objWriter->writeAttribute('lang', ($element->getLanguage() ?
532
                            $element->getLanguage() : 'en-US'));
533
                        // Bold
534
                        $objWriter->writeAttribute('b', ($element->getFont()->isBold() ? '1' : '0'));
535
                        // Italic
536
                        $objWriter->writeAttribute('i', ($element->getFont()->isItalic() ? '1' : '0'));
537
                        // Strikethrough
538
                        $objWriter->writeAttribute('strike', ($element->getFont()->isStrikethrough() ?
539
                            'sngStrike' : 'noStrike'));
540
                        // Size
541
                        $objWriter->writeAttribute('sz', ($element->getFont()->getSize() * 100));
542
                        // Underline
543
                        $objWriter->writeAttribute('u', $element->getFont()->getUnderline());
544
                        // Superscript / subscript
545
                        if ($element->getFont()->isSuperScript() || $element->getFont()->isSubScript()) {
546
                            if ($element->getFont()->isSuperScript()) {
547
                                $objWriter->writeAttribute('baseline', '30000');
548
                            } elseif ($element->getFont()->isSubScript()) {
549
                                $objWriter->writeAttribute('baseline', '-25000');
550
                            }
551
                        }
552
                        // Color - a:solidFill
553
                        $objWriter->startElement('a:solidFill');
554
                        // a:srgbClr
555
                        $objWriter->startElement('a:srgbClr');
556
                        $objWriter->writeAttribute('val', $element->getFont()->getColor()->getRGB());
557
                        $objWriter->endElement();
558
                        $objWriter->endElement();
559
                        // Font - a:latin
560
                        $objWriter->startElement('a:latin');
561
                        $objWriter->writeAttribute('typeface', $element->getFont()->getName());
562
                        $objWriter->endElement();
563
                        // a:hlinkClick
564
                        if ($element->hasHyperlink()) {
565
                            $this->writeHyperlink($objWriter, $element);
566
                        }
567
                        $objWriter->endElement();
568
                    }
569
                    // t
570
                    $objWriter->startElement('a:t');
571
                    $objWriter->writeCData(Text::controlCharacterPHP2OOXML($element->getText()));
572
                    $objWriter->endElement();
573
                    $objWriter->endElement();
574
                }
575
            }
576
            $objWriter->endElement();
577
        }
578
    }
579
580
    /**
581
     * Write Line Shape
582
     *
583
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
584
     * @param \PhpOffice\PhpPresentation\Shape\Line $shape
585
     * @param  int $shapeId
586
     */
587
    protected function writeShapeLine(XMLWriter $objWriter, Line $shape, $shapeId)
588
    {
589
        // p:sp
590
        $objWriter->startElement('p:cxnSp');
591
        // p:nvSpPr
592
        $objWriter->startElement('p:nvCxnSpPr');
593
        // p:cNvPr
594
        $objWriter->startElement('p:cNvPr');
595
        $objWriter->writeAttribute('id', $shapeId);
596
        $objWriter->writeAttribute('name', '');
597
        $objWriter->endElement();
598
        // p:cNvCxnSpPr
599
        $objWriter->writeElement('p:cNvCxnSpPr', null);
600
        // p:nvPr
601
        $objWriter->writeElement('p:nvPr', null);
602
        $objWriter->endElement();
603
        // p:spPr
604
        $objWriter->startElement('p:spPr');
605
        // a:xfrm
606
        $objWriter->startElement('a:xfrm');
607
        if ($shape->getWidth() >= 0 && $shape->getHeight() >= 0) {
608
            // a:off
609
            $objWriter->startElement('a:off');
610
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
611
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
612
            $objWriter->endElement();
613
            // a:ext
614
            $objWriter->startElement('a:ext');
615
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
616
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
617
            $objWriter->endElement();
618
        } elseif ($shape->getWidth() < 0 && $shape->getHeight() < 0) {
619
            // a:off
620
            $objWriter->startElement('a:off');
621
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth()));
622
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight()));
623
            $objWriter->endElement();
624
            // a:ext
625
            $objWriter->startElement('a:ext');
626
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(-$shape->getWidth()));
627
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(-$shape->getHeight()));
628
            $objWriter->endElement();
629
        } elseif ($shape->getHeight() < 0) {
630
            $objWriter->writeAttribute('flipV', 1);
631
            // a:off
632
            $objWriter->startElement('a:off');
633
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
634
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY() + $shape->getHeight()));
635
            $objWriter->endElement();
636
            // a:ext
637
            $objWriter->startElement('a:ext');
638
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
639
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu(-$shape->getHeight()));
640
            $objWriter->endElement();
641
        } elseif ($shape->getWidth() < 0) {
642
            $objWriter->writeAttribute('flipV', 1);
643
            // a:off
644
            $objWriter->startElement('a:off');
645
            $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX() + $shape->getWidth()));
646
            $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
647
            $objWriter->endElement();
648
            // a:ext
649
            $objWriter->startElement('a:ext');
650
            $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu(-$shape->getWidth()));
651
            $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
652
            $objWriter->endElement();
653
        }
654
        $objWriter->endElement();
655
        // a:prstGeom
656
        $objWriter->startElement('a:prstGeom');
657
        $objWriter->writeAttribute('prst', 'line');
658
659
        // a:prstGeom/a:avLst
660
        $objWriter->writeElement('a:avLst');
661
662
        $objWriter->endElement();
663
        if ($shape->getBorder()->getLineStyle() != Border::LINE_NONE) {
664
            $this->writeBorder($objWriter, $shape->getBorder(), '');
665
        }
666
        $objWriter->endElement();
667
        $objWriter->endElement();
668
    }
669
670
    /**
671
     * Write Shadow
672
     * @param XMLWriter $objWriter
673
     * @param Shadow $oShadow
674 25
     */
675
    protected function writeShadow(XMLWriter $objWriter, $oShadow)
676 25
    {
677
        if (!($oShadow instanceof Shadow)) {
678
            return;
679
        }
680 25
681 23
        if (!$oShadow->isVisible()) {
682
            return;
683
        }
684
685 2
        // a:effectLst
686
        $objWriter->startElement('a:effectLst');
687
688 2
        // a:outerShdw
689 2
        $objWriter->startElement('a:outerShdw');
690 2
        $objWriter->writeAttribute('blurRad', CommonDrawing::pixelsToEmu($oShadow->getBlurRadius()));
691 2
        $objWriter->writeAttribute('dist', CommonDrawing::pixelsToEmu($oShadow->getDistance()));
692 2
        $objWriter->writeAttribute('dir', CommonDrawing::degreesToAngle($oShadow->getDirection()));
693 2
        $objWriter->writeAttribute('algn', $oShadow->getAlignment());
694
        $objWriter->writeAttribute('rotWithShape', '0');
695 2
696
        $this->writeColor($objWriter, $oShadow->getColor(), $oShadow->getAlpha());
697 2
698
        $objWriter->endElement();
699 2
700 2
        $objWriter->endElement();
701
    }
702
703
    /**
704
     * Write hyperlink
705
     *
706
     * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
707
     * @param \PhpOffice\PhpPresentation\AbstractShape|\PhpOffice\PhpPresentation\Shape\RichText\TextElement $shape
708
     */
709
    protected function writeHyperlink(XMLWriter $objWriter, $shape)
710
    {
711
        // a:hlinkClick
712
        $objWriter->startElement('a:hlinkClick');
713
        $objWriter->writeAttribute('r:id', $shape->getHyperlink()->relationId);
714
        $objWriter->writeAttribute('tooltip', $shape->getHyperlink()->getTooltip());
715
        if ($shape->getHyperlink()->isInternal()) {
716
            $objWriter->writeAttribute('action', $shape->getHyperlink()->getUrl());
717
        }
718
        $objWriter->endElement();
719
    }
720
721
    /**
722
     * Write Note Slide
723
     * @param Note $pNote
724
     * @throws \Exception
725
     * @return  string
726
     */
727
    protected function writeNote(Note $pNote)
728
    {
729
        // Create XML writer
730
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
731
        // XML header
732
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
733
        // p:notes
734
        $objWriter->startElement('p:notes');
735
        $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');
736
        $objWriter->writeAttribute('xmlns:p', 'http://schemas.openxmlformats.org/presentationml/2006/main');
737
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
738
        // p:cSld
739
        $objWriter->startElement('p:cSld');
740
        // p:spTree
741
        $objWriter->startElement('p:spTree');
742
        // p:nvGrpSpPr
743
        $objWriter->startElement('p:nvGrpSpPr');
744
        // p:cNvPr
745
        $objWriter->startElement('p:cNvPr');
746
        $objWriter->writeAttribute('id', '1');
747
        $objWriter->writeAttribute('name', '');
748
        $objWriter->endElement();
749
        // p:cNvGrpSpPr
750
        $objWriter->writeElement('p:cNvGrpSpPr', null);
751
        // p:nvPr
752
        $objWriter->writeElement('p:nvPr', null);
753
        // ## p:nvGrpSpPr
754
        $objWriter->endElement();
755
        // p:grpSpPr
756
        $objWriter->startElement('p:grpSpPr');
757
        // a:xfrm
758
        $objWriter->startElement('a:xfrm');
759
        // a:off
760
        $objWriter->startElement('a:off');
761
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX()));
762
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pNote->getOffsetY()));
763
        $objWriter->endElement(); // a:off
764
        // a:ext
765
        $objWriter->startElement('a:ext');
766
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pNote->getExtentX()));
767
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pNote->getExtentY()));
768
        $objWriter->endElement(); // a:ext
769
        // a:chOff
770
        $objWriter->startElement('a:chOff');
771
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($pNote->getOffsetX()));
772
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($pNote->getOffsetY()));
773
        $objWriter->endElement(); // a:chOff
774
        // a:chExt
775
        $objWriter->startElement('a:chExt');
776
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($pNote->getExtentX()));
777
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($pNote->getExtentY()));
778
        $objWriter->endElement(); // a:chExt
779
        // ## a:xfrm
780
        $objWriter->endElement();
781
        // ## p:grpSpPr
782
        $objWriter->endElement();
783
        // p:sp
784
        $objWriter->startElement('p:sp');
785
        // p:nvSpPr
786
        $objWriter->startElement('p:nvSpPr');
787
        $objWriter->startElement('p:cNvPr');
788
        $objWriter->writeAttribute('id', '1');
789
        $objWriter->writeAttribute('name', 'Notes Placeholder');
790
        $objWriter->endElement();
791
        // p:cNvSpPr
792
        $objWriter->startElement('p:cNvSpPr');
793
        //a:spLocks
794
        $objWriter->startElement('a:spLocks');
795
        $objWriter->writeAttribute('noGrp', '1');
796
        $objWriter->endElement();
797
        // ## p:cNvSpPr
798
        $objWriter->endElement();
799
        // p:nvPr
800
        $objWriter->startElement('p:nvPr');
801
        $objWriter->startElement('p:ph');
802
        $objWriter->writeAttribute('type', 'body');
803
        $objWriter->writeAttribute('idx', '1');
804
        $objWriter->endElement();
805
        // ## p:nvPr
806
        $objWriter->endElement();
807
        // ## p:nvSpPr
808
        $objWriter->endElement();
809
        $objWriter->writeElement('p:spPr', null);
810
        // p:txBody
811
        $objWriter->startElement('p:txBody');
812
        $objWriter->writeElement('a:bodyPr', null);
813
        $objWriter->writeElement('a:lstStyle', null);
814
        // Loop shapes
815
        $shapes = $pNote->getShapeCollection();
816
        foreach ($shapes as $shape) {
817
            // Check type
818
            if ($shape instanceof RichText) {
819
                $paragraphs = $shape->getParagraphs();
820
                $this->writeParagraphs($objWriter, $paragraphs);
821
            }
822
        }
823
        // ## p:txBody
824
        $objWriter->endElement();
825
        // ## p:sp
826
        $objWriter->endElement();
827
        // ## p:spTree
828
        $objWriter->endElement();
829
        // ## p:cSld
830
        $objWriter->endElement();
831
        // ## p:notes
832
        $objWriter->endElement();
833
        // Return
834
        return $objWriter->getData();
835
    }
836
837
    /**
838
     * Write chart
839
     *
840
     * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
841
     * @param \PhpOffice\PhpPresentation\Shape\Chart $shape
842
     * @param  int $shapeId
843
     */
844
    protected function writeShapeChart(XMLWriter $objWriter, ShapeChart $shape, $shapeId)
845
    {
846
        // p:graphicFrame
847
        $objWriter->startElement('p:graphicFrame');
848
        // p:nvGraphicFramePr
849
        $objWriter->startElement('p:nvGraphicFramePr');
850
        // p:cNvPr
851
        $objWriter->startElement('p:cNvPr');
852
        $objWriter->writeAttribute('id', $shapeId);
853
        $objWriter->writeAttribute('name', $shape->getName());
854
        $objWriter->writeAttribute('descr', $shape->getDescription());
855
        $objWriter->endElement();
856
        // p:cNvGraphicFramePr
857
        $objWriter->writeElement('p:cNvGraphicFramePr', null);
858
        // p:nvPr
859
        $objWriter->writeElement('p:nvPr', null);
860
        $objWriter->endElement();
861
        // p:xfrm
862
        $objWriter->startElement('p:xfrm');
863
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
864
        // a:off
865
        $objWriter->startElement('a:off');
866
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
867
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
868
        $objWriter->endElement();
869
        // a:ext
870
        $objWriter->startElement('a:ext');
871
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
872
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
873
        $objWriter->endElement();
874
        $objWriter->endElement();
875
        // a:graphic
876
        $objWriter->startElement('a:graphic');
877
        // a:graphicData
878
        $objWriter->startElement('a:graphicData');
879
        $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
880
        // c:chart
881
        $objWriter->startElement('c:chart');
882
        $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');
883
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
884
        $objWriter->writeAttribute('r:id', $shape->relationId);
885
        $objWriter->endElement();
886
        $objWriter->endElement();
887
        $objWriter->endElement();
888
        $objWriter->endElement();
889
    }
890
891
    /**
892
     * Write pic
893
     *
894
     * @param  \PhpOffice\Common\XMLWriter $objWriter XML Writer
895
     * @param  \PhpOffice\PhpPresentation\Shape\AbstractGraphic $shape
896
     * @param  int $shapeId
897
     * @throws \Exception
898 8
     */
899
    protected function writeShapePic(XMLWriter $objWriter, AbstractGraphic $shape, $shapeId)
900
    {
901 8
        // p:pic
902
        $objWriter->startElement('p:pic');
903 8
        // p:nvPicPr
904
        $objWriter->startElement('p:nvPicPr');
905 8
        // p:cNvPr
906 8
        $objWriter->startElement('p:cNvPr');
907 8
        $objWriter->writeAttribute('id', $shapeId);
908 8
        $objWriter->writeAttribute('name', $shape->getName());
909
        $objWriter->writeAttribute('descr', $shape->getDescription());
910 8
        // a:hlinkClick
911 1
        if ($shape->hasHyperlink()) {
912 1
            $this->writeHyperlink($objWriter, $shape);
913 8
        }
914
        $objWriter->endElement();
915 8
        // p:cNvPicPr
916
        $objWriter->startElement('p:cNvPicPr');
917 8
        // a:picLocks
918 8
        $objWriter->startElement('a:picLocks');
919 8
        $objWriter->writeAttribute('noChangeAspect', '1');
920 8
        $objWriter->endElement();
921
        $objWriter->endElement();
922 8
        // p:nvPr
923
        $objWriter->startElement('p:nvPr');
924
        /**
925
         * @link : https://github.com/stefslon/exportToPPTX/blob/master/exportToPPTX.m#L2128
926 8
         */
927
        if ($shape instanceof Media) {
928 1
            // p:nvPr > a:videoFile
929 1
            $objWriter->startElement('a:videoFile');
930 1
            $objWriter->writeAttribute('r:link', $shape->relationId);
931
            $objWriter->endElement();
932 1
            // p:nvPr > p:extLst
933
            $objWriter->startElement('p:extLst');
934 1
            // p:nvPr > p:extLst > p:ext
935 1
            $objWriter->startElement('p:ext');
936
            $objWriter->writeAttribute('uri', '{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}');
937 1
            // p:nvPr > p:extLst > p:ext > p14:media
938 1
            $objWriter->startElement('p14:media');
939 1
            $objWriter->writeAttribute('r:embed', $shape->relationId);
940
            $objWriter->writeAttribute('xmlns:p14', 'http://schemas.microsoft.com/office/powerpoint/2010/main');
941 1
            // p:nvPr > p:extLst > p:ext > ##p14:media
942
            $objWriter->endElement();
943 1
            // p:nvPr > p:extLst > ##p:ext
944
            $objWriter->endElement();
945 1
            // p:nvPr > ##p:extLst
946 1
            $objWriter->endElement();
947
        }
948 8
        // ##p:nvPr
949 8
        $objWriter->endElement();
950
        $objWriter->endElement();
951 8
        // p:blipFill
952
        $objWriter->startElement('p:blipFill');
953 8
        // a:blip
954 8
        $objWriter->startElement('a:blip');
955 8
        $objWriter->writeAttribute('r:embed', $shape->relationId);
956
        $objWriter->endElement();
957 8
        // a:stretch
958 8
        $objWriter->startElement('a:stretch');
959 8
        $objWriter->writeElement('a:fillRect', null);
960 8
        $objWriter->endElement();
961
        $objWriter->endElement();
962 8
        // p:spPr
963
        $objWriter->startElement('p:spPr');
964 8
        // a:xfrm
965 8
        $objWriter->startElement('a:xfrm');
966
        $objWriter->writeAttributeIf($shape->getRotation() != 0, 'rot', CommonDrawing::degreesToAngle($shape->getRotation()));
967 8
        // a:off
968 8
        $objWriter->startElement('a:off');
969 8
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($shape->getOffsetX()));
970 8
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($shape->getOffsetY()));
971
        $objWriter->endElement();
972 8
        // a:ext
973 8
        $objWriter->startElement('a:ext');
974 8
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($shape->getWidth()));
975 8
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($shape->getHeight()));
976 8
        $objWriter->endElement();
977
        $objWriter->endElement();
978 8
        // a:prstGeom
979 8
        $objWriter->startElement('a:prstGeom');
980
        $objWriter->writeAttribute('prst', 'rect');
981 8
        // a:avLst
982 8
        $objWriter->writeElement('a:avLst', null);
983 8
        $objWriter->endElement();
984 1
        if ($shape->getBorder()->getLineStyle() != Border::LINE_NONE) {
985 1
            $this->writeBorder($objWriter, $shape->getBorder(), '');
986 8
        }
987 1
        if ($shape->getShadow()->isVisible()) {
988 1
            $this->writeShadow($objWriter, $shape->getShadow());
989 8
        }
990 8
        $objWriter->endElement();
991 8
        $objWriter->endElement();
992
    }
993
994
    /**
995
     * Write group
996
     *
997
     * @param \PhpOffice\Common\XMLWriter $objWriter XML Writer
998
     * @param \PhpOffice\PhpPresentation\Shape\Group $group
999
     * @param  int $shapeId
1000
     */
1001
    protected function writeShapeGroup(XMLWriter $objWriter, Group $group, &$shapeId)
1002
    {
1003
        // p:grpSp
1004
        $objWriter->startElement('p:grpSp');
1005
        // p:nvGrpSpPr
1006
        $objWriter->startElement('p:nvGrpSpPr');
1007
        // p:cNvPr
1008
        $objWriter->startElement('p:cNvPr');
1009
        $objWriter->writeAttribute('name', 'Group ' . $shapeId++);
1010
        $objWriter->writeAttribute('id', $shapeId);
1011
        $objWriter->endElement(); // p:cNvPr
1012
        // NOTE: Re: $shapeId This seems to be how PowerPoint 2010 does business.
1013
        // p:cNvGrpSpPr
1014
        $objWriter->writeElement('p:cNvGrpSpPr', null);
1015
        // p:nvPr
1016
        $objWriter->writeElement('p:nvPr', null);
1017
        $objWriter->endElement(); // p:nvGrpSpPr
1018
        // p:grpSpPr
1019
        $objWriter->startElement('p:grpSpPr');
1020
        // a:xfrm
1021
        $objWriter->startElement('a:xfrm');
1022
        // a:off
1023
        $objWriter->startElement('a:off');
1024
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($group->getOffsetX()));
1025
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($group->getOffsetY()));
1026
        $objWriter->endElement(); // a:off
1027
        // a:ext
1028
        $objWriter->startElement('a:ext');
1029
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($group->getExtentX()));
1030
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($group->getExtentY()));
1031
        $objWriter->endElement(); // a:ext
1032
        // a:chOff
1033
        $objWriter->startElement('a:chOff');
1034
        $objWriter->writeAttribute('x', CommonDrawing::pixelsToEmu($group->getOffsetX()));
1035
        $objWriter->writeAttribute('y', CommonDrawing::pixelsToEmu($group->getOffsetY()));
1036
        $objWriter->endElement(); // a:chOff
1037
        // a:chExt
1038
        $objWriter->startElement('a:chExt');
1039
        $objWriter->writeAttribute('cx', CommonDrawing::pixelsToEmu($group->getExtentX()));
1040
        $objWriter->writeAttribute('cy', CommonDrawing::pixelsToEmu($group->getExtentY()));
1041
        $objWriter->endElement(); // a:chExt
1042
        $objWriter->endElement(); // a:xfrm
1043
        $objWriter->endElement(); // p:grpSpPr
1044
1045
        $this->writeShapeCollection($objWriter, $group->getShapeCollection(), $shapeId);
1046
1047
        $objWriter->endElement(); // p:grpSp
1048
    }
1049
1050
    /**
1051
     * @param \PhpOffice\PhpPresentation\Slide\AbstractSlide $pSlide
1052
     * @param $objWriter
1053 99
     */
1054
    protected function writeSlideBackground(AbstractSlideAlias $pSlide, XMLWriter $objWriter)
1055 99
    {
1056 99
        if (!($pSlide->getBackground() instanceof Slide\AbstractBackground)) {
1057
            return;
1058 99
        }
1059
        $oBackground = $pSlide->getBackground();
1060 99
        // p:bg
1061 99
        $objWriter->startElement('p:bg');
1062
        if ($oBackground instanceof Slide\Background\Color) {
1063 99
            // p:bgPr
1064
            $objWriter->startElement('p:bgPr');
1065 99
            // a:solidFill
1066
            $objWriter->startElement('a:solidFill');
1067 99
            // a:srgbClr
1068 99
            $objWriter->startElement('a:srgbClr');
1069 99
            $objWriter->writeAttribute('val', $oBackground->getColor()->getRGB());
1070
            $objWriter->endElement();
1071 99
            // > a:solidFill
1072
            $objWriter->endElement();
1073
1074 99
            // p:bgPr/a:effectLst
1075
            $objWriter->writeElement('a:effectLst');
1076
1077 99
            // > p:bgPr
1078 99
            $objWriter->endElement();
1079 99
        }
1080
        if ($oBackground instanceof Slide\Background\Image) {
1081
            // p:bgPr
1082
            $objWriter->startElement('p:bgPr');
1083
            // a:blipFill
1084
            $objWriter->startElement('a:blipFill');
1085
            // a:blip
1086
            $objWriter->startElement('a:blip');
1087
            $objWriter->writeAttribute('r:embed', $oBackground->relationId);
1088
            // > a:blipFill
1089
            $objWriter->endElement();
1090
            // a:stretch
1091
            $objWriter->startElement('a:stretch');
1092
            // a:fillRect
1093
            $objWriter->writeElement('a:fillRect');
1094
            // > a:stretch
1095
            $objWriter->endElement();
1096
            // > a:blipFill
1097
            $objWriter->endElement();
1098
            // > p:bgPr
1099
            $objWriter->endElement();
1100
        }
1101
        /**
1102
         * @link : http://www.officeopenxml.com/prSlide-background.php
1103 99
         */
1104
        if ($oBackground instanceof Slide\Background\SchemeColor) {
1105
            // p:bgRef
1106
            $objWriter->startElement('p:bgRef');
1107
            $objWriter->writeAttribute('idx', '1001');
1108
            // a:schemeClr
1109
            $objWriter->startElement('a:schemeClr');
1110
            $objWriter->writeAttribute('val', $oBackground->getSchemeColor()->getValue());
1111
            $objWriter->endElement();
1112
            // > p:bgRef
1113
            $objWriter->endElement();
1114
        }
1115 99
        // > p:bg
1116 99
        $objWriter->endElement();
1117
    }
1118
1119
1120
    /**
1121
     * Write Transition Slide
1122
     * @link http://officeopenxml.com/prSlide-transitions.php
1123
     * @param XMLWriter $objWriter
1124
     * @param Transition $transition
1125
     */
1126
    protected function writeSlideTransition(XMLWriter $objWriter, $transition)
1127
    {
1128
        if (!$transition instanceof Transition) {
1129
            return;
1130
        }
1131
        $objWriter->startElement('p:transition');
1132
        if (!is_null($transition->getSpeed())) {
1133
            $objWriter->writeAttribute('spd', $transition->getSpeed());
1134
        }
1135
        $objWriter->writeAttribute('advClick', $transition->hasManualTrigger() ? '1' : '0');
1136
        if ($transition->hasTimeTrigger()) {
1137 1
            $objWriter->writeAttribute('advTm', $transition->getAdvanceTimeTrigger());
1138
        }
1139
1140
        switch ($transition->getTransitionType()) {
1141
            case Transition::TRANSITION_BLINDS_HORIZONTAL:
1142
                $objWriter->startElement('p:blinds');
1143
                $objWriter->writeAttribute('dir', 'horz');
1144
                $objWriter->endElement();
1145
                break;
1146
            case Transition::TRANSITION_BLINDS_VERTICAL:
1147
                $objWriter->startElement('p:blinds');
1148
                $objWriter->writeAttribute('dir', 'vert');
1149
                $objWriter->endElement();
1150
                break;
1151
            case Transition::TRANSITION_CHECKER_HORIZONTAL:
1152
                $objWriter->startElement('p:checker');
1153
                $objWriter->writeAttribute('dir', 'horz');
1154
                $objWriter->endElement();
1155
                break;
1156
            case Transition::TRANSITION_CHECKER_VERTICAL:
1157
                $objWriter->startElement('p:checker');
1158
                $objWriter->writeAttribute('dir', 'vert');
1159
                $objWriter->endElement();
1160
                break;
1161
            case Transition::TRANSITION_CIRCLE_HORIZONTAL:
1162
                $objWriter->startElement('p:circle');
1163
                $objWriter->writeAttribute('dir', 'horz');
1164
                $objWriter->endElement();
1165
                break;
1166
            case Transition::TRANSITION_CIRCLE_VERTICAL:
1167
                $objWriter->startElement('p:circle');
1168
                $objWriter->writeAttribute('dir', 'vert');
1169
                $objWriter->endElement();
1170
                break;
1171
            case Transition::TRANSITION_COMB_HORIZONTAL:
1172
                $objWriter->startElement('p:comb');
1173
                $objWriter->writeAttribute('dir', 'horz');
1174
                $objWriter->endElement();
1175
                break;
1176
            case Transition::TRANSITION_COMB_VERTICAL:
1177
                $objWriter->startElement('p:comb');
1178
                $objWriter->writeAttribute('dir', 'vert');
1179
                $objWriter->endElement();
1180
                break;
1181
            case Transition::TRANSITION_COVER_DOWN:
1182
                $objWriter->startElement('p:cover');
1183
                $objWriter->writeAttribute('dir', 'd');
1184
                $objWriter->endElement();
1185
                break;
1186
            case Transition::TRANSITION_COVER_LEFT:
1187
                $objWriter->startElement('p:cover');
1188
                $objWriter->writeAttribute('dir', 'l');
1189
                $objWriter->endElement();
1190
                break;
1191
            case Transition::TRANSITION_COVER_LEFT_DOWN:
1192
                $objWriter->startElement('p:cover');
1193
                $objWriter->writeAttribute('dir', 'ld');
1194
                $objWriter->endElement();
1195
                break;
1196
            case Transition::TRANSITION_COVER_LEFT_UP:
1197
                $objWriter->startElement('p:cover');
1198
                $objWriter->writeAttribute('dir', 'lu');
1199
                $objWriter->endElement();
1200
                break;
1201
            case Transition::TRANSITION_COVER_RIGHT:
1202
                $objWriter->startElement('p:cover');
1203
                $objWriter->writeAttribute('dir', 'r');
1204
                $objWriter->endElement();
1205
                break;
1206
            case Transition::TRANSITION_COVER_RIGHT_DOWN:
1207
                $objWriter->startElement('p:cover');
1208
                $objWriter->writeAttribute('dir', 'rd');
1209
                $objWriter->endElement();
1210
                break;
1211
            case Transition::TRANSITION_COVER_RIGHT_UP:
1212
                $objWriter->startElement('p:cover');
1213
                $objWriter->writeAttribute('dir', 'ru');
1214
                $objWriter->endElement();
1215
                break;
1216
            case Transition::TRANSITION_COVER_UP:
1217
                $objWriter->startElement('p:cover');
1218
                $objWriter->writeAttribute('dir', 'u');
1219
                $objWriter->endElement();
1220
                break;
1221
            case Transition::TRANSITION_CUT:
1222
                $objWriter->writeElement('p:cut');
1223
                break;
1224
            case Transition::TRANSITION_DIAMOND:
1225
                $objWriter->writeElement('p:diamond');
1226
                break;
1227
            case Transition::TRANSITION_DISSOLVE:
1228
                $objWriter->writeElement('p:dissolve');
1229
                break;
1230
            case Transition::TRANSITION_FADE:
1231
                $objWriter->writeElement('p:fade');
1232
                break;
1233
            case Transition::TRANSITION_NEWSFLASH:
1234
                $objWriter->writeElement('p:newsflash');
1235
                break;
1236
            case Transition::TRANSITION_PLUS:
1237
                $objWriter->writeElement('p:plus');
1238
                break;
1239
            case Transition::TRANSITION_PULL_DOWN:
1240
                $objWriter->startElement('p:pull');
1241
                $objWriter->writeAttribute('dir', 'd');
1242
                $objWriter->endElement();
1243
                break;
1244
            case Transition::TRANSITION_PULL_LEFT:
1245
                $objWriter->startElement('p:pull');
1246
                $objWriter->writeAttribute('dir', 'l');
1247
                $objWriter->endElement();
1248
                break;
1249
            case Transition::TRANSITION_PULL_RIGHT:
1250
                $objWriter->startElement('p:pull');
1251
                $objWriter->writeAttribute('dir', 'r');
1252
                $objWriter->endElement();
1253
                break;
1254
            case Transition::TRANSITION_PULL_UP:
1255
                $objWriter->startElement('p:pull');
1256
                $objWriter->writeAttribute('dir', 'u');
1257
                $objWriter->endElement();
1258
                break;
1259
            case Transition::TRANSITION_PUSH_DOWN:
1260
                $objWriter->startElement('p:push');
1261
                $objWriter->writeAttribute('dir', 'd');
1262
                $objWriter->endElement();
1263
                break;
1264
            case Transition::TRANSITION_PUSH_LEFT:
1265
                $objWriter->startElement('p:push');
1266
                $objWriter->writeAttribute('dir', 'l');
1267
                $objWriter->endElement();
1268
                break;
1269
            case Transition::TRANSITION_PUSH_RIGHT:
1270
                $objWriter->startElement('p:push');
1271
                $objWriter->writeAttribute('dir', 'r');
1272
                $objWriter->endElement();
1273
                break;
1274
            case Transition::TRANSITION_PUSH_UP:
1275
                $objWriter->startElement('p:push');
1276
                $objWriter->writeAttribute('dir', 'u');
1277
                $objWriter->endElement();
1278
                break;
1279
            case Transition::TRANSITION_RANDOM:
1280
                $objWriter->writeElement('p:random');
1281
                break;
1282
            case Transition::TRANSITION_RANDOMBAR_HORIZONTAL:
1283
                $objWriter->startElement('p:randomBar');
1284
                $objWriter->writeAttribute('dir', 'horz');
1285
                $objWriter->endElement();
1286
                break;
1287
            case Transition::TRANSITION_RANDOMBAR_VERTICAL:
1288
                $objWriter->startElement('p:randomBar');
1289
                $objWriter->writeAttribute('dir', 'vert');
1290
                $objWriter->endElement();
1291
                break;
1292
            case Transition::TRANSITION_SPLIT_IN_HORIZONTAL:
1293
                $objWriter->startElement('p:split');
1294
                $objWriter->writeAttribute('dir', 'in');
1295
                $objWriter->writeAttribute('orient', 'horz');
1296
                $objWriter->endElement();
1297
                break;
1298
            case Transition::TRANSITION_SPLIT_OUT_HORIZONTAL:
1299
                $objWriter->startElement('p:split');
1300
                $objWriter->writeAttribute('dir', 'out');
1301
                $objWriter->writeAttribute('orient', 'horz');
1302
                $objWriter->endElement();
1303
                break;
1304
            case Transition::TRANSITION_SPLIT_IN_VERTICAL:
1305
                $objWriter->startElement('p:split');
1306
                $objWriter->writeAttribute('dir', 'in');
1307
                $objWriter->writeAttribute('orient', 'vert');
1308
                $objWriter->endElement();
1309
                break;
1310
            case Transition::TRANSITION_SPLIT_OUT_VERTICAL:
1311
                $objWriter->startElement('p:split');
1312
                $objWriter->writeAttribute('dir', 'out');
1313
                $objWriter->writeAttribute('orient', 'vert');
1314
                $objWriter->endElement();
1315
                break;
1316
            case Transition::TRANSITION_STRIPS_LEFT_DOWN:
1317
                $objWriter->startElement('p:strips');
1318
                $objWriter->writeAttribute('dir', 'ld');
1319
                $objWriter->endElement();
1320
                break;
1321
            case Transition::TRANSITION_STRIPS_LEFT_UP:
1322
                $objWriter->startElement('p:strips');
1323
                $objWriter->writeAttribute('dir', 'lu');
1324
                $objWriter->endElement();
1325
                break;
1326
            case Transition::TRANSITION_STRIPS_RIGHT_DOWN:
1327
                $objWriter->startElement('p:strips');
1328
                $objWriter->writeAttribute('dir', 'rd');
1329
                $objWriter->endElement();
1330
                break;
1331
            case Transition::TRANSITION_STRIPS_RIGHT_UP:
1332
                $objWriter->startElement('p:strips');
1333
                $objWriter->writeAttribute('dir', 'ru');
1334
                $objWriter->endElement();
1335
                break;
1336
            case Transition::TRANSITION_WEDGE:
1337
                $objWriter->writeElement('p:wedge');
1338
                break;
1339
            case Transition::TRANSITION_WIPE_DOWN:
1340
                $objWriter->startElement('p:wipe');
1341
                $objWriter->writeAttribute('dir', 'd');
1342
                $objWriter->endElement();
1343
                break;
1344
            case Transition::TRANSITION_WIPE_LEFT:
1345
                $objWriter->startElement('p:wipe');
1346
                $objWriter->writeAttribute('dir', 'l');
1347
                $objWriter->endElement();
1348
                break;
1349
            case Transition::TRANSITION_WIPE_RIGHT:
1350
                $objWriter->startElement('p:wipe');
1351
                $objWriter->writeAttribute('dir', 'r');
1352
                $objWriter->endElement();
1353
                break;
1354
            case Transition::TRANSITION_WIPE_UP:
1355
                $objWriter->startElement('p:wipe');
1356
                $objWriter->writeAttribute('dir', 'u');
1357
                $objWriter->endElement();
1358
                break;
1359
            case Transition::TRANSITION_ZOOM_IN:
1360
                $objWriter->startElement('p:zoom');
1361
                $objWriter->writeAttribute('dir', 'in');
1362
                $objWriter->endElement();
1363
                break;
1364
            case Transition::TRANSITION_ZOOM_OUT:
1365
                $objWriter->startElement('p:zoom');
1366
                $objWriter->writeAttribute('dir', 'out');
1367
                $objWriter->endElement();
1368
                break;
1369
        }
1370
1371
        $objWriter->endElement();
1372
    }
1373
1374
    private function getGUID()
1375
    {
1376
        if (function_exists('com_create_guid')) {
1377
            return com_create_guid();
1378
        } else {
1379
            mt_srand((double)microtime() * 10000);//optional for php 4.2.0 and up.
1380
            $charid = strtoupper(md5(uniqid(rand(), true)));
1381
            $hyphen = chr(45);// "-"
1382
            $uuid = chr(123)// "{"
1383
                . substr($charid, 0, 8) . $hyphen
1384
                . substr($charid, 8, 4) . $hyphen
1385
                . substr($charid, 12, 4) . $hyphen
1386
                . substr($charid, 16, 4) . $hyphen
1387
                . substr($charid, 20, 12)
1388
                . chr(125);// "}"
1389
            return $uuid;
1390
        }
1391
    }
1392
}
1393