Completed
Pull Request — develop (#335)
by Franck
08:32
created

PowerPoint2007::loadMasterSlide()   F

Complexity

Conditions 33
Paths 449

Size

Total Lines 133
Code Lines 85

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 81
CRAP Score 33.1137

Importance

Changes 0
Metric Value
dl 0
loc 133
ccs 81
cts 85
cp 0.9529
rs 3.1788
c 0
b 0
f 0
cc 33
eloc 85
nc 449
nop 2
crap 33.1137

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

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