Completed
Push — develop ( eaad91...fa28cf )
by Franck
15s queued 11s
created

PowerPoint2007   F

Complexity

Total Complexity 282

Size/Duplication

Total Lines 1267
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 29

Test Coverage

Coverage 68.14%

Importance

Changes 0
Metric Value
wmc 282
lcom 1
cbo 29
dl 0
loc 1267
ccs 462
cts 678
cp 0.6814
rs 0.8
c 0
b 0
f 0

25 Methods

Rating   Name   Duplication   Size   Complexity  
A canRead() 0 4 1
A fileSupportsUnserializePhpPresentation() 0 18 5
A load() 0 9 2
A loadFile() 0 32 5
B loadDocumentLayout() 0 22 6
B loadDocumentProperties() 0 30 6
A loadCustomProperties() 0 13 4
A loadViewProperties() 0 13 5
B loadSlides() 0 31 9
B loadMasterSlides() 0 20 6
C loadSlide() 0 83 15
F loadMasterSlide() 0 136 35
B loadLayoutSlide() 0 40 9
B loadTheme() 0 22 7
B loadSlideBackground() 0 55 9
A loadSlideNote() 0 13 3
F loadShapeDrawing() 0 116 33
F loadShapeRichText() 0 55 15
F loadShapeTable() 0 134 37
F loadParagraph() 0 118 39
B loadStyleBorder() 0 24 8
A loadStyleColor() 0 11 3
B loadStyleFill() 0 39 10
A loadRels() 0 18 5
A loadSlideShapes() 0 18 5

How to fix   Complexity   

Complex Class

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

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

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

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
     * @throws \Exception
135
     */
136 4
    protected function loadFile($pFilename)
137
    {
138 4
        $this->oPhpPresentation = new PhpPresentation();
139 4
        $this->oPhpPresentation->removeSlideByIndex();
140 4
        $this->oPhpPresentation->setAllMasterSlides(array());
141 4
        $this->filename = $pFilename;
142
143 4
        $this->oZip = new ZipArchive();
144 4
        $this->oZip->open($this->filename);
145 4
        $docPropsCore = $this->oZip->getFromName('docProps/core.xml');
146 4
        if ($docPropsCore !== false) {
147 4
            $this->loadDocumentProperties($docPropsCore);
148
        }
149
150 4
        $docPropsCustom = $this->oZip->getFromName('docProps/custom.xml');
151 4
        if ($docPropsCustom !== false) {
152 1
            $this->loadCustomProperties($docPropsCustom);
153
        }
154
155 4
        $pptViewProps = $this->oZip->getFromName('ppt/viewProps.xml');
156 4
        if ($pptViewProps !== false) {
157 4
            $this->loadViewProperties($pptViewProps);
158
        }
159
160 4
        $pptPresentation = $this->oZip->getFromName('ppt/presentation.xml');
161 4
        if ($pptPresentation !== false) {
162 4
            $this->loadDocumentLayout($pptPresentation);
163 4
            $this->loadSlides($pptPresentation);
164
        }
165
166 4
        return $this->oPhpPresentation;
167
    }
168
169
    /**
170
     * Read Document Layout
171
     * @param $sPart
172
     */
173 4
    protected function loadDocumentLayout($sPart)
174
    {
175 4
        $xmlReader = new XMLReader();
176 4
        if ($xmlReader->getDomFromString($sPart)) {
177 4
            foreach ($xmlReader->getElements('/p:presentation/p:sldSz') as $oElement) {
178 4
                if (!($oElement instanceof \DOMElement)) {
179
                    continue;
180
                }
181 4
                $type = $oElement->getAttribute('type');
182 4
                $oLayout = $this->oPhpPresentation->getLayout();
183 4
                if ($type == DocumentLayout::LAYOUT_CUSTOM) {
184
                    $oLayout->setCX($oElement->getAttribute('cx'));
185
                    $oLayout->setCY($oElement->getAttribute('cy'));
186
                } else {
187 4
                    $oLayout->setDocumentLayout($type, true);
188 4
                    if ($oElement->getAttribute('cx') < $oElement->getAttribute('cy')) {
189 4
                        $oLayout->setDocumentLayout($type, false);
190
                    }
191
                }
192
            }
193
        }
194 4
    }
195
196
    /**
197
     * Read Document Properties
198
     * @param string $sPart
199
     */
200 4
    protected function loadDocumentProperties($sPart)
201
    {
202 4
        $xmlReader = new XMLReader();
203 4
        if ($xmlReader->getDomFromString($sPart)) {
204
            $arrayProperties = array(
205 4
                '/cp:coreProperties/dc:creator' => 'setCreator',
206
                '/cp:coreProperties/cp:lastModifiedBy' => 'setLastModifiedBy',
207
                '/cp:coreProperties/dc:title' => 'setTitle',
208
                '/cp:coreProperties/dc:description' => 'setDescription',
209
                '/cp:coreProperties/dc:subject' => 'setSubject',
210
                '/cp:coreProperties/cp:keywords' => 'setKeywords',
211
                '/cp:coreProperties/cp:category' => 'setCategory',
212
                '/cp:coreProperties/dcterms:created' => 'setCreated',
213
                '/cp:coreProperties/dcterms:modified' => 'setModified',
214
            );
215 4
            $oProperties = $this->oPhpPresentation->getDocumentProperties();
216 4
            foreach ($arrayProperties as $path => $property) {
217 4
                $oElement = $xmlReader->getElement($path);
218 4
                if ($oElement instanceof \DOMElement) {
219 4
                    if ($oElement->hasAttribute('xsi:type') && $oElement->getAttribute('xsi:type') == 'dcterms:W3CDTF') {
220 4
                        $oDateTime = new \DateTime();
221 4
                        $oDateTime->createFromFormat(\DateTime::W3C, $oElement->nodeValue);
222 4
                        $oProperties->{$property}($oDateTime->getTimestamp());
223
                    } else {
224 4
                        $oProperties->{$property}($oElement->nodeValue);
225
                    }
226
                }
227
            }
228
        }
229 4
    }
230
231
    /**
232
     * Read Custom Properties
233
     * @param string $sPart
234
     */
235 1
    protected function loadCustomProperties($sPart)
236
    {
237 1
        $xmlReader = new XMLReader();
238 1
        $sPart = str_replace(' xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"', '', $sPart);
239 1
        if ($xmlReader->getDomFromString($sPart)) {
240 1
            $pathMarkAsFinal = '/Properties/property[@pid="2"][@fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"][@name="_MarkAsFinal"]/vt:bool';
241 1
            if (is_object($oElement = $xmlReader->getElement($pathMarkAsFinal))) {
242 1
                if ($oElement->nodeValue == 'true') {
243 1
                    $this->oPhpPresentation->getPresentationProperties()->markAsFinal(true);
244
                }
245
            }
246
        }
247 1
    }
248
249
    /**
250
     * Read View Properties
251
     * @param string $sPart
252
     */
253 4
    protected function loadViewProperties($sPart)
254
    {
255 4
        $xmlReader = new XMLReader();
256 4
        if ($xmlReader->getDomFromString($sPart)) {
257 4
            $pathZoom = '/p:viewPr/p:slideViewPr/p:cSldViewPr/p:cViewPr/p:scale/a:sx';
258 4
            $oElement = $xmlReader->getElement($pathZoom);
259 4
            if ($oElement instanceof \DOMElement) {
260 3
                if ($oElement->hasAttribute('d') && $oElement->hasAttribute('n')) {
261 3
                    $this->oPhpPresentation->getPresentationProperties()->setZoom($oElement->getAttribute('n') / $oElement->getAttribute('d'));
262
                }
263
            }
264
        }
265 4
    }
266
267
    /**
268
     * Extract all slides
269
     * @param $sPart
270
     * @throws \Exception
271
     */
272 4
    protected function loadSlides($sPart)
273
    {
274 4
        $xmlReader = new XMLReader();
275 4
        if ($xmlReader->getDomFromString($sPart)) {
276 4
            $fileRels = 'ppt/_rels/presentation.xml.rels';
277 4
            $this->loadRels($fileRels);
278
            // Load the Masterslides
279 4
            $this->loadMasterSlides($xmlReader, $fileRels);
280
            // Continue with loading the slides
281 4
            foreach ($xmlReader->getElements('/p:presentation/p:sldIdLst/p:sldId') as $oElement) {
282 4
                if (!($oElement instanceof \DOMElement)) {
283
                    continue;
284
                }
285 4
                $rId = $oElement->getAttribute('r:id');
286 4
                $pathSlide = isset($this->arrayRels[$fileRels][$rId]) ? $this->arrayRels[$fileRels][$rId]['Target'] : '';
287 4
                if (!empty($pathSlide)) {
288 4
                    $pptSlide = $this->oZip->getFromName('ppt/' . $pathSlide);
289 4
                    if ($pptSlide !== false) {
290 4
                        $slideRels = 'ppt/slides/_rels/' . basename($pathSlide) . '.rels';
291 4
                        $this->loadRels($slideRels);
292 4
                        $this->loadSlide($pptSlide, basename($pathSlide));
293 4
                        foreach ($this->arrayRels[$slideRels] as $rel) {
294 4
                            if ($rel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide') {
295 4
                                $this->loadSlideNote(basename($rel['Target']), $this->oPhpPresentation->getActiveSlide());
296
                            }
297
                        }
298
                    }
299
                }
300
            }
301
        }
302 4
    }
303
304
    /**
305
     * Extract all MasterSlides
306
     * @param XMLReader $xmlReader
307
     * @param string $fileRels
308
     * @throws \Exception
309
     */
310 4
    protected function loadMasterSlides(XMLReader $xmlReader, $fileRels)
311
    {
312
        // Get all the MasterSlide Id's from the presentation.xml file
313 4
        foreach ($xmlReader->getElements('/p:presentation/p:sldMasterIdLst/p:sldMasterId') as $oElement) {
314 4
            if (!($oElement instanceof \DOMElement)) {
315
                continue;
316
            }
317 4
            $rId = $oElement->getAttribute('r:id');
318
            // Get the path to the masterslide from the array with _rels files
319 4
            $pathMasterSlide = isset($this->arrayRels[$fileRels][$rId]) ?
320 4
                $this->arrayRels[$fileRels][$rId]['Target'] : '';
321 4
            if (!empty($pathMasterSlide)) {
322 4
                $pptMasterSlide = $this->oZip->getFromName('ppt/' . $pathMasterSlide);
323 4
                if ($pptMasterSlide !== false) {
324 4
                    $this->loadRels('ppt/slideMasters/_rels/' . basename($pathMasterSlide) . '.rels');
325 4
                    $this->loadMasterSlide($pptMasterSlide, basename($pathMasterSlide));
326
                }
327
            }
328
        }
329 4
    }
330
331
    /**
332
     * Extract data from slide
333
     * @param string $sPart
334
     * @param string $baseFile
335
     * @throws \Exception
336
     */
337 4
    protected function loadSlide($sPart, $baseFile)
338
    {
339 4
        $xmlReader = new XMLReader();
340 4
        if ($xmlReader->getDomFromString($sPart)) {
341
            // Core
342 4
            $oSlide = $this->oPhpPresentation->createSlide();
343 4
            $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1);
344 4
            $oSlide->setRelsIndex('ppt/slides/_rels/' . $baseFile . '.rels');
345
346
            // Background
347 4
            $oElement = $xmlReader->getElement('/p:sld/p:cSld/p:bg/p:bgPr');
348 4
            if ($oElement instanceof \DOMElement) {
349
                $oElementColor = $xmlReader->getElement('a:solidFill/a:srgbClr', $oElement);
350
                if ($oElementColor instanceof \DOMElement) {
351
                    // Color
352
                    $oColor = new Color();
353
                    $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
354
                    // Background
355
                    $oBackground = new Slide\Background\Color();
356
                    $oBackground->setColor($oColor);
357
                    // Slide Background
358
                    $oSlide = $this->oPhpPresentation->getActiveSlide();
359
                    $oSlide->setBackground($oBackground);
360
                }
361
                $oElementColor = $xmlReader->getElement('a:solidFill/a:schemeClr', $oElement);
362
                if ($oElementColor instanceof \DOMElement) {
363
                    // Color
364
                    $oColor = new SchemeColor();
365
                    $oColor->setValue($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
366
                    // Background
367
                    $oBackground = new Slide\Background\SchemeColor();
368
                    $oBackground->setSchemeColor($oColor);
369
                    // Slide Background
370
                    $oSlide = $this->oPhpPresentation->getActiveSlide();
371
                    $oSlide->setBackground($oBackground);
372
                }
373
                $oElementImage = $xmlReader->getElement('a:blipFill/a:blip', $oElement);
374
                if ($oElementImage instanceof \DOMElement) {
375
                    $relImg = $this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'][$oElementImage->getAttribute('r:embed')];
376
                    if (is_array($relImg)) {
377
                        // File
378
                        $pathImage = 'ppt/slides/' . $relImg['Target'];
379
                        $pathImage = explode('/', $pathImage);
380
                        foreach ($pathImage as $key => $partPath) {
381
                            if ($partPath == '..') {
382
                                unset($pathImage[$key - 1]);
383
                                unset($pathImage[$key]);
384
                            }
385
                        }
386
                        $pathImage = implode('/', $pathImage);
387
                        $contentImg = $this->oZip->getFromName($pathImage);
388
389
                        $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg');
390
                        file_put_contents($tmpBkgImg, $contentImg);
391
                        // Background
392
                        $oBackground = new Slide\Background\Image();
393
                        $oBackground->setPath($tmpBkgImg);
394
                        // Slide Background
395
                        $oSlide = $this->oPhpPresentation->getActiveSlide();
396
                        $oSlide->setBackground($oBackground);
397
                    }
398
                }
399
            }
400
401
            // Shapes
402 4
            $arrayElements = $xmlReader->getElements('/p:sld/p:cSld/p:spTree/*');
403 4
            if ($arrayElements) {
404 4
                $this->loadSlideShapes($oSlide, $arrayElements, $xmlReader);
405
            }
406
407
            // Layout
408 4
            $oSlide = $this->oPhpPresentation->getActiveSlide();
409 4
            foreach ($this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'] as $valueRel) {
410 4
                if ($valueRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout') {
411 4
                    $layoutBasename = basename($valueRel['Target']);
412 4
                    if (array_key_exists($layoutBasename, $this->arraySlideLayouts)) {
413 4
                        $oSlide->setSlideLayout($this->arraySlideLayouts[$layoutBasename]);
414
                    }
415 4
                    break;
416
                }
417
            }
418
        }
419 4
    }
420
421
    /**
422
     * @param string $sPart
423
     * @param string $baseFile
424
     * @throws \Exception
425
     */
426 4
    protected function loadMasterSlide($sPart, $baseFile)
427
    {
428 4
        $xmlReader = new XMLReader();
429 4
        if ($xmlReader->getDomFromString($sPart)) {
430
            // Core
431 4
            $oSlideMaster = $this->oPhpPresentation->createMasterSlide();
432 4
            $oSlideMaster->setTextStyles(new TextStyle(false));
433 4
            $oSlideMaster->setRelsIndex('ppt/slideMasters/_rels/' . $baseFile . '.rels');
434
435
            // Background
436 4
            $oElement = $xmlReader->getElement('/p:sldMaster/p:cSld/p:bg');
437 4
            if ($oElement instanceof \DOMElement) {
438 4
                $this->loadSlideBackground($xmlReader, $oElement, $oSlideMaster);
439
            }
440
441
            // Shapes
442 4
            $arrayElements = $xmlReader->getElements('/p:sldMaster/p:cSld/p:spTree/*');
443 4
            if ($arrayElements) {
444 4
                $this->loadSlideShapes($oSlideMaster, $arrayElements, $xmlReader);
445
            }
446
            // Header & Footer
447
448
            // ColorMapping
449 4
            $colorMap = array();
450 4
            $oElement = $xmlReader->getElement('/p:sldMaster/p:clrMap');
451 4
            if ($oElement->hasAttributes()) {
452 4
                foreach ($oElement->attributes as $attr) {
453 4
                    $colorMap[$attr->nodeName] = $attr->nodeValue;
454
                }
455 4
                $oSlideMaster->colorMap->setMapping($colorMap);
456
            }
457
458
            // TextStyles
459 4
            $arrayElementTxStyles = $xmlReader->getElements('/p:sldMaster/p:txStyles/*');
460 4
            if ($arrayElementTxStyles) {
461 4
                foreach ($arrayElementTxStyles as $oElementTxStyle) {
462 4
                    $arrayElementsLvl = $xmlReader->getElements('/p:sldMaster/p:txStyles/' . $oElementTxStyle->nodeName . '/*');
463 4
                    foreach ($arrayElementsLvl as $oElementLvl) {
464 4
                        if (!($oElementLvl instanceof \DOMElement) || $oElementLvl->nodeName == 'a:extLst') {
465 1
                            continue;
466
                        }
467 4
                        $oRTParagraph = new Paragraph();
468
469 4
                        if ($oElementLvl->nodeName == 'a:defPPr') {
470 3
                            $level = 0;
471
                        } else {
472 4
                            $level = str_replace('a:lvl', '', $oElementLvl->nodeName);
473 4
                            $level = str_replace('pPr', '', $level);
474
                        }
475
476 4
                        if ($oElementLvl->hasAttribute('algn')) {
477 4
                            $oRTParagraph->getAlignment()->setHorizontal($oElementLvl->getAttribute('algn'));
478
                        }
479 4
                        if ($oElementLvl->hasAttribute('marL')) {
480 4
                            $val = $oElementLvl->getAttribute('marL');
481 4
                            $val = CommonDrawing::emuToPixels($val);
482 4
                            $oRTParagraph->getAlignment()->setMarginLeft($val);
483
                        }
484 4
                        if ($oElementLvl->hasAttribute('marR')) {
485
                            $val = $oElementLvl->getAttribute('marR');
486
                            $val = CommonDrawing::emuToPixels($val);
487
                            $oRTParagraph->getAlignment()->setMarginRight($val);
488
                        }
489 4
                        if ($oElementLvl->hasAttribute('indent')) {
490 4
                            $val = $oElementLvl->getAttribute('indent');
491 4
                            $val = CommonDrawing::emuToPixels($val);
492 4
                            $oRTParagraph->getAlignment()->setIndent($val);
493
                        }
494 4
                        $oElementLvlDefRPR = $xmlReader->getElement('a:defRPr', $oElementLvl);
495 4
                        if ($oElementLvlDefRPR instanceof \DOMElement) {
496 4
                            if ($oElementLvlDefRPR->hasAttribute('sz')) {
497 4
                                $oRTParagraph->getFont()->setSize($oElementLvlDefRPR->getAttribute('sz') / 100);
498
                            }
499 4
                            if ($oElementLvlDefRPR->hasAttribute('b') && $oElementLvlDefRPR->getAttribute('b') == 1) {
500 1
                                $oRTParagraph->getFont()->setBold(true);
501
                            }
502 4
                            if ($oElementLvlDefRPR->hasAttribute('i') && $oElementLvlDefRPR->getAttribute('i') == 1) {
503
                                $oRTParagraph->getFont()->setItalic(true);
504
                            }
505
                        }
506 4
                        $oElementSchemeColor = $xmlReader->getElement('a:defRPr/a:solidFill/a:schemeClr', $oElementLvl);
507 4
                        if ($oElementSchemeColor instanceof \DOMElement) {
508 4
                            if ($oElementSchemeColor->hasAttribute('val')) {
509 4
                                $oSchemeColor = new SchemeColor();
510 4
                                $oSchemeColor->setValue($oElementSchemeColor->getAttribute('val'));
511 4
                                $oRTParagraph->getFont()->setColor($oSchemeColor);
512
                            }
513
                        }
514
515 4
                        switch ($oElementTxStyle->nodeName) {
516 4
                            case 'p:bodyStyle':
517 4
                                $oSlideMaster->getTextStyles()->setBodyStyleAtLvl($oRTParagraph, $level);
518 4
                                break;
519 4
                            case 'p:otherStyle':
520 4
                                $oSlideMaster->getTextStyles()->setOtherStyleAtLvl($oRTParagraph, $level);
521 4
                                break;
522 4
                            case 'p:titleStyle':
523 4
                                $oSlideMaster->getTextStyles()->setTitleStyleAtLvl($oRTParagraph, $level);
524 4
                                break;
525
                        }
526
                    }
527
                }
528
            }
529
530
            // Load the theme
531 4
            foreach ($this->arrayRels[$oSlideMaster->getRelsIndex()] as $arrayRel) {
532 4
                if ($arrayRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme') {
533 4
                    $pptTheme = $this->oZip->getFromName('ppt/' . substr($arrayRel['Target'], strrpos($arrayRel['Target'], '../') + 3));
534 4
                    if ($pptTheme !== false) {
535 4
                        $this->loadTheme($pptTheme, $oSlideMaster);
536
                    }
537 4
                    break;
538
                }
539
            }
540
541
            // Load the Layoutslide
542 4
            foreach ($xmlReader->getElements('/p:sldMaster/p:sldLayoutIdLst/p:sldLayoutId') as $oElement) {
543 4
                if (!($oElement instanceof \DOMElement)) {
544
                    continue;
545
                }
546 4
                $rId = $oElement->getAttribute('r:id');
547
                // Get the path to the masterslide from the array with _rels files
548 4
                $pathLayoutSlide = isset($this->arrayRels[$oSlideMaster->getRelsIndex()][$rId]) ?
549 4
                    $this->arrayRels[$oSlideMaster->getRelsIndex()][$rId]['Target'] : '';
550 4
                if (!empty($pathLayoutSlide)) {
551 4
                    $pptLayoutSlide = $this->oZip->getFromName('ppt/' . substr($pathLayoutSlide, strrpos($pathLayoutSlide, '../') + 3));
552 4
                    if ($pptLayoutSlide !== false) {
553 4
                        $this->loadRels('ppt/slideLayouts/_rels/' . basename($pathLayoutSlide) . '.rels');
554 4
                        $oSlideMaster->addSlideLayout(
555 4
                            $this->loadLayoutSlide($pptLayoutSlide, basename($pathLayoutSlide), $oSlideMaster)
556
                        );
557
                    }
558
                }
559
            }
560
        }
561 4
    }
562
563
    /**
564
     * @param string $sPart
565
     * @param string $baseFile
566
     * @param SlideMaster $oSlideMaster
567
     * @return SlideLayout|null
568
     * @throws \Exception
569
     */
570 4
    protected function loadLayoutSlide($sPart, $baseFile, SlideMaster $oSlideMaster)
571
    {
572 4
        $xmlReader = new XMLReader();
573 4
        if ($xmlReader->getDomFromString($sPart)) {
574
            // Core
575 4
            $oSlideLayout = new SlideLayout($oSlideMaster);
576 4
            $oSlideLayout->setRelsIndex('ppt/slideLayouts/_rels/' . $baseFile . '.rels');
577
578
            // Name
579 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:cSld');
580 4
            if ($oElement instanceof \DOMElement && $oElement->hasAttribute('name')) {
581 4
                $oSlideLayout->setLayoutName($oElement->getAttribute('name'));
582
            }
583
584
            // Background
585 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:cSld/p:bg');
586 4
            if ($oElement instanceof \DOMElement) {
587 1
                $this->loadSlideBackground($xmlReader, $oElement, $oSlideLayout);
588
            }
589
590
            // ColorMapping
591 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:clrMapOvr/a:overrideClrMapping');
592 4
            if ($oElement instanceof \DOMElement && $oElement->hasAttributes()) {
593 1
                $colorMap = array();
594 1
                foreach ($oElement->attributes as $attr) {
595 1
                    $colorMap[$attr->nodeName] = $attr->nodeValue;
596
                }
597 1
                $oSlideLayout->colorMap->setMapping($colorMap);
598
            }
599
600
            // Shapes
601 4
            $oElements = $xmlReader->getElements('/p:sldLayout/p:cSld/p:spTree/*');
602 4
            if ($oElements) {
603 4
                $this->loadSlideShapes($oSlideLayout, $oElements, $xmlReader);
604
            }
605 4
            $this->arraySlideLayouts[$baseFile] = &$oSlideLayout;
606 4
            return $oSlideLayout;
607
        }
608
        return null;
609
    }
610
611
    /**
612
     * @param string $sPart
613
     * @param SlideMaster $oSlideMaster
614
     */
615 4
    protected function loadTheme($sPart, SlideMaster $oSlideMaster)
616
    {
617 4
        $xmlReader = new XMLReader();
618 4
        if ($xmlReader->getDomFromString($sPart)) {
619 4
            $oElements = $xmlReader->getElements('/a:theme/a:themeElements/a:clrScheme/*');
620 4
            if ($oElements) {
621 4
                foreach ($oElements as $oElement) {
622 4
                    $oSchemeColor = new SchemeColor();
623 4
                    $oSchemeColor->setValue(str_replace('a:', '', $oElement->tagName));
624 4
                    $colorElement = $xmlReader->getElement('*', $oElement);
625 4
                    if ($colorElement instanceof \DOMElement) {
626 4
                        if ($colorElement->hasAttribute('lastClr')) {
627 4
                            $oSchemeColor->setRGB($colorElement->getAttribute('lastClr'));
628 4
                        } elseif ($colorElement->hasAttribute('val')) {
629 4
                            $oSchemeColor->setRGB($colorElement->getAttribute('val'));
630
                        }
631
                    }
632 4
                    $oSlideMaster->addSchemeColor($oSchemeColor);
633
                }
634
            }
635
        }
636 4
    }
637
638
    /**
639
     * @param XMLReader $xmlReader
640
     * @param \DOMElement $oElement
641
     * @param AbstractSlide $oSlide
642
     * @throws \Exception
643
     */
644 4
    protected function loadSlideBackground(XMLReader $xmlReader, \DOMElement $oElement, AbstractSlide $oSlide)
645
    {
646
        // Background color
647 4
        $oElementColor = $xmlReader->getElement('p:bgPr/a:solidFill/a:srgbClr', $oElement);
648 4
        if ($oElementColor instanceof \DOMElement) {
649
            // Color
650
            $oColor = new Color();
651
            $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
652
            // Background
653
            $oBackground = new Slide\Background\Color();
654
            $oBackground->setColor($oColor);
655
            // Slide Background
656
            $oSlide->setBackground($oBackground);
657
        }
658
659
        // Background scheme color
660 4
        $oElementSchemeColor = $xmlReader->getElement('p:bgRef/a:schemeClr', $oElement);
661 4
        if ($oElementSchemeColor instanceof \DOMElement) {
662
            // Color
663 4
            $oColor = new SchemeColor();
664 4
            $oColor->setValue($oElementSchemeColor->hasAttribute('val') ? $oElementSchemeColor->getAttribute('val') : null);
665
            // Background
666 4
            $oBackground = new Slide\Background\SchemeColor();
667 4
            $oBackground->setSchemeColor($oColor);
668
            // Slide Background
669 4
            $oSlide->setBackground($oBackground);
670
        }
671
672
        // Background image
673 4
        $oElementImage = $xmlReader->getElement('p:bgPr/a:blipFill/a:blip', $oElement);
674 4
        if ($oElementImage instanceof \DOMElement) {
675
            $relImg = $this->arrayRels[$oSlide->getRelsIndex()][$oElementImage->getAttribute('r:embed')];
676
            if (is_array($relImg)) {
677
                // File
678
                $pathImage = 'ppt/slides/' . $relImg['Target'];
679
                $pathImage = explode('/', $pathImage);
680
                foreach ($pathImage as $key => $partPath) {
681
                    if ($partPath == '..') {
682
                        unset($pathImage[$key - 1]);
683
                        unset($pathImage[$key]);
684
                    }
685
                }
686
                $pathImage = implode('/', $pathImage);
687
                $contentImg = $this->oZip->getFromName($pathImage);
688
689
                $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg');
690
                file_put_contents($tmpBkgImg, $contentImg);
691
                // Background
692
                $oBackground = new Slide\Background\Image();
693
                $oBackground->setPath($tmpBkgImg);
694
                // Slide Background
695
                $oSlide->setBackground($oBackground);
696
            }
697
        }
698 4
    }
699
700
    /**
701
     * @param string $baseFile
702
     * @param Slide $oSlide
703
     * @throws \Exception
704
     */
705
    protected function loadSlideNote($baseFile, Slide $oSlide)
706
    {
707
        $sPart = $this->oZip->getFromName('ppt/notesSlides/' . $baseFile);
708
        $xmlReader = new XMLReader();
709
        if ($xmlReader->getDomFromString($sPart)) {
710
            $oNote = $oSlide->getNote();
711
712
            $arrayElements = $xmlReader->getElements('/p:notes/p:cSld/p:spTree/*');
713
            if ($arrayElements) {
714
                $this->loadSlideShapes($oNote, $arrayElements, $xmlReader);
715
            }
716
        }
717
    }
718
719
    /**
720
     * @param XMLReader $document
721
     * @param \DOMElement $node
722
     * @param AbstractSlide $oSlide
723
     * @throws \Exception
724
     */
725 3
    protected function loadShapeDrawing(XMLReader $document, \DOMElement $node, AbstractSlide $oSlide)
726
    {
727
        // Core
728 3
        $oShape = new Gd();
729 3
        $oShape->getShadow()->setVisible(false);
730
        // Variables
731 3
        $fileRels = $oSlide->getRelsIndex();
732
733 3
        $oElement = $document->getElement('p:nvPicPr/p:cNvPr', $node);
734 3
        if ($oElement instanceof \DOMElement) {
735 3
            $oShape->setName($oElement->hasAttribute('name') ? $oElement->getAttribute('name') : '');
736 3
            $oShape->setDescription($oElement->hasAttribute('descr') ? $oElement->getAttribute('descr') : '');
737
738
            // Hyperlink
739 3
            $oElementHlinkClick = $document->getElement('a:hlinkClick', $oElement);
740 3
            if (is_object($oElementHlinkClick)) {
741 1
                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...
742 1
                    $oShape->getHyperlink()->setTooltip($oElementHlinkClick->getAttribute('tooltip'));
743
                }
744 1
                if ($oElementHlinkClick->hasAttribute('r:id') && isset($this->arrayRels[$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...
745 1
                    $oShape->getHyperlink()->setUrl($this->arrayRels[$fileRels][$oElementHlinkClick->getAttribute('r:id')]['Target']);
746
                }
747
            }
748
        }
749
750 3
        $oElement = $document->getElement('p:blipFill/a:blip', $node);
751 3
        if ($oElement instanceof \DOMElement) {
752 3
            if ($oElement->hasAttribute('r:embed') && isset($this->arrayRels[$fileRels][$oElement->getAttribute('r:embed')]['Target'])) {
753 3
                $pathImage = 'ppt/slides/' . $this->arrayRels[$fileRels][$oElement->getAttribute('r:embed')]['Target'];
754 3
                $pathImage = explode('/', $pathImage);
755 3
                foreach ($pathImage as $key => $partPath) {
756 3
                    if ($partPath == '..') {
757 3
                        unset($pathImage[$key - 1]);
758 3
                        unset($pathImage[$key]);
759
                    }
760
                }
761 3
                $pathImage = implode('/', $pathImage);
762 3
                $imageFile = $this->oZip->getFromName($pathImage);
763 3
                if (!empty($imageFile)) {
764 3
                    $oShape->setImageResource(imagecreatefromstring($imageFile));
765
                }
766
            }
767
        }
768
769 3
        $oElement = $document->getElement('p:spPr', $node);
770 3
        if ($oElement instanceof \DOMElement) {
771 3
            $oFill = $this->loadStyleFill($document, $oElement);
772 3
            $oShape->setFill($oFill);
773
        }
774
775 3
        $oElement = $document->getElement('p:spPr/a:xfrm', $node);
776 3
        if ($oElement instanceof \DOMElement) {
777 3
            if ($oElement->hasAttribute('rot')) {
778 3
                $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
779
            }
780
        }
781
782 3
        $oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
783 3
        if ($oElement instanceof \DOMElement) {
784 3
            if ($oElement->hasAttribute('x')) {
785 3
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
786
            }
787 3
            if ($oElement->hasAttribute('y')) {
788 3
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
789
            }
790
        }
791
792 3
        $oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
793 3
        if ($oElement instanceof \DOMElement) {
794 3
            if ($oElement->hasAttribute('cx')) {
795 3
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
796
            }
797 3
            if ($oElement->hasAttribute('cy')) {
798 3
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
799
            }
800
        }
801
802 3
        $oElement = $document->getElement('p:spPr/a:effectLst', $node);
803 3
        if ($oElement instanceof \DOMElement) {
804 3
            $oShape->getShadow()->setVisible(true);
805
806 3
            $oSubElement = $document->getElement('a:outerShdw', $oElement);
807 3
            if ($oSubElement instanceof \DOMElement) {
808 3
                if ($oSubElement->hasAttribute('blurRad')) {
809 3
                    $oShape->getShadow()->setBlurRadius(CommonDrawing::emuToPixels($oSubElement->getAttribute('blurRad')));
810
                }
811 3
                if ($oSubElement->hasAttribute('dist')) {
812 3
                    $oShape->getShadow()->setDistance(CommonDrawing::emuToPixels($oSubElement->getAttribute('dist')));
813
                }
814 3
                if ($oSubElement->hasAttribute('dir')) {
815 3
                    $oShape->getShadow()->setDirection(CommonDrawing::angleToDegrees($oSubElement->getAttribute('dir')));
816
                }
817 3
                if ($oSubElement->hasAttribute('algn')) {
818 3
                    $oShape->getShadow()->setAlignment($oSubElement->getAttribute('algn'));
819
                }
820
            }
821
822 3
            $oSubElement = $document->getElement('a:outerShdw/a:srgbClr', $oElement);
823 3
            if ($oSubElement instanceof \DOMElement) {
824 3
                if ($oSubElement->hasAttribute('val')) {
825 3
                    $oColor = new Color();
826 3
                    $oColor->setRGB($oSubElement->getAttribute('val'));
827 3
                    $oShape->getShadow()->setColor($oColor);
828
                }
829
            }
830
831 3
            $oSubElement = $document->getElement('a:outerShdw/a:srgbClr/a:alpha', $oElement);
832 3
            if ($oSubElement instanceof \DOMElement) {
833 3
                if ($oSubElement->hasAttribute('val')) {
834 3
                    $oShape->getShadow()->setAlpha((int)$oSubElement->getAttribute('val') / 1000);
835
                }
836
            }
837
        }
838
839 3
        $oSlide->addShape($oShape);
840 3
    }
841
842
    /**
843
     * @param XMLReader $document
844
     * @param \DOMElement $node
845
     * @param AbstractSlide $oSlide
846
     * @throws \Exception
847
     */
848 4
    protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oSlide)
849
    {
850 4
        if (!$document->elementExists('p:txBody/a:p/a:r', $node)) {
851 4
            return;
852
        }
853
        // Core
854 4
        $oShape = $oSlide->createRichTextShape();
855 4
        $oShape->setParagraphs(array());
856
        // Variables
857 4
        if ($oSlide instanceof AbstractSlide) {
858 4
            $this->fileRels = $oSlide->getRelsIndex();
859
        }
860
861 4
        $oElement = $document->getElement('p:spPr/a:xfrm', $node);
862 4
        if ($oElement instanceof \DOMElement && $oElement->hasAttribute('rot')) {
863 4
            $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
864
        }
865
866 4
        $oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
867 4
        if ($oElement instanceof \DOMElement) {
868 4
            if ($oElement->hasAttribute('x')) {
869 4
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
870
            }
871 4
            if ($oElement->hasAttribute('y')) {
872 4
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
873
            }
874
        }
875
876 4
        $oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
877 4
        if ($oElement instanceof \DOMElement) {
878 4
            if ($oElement->hasAttribute('cx')) {
879 4
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
880
            }
881 4
            if ($oElement->hasAttribute('cy')) {
882 4
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
883
            }
884
        }
885
886 4
        $oElement = $document->getElement('p:nvSpPr/p:nvPr/p:ph', $node);
887 4
        if ($oElement instanceof \DOMElement) {
888 4
            if ($oElement->hasAttribute('type')) {
889 4
                $placeholder = new Placeholder($oElement->getAttribute('type'));
890 4
                $oShape->setPlaceHolder($placeholder);
891
            }
892
        }
893
894 4
        $arrayElements = $document->getElements('p:txBody/a:p', $node);
895 4
        foreach ($arrayElements as $oElement) {
896 4
            $this->loadParagraph($document, $oElement, $oShape);
897
        }
898
899 4
        if (count($oShape->getParagraphs()) > 0) {
900 4
            $oShape->setActiveParagraph(0);
901
        }
902 4
    }
903
904
    /**
905
     * @param XMLReader $document
906
     * @param \DOMElement $node
907
     * @param AbstractSlide $oSlide
908
     * @throws \Exception
909
     */
910
    protected function loadShapeTable(XMLReader $document, \DOMElement $node, AbstractSlide $oSlide)
911
    {
912
        $this->fileRels = $oSlide->getRelsIndex();
913
914
        $oShape = $oSlide->createTableShape();
915
916
        $oElement = $document->getElement('p:cNvPr', $node);
917
        if ($oElement instanceof \DOMElement) {
918
            if ($oElement->hasAttribute('name')) {
919
                $oShape->setName($oElement->getAttribute('name'));
920
            }
921
            if ($oElement->hasAttribute('descr')) {
922
                $oShape->setDescription($oElement->getAttribute('descr'));
923
            }
924
        }
925
926
        $oElement = $document->getElement('p:xfrm/a:off', $node);
927
        if ($oElement instanceof \DOMElement) {
928
            if ($oElement->hasAttribute('x')) {
929
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
930
            }
931
            if ($oElement->hasAttribute('y')) {
932
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
933
            }
934
        }
935
936
        $oElement = $document->getElement('p:xfrm/a:ext', $node);
937
        if ($oElement instanceof \DOMElement) {
938
            if ($oElement->hasAttribute('cx')) {
939
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
940
            }
941
            if ($oElement->hasAttribute('cy')) {
942
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
943
            }
944
        }
945
946
        $arrayElements = $document->getElements('a:graphic/a:graphicData/a:tbl/a:tblGrid/a:gridCol', $node);
947
        $oShape->setNumColumns($arrayElements->length);
948
        $oShape->createRow();
949
        foreach ($arrayElements as $key => $oElement) {
950
            if ($oElement instanceof \DOMElement && $oElement->getAttribute('w')) {
951
                $oShape->getRow(0)->getCell($key)->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('w')));
952
            }
953
        }
954
955
        $arrayElements = $document->getElements('a:graphic/a:graphicData/a:tbl/a:tr', $node);
956
        foreach ($arrayElements as $keyRow => $oElementRow) {
957
            if (!($oElementRow instanceof \DOMElement)) {
958
                continue;
959
            }
960
            $oRow = $oShape->getRow($keyRow, true);
961
            if (is_null($oRow)) {
962
                $oRow = $oShape->createRow();
963
            }
964
            if ($oElementRow->hasAttribute('h')) {
965
                $oRow->setHeight(CommonDrawing::emuToPixels($oElementRow->getAttribute('h')));
966
            }
967
            $arrayElementsCell = $document->getElements('a:tc', $oElementRow);
968
            foreach ($arrayElementsCell as $keyCell => $oElementCell) {
969
                if (!($oElementCell instanceof \DOMElement)) {
970
                    continue;
971
                }
972
                $oCell = $oRow->getCell($keyCell);
973
                $oCell->setParagraphs(array());
974
                if ($oElementCell->hasAttribute('gridSpan')) {
975
                    $oCell->setColSpan($oElementCell->getAttribute('gridSpan'));
976
                }
977
                if ($oElementCell->hasAttribute('rowSpan')) {
978
                    $oCell->setRowSpan($oElementCell->getAttribute('rowSpan'));
979
                }
980
981
                foreach ($document->getElements('a:txBody/a:p', $oElementCell) as $oElementPara) {
982
                    $this->loadParagraph($document, $oElementPara, $oCell);
0 ignored issues
show
Bug introduced by
It seems like $oCell defined by $oRow->getCell($keyCell) on line 972 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...
983
                }
984
985
                $oElementTcPr = $document->getElement('a:tcPr', $oElementCell);
986
                if ($oElementTcPr instanceof \DOMElement) {
987
                    $numParagraphs = count($oCell->getParagraphs());
988
                    if ($numParagraphs > 0) {
989
                        if ($oElementTcPr->hasAttribute('vert')) {
990
                            $oCell->getParagraph(0)->getAlignment()->setTextDirection($oElementTcPr->getAttribute('vert'));
991
                        }
992
                        if ($oElementTcPr->hasAttribute('anchor')) {
993
                            $oCell->getParagraph(0)->getAlignment()->setVertical($oElementTcPr->getAttribute('anchor'));
994
                        }
995
                        if ($oElementTcPr->hasAttribute('marB')) {
996
                            $oCell->getParagraph(0)->getAlignment()->setMarginBottom($oElementTcPr->getAttribute('marB'));
997
                        }
998
                        if ($oElementTcPr->hasAttribute('marL')) {
999
                            $oCell->getParagraph(0)->getAlignment()->setMarginLeft($oElementTcPr->getAttribute('marL'));
1000
                        }
1001
                        if ($oElementTcPr->hasAttribute('marR')) {
1002
                            $oCell->getParagraph(0)->getAlignment()->setMarginRight($oElementTcPr->getAttribute('marR'));
1003
                        }
1004
                        if ($oElementTcPr->hasAttribute('marT')) {
1005
                            $oCell->getParagraph(0)->getAlignment()->setMarginTop($oElementTcPr->getAttribute('marT'));
1006
                        }
1007
                    }
1008
1009
                    $oFill = $this->loadStyleFill($document, $oElementTcPr);
1010
                    if ($oFill instanceof Fill) {
1011
                        $oCell->setFill($oFill);
1012
                    }
1013
1014
                    $oBorders = new Borders();
1015
                    $oElementBorderL = $document->getElement('a:lnL', $oElementTcPr);
1016
                    if ($oElementBorderL instanceof \DOMElement) {
1017
                        $this->loadStyleBorder($document, $oElementBorderL, $oBorders->getLeft());
1018
                    }
1019
                    $oElementBorderR = $document->getElement('a:lnR', $oElementTcPr);
1020
                    if ($oElementBorderR instanceof \DOMElement) {
1021
                        $this->loadStyleBorder($document, $oElementBorderR, $oBorders->getRight());
1022
                    }
1023
                    $oElementBorderT = $document->getElement('a:lnT', $oElementTcPr);
1024
                    if ($oElementBorderT instanceof \DOMElement) {
1025
                        $this->loadStyleBorder($document, $oElementBorderT, $oBorders->getTop());
1026
                    }
1027
                    $oElementBorderB = $document->getElement('a:lnB', $oElementTcPr);
1028
                    if ($oElementBorderB instanceof \DOMElement) {
1029
                        $this->loadStyleBorder($document, $oElementBorderB, $oBorders->getBottom());
1030
                    }
1031
                    $oElementBorderDiagDown = $document->getElement('a:lnTlToBr', $oElementTcPr);
1032
                    if ($oElementBorderDiagDown instanceof \DOMElement) {
1033
                        $this->loadStyleBorder($document, $oElementBorderDiagDown, $oBorders->getDiagonalDown());
1034
                    }
1035
                    $oElementBorderDiagUp = $document->getElement('a:lnBlToTr', $oElementTcPr);
1036
                    if ($oElementBorderDiagUp instanceof \DOMElement) {
1037
                        $this->loadStyleBorder($document, $oElementBorderDiagUp, $oBorders->getDiagonalUp());
1038
                    }
1039
                    $oCell->setBorders($oBorders);
1040
                }
1041
            }
1042
        }
1043
    }
1044
1045
    /**
1046
     * @param XMLReader $document
1047
     * @param \DOMElement $oElement
1048
     * @param Cell|RichText $oShape
1049
     * @throws \Exception
1050
     */
1051 4
    protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oShape)
1052
    {
1053
        // Core
1054 4
        $oParagraph = $oShape->createParagraph();
1055 4
        $oParagraph->setRichTextElements(array());
1056
1057 4
        $oSubElement = $document->getElement('a:pPr', $oElement);
1058 4
        if ($oSubElement instanceof \DOMElement) {
1059 4
            if ($oSubElement->hasAttribute('algn')) {
1060 3
                $oParagraph->getAlignment()->setHorizontal($oSubElement->getAttribute('algn'));
1061
            }
1062 4
            if ($oSubElement->hasAttribute('fontAlgn')) {
1063 3
                $oParagraph->getAlignment()->setVertical($oSubElement->getAttribute('fontAlgn'));
1064
            }
1065 4
            if ($oSubElement->hasAttribute('marL')) {
1066 3
                $oParagraph->getAlignment()->setMarginLeft(CommonDrawing::emuToPixels($oSubElement->getAttribute('marL')));
1067
            }
1068 4
            if ($oSubElement->hasAttribute('marR')) {
1069 3
                $oParagraph->getAlignment()->setMarginRight(CommonDrawing::emuToPixels($oSubElement->getAttribute('marR')));
1070
            }
1071 4
            if ($oSubElement->hasAttribute('indent')) {
1072 3
                $oParagraph->getAlignment()->setIndent(CommonDrawing::emuToPixels($oSubElement->getAttribute('indent')));
1073
            }
1074 4
            if ($oSubElement->hasAttribute('lvl')) {
1075 4
                $oParagraph->getAlignment()->setLevel($oSubElement->getAttribute('lvl'));
1076
            }
1077
1078 4
            $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NONE);
1079
1080 4
            $oElementBuFont = $document->getElement('a:buFont', $oSubElement);
1081 4
            if ($oElementBuFont instanceof \DOMElement) {
1082 3
                if ($oElementBuFont->hasAttribute('typeface')) {
1083 3
                    $oParagraph->getBulletStyle()->setBulletFont($oElementBuFont->getAttribute('typeface'));
1084
                }
1085
            }
1086 4
            $oElementBuChar = $document->getElement('a:buChar', $oSubElement);
1087 4
            if ($oElementBuChar instanceof \DOMElement) {
1088 3
                $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_BULLET);
1089 3
                if ($oElementBuChar->hasAttribute('char')) {
1090 3
                    $oParagraph->getBulletStyle()->setBulletChar($oElementBuChar->getAttribute('char'));
1091
                }
1092
            }
1093 4
            $oElementBuAutoNum = $document->getElement('a:buAutoNum', $oSubElement);
1094 4
            if ($oElementBuAutoNum instanceof \DOMElement) {
1095
                $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NUMERIC);
1096
                if ($oElementBuAutoNum->hasAttribute('type')) {
1097
                    $oParagraph->getBulletStyle()->setBulletNumericStyle($oElementBuAutoNum->getAttribute('type'));
1098
                }
1099
                if ($oElementBuAutoNum->hasAttribute('startAt') && $oElementBuAutoNum->getAttribute('startAt') != 1) {
1100
                    $oParagraph->getBulletStyle()->setBulletNumericStartAt($oElementBuAutoNum->getAttribute('startAt'));
1101
                }
1102
            }
1103 4
            $oElementBuClr = $document->getElement('a:buClr', $oSubElement);
1104 4
            if ($oElementBuClr instanceof \DOMElement) {
1105
                $oColor = new Color();
1106
                /**
1107
                 * @todo Create protected for reading Color
1108
                 */
1109
                $oElementColor = $document->getElement('a:srgbClr', $oElementBuClr);
1110
                if ($oElementColor instanceof \DOMElement) {
1111
                    $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
1112
                }
1113
                $oParagraph->getBulletStyle()->setBulletColor($oColor);
1114
            }
1115
        }
1116 4
        $arraySubElements = $document->getElements('(a:r|a:br)', $oElement);
1117 4
        foreach ($arraySubElements as $oSubElement) {
1118 4
            if ($oSubElement->tagName == 'a:br') {
1119 3
                $oParagraph->createBreak();
1120
            }
1121 4
            if ($oSubElement->tagName == 'a:r') {
1122 4
                $oElementrPr = $document->getElement('a:rPr', $oSubElement);
1123 4
                if (is_object($oElementrPr)) {
1124 4
                    $oText = $oParagraph->createTextRun();
1125
1126 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...
1127 3
                        $att = $oElementrPr->getAttribute('b');
1128 3
                        $oText->getFont()->setBold($att == 'true' || $att == '1' ? true : false);
1129
                    }
1130 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...
1131 3
                        $att = $oElementrPr->getAttribute('i');
1132 3
                        $oText->getFont()->setItalic($att == 'true' || $att == '1' ? true : false);
1133
                    }
1134 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...
1135 3
                        $oText->getFont()->setStrikethrough($oElementrPr->getAttribute('strike') == 'noStrike' ? false : true);
1136
                    }
1137 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...
1138 3
                        $oText->getFont()->setSize((int)($oElementrPr->getAttribute('sz') / 100));
1139
                    }
1140 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...
1141 3
                        $oText->getFont()->setUnderline($oElementrPr->getAttribute('u'));
1142
                    }
1143
                    // Color
1144 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...
1145 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...
1146 3
                        $oColor = new Color();
1147 3
                        $oColor->setRGB($oElementSrgbClr->getAttribute('val'));
1148 3
                        $oText->getFont()->setColor($oColor);
1149
                    }
1150
                    // Hyperlink
1151 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...
1152 4
                    if (is_object($oElementHlinkClick)) {
1153 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...
1154 3
                            $oText->getHyperlink()->setTooltip($oElementHlinkClick->getAttribute('tooltip'));
1155
                        }
1156 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...
1157 3
                            $oText->getHyperlink()->setUrl($this->arrayRels[$this->fileRels][$oElementHlinkClick->getAttribute('r:id')]['Target']);
1158
                        }
1159
                    }
1160
                    //} else {
1161
                    // $oText = $oParagraph->createText();
1162
1163 4
                    $oSubSubElement = $document->getElement('a:t', $oSubElement);
1164 4
                    $oText->setText($oSubSubElement->nodeValue);
1165
                }
1166
            }
1167
        }
1168 4
    }
1169
1170
    /**
1171
     * @param XMLReader $xmlReader
1172
     * @param \DOMElement $oElement
1173
     * @param Border $oBorder
1174
     * @throws \Exception
1175
     */
1176
    protected function loadStyleBorder(XMLReader $xmlReader, \DOMElement $oElement, Border $oBorder)
1177
    {
1178
        if ($oElement->hasAttribute('w')) {
1179
            $oBorder->setLineWidth($oElement->getAttribute('w') / 12700);
1180
        }
1181
        if ($oElement->hasAttribute('cmpd')) {
1182
            $oBorder->setLineStyle($oElement->getAttribute('cmpd'));
1183
        }
1184
1185
        $oElementNoFill = $xmlReader->getElement('a:noFill', $oElement);
1186
        if ($oElementNoFill instanceof \DOMElement && $oBorder->getLineStyle() == Border::LINE_SINGLE) {
1187
            $oBorder->setLineStyle(Border::LINE_NONE);
1188
        }
1189
1190
        $oElementColor = $xmlReader->getElement('a:solidFill/a:srgbClr', $oElement);
1191
        if ($oElementColor instanceof \DOMElement) {
1192
            $oBorder->setColor($this->loadStyleColor($xmlReader, $oElementColor));
1193
        }
1194
1195
        $oElementDashStyle = $xmlReader->getElement('a:prstDash', $oElement);
1196
        if ($oElementDashStyle instanceof \DOMElement && $oElementDashStyle->hasAttribute('val')) {
1197
            $oBorder->setDashStyle($oElementDashStyle->getAttribute('val'));
1198
        }
1199
    }
1200
1201
    /**
1202
     * @param XMLReader $xmlReader
1203
     * @param \DOMElement $oElement
1204
     * @return Color
1205
     */
1206
    protected function loadStyleColor(XMLReader $xmlReader, \DOMElement $oElement)
1207
    {
1208
        $oColor = new Color();
1209
        $oColor->setRGB($oElement->getAttribute('val'));
1210
        $oElementAlpha = $xmlReader->getElement('a:alpha', $oElement);
1211
        if ($oElementAlpha instanceof \DOMElement && $oElementAlpha->hasAttribute('val')) {
1212
            $alpha = strtoupper(dechex((($oElementAlpha->getAttribute('val') / 1000) / 100) * 255));
1213
            $oColor->setRGB($oElement->getAttribute('val'), $alpha);
1214
        }
1215
        return $oColor;
1216
    }
1217
1218
    /**
1219
     * @param XMLReader $xmlReader
1220
     * @param \DOMElement $oElement
1221
     * @return null|Fill
1222
     * @throws \Exception
1223
     */
1224 3
    protected function loadStyleFill(XMLReader $xmlReader, \DOMElement $oElement)
1225
    {
1226
        // Gradient fill
1227 3
        $oElementFill = $xmlReader->getElement('a:gradFill', $oElement);
1228 3
        if ($oElementFill instanceof \DOMElement) {
1229
            $oFill = new Fill();
1230
            $oFill->setFillType(Fill::FILL_GRADIENT_LINEAR);
1231
1232
            $oElementColor = $xmlReader->getElement('a:gsLst/a:gs[@pos="0"]/a:srgbClr', $oElementFill);
1233
            if ($oElementColor instanceof \DOMElement && $oElementColor->hasAttribute('val')) {
1234
                $oFill->setStartColor($this->loadStyleColor($xmlReader, $oElementColor));
1235
            }
1236
1237
            $oElementColor = $xmlReader->getElement('a:gsLst/a:gs[@pos="100000"]/a:srgbClr', $oElementFill);
1238
            if ($oElementColor instanceof \DOMElement && $oElementColor->hasAttribute('val')) {
1239
                $oFill->setEndColor($this->loadStyleColor($xmlReader, $oElementColor));
1240
            }
1241
1242
            $oRotation = $xmlReader->getElement('a:lin', $oElementFill);
1243
            if ($oRotation instanceof \DOMElement && $oRotation->hasAttribute('ang')) {
1244
                $oFill->setRotation(CommonDrawing::angleToDegrees($oRotation->getAttribute('ang')));
1245
            }
1246
            return $oFill;
1247
        }
1248
1249
        // Solid fill
1250 3
        $oElementFill = $xmlReader->getElement('a:solidFill', $oElement);
1251 3
        if ($oElementFill instanceof \DOMElement) {
1252
            $oFill = new Fill();
1253
            $oFill->setFillType(Fill::FILL_SOLID);
1254
1255
            $oElementColor = $xmlReader->getElement('a:srgbClr', $oElementFill);
1256
            if ($oElementColor instanceof \DOMElement) {
1257
                $oFill->setStartColor($this->loadStyleColor($xmlReader, $oElementColor));
1258
            }
1259
            return $oFill;
1260
        }
1261 3
        return null;
1262
    }
1263
1264
    /**
1265
     * @param string $fileRels
1266
     */
1267 4
    protected function loadRels($fileRels)
1268
    {
1269 4
        $sPart = $this->oZip->getFromName($fileRels);
1270 4
        if ($sPart !== false) {
1271 4
            $xmlReader = new XMLReader();
1272 4
            if ($xmlReader->getDomFromString($sPart)) {
1273 4
                foreach ($xmlReader->getElements('*') as $oNode) {
1274 4
                    if (!($oNode instanceof \DOMElement)) {
1275
                        continue;
1276
                    }
1277 4
                    $this->arrayRels[$fileRels][$oNode->getAttribute('Id')] = array(
1278 4
                        'Target' => $oNode->getAttribute('Target'),
1279 4
                        'Type' => $oNode->getAttribute('Type'),
1280
                    );
1281
                }
1282
            }
1283
        }
1284 4
    }
1285
1286
    /**
1287
     * @param $oSlide
1288
     * @param \DOMNodeList $oElements
1289
     * @param XMLReader $xmlReader
1290
     * @throws \Exception
1291
     * @internal param $baseFile
1292
     */
1293 4
    protected function loadSlideShapes($oSlide, $oElements, $xmlReader)
1294
    {
1295 4
        foreach ($oElements as $oNode) {
1296 4
            switch ($oNode->tagName) {
1297 4
                case 'p:graphicFrame':
1298
                    $this->loadShapeTable($xmlReader, $oNode, $oSlide);
1299
                    break;
1300 4
                case 'p:pic':
1301 3
                    $this->loadShapeDrawing($xmlReader, $oNode, $oSlide);
1302 3
                    break;
1303 4
                case 'p:sp':
1304 4
                    $this->loadShapeRichText($xmlReader, $oNode, $oSlide);
1305 4
                    break;
1306 4
                default:
1307
                    //var_export($oNode->tagName);
1308
            }
1309
        }
1310 4
    }
1311
}
1312