Completed
Pull Request — master (#553)
by Ryota
09:17
created

PowerPoint2007::loadStyleColor()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 0
cts 8
cp 0
rs 9.9
c 0
b 0
f 0
cc 3
nc 2
nop 2
crap 12
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
18
namespace PhpOffice\PhpPresentation\Reader;
19
20
use PhpOffice\PhpPresentation\DocumentLayout;
21
use PhpOffice\PhpPresentation\PhpPresentation;
22
use PhpOffice\PhpPresentation\Shape\Placeholder;
23
use PhpOffice\PhpPresentation\Shape\RichText;
24
use PhpOffice\PhpPresentation\Shape\RichText\Paragraph;
25
use PhpOffice\PhpPresentation\Shape\Table\Cell;
26
use PhpOffice\PhpPresentation\Slide;
27
use PhpOffice\PhpPresentation\Slide\AbstractSlide;
28
use PhpOffice\PhpPresentation\Slide\SlideLayout;
29
use PhpOffice\PhpPresentation\Slide\SlideMaster;
30
use PhpOffice\PhpPresentation\Shape\Drawing\Gd;
31
use PhpOffice\PhpPresentation\Style\Bullet;
32
use PhpOffice\PhpPresentation\Style\Border;
33
use PhpOffice\PhpPresentation\Style\Borders;
34
use PhpOffice\PhpPresentation\Style\Color;
35
use PhpOffice\PhpPresentation\Style\Fill;
36
use PhpOffice\PhpPresentation\Style\SchemeColor;
37
use PhpOffice\PhpPresentation\Style\TextStyle;
38
use PhpOffice\Common\XMLReader;
39
use PhpOffice\Common\Drawing as CommonDrawing;
40
use ZipArchive;
41
42
/**
43
 * Serialized format reader
44
 */
45
class PowerPoint2007 implements ReaderInterface
46
{
47
    /**
48
     * Output Object
49
     * @var PhpPresentation
50
     */
51
    protected $oPhpPresentation;
52
    /**
53
     * Output Object
54
     * @var \ZipArchive
55
     */
56
    protected $oZip;
57
    /**
58
     * @var array[]
59
     */
60
    protected $arrayRels = array();
61
    /**
62
     * @var SlideLayout[]
63
     */
64
    protected $arraySlideLayouts = array();
65
    /*
66
     * @var string
67
     */
68
    protected $filename;
69
    /*
70
     * @var string
71
     */
72
    protected $fileRels;
73
74
    /**
75
     * Can the current \PhpOffice\PhpPresentation\Reader\ReaderInterface read the file?
76
     *
77
     * @param  string $pFilename
78
     * @throws \Exception
79
     * @return boolean
80
     */
81 2
    public function canRead($pFilename)
82
    {
83 2
        return $this->fileSupportsUnserializePhpPresentation($pFilename);
84
    }
85
86
    /**
87
     * Does a file support UnserializePhpPresentation ?
88
     *
89
     * @param  string $pFilename
90
     * @throws \Exception
91
     * @return boolean
92
     */
93 9
    public function fileSupportsUnserializePhpPresentation($pFilename = '')
94
    {
95
        // Check if file exists
96 9
        if (!file_exists($pFilename)) {
97 2
            throw new \Exception("Could not open " . $pFilename . " for reading! File does not exist.");
98
        }
99
100 7
        $oZip = new ZipArchive();
101
        // Is it a zip ?
102 7
        if ($oZip->open($pFilename) === true) {
103
            // Is it an OpenXML Document ?
104
            // Is it a Presentation ?
105 5
            if (is_array($oZip->statName('[Content_Types].xml')) && is_array($oZip->statName('ppt/presentation.xml'))) {
106 5
                return true;
107
            }
108
        }
109 3
        return false;
110
    }
111
112
    /**
113
     * Loads PhpPresentation Serialized file
114
     *
115
     * @param  string $pFilename
116
     * @return \PhpOffice\PhpPresentation\PhpPresentation
117
     * @throws \Exception
118
     */
119 6
    public function load($pFilename)
120
    {
121
        // Unserialize... First make sure the file supports it!
122 6
        if (!$this->fileSupportsUnserializePhpPresentation($pFilename)) {
123 1
            throw new \Exception("Invalid file format for PhpOffice\PhpPresentation\Reader\PowerPoint2007: " . $pFilename . ".");
124
        }
125
126 4
        return $this->loadFile($pFilename);
127
    }
128
129
    /**
130
     * Load PhpPresentation Serialized file
131
     *
132
     * @param  string $pFilename
133
     * @return \PhpOffice\PhpPresentation\PhpPresentation
134
     */
135 4
    protected function loadFile($pFilename)
136
    {
137 4
        $this->oPhpPresentation = new PhpPresentation();
138 4
        $this->oPhpPresentation->removeSlideByIndex();
139 4
        $this->oPhpPresentation->setAllMasterSlides(array());
140 4
        $this->filename = $pFilename;
141
142 4
        $this->oZip = new ZipArchive();
143 4
        $this->oZip->open($this->filename);
144 4
        $docPropsCore = $this->oZip->getFromName('docProps/core.xml');
145 4
        if ($docPropsCore !== false) {
146 4
            $this->loadDocumentProperties($docPropsCore);
147
        }
148
149 4
        $docPropsCustom = $this->oZip->getFromName('docProps/custom.xml');
150 4
        if ($docPropsCustom !== false) {
151 1
            $this->loadCustomProperties($docPropsCustom);
152
        }
153
154 4
        $pptViewProps = $this->oZip->getFromName('ppt/viewProps.xml');
155 4
        if ($pptViewProps !== false) {
156 4
            $this->loadViewProperties($pptViewProps);
157
        }
158
159 4
        $pptPresentation = $this->oZip->getFromName('ppt/presentation.xml');
160 4
        if ($pptPresentation !== false) {
161 4
            $this->loadDocumentLayout($pptPresentation);
162 4
            $this->loadSlides($pptPresentation);
163
        }
164
165 4
        return $this->oPhpPresentation;
166
    }
167
168
    /**
169
     * Read Document Layout
170
     * @param $sPart
171
     */
172 4
    protected function loadDocumentLayout($sPart)
173
    {
174 4
        $xmlReader = new XMLReader();
175 4
        if ($xmlReader->getDomFromString($sPart)) {
176 4
            foreach ($xmlReader->getElements('/p:presentation/p:sldSz') as $oElement) {
177 4
                if (!($oElement instanceof \DOMElement)) {
178
                    continue;
179
                }
180 4
                $type = $oElement->getAttribute('type');
181 4
                $oLayout = $this->oPhpPresentation->getLayout();
182 4
                if ($type == DocumentLayout::LAYOUT_CUSTOM) {
183
                    $oLayout->setCX($oElement->getAttribute('cx'));
184
                    $oLayout->setCY($oElement->getAttribute('cy'));
185
                } else {
186 4
                    $oLayout->setDocumentLayout($type, true);
187 4
                    if ($oElement->getAttribute('cx') < $oElement->getAttribute('cy')) {
188 4
                        $oLayout->setDocumentLayout($type, false);
189
                    }
190
                }
191
            }
192
        }
193 4
    }
194
195
    /**
196
     * Read Document Properties
197
     * @param string $sPart
198
     */
199 4
    protected function loadDocumentProperties($sPart)
200
    {
201 4
        $xmlReader = new XMLReader();
202 4
        if ($xmlReader->getDomFromString($sPart)) {
203
            $arrayProperties = array(
204 4
                '/cp:coreProperties/dc:creator' => 'setCreator',
205
                '/cp:coreProperties/cp:lastModifiedBy' => 'setLastModifiedBy',
206
                '/cp:coreProperties/dc:title' => 'setTitle',
207
                '/cp:coreProperties/dc:description' => 'setDescription',
208
                '/cp:coreProperties/dc:subject' => 'setSubject',
209
                '/cp:coreProperties/cp:keywords' => 'setKeywords',
210
                '/cp:coreProperties/cp:category' => 'setCategory',
211
                '/cp:coreProperties/dcterms:created' => 'setCreated',
212
                '/cp:coreProperties/dcterms:modified' => 'setModified',
213
            );
214 4
            $oProperties = $this->oPhpPresentation->getDocumentProperties();
215 4
            foreach ($arrayProperties as $path => $property) {
216 4
                $oElement = $xmlReader->getElement($path);
217 4
                if ($oElement instanceof \DOMElement) {
218 4
                    if ($oElement->hasAttribute('xsi:type') && $oElement->getAttribute('xsi:type') == 'dcterms:W3CDTF') {
219 4
                        $oDateTime = new \DateTime();
220 4
                        $oDateTime->createFromFormat(\DateTime::W3C, $oElement->nodeValue);
221 4
                        $oProperties->{$property}($oDateTime->getTimestamp());
222
                    } else {
223 4
                        $oProperties->{$property}($oElement->nodeValue);
224
                    }
225
                }
226
            }
227
        }
228 4
    }
229
230
    /**
231
     * Read Custom Properties
232
     * @param string $sPart
233
     */
234 1
    protected function loadCustomProperties($sPart)
235
    {
236 1
        $xmlReader = new XMLReader();
237 1
        $sPart = str_replace(' xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"', '', $sPart);
238 1
        if ($xmlReader->getDomFromString($sPart)) {
239 1
            $pathMarkAsFinal = '/Properties/property[@pid="2"][@fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"][@name="_MarkAsFinal"]/vt:bool';
240 1
            if (is_object($oElement = $xmlReader->getElement($pathMarkAsFinal))) {
241 1
                if ($oElement->nodeValue == 'true') {
242 1
                    $this->oPhpPresentation->getPresentationProperties()->markAsFinal(true);
243
                }
244
            }
245
        }
246 1
    }
247
248
    /**
249
     * Read View Properties
250
     * @param string $sPart
251
     */
252 4
    protected function loadViewProperties($sPart)
253
    {
254 4
        $xmlReader = new XMLReader();
255 4
        if ($xmlReader->getDomFromString($sPart)) {
256 4
            $pathZoom = '/p:viewPr/p:slideViewPr/p:cSldViewPr/p:cViewPr/p:scale/a:sx';
257 4
            $oElement = $xmlReader->getElement($pathZoom);
258 4
            if ($oElement instanceof \DOMElement) {
259 3
                if ($oElement->hasAttribute('d') && $oElement->hasAttribute('n')) {
260 3
                    $this->oPhpPresentation->getPresentationProperties()->setZoom($oElement->getAttribute('n') / $oElement->getAttribute('d'));
261
                }
262
            }
263
        }
264 4
    }
265
266
    /**
267
     * Extract all slides
268
     */
269 4
    protected function loadSlides($sPart)
270
    {
271 4
        $xmlReader = new XMLReader();
272 4
        if ($xmlReader->getDomFromString($sPart)) {
273 4
            $fileRels = 'ppt/_rels/presentation.xml.rels';
274 4
            $this->loadRels($fileRels);
275
            // Load the Masterslides
276 4
            $this->loadMasterSlides($xmlReader, $fileRels);
277
            // Continue with loading the slides
278 4
            foreach ($xmlReader->getElements('/p:presentation/p:sldIdLst/p:sldId') as $oElement) {
279 4
                if (!($oElement instanceof \DOMElement)) {
280
                    continue;
281
                }
282 4
                $rId = $oElement->getAttribute('r:id');
283 4
                $pathSlide = isset($this->arrayRels[$fileRels][$rId]) ? $this->arrayRels[$fileRels][$rId]['Target'] : '';
284 4
                if (!empty($pathSlide)) {
285 4
                    $pptSlide = $this->oZip->getFromName('ppt/' . $pathSlide);
286 4
                    if ($pptSlide !== false) {
287 4
                        $slideRels = 'ppt/slides/_rels/' . basename($pathSlide) . '.rels';
288 4
                        $this->loadRels($slideRels);
289 4
                        $this->loadSlide($pptSlide, basename($pathSlide));
290 4
                        foreach ($this->arrayRels[$slideRels] as $rel) {
291 4
                            if ($rel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide') {
292 4
                                $this->loadSlideNote(basename($rel['Target']), $this->oPhpPresentation->getActiveSlide());
293
                            }
294
                        }
295
                    }
296
                }
297
            }
298
        }
299 4
    }
300
301
    /**
302
     * Extract all MasterSlides
303
     * @param XMLReader $xmlReader
304
     * @param string $fileRels
305
     */
306 4
    protected function loadMasterSlides(XMLReader $xmlReader, $fileRels)
307
    {
308
        // Get all the MasterSlide Id's from the presentation.xml file
309 4
        foreach ($xmlReader->getElements('/p:presentation/p:sldMasterIdLst/p:sldMasterId') as $oElement) {
310 4
            if (!($oElement instanceof \DOMElement)) {
311
                continue;
312
            }
313 4
            $rId = $oElement->getAttribute('r:id');
314
            // Get the path to the masterslide from the array with _rels files
315 4
            $pathMasterSlide = isset($this->arrayRels[$fileRels][$rId]) ?
316 4
                $this->arrayRels[$fileRels][$rId]['Target'] : '';
317 4
            if (!empty($pathMasterSlide)) {
318 4
                $pptMasterSlide = $this->oZip->getFromName('ppt/' . $pathMasterSlide);
319 4
                if ($pptMasterSlide !== false) {
320 4
                    $this->loadRels('ppt/slideMasters/_rels/' . basename($pathMasterSlide) . '.rels');
321 4
                    $this->loadMasterSlide($pptMasterSlide, basename($pathMasterSlide));
322
                }
323
            }
324
        }
325 4
    }
326
327
    /**
328
     * Extract data from slide
329
     * @param string $sPart
330
     * @param string $baseFile
331
     */
332 4
    protected function loadSlide($sPart, $baseFile)
333
    {
334 4
        $xmlReader = new XMLReader();
335 4
        if ($xmlReader->getDomFromString($sPart)) {
336
            // Core
337 4
            $oSlide = $this->oPhpPresentation->createSlide();
338 4
            $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1);
339 4
            $oSlide->setRelsIndex('ppt/slides/_rels/' . $baseFile . '.rels');
340
341
            // Background
342 4
            $oElement = $xmlReader->getElement('/p:sld/p:cSld/p:bg/p:bgPr');
343 4
            if ($oElement instanceof \DOMElement) {
344
                $oElementColor = $xmlReader->getElement('a:solidFill/a:srgbClr', $oElement);
345
                if ($oElementColor instanceof \DOMElement) {
346
                    // Color
347
                    $oColor = new Color();
348
                    $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
349
                    // Background
350
                    $oBackground = new Slide\Background\Color();
351
                    $oBackground->setColor($oColor);
352
                    // Slide Background
353
                    $oSlide = $this->oPhpPresentation->getActiveSlide();
354
                    $oSlide->setBackground($oBackground);
355
                }
356
                $oElementImage = $xmlReader->getElement('a:blipFill/a:blip', $oElement);
357
                if ($oElementImage instanceof \DOMElement) {
358
                    $relImg = $this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'][$oElementImage->getAttribute('r:embed')];
359
                    if (is_array($relImg)) {
360
                        // File
361
                        $pathImage = 'ppt/slides/' . $relImg['Target'];
362
                        $pathImage = explode('/', $pathImage);
363
                        foreach ($pathImage as $key => $partPath) {
364
                            if ($partPath == '..') {
365
                                unset($pathImage[$key - 1]);
366
                                unset($pathImage[$key]);
367
                            }
368
                        }
369
                        $pathImage = implode('/', $pathImage);
370
                        $contentImg = $this->oZip->getFromName($pathImage);
371
372
                        $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg');
373
                        file_put_contents($tmpBkgImg, $contentImg);
374
                        // Background
375
                        $oBackground = new Slide\Background\Image();
376
                        $oBackground->setPath($tmpBkgImg);
377
                        // Slide Background
378
                        $oSlide = $this->oPhpPresentation->getActiveSlide();
379
                        $oSlide->setBackground($oBackground);
380
                    }
381
                }
382
            }
383
384
            // Shapes
385 4
            $arrayElements = $xmlReader->getElements('/p:sld/p:cSld/p:spTree/*');
386 4
            if ($arrayElements) {
387 4
                $this->loadSlideShapes($oSlide, $arrayElements, $xmlReader);
388
            }
389
390
            // Layout
391 4
            $oSlide = $this->oPhpPresentation->getActiveSlide();
392 4
            foreach ($this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'] as $valueRel) {
393 4
                if ($valueRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout') {
394 4
                    $layoutBasename = basename($valueRel['Target']);
395 4
                    if (array_key_exists($layoutBasename, $this->arraySlideLayouts)) {
396 4
                        $oSlide->setSlideLayout($this->arraySlideLayouts[$layoutBasename]);
397
                    }
398 4
                    break;
399
                }
400
            }
401
        }
402 4
    }
403
404
    /**
405
     * @param string $sPart
406
     * @param string $baseFile
407
     */
408 4
    protected function loadMasterSlide($sPart, $baseFile)
409
    {
410 4
        $xmlReader = new XMLReader();
411 4
        if ($xmlReader->getDomFromString($sPart)) {
412
            // Core
413 4
            $oSlideMaster = $this->oPhpPresentation->createMasterSlide();
414 4
            $oSlideMaster->setTextStyles(new TextStyle(false));
415 4
            $oSlideMaster->setRelsIndex('ppt/slideMasters/_rels/' . $baseFile . '.rels');
416
417
            // Background
418 4
            $oElement = $xmlReader->getElement('/p:sldMaster/p:cSld/p:bg');
419 4
            if ($oElement instanceof \DOMElement) {
420 4
                $this->loadSlideBackground($xmlReader, $oElement, $oSlideMaster);
421
            }
422
423
            // Shapes
424 4
            $arrayElements = $xmlReader->getElements('/p:sldMaster/p:cSld/p:spTree/*');
425 4
            if ($arrayElements) {
426 4
                $this->loadSlideShapes($oSlideMaster, $arrayElements, $xmlReader);
427
            }
428
            // Header & Footer
429
430
            // ColorMapping
431 4
            $colorMap = array();
432 4
            $oElement = $xmlReader->getElement('/p:sldMaster/p:clrMap');
433 4
            if ($oElement->hasAttributes()) {
434 4
                foreach ($oElement->attributes as $attr) {
435 4
                    $colorMap[$attr->nodeName] = $attr->nodeValue;
436
                }
437 4
                $oSlideMaster->colorMap->setMapping($colorMap);
438
            }
439
440
            // TextStyles
441 4
            $arrayElementTxStyles = $xmlReader->getElements('/p:sldMaster/p:txStyles/*');
442 4
            if ($arrayElementTxStyles) {
443 4
                foreach ($arrayElementTxStyles as $oElementTxStyle) {
444 4
                    $arrayElementsLvl = $xmlReader->getElements('/p:sldMaster/p:txStyles/' . $oElementTxStyle->nodeName . '/*');
445 4
                    foreach ($arrayElementsLvl as $oElementLvl) {
446 4
                        if (!($oElementLvl instanceof \DOMElement) || $oElementLvl->nodeName == 'a:extLst') {
447 1
                            continue;
448
                        }
449 4
                        $oRTParagraph = new Paragraph();
450
451 4
                        if ($oElementLvl->nodeName == 'a:defPPr') {
452 3
                            $level = 0;
453
                        } else {
454 4
                            $level = str_replace('a:lvl', '', $oElementLvl->nodeName);
455 4
                            $level = str_replace('pPr', '', $level);
456
                        }
457
458 4
                        if ($oElementLvl->hasAttribute('algn')) {
459 4
                            $oRTParagraph->getAlignment()->setHorizontal($oElementLvl->getAttribute('algn'));
460
                        }
461 4
                        if ($oElementLvl->hasAttribute('marL')) {
462 4
                            $val = $oElementLvl->getAttribute('marL');
463 4
                            $val = CommonDrawing::emuToPixels($val);
464 4
                            $oRTParagraph->getAlignment()->setMarginLeft($val);
465
                        }
466 4
                        if ($oElementLvl->hasAttribute('marR')) {
467
                            $val = $oElementLvl->getAttribute('marR');
468
                            $val = CommonDrawing::emuToPixels($val);
469
                            $oRTParagraph->getAlignment()->setMarginRight($val);
470
                        }
471 4
                        if ($oElementLvl->hasAttribute('indent')) {
472 4
                            $val = $oElementLvl->getAttribute('indent');
473 4
                            $val = CommonDrawing::emuToPixels($val);
474 4
                            $oRTParagraph->getAlignment()->setIndent($val);
475
                        }
476 4
                        $oElementLvlDefRPR = $xmlReader->getElement('a:defRPr', $oElementLvl);
477 4
                        if ($oElementLvlDefRPR instanceof \DOMElement) {
478 4
                            if ($oElementLvlDefRPR->hasAttribute('sz')) {
479 4
                                $oRTParagraph->getFont()->setSize($oElementLvlDefRPR->getAttribute('sz') / 100);
480
                            }
481 4
                            if ($oElementLvlDefRPR->hasAttribute('b') && $oElementLvlDefRPR->getAttribute('b') == 1) {
482 1
                                $oRTParagraph->getFont()->setBold(true);
483
                            }
484 4
                            if ($oElementLvlDefRPR->hasAttribute('i') && $oElementLvlDefRPR->getAttribute('i') == 1) {
485
                                $oRTParagraph->getFont()->setItalic(true);
486
                            }
487
                        }
488 4
                        $oElementSchemeColor = $xmlReader->getElement('a:defRPr/a:solidFill/a:schemeClr', $oElementLvl);
489 4
                        if ($oElementSchemeColor instanceof \DOMElement) {
490 4
                            if ($oElementSchemeColor->hasAttribute('val')) {
491 4
                                $oSchemeColor = new SchemeColor();
492 4
                                $oSchemeColor->setValue($oElementSchemeColor->getAttribute('val'));
493 4
                                $oRTParagraph->getFont()->setColor($oSchemeColor);
494
                            }
495
                        }
496
497 4
                        switch ($oElementTxStyle->nodeName) {
498 4
                            case 'p:bodyStyle':
499 4
                                $oSlideMaster->getTextStyles()->setBodyStyleAtLvl($oRTParagraph, $level);
500 4
                                break;
501 4
                            case 'p:otherStyle':
502 4
                                $oSlideMaster->getTextStyles()->setOtherStyleAtLvl($oRTParagraph, $level);
503 4
                                break;
504 4
                            case 'p:titleStyle':
505 4
                                $oSlideMaster->getTextStyles()->setTitleStyleAtLvl($oRTParagraph, $level);
506 4
                                break;
507
                        }
508
                    }
509
                }
510
            }
511
512
            // Load the theme
513 4
            foreach ($this->arrayRels[$oSlideMaster->getRelsIndex()] as $arrayRel) {
514 4
                if ($arrayRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme') {
515 4
                    $pptTheme = $this->oZip->getFromName('ppt/' . substr($arrayRel['Target'], strrpos($arrayRel['Target'], '../') + 3));
516 4
                    if ($pptTheme !== false) {
517 4
                        $this->loadTheme($pptTheme, $oSlideMaster);
518
                    }
519 4
                    break;
520
                }
521
            }
522
523
            // Load the Layoutslide
524 4
            foreach ($xmlReader->getElements('/p:sldMaster/p:sldLayoutIdLst/p:sldLayoutId') as $oElement) {
525 4
                if (!($oElement instanceof \DOMElement)) {
526
                    continue;
527
                }
528 4
                $rId = $oElement->getAttribute('r:id');
529
                // Get the path to the masterslide from the array with _rels files
530 4
                $pathLayoutSlide = isset($this->arrayRels[$oSlideMaster->getRelsIndex()][$rId]) ?
531 4
                    $this->arrayRels[$oSlideMaster->getRelsIndex()][$rId]['Target'] : '';
532 4
                if (!empty($pathLayoutSlide)) {
533 4
                    $pptLayoutSlide = $this->oZip->getFromName('ppt/' . substr($pathLayoutSlide, strrpos($pathLayoutSlide, '../') + 3));
534 4
                    if ($pptLayoutSlide !== false) {
535 4
                        $this->loadRels('ppt/slideLayouts/_rels/' . basename($pathLayoutSlide) . '.rels');
536 4
                        $oSlideMaster->addSlideLayout(
537 4
                            $this->loadLayoutSlide($pptLayoutSlide, basename($pathLayoutSlide), $oSlideMaster)
538
                        );
539
                    }
540
                }
541
            }
542
        }
543 4
    }
544
545
    /**
546
     * @param string $sPart
547
     * @param string $baseFile
548
     * @param SlideMaster $oSlideMaster
549
     * @return SlideLayout|null
550
     */
551 4
    protected function loadLayoutSlide($sPart, $baseFile, SlideMaster $oSlideMaster)
552
    {
553 4
        $xmlReader = new XMLReader();
554 4
        if ($xmlReader->getDomFromString($sPart)) {
555
            // Core
556 4
            $oSlideLayout = new SlideLayout($oSlideMaster);
557 4
            $oSlideLayout->setRelsIndex('ppt/slideLayouts/_rels/' . $baseFile . '.rels');
558
559
            // Name
560 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:cSld');
561 4
            if ($oElement instanceof \DOMElement && $oElement->hasAttribute('name')) {
562 4
                $oSlideLayout->setLayoutName($oElement->getAttribute('name'));
563
            }
564
565
            // Background
566 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:cSld/p:bg');
567 4
            if ($oElement instanceof \DOMElement) {
568 1
                $this->loadSlideBackground($xmlReader, $oElement, $oSlideLayout);
569
            }
570
571
            // ColorMapping
572 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:clrMapOvr/a:overrideClrMapping');
573 4
            if ($oElement instanceof \DOMElement && $oElement->hasAttributes()) {
574 1
                $colorMap = array();
575 1
                foreach ($oElement->attributes as $attr) {
576 1
                    $colorMap[$attr->nodeName] = $attr->nodeValue;
577
                }
578 1
                $oSlideLayout->colorMap->setMapping($colorMap);
579
            }
580
581
            // Shapes
582 4
            $oElements = $xmlReader->getElements('/p:sldLayout/p:cSld/p:spTree/*');
583 4
            if ($oElements) {
584 4
                $this->loadSlideShapes($oSlideLayout, $oElements, $xmlReader);
585
            }
586 4
            $this->arraySlideLayouts[$baseFile] = &$oSlideLayout;
587 4
            return $oSlideLayout;
588
        }
589
        return null;
590
    }
591
592
    /**
593
     * @param string $sPart
594
     * @param SlideMaster $oSlideMaster
595
     */
596 4
    protected function loadTheme($sPart, SlideMaster $oSlideMaster)
597
    {
598 4
        $xmlReader = new XMLReader();
599 4
        if ($xmlReader->getDomFromString($sPart)) {
600 4
            $oElements = $xmlReader->getElements('/a:theme/a:themeElements/a:clrScheme/*');
601 4
            if ($oElements) {
602 4
                foreach ($oElements as $oElement) {
603 4
                    $oSchemeColor = new SchemeColor();
604 4
                    $oSchemeColor->setValue(str_replace('a:', '', $oElement->tagName));
605 4
                    $colorElement = $xmlReader->getElement('*', $oElement);
606 4
                    if ($colorElement instanceof \DOMElement) {
607 4
                        if ($colorElement->hasAttribute('lastClr')) {
608 4
                            $oSchemeColor->setRGB($colorElement->getAttribute('lastClr'));
609 4
                        } elseif ($colorElement->hasAttribute('val')) {
610 4
                            $oSchemeColor->setRGB($colorElement->getAttribute('val'));
611
                        }
612
                    }
613 4
                    $oSlideMaster->addSchemeColor($oSchemeColor);
614
                }
615
            }
616
        }
617 4
    }
618
619
    /**
620
     * @param XMLReader $xmlReader
621
     * @param \DOMElement $oElement
622
     * @param AbstractSlide $oSlide
623
     */
624 4
    protected function loadSlideBackground(XMLReader $xmlReader, \DOMElement $oElement, AbstractSlide $oSlide)
625
    {
626
        // Background color
627 4
        $oElementColor = $xmlReader->getElement('p:bgPr/a:solidFill/a:srgbClr', $oElement);
628 4
        if ($oElementColor instanceof \DOMElement) {
629
            // Color
630
            $oColor = new Color();
631
            $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
632
            // Background
633
            $oBackground = new Slide\Background\Color();
634
            $oBackground->setColor($oColor);
635
            // Slide Background
636
            $oSlide->setBackground($oBackground);
637
        }
638
639
        // Background scheme color
640 4
        $oElementSchemeColor = $xmlReader->getElement('p:bgRef/a:schemeClr', $oElement);
641 4
        if ($oElementSchemeColor instanceof \DOMElement) {
642
            // Color
643 4
            $oColor = new SchemeColor();
644 4
            $oColor->setValue($oElementSchemeColor->hasAttribute('val') ? $oElementSchemeColor->getAttribute('val') : null);
645
            // Background
646 4
            $oBackground = new Slide\Background\SchemeColor();
647 4
            $oBackground->setSchemeColor($oColor);
648
            // Slide Background
649 4
            $oSlide->setBackground($oBackground);
650
        }
651
652
        // Background image
653 4
        $oElementImage = $xmlReader->getElement('p:bgPr/a:blipFill/a:blip', $oElement);
654 4
        if ($oElementImage instanceof \DOMElement) {
655
            $relImg = $this->arrayRels[$oSlide->getRelsIndex()][$oElementImage->getAttribute('r:embed')];
656
            if (is_array($relImg)) {
657
                // File
658
                $pathImage = 'ppt/slides/' . $relImg['Target'];
659
                $pathImage = explode('/', $pathImage);
660
                foreach ($pathImage as $key => $partPath) {
661
                    if ($partPath == '..') {
662
                        unset($pathImage[$key - 1]);
663
                        unset($pathImage[$key]);
664
                    }
665
                }
666
                $pathImage = implode('/', $pathImage);
667
                $contentImg = $this->oZip->getFromName($pathImage);
668
669
                $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg');
670
                file_put_contents($tmpBkgImg, $contentImg);
671
                // Background
672
                $oBackground = new Slide\Background\Image();
673
                $oBackground->setPath($tmpBkgImg);
674
                // Slide Background
675
                $oSlide->setBackground($oBackground);
676
            }
677
        }
678 4
    }
679
680
    /**
681
     * @param string $baseFile
682
     * @param Slide $oSlide
683
     */
684
    protected function loadSlideNote($baseFile, Slide $oSlide)
685
    {
686
        $sPart = $this->oZip->getFromName('ppt/notesSlides/' . $baseFile);
687
        $xmlReader = new XMLReader();
688
        if ($xmlReader->getDomFromString($sPart)) {
689
            $oNote = $oSlide->getNote();
690
691
            $arrayElements = $xmlReader->getElements('/p:notes/p:cSld/p:spTree/*');
692
            if ($arrayElements) {
693
                $this->loadSlideShapes($oNote, $arrayElements, $xmlReader);
694
            }
695
        }
696
    }
697
698
    /**
699
     * @param XMLReader $document
700
     * @param \DOMElement $node
701
     * @param AbstractSlide $oSlide
702
     */
703 3
    protected function loadShapeDrawing(XMLReader $document, \DOMElement $node, AbstractSlide $oSlide)
704
    {
705
        // Core
706 3
        $oShape = new Gd();
707 3
        $oShape->getShadow()->setVisible(false);
708
        // Variables
709 3
        $fileRels = $oSlide->getRelsIndex();
710
711 3
        $oElement = $document->getElement('p:nvPicPr/p:cNvPr', $node);
712 3
        if ($oElement instanceof \DOMElement) {
713 3
            $oShape->setName($oElement->hasAttribute('name') ? $oElement->getAttribute('name') : '');
714 3
            $oShape->setDescription($oElement->hasAttribute('descr') ? $oElement->getAttribute('descr') : '');
715
        }
716
717 3
        $oElement = $document->getElement('p:blipFill/a:blip', $node);
718 3
        if ($oElement instanceof \DOMElement) {
719 3
            if ($oElement->hasAttribute('r:embed') && isset($this->arrayRels[$fileRels][$oElement->getAttribute('r:embed')]['Target'])) {
720 3
                $pathImage = 'ppt/slides/' . $this->arrayRels[$fileRels][$oElement->getAttribute('r:embed')]['Target'];
721 3
                $pathImage = explode('/', $pathImage);
722 3
                foreach ($pathImage as $key => $partPath) {
723 3
                    if ($partPath == '..') {
724 3
                        unset($pathImage[$key - 1]);
725 3
                        unset($pathImage[$key]);
726
                    }
727
                }
728 3
                $pathImage = implode('/', $pathImage);
729 3
                $imageFile = $this->oZip->getFromName($pathImage);
730 3
                if (!empty($imageFile)) {
731 3
                    $info = getimagesizefromstring($imageFile);
732 3
                    $oShape->setMimeType($info['mime']);
733 3
                    $oShape->setRenderingFunction(str_replace('/', '', $info['mime']));
734 3
                    $oShape->setImageResource(imagecreatefromstring($imageFile));
735
                }
736
            }
737
        }
738
739 3
        $oElement = $document->getElement('p:spPr/a:xfrm', $node);
740 3
        if ($oElement instanceof \DOMElement) {
741 3
            if ($oElement->hasAttribute('rot')) {
742 3
                $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
743
            }
744
        }
745
746 3
        $oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
747 3
        if ($oElement instanceof \DOMElement) {
748 3
            if ($oElement->hasAttribute('x')) {
749 3
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
750
            }
751 3
            if ($oElement->hasAttribute('y')) {
752 3
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
753
            }
754
        }
755
756 3
        $oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
757 3
        if ($oElement instanceof \DOMElement) {
758 3
            if ($oElement->hasAttribute('cx')) {
759 3
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
760
            }
761 3
            if ($oElement->hasAttribute('cy')) {
762 3
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
763
            }
764
        }
765
766 3
        $oElement = $document->getElement('p:spPr/a:effectLst', $node);
767 3
        if ($oElement instanceof \DOMElement) {
768 3
            $oShape->getShadow()->setVisible(true);
769
770 3
            $oSubElement = $document->getElement('a:outerShdw', $oElement);
771 3
            if ($oSubElement instanceof \DOMElement) {
772 3
                if ($oSubElement->hasAttribute('blurRad')) {
773 3
                    $oShape->getShadow()->setBlurRadius(CommonDrawing::emuToPixels($oSubElement->getAttribute('blurRad')));
774
                }
775 3
                if ($oSubElement->hasAttribute('dist')) {
776 3
                    $oShape->getShadow()->setDistance(CommonDrawing::emuToPixels($oSubElement->getAttribute('dist')));
777
                }
778 3
                if ($oSubElement->hasAttribute('dir')) {
779 3
                    $oShape->getShadow()->setDirection(CommonDrawing::angleToDegrees($oSubElement->getAttribute('dir')));
780
                }
781 3
                if ($oSubElement->hasAttribute('algn')) {
782 3
                    $oShape->getShadow()->setAlignment($oSubElement->getAttribute('algn'));
783
                }
784
            }
785
786 3
            $oSubElement = $document->getElement('a:outerShdw/a:srgbClr', $oElement);
787 3
            if ($oSubElement instanceof \DOMElement) {
788 3
                if ($oSubElement->hasAttribute('val')) {
789 3
                    $oColor = new Color();
790 3
                    $oColor->setRGB($oSubElement->getAttribute('val'));
791 3
                    $oShape->getShadow()->setColor($oColor);
792
                }
793
            }
794
795 3
            $oSubElement = $document->getElement('a:outerShdw/a:srgbClr/a:alpha', $oElement);
796 3
            if ($oSubElement instanceof \DOMElement) {
797 3
                if ($oSubElement->hasAttribute('val')) {
798 3
                    $oShape->getShadow()->setAlpha((int)$oSubElement->getAttribute('val') / 1000);
799
                }
800
            }
801
        }
802
803 3
        $oSlide->addShape($oShape);
804 3
    }
805
806
    /**
807
     * @param XMLReader $document
808
     * @param \DOMElement $node
809
     * @param AbstractSlide $oSlide
810
     * @throws \Exception
811
     */
812 4
    protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oSlide)
813
    {
814 4
        if (!$document->elementExists('p:txBody/a:p/a:r', $node)) {
815 4
            return;
816
        }
817
        // Core
818 4
        $oShape = $oSlide->createRichTextShape();
819 4
        $oShape->setParagraphs(array());
820
        // Variables
821 4
        if ($oSlide instanceof AbstractSlide) {
822 4
            $this->fileRels = $oSlide->getRelsIndex();
823
        }
824
825 4
        $oElement = $document->getElement('p:spPr/a:xfrm', $node);
826 4
        if ($oElement instanceof \DOMElement && $oElement->hasAttribute('rot')) {
827 4
            $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
828
        }
829
830 4
        $oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
831 4
        if ($oElement instanceof \DOMElement) {
832 4
            if ($oElement->hasAttribute('x')) {
833 4
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
834
            }
835 4
            if ($oElement->hasAttribute('y')) {
836 4
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
837
            }
838
        }
839
840 4
        $oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
841 4
        if ($oElement instanceof \DOMElement) {
842 4
            if ($oElement->hasAttribute('cx')) {
843 4
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
844
            }
845 4
            if ($oElement->hasAttribute('cy')) {
846 4
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
847
            }
848
        }
849
850 4
        $oElement = $document->getElement('p:nvSpPr/p:nvPr/p:ph', $node);
851 4
        if ($oElement instanceof \DOMElement) {
852 4
            if ($oElement->hasAttribute('type')) {
853 4
                $placeholder = new Placeholder($oElement->getAttribute('type'));
854 4
                $oShape->setPlaceHolder($placeholder);
855
            }
856
        }
857
858 4
        $arrayElements = $document->getElements('p:txBody/a:p', $node);
859 4
        foreach ($arrayElements as $oElement) {
860 4
            $this->loadParagraph($document, $oElement, $oShape);
861
        }
862
863 4
        if (count($oShape->getParagraphs()) > 0) {
864 4
            $oShape->setActiveParagraph(0);
865
        }
866 4
    }
867
868
    /**
869
     * @param XMLReader $document
870
     * @param \DOMElement $node
871
     * @param AbstractSlide $oSlide
872
     * @throws \Exception
873
     */
874
    protected function loadShapeTable(XMLReader $document, \DOMElement $node, AbstractSlide $oSlide)
875
    {
876
        $this->fileRels = $oSlide->getRelsIndex();
877
878
        $oShape = $oSlide->createTableShape();
879
880
        $oElement = $document->getElement('p:cNvPr', $node);
881
        if ($oElement instanceof \DOMElement) {
882
            if ($oElement->hasAttribute('name')) {
883
                $oShape->setName($oElement->getAttribute('name'));
884
            }
885
            if ($oElement->hasAttribute('descr')) {
886
                $oShape->setDescription($oElement->getAttribute('descr'));
887
            }
888
        }
889
890
        $oElement = $document->getElement('p:xfrm/a:off', $node);
891
        if ($oElement instanceof \DOMElement) {
892
            if ($oElement->hasAttribute('x')) {
893
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
894
            }
895
            if ($oElement->hasAttribute('y')) {
896
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
897
            }
898
        }
899
900
        $oElement = $document->getElement('p:xfrm/a:ext', $node);
901
        if ($oElement instanceof \DOMElement) {
902
            if ($oElement->hasAttribute('cx')) {
903
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
904
            }
905
            if ($oElement->hasAttribute('cy')) {
906
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
907
            }
908
        }
909
910
        $arrayElements = $document->getElements('a:graphic/a:graphicData/a:tbl/a:tblGrid/a:gridCol', $node);
911
        $oShape->setNumColumns($arrayElements->length);
912
        $oShape->createRow();
913
        foreach ($arrayElements as $key => $oElement) {
914
            if ($oElement instanceof \DOMElement && $oElement->getAttribute('w')) {
915
                $oShape->getRow(0)->getCell($key)->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('w')));
916
            }
917
        }
918
919
        $arrayElements = $document->getElements('a:graphic/a:graphicData/a:tbl/a:tr', $node);
920
        foreach ($arrayElements as $keyRow => $oElementRow) {
921
            if (!($oElementRow instanceof \DOMElement)) {
922
                continue;
923
            }
924
            $oRow = $oShape->getRow($keyRow, true);
925
            if (is_null($oRow)) {
926
                $oRow = $oShape->createRow();
927
            }
928
            if ($oElementRow->hasAttribute('h')) {
929
                $oRow->setHeight(CommonDrawing::emuToPixels($oElementRow->getAttribute('h')));
930
            }
931
            $arrayElementsCell = $document->getElements('a:tc', $oElementRow);
932
            foreach ($arrayElementsCell as $keyCell => $oElementCell) {
933
                if (!($oElementCell instanceof \DOMElement)) {
934
                    continue;
935
                }
936
                $oCell = $oRow->getCell($keyCell);
937
                $oCell->setParagraphs(array());
938
                if ($oElementCell->hasAttribute('gridSpan')) {
939
                    $oCell->setColSpan($oElementCell->getAttribute('gridSpan'));
940
                }
941
                if ($oElementCell->hasAttribute('rowSpan')) {
942
                    $oCell->setRowSpan($oElementCell->getAttribute('rowSpan'));
943
                }
944
945
                foreach ($document->getElements('a:txBody/a:p', $oElementCell) as $oElementPara) {
946
                    $this->loadParagraph($document, $oElementPara, $oCell);
0 ignored issues
show
Bug introduced by
It seems like $oCell defined by $oRow->getCell($keyCell) on line 936 can be null; however, PhpOffice\PhpPresentatio...nt2007::loadParagraph() 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...
947
                }
948
949
                $oElementTcPr = $document->getElement('a:tcPr', $oElementCell);
950
                if ($oElementTcPr instanceof \DOMElement) {
951
                    $numParagraphs = count($oCell->getParagraphs());
952
                    if ($numParagraphs > 0) {
953
                        if ($oElementTcPr->hasAttribute('vert')) {
954
                            $oCell->getParagraph(0)->getAlignment()->setTextDirection($oElementTcPr->getAttribute('vert'));
955
                        }
956
                        if ($oElementTcPr->hasAttribute('anchor')) {
957
                            $oCell->getParagraph(0)->getAlignment()->setVertical($oElementTcPr->getAttribute('anchor'));
958
                        }
959
                        if ($oElementTcPr->hasAttribute('marB')) {
960
                            $oCell->getParagraph(0)->getAlignment()->setMarginBottom($oElementTcPr->getAttribute('marB'));
961
                        }
962
                        if ($oElementTcPr->hasAttribute('marL')) {
963
                            $oCell->getParagraph(0)->getAlignment()->setMarginLeft($oElementTcPr->getAttribute('marL'));
964
                        }
965
                        if ($oElementTcPr->hasAttribute('marR')) {
966
                            $oCell->getParagraph(0)->getAlignment()->setMarginRight($oElementTcPr->getAttribute('marR'));
967
                        }
968
                        if ($oElementTcPr->hasAttribute('marT')) {
969
                            $oCell->getParagraph(0)->getAlignment()->setMarginTop($oElementTcPr->getAttribute('marT'));
970
                        }
971
                    }
972
973
                    $oFill = $this->loadStyleFill($document, $oElementTcPr);
974
                    if ($oFill instanceof Fill) {
975
                        $oCell->setFill($oFill);
976
                    }
977
978
                    $oBorders = new Borders();
979
                    $oElementBorderL = $document->getElement('a:lnL', $oElementTcPr);
980
                    if ($oElementBorderL instanceof \DOMElement) {
981
                        $this->loadStyleBorder($document, $oElementBorderL, $oBorders->getLeft());
982
                    }
983
                    $oElementBorderR = $document->getElement('a:lnR', $oElementTcPr);
984
                    if ($oElementBorderR instanceof \DOMElement) {
985
                        $this->loadStyleBorder($document, $oElementBorderR, $oBorders->getRight());
986
                    }
987
                    $oElementBorderT = $document->getElement('a:lnT', $oElementTcPr);
988
                    if ($oElementBorderT instanceof \DOMElement) {
989
                        $this->loadStyleBorder($document, $oElementBorderT, $oBorders->getTop());
990
                    }
991
                    $oElementBorderB = $document->getElement('a:lnB', $oElementTcPr);
992
                    if ($oElementBorderB instanceof \DOMElement) {
993
                        $this->loadStyleBorder($document, $oElementBorderB, $oBorders->getBottom());
994
                    }
995
                    $oElementBorderDiagDown = $document->getElement('a:lnTlToBr', $oElementTcPr);
996
                    if ($oElementBorderDiagDown instanceof \DOMElement) {
997
                        $this->loadStyleBorder($document, $oElementBorderDiagDown, $oBorders->getDiagonalDown());
998
                    }
999
                    $oElementBorderDiagUp = $document->getElement('a:lnBlToTr', $oElementTcPr);
1000
                    if ($oElementBorderDiagUp instanceof \DOMElement) {
1001
                        $this->loadStyleBorder($document, $oElementBorderDiagUp, $oBorders->getDiagonalUp());
1002
                    }
1003
                    $oCell->setBorders($oBorders);
1004
                }
1005
            }
1006
        }
1007
    }
1008
1009
    /**
1010
     * @param XMLReader $document
1011
     * @param \DOMElement $oElement
1012
     * @param Cell|RichText $oShape
1013
     * @throws \Exception
1014
     */
1015 4
    protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oShape)
1016
    {
1017
        // Core
1018 4
        $oParagraph = $oShape->createParagraph();
1019 4
        $oParagraph->setRichTextElements(array());
1020
1021 4
        $oSubElement = $document->getElement('a:pPr', $oElement);
1022 4
        if ($oSubElement instanceof \DOMElement) {
1023 4
            if ($oSubElement->hasAttribute('algn')) {
1024 3
                $oParagraph->getAlignment()->setHorizontal($oSubElement->getAttribute('algn'));
1025
            }
1026 4
            if ($oSubElement->hasAttribute('fontAlgn')) {
1027 3
                $oParagraph->getAlignment()->setVertical($oSubElement->getAttribute('fontAlgn'));
1028
            }
1029 4
            if ($oSubElement->hasAttribute('marL')) {
1030 3
                $oParagraph->getAlignment()->setMarginLeft(CommonDrawing::emuToPixels($oSubElement->getAttribute('marL')));
1031
            }
1032 4
            if ($oSubElement->hasAttribute('marR')) {
1033 3
                $oParagraph->getAlignment()->setMarginRight(CommonDrawing::emuToPixels($oSubElement->getAttribute('marR')));
1034
            }
1035 4
            if ($oSubElement->hasAttribute('indent')) {
1036 3
                $oParagraph->getAlignment()->setIndent(CommonDrawing::emuToPixels($oSubElement->getAttribute('indent')));
1037
            }
1038 4
            if ($oSubElement->hasAttribute('lvl')) {
1039 4
                $oParagraph->getAlignment()->setLevel($oSubElement->getAttribute('lvl'));
1040
            }
1041
1042 4
            $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NONE);
1043
1044 4
            $oElementBuFont = $document->getElement('a:buFont', $oSubElement);
1045 4
            if ($oElementBuFont instanceof \DOMElement) {
1046 3
                if ($oElementBuFont->hasAttribute('typeface')) {
1047 3
                    $oParagraph->getBulletStyle()->setBulletFont($oElementBuFont->getAttribute('typeface'));
1048
                }
1049
            }
1050 4
            $oElementBuChar = $document->getElement('a:buChar', $oSubElement);
1051 4
            if ($oElementBuChar instanceof \DOMElement) {
1052 3
                $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_BULLET);
1053 3
                if ($oElementBuChar->hasAttribute('char')) {
1054 3
                    $oParagraph->getBulletStyle()->setBulletChar($oElementBuChar->getAttribute('char'));
1055
                }
1056
            }
1057 4
            $oElementBuAutoNum = $document->getElement('a:buAutoNum', $oSubElement);
1058 4
            if ($oElementBuAutoNum instanceof \DOMElement) {
1059
                $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NUMERIC);
1060
                if ($oElementBuAutoNum->hasAttribute('type')) {
1061
                    $oParagraph->getBulletStyle()->setBulletNumericStyle($oElementBuAutoNum->getAttribute('type'));
1062
                }
1063
                if ($oElementBuAutoNum->hasAttribute('startAt') && $oElementBuAutoNum->getAttribute('startAt') != 1) {
1064
                    $oParagraph->getBulletStyle()->setBulletNumericStartAt($oElementBuAutoNum->getAttribute('startAt'));
1065
                }
1066
            }
1067 4
            $oElementBuClr = $document->getElement('a:buClr', $oSubElement);
1068 4
            if ($oElementBuClr instanceof \DOMElement) {
1069
                $oColor = new Color();
1070
                /**
1071
                 * @todo Create protected for reading Color
1072
                 */
1073
                $oElementColor = $document->getElement('a:srgbClr', $oElementBuClr);
1074
                if ($oElementColor instanceof \DOMElement) {
1075
                    $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
1076
                }
1077
                $oParagraph->getBulletStyle()->setBulletColor($oColor);
1078
            }
1079
        }
1080 4
        $arraySubElements = $document->getElements('(a:r|a:br)', $oElement);
1081 4
        foreach ($arraySubElements as $oSubElement) {
1082 4
            if ($oSubElement->tagName == 'a:br') {
1083 3
                $oParagraph->createBreak();
1084
            }
1085 4
            if ($oSubElement->tagName == 'a:r') {
1086 4
                $oElementrPr = $document->getElement('a:rPr', $oSubElement);
1087 4
                if (is_object($oElementrPr)) {
1088 4
                    $oText = $oParagraph->createTextRun();
1089
1090 4
                    if ($oElementrPr->hasAttribute('b')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1091 3
                        $att = $oElementrPr->getAttribute('b');
1092 3
                        $oText->getFont()->setBold($att == 'true' || $att == '1' ? true : false);
1093
                    }
1094 4
                    if ($oElementrPr->hasAttribute('i')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1095 3
                        $att = $oElementrPr->getAttribute('i');
1096 3
                        $oText->getFont()->setItalic($att == 'true' || $att == '1' ? true : false);
1097
                    }
1098 4
                    if ($oElementrPr->hasAttribute('strike')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1099 3
                        $oText->getFont()->setStrikethrough($oElementrPr->getAttribute('strike') == 'noStrike' ? false : true);
1100
                    }
1101 4
                    if ($oElementrPr->hasAttribute('sz')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1102 3
                        $oText->getFont()->setSize((int)($oElementrPr->getAttribute('sz') / 100));
1103
                    }
1104 4
                    if ($oElementrPr->hasAttribute('u')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1105 3
                        $oText->getFont()->setUnderline($oElementrPr->getAttribute('u'));
1106
                    }
1107
                    // Color
1108 4
                    $oElementSrgbClr = $document->getElement('a:solidFill/a:srgbClr', $oElementrPr);
0 ignored issues
show
Documentation introduced by
$oElementrPr is of type object<DOMNode>, but the function expects a null|object<DOMElement>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1109 4
                    if (is_object($oElementSrgbClr) && $oElementSrgbClr->hasAttribute('val')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1110 3
                        $oColor = new Color();
1111 3
                        $oColor->setRGB($oElementSrgbClr->getAttribute('val'));
1112 3
                        $oText->getFont()->setColor($oColor);
1113
                    }
1114
                    // Hyperlink
1115 4
                    $oElementHlinkClick = $document->getElement('a:hlinkClick', $oElementrPr);
0 ignored issues
show
Documentation introduced by
$oElementrPr is of type object<DOMNode>, but the function expects a null|object<DOMElement>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1116 4
                    if (is_object($oElementHlinkClick)) {
1117 3
                        if ($oElementHlinkClick->hasAttribute('tooltip')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1118 3
                            $oText->getHyperlink()->setTooltip($oElementHlinkClick->getAttribute('tooltip'));
1119
                        }
1120 3
                        if ($oElementHlinkClick->hasAttribute('r:id') && isset($this->arrayRels[$this->fileRels][$oElementHlinkClick->getAttribute('r:id')]['Target'])) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
1121 3
                            $oText->getHyperlink()->setUrl($this->arrayRels[$this->fileRels][$oElementHlinkClick->getAttribute('r:id')]['Target']);
1122
                        }
1123
                    }
1124
                    //} else {
1125
                    // $oText = $oParagraph->createText();
1126
1127 4
                    $oSubSubElement = $document->getElement('a:t', $oSubElement);
1128 4
                    $oText->setText($oSubSubElement->nodeValue);
1129
                }
1130
            }
1131
        }
1132 4
    }
1133
1134
    /**
1135
     * @param XMLReader $xmlReader
1136
     * @param \DOMElement $oElement
1137
     * @param Border $oBorder
1138
     */
1139
    protected function loadStyleBorder(XMLReader $xmlReader, \DOMElement $oElement, Border $oBorder)
1140
    {
1141
        if ($oElement->hasAttribute('w')) {
1142
            $oBorder->setLineWidth($oElement->getAttribute('w') / 12700);
1143
        }
1144
        if ($oElement->hasAttribute('cmpd')) {
1145
            $oBorder->setLineStyle($oElement->getAttribute('cmpd'));
1146
        }
1147
1148
        $oElementNoFill = $xmlReader->getElement('a:noFill', $oElement);
1149
        if ($oElementNoFill instanceof \DOMElement && $oBorder->getLineStyle() == Border::LINE_SINGLE) {
1150
            $oBorder->setLineStyle(Border::LINE_NONE);
1151
        }
1152
1153
        $oElementColor = $xmlReader->getElement('a:solidFill/a:srgbClr', $oElement);
1154
        if ($oElementColor instanceof \DOMElement) {
1155
            $oBorder->setColor($this->loadStyleColor($xmlReader, $oElementColor));
1156
        }
1157
1158
        $oElementDashStyle = $xmlReader->getElement('a:prstDash', $oElement);
1159
        if ($oElementDashStyle instanceof \DOMElement && $oElementDashStyle->hasAttribute('val')) {
1160
            $oBorder->setDashStyle($oElementDashStyle->getAttribute('val'));
1161
        }
1162
    }
1163
1164
    /**
1165
     * @param XMLReader $xmlReader
1166
     * @param \DOMElement $oElement
1167
     * @return Color
1168
     */
1169
    protected function loadStyleColor(XMLReader $xmlReader, \DOMElement $oElement)
1170
    {
1171
        $oColor = new Color();
1172
        $oColor->setRGB($oElement->getAttribute('val'));
1173
        $oElementAlpha = $xmlReader->getElement('a:alpha', $oElement);
1174
        if ($oElementAlpha instanceof \DOMElement && $oElementAlpha->hasAttribute('val')) {
1175
            $alpha = strtoupper(dechex((($oElementAlpha->getAttribute('val') / 1000) / 100) * 255));
1176
            $oColor->setRGB($oElement->getAttribute('val'), $alpha);
1177
        }
1178
        return $oColor;
1179
    }
1180
1181
    /**
1182
     * @param XMLReader $xmlReader
1183
     * @param \DOMElement $oElement
1184
     * @return null|Fill
1185
     */
1186
    protected function loadStyleFill(XMLReader $xmlReader, \DOMElement $oElement)
1187
    {
1188
        // Gradient fill
1189
        $oElementFill = $xmlReader->getElement('a:gradFill', $oElement);
1190
        if ($oElementFill instanceof \DOMElement) {
1191
            $oFill = new Fill();
1192
            $oFill->setFillType(Fill::FILL_GRADIENT_LINEAR);
1193
1194
            $oElementColor = $xmlReader->getElement('a:gsLst/a:gs[@pos="0"]/a:srgbClr', $oElementFill);
1195
            if ($oElementColor instanceof \DOMElement && $oElementColor->hasAttribute('val')) {
1196
                $oFill->setStartColor($this->loadStyleColor($xmlReader, $oElementColor));
1197
            }
1198
1199
            $oElementColor = $xmlReader->getElement('a:gsLst/a:gs[@pos="100000"]/a:srgbClr', $oElementFill);
1200
            if ($oElementColor instanceof \DOMElement && $oElementColor->hasAttribute('val')) {
1201
                $oFill->setEndColor($this->loadStyleColor($xmlReader, $oElementColor));
1202
            }
1203
1204
            $oRotation = $xmlReader->getElement('a:lin', $oElementFill);
1205
            if ($oRotation instanceof \DOMElement && $oRotation->hasAttribute('ang')) {
1206
                $oFill->setRotation(CommonDrawing::angleToDegrees($oRotation->getAttribute('ang')));
1207
            }
1208
            return $oFill;
1209
        }
1210
1211
        // Solid fill
1212
        $oElementFill = $xmlReader->getElement('a:solidFill', $oElement);
1213
        if ($oElementFill instanceof \DOMElement) {
1214
            $oFill = new Fill();
1215
            $oFill->setFillType(Fill::FILL_SOLID);
1216
1217
            $oElementColor = $xmlReader->getElement('a:srgbClr', $oElementFill);
1218
            if ($oElementColor instanceof \DOMElement) {
1219
                $oFill->setStartColor($this->loadStyleColor($xmlReader, $oElementColor));
1220
            }
1221
            return $oFill;
1222
        }
1223
        return null;
1224
    }
1225
1226
    /**
1227
     * @param string $fileRels
1228
     * @return string
1229
     */
1230 4
    protected function loadRels($fileRels)
1231
    {
1232 4
        $sPart = $this->oZip->getFromName($fileRels);
1233 4
        if ($sPart !== false) {
1234 4
            $xmlReader = new XMLReader();
1235 4
            if ($xmlReader->getDomFromString($sPart)) {
1236 4
                foreach ($xmlReader->getElements('*') as $oNode) {
1237 4
                    if (!($oNode instanceof \DOMElement)) {
1238
                        continue;
1239
                    }
1240 4
                    $this->arrayRels[$fileRels][$oNode->getAttribute('Id')] = array(
1241 4
                        'Target' => $oNode->getAttribute('Target'),
1242 4
                        'Type' => $oNode->getAttribute('Type'),
1243
                    );
1244
                }
1245
            }
1246
        }
1247 4
    }
1248
1249
    /**
1250
     * @param $oSlide
1251
     * @param \DOMNodeList $oElements
1252
     * @param XMLReader $xmlReader
1253
     * @internal param $baseFile
1254
     */
1255 4
    protected function loadSlideShapes($oSlide, $oElements, $xmlReader)
1256
    {
1257 4
        foreach ($oElements as $oNode) {
1258 4
            switch ($oNode->tagName) {
1259 4
                case 'p:graphicFrame':
1260
                    $this->loadShapeTable($xmlReader, $oNode, $oSlide);
1261
                    break;
1262 4
                case 'p:pic':
1263 3
                    $this->loadShapeDrawing($xmlReader, $oNode, $oSlide);
1264 3
                    break;
1265 4
                case 'p:sp':
1266 4
                    $this->loadShapeRichText($xmlReader, $oNode, $oSlide);
1267 4
                    break;
1268 4
                default:
1269
                    //var_export($oNode->tagName);
1270
            }
1271
        }
1272 4
    }
1273
}
1274