Completed
Pull Request — develop (#565)
by
unknown
06:14
created

PowerPoint2007::loadStyleFill()   B

Complexity

Conditions 10
Paths 11

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 52.1875

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 6
cts 24
cp 0.25
rs 7.6666
c 0
b 0
f 0
cc 10
nc 11
nop 2
crap 52.1875

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