PowerPoint2007::loadShapeTable()   F
last analyzed

Complexity

Conditions 37
Paths > 20000

Size

Total Lines 134

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 1406

Importance

Changes 0
Metric Value
dl 0
loc 134
ccs 0
cts 88
cp 0
rs 0
c 0
b 0
f 0
cc 37
nc 99855750
nop 3
crap 1406

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\PhpPresentation;
22
use PhpOffice\PhpPresentation\Shape\Placeholder;
23
use PhpOffice\PhpPresentation\Shape\RichText;
24
use PhpOffice\PhpPresentation\Shape\RichText\Paragraph;
25
use PhpOffice\PhpPresentation\Shape\Table\Cell;
26
use PhpOffice\PhpPresentation\Slide;
27
use PhpOffice\PhpPresentation\Slide\AbstractSlide;
28
use PhpOffice\PhpPresentation\Slide\SlideLayout;
29
use PhpOffice\PhpPresentation\Slide\SlideMaster;
30
use PhpOffice\PhpPresentation\Shape\Drawing\Gd;
31
use PhpOffice\PhpPresentation\Style\Bullet;
32
use PhpOffice\PhpPresentation\Style\Border;
33
use PhpOffice\PhpPresentation\Style\Borders;
34
use PhpOffice\PhpPresentation\Style\Color;
35
use PhpOffice\PhpPresentation\Style\Fill;
36
use PhpOffice\PhpPresentation\Style\SchemeColor;
37
use PhpOffice\PhpPresentation\Style\TextStyle;
38
use PhpOffice\Common\XMLReader;
39
use PhpOffice\Common\Drawing as CommonDrawing;
40
use ZipArchive;
41
42
/**
43
 * Serialized format reader
44
 */
45
class PowerPoint2007 implements ReaderInterface
46
{
47
    /**
48
     * Output Object
49
     * @var PhpPresentation
50
     */
51
    protected $oPhpPresentation;
52
    /**
53
     * Output Object
54
     * @var \ZipArchive
55
     */
56
    protected $oZip;
57
    /**
58
     * @var array[]
59
     */
60
    protected $arrayRels = array();
61
    /**
62
     * @var SlideLayout[]
63
     */
64
    protected $arraySlideLayouts = array();
65
    /*
66
     * @var string
67
     */
68
    protected $filename;
69
    /*
70
     * @var string
71
     */
72
    protected $fileRels;
73
74
    /**
75
     * Can the current \PhpOffice\PhpPresentation\Reader\ReaderInterface read the file?
76
     *
77
     * @param  string $pFilename
78
     * @throws \Exception
79
     * @return boolean
80
     */
81 2
    public function canRead($pFilename)
82
    {
83 2
        return $this->fileSupportsUnserializePhpPresentation($pFilename);
84
    }
85
86
    /**
87
     * Does a file support UnserializePhpPresentation ?
88
     *
89
     * @param  string $pFilename
90
     * @throws \Exception
91
     * @return boolean
92
     */
93 9
    public function fileSupportsUnserializePhpPresentation($pFilename = '')
94
    {
95
        // Check if file exists
96 9
        if (!file_exists($pFilename)) {
97 2
            throw new \Exception("Could not open " . $pFilename . " for reading! File does not exist.");
98
        }
99
100 7
        $oZip = new ZipArchive();
101
        // Is it a zip ?
102 7
        if ($oZip->open($pFilename) === true) {
103
            // Is it an OpenXML Document ?
104
            // Is it a Presentation ?
105 5
            if (is_array($oZip->statName('[Content_Types].xml')) && is_array($oZip->statName('ppt/presentation.xml'))) {
106 5
                return true;
107
            }
108
        }
109 3
        return false;
110
    }
111
112
    /**
113
     * Loads PhpPresentation Serialized file
114
     *
115
     * @param  string $pFilename
116
     * @return \PhpOffice\PhpPresentation\PhpPresentation
117
     * @throws \Exception
118
     */
119 6
    public function load($pFilename)
120
    {
121
        // Unserialize... First make sure the file supports it!
122 6
        if (!$this->fileSupportsUnserializePhpPresentation($pFilename)) {
123 1
            throw new \Exception("Invalid file format for PhpOffice\PhpPresentation\Reader\PowerPoint2007: " . $pFilename . ".");
124
        }
125
126 4
        return $this->loadFile($pFilename);
127
    }
128
129
    /**
130
     * Load PhpPresentation Serialized file
131
     *
132
     * @param  string $pFilename
133
     * @return \PhpOffice\PhpPresentation\PhpPresentation
134
     * @throws \Exception
135
     */
136 4
    protected function loadFile($pFilename)
137
    {
138 4
        $this->oPhpPresentation = new PhpPresentation();
139 4
        $this->oPhpPresentation->removeSlideByIndex();
140 4
        $this->oPhpPresentation->setAllMasterSlides(array());
141 4
        $this->filename = $pFilename;
142
143 4
        $this->oZip = new ZipArchive();
144 4
        $this->oZip->open($this->filename);
145 4
        $docPropsCore = $this->oZip->getFromName('docProps/core.xml');
146 4
        if ($docPropsCore !== false) {
147 4
            $this->loadDocumentProperties($docPropsCore);
148
        }
149
150 4
        $docPropsCustom = $this->oZip->getFromName('docProps/custom.xml');
151 4
        if ($docPropsCustom !== false) {
152 1
            $this->loadCustomProperties($docPropsCustom);
153
        }
154
155 4
        $pptViewProps = $this->oZip->getFromName('ppt/viewProps.xml');
156 4
        if ($pptViewProps !== false) {
157 4
            $this->loadViewProperties($pptViewProps);
158
        }
159
160 4
        $pptPresentation = $this->oZip->getFromName('ppt/presentation.xml');
161 4
        if ($pptPresentation !== false) {
162 4
            $this->loadDocumentLayout($pptPresentation);
163 4
            $this->loadSlides($pptPresentation);
164
        }
165
166 4
        return $this->oPhpPresentation;
167
    }
168
169
    /**
170
     * Read Document Layout
171
     * @param $sPart
172
     */
173 4
    protected function loadDocumentLayout($sPart)
174
    {
175 4
        $xmlReader = new XMLReader();
176 4
        if ($xmlReader->getDomFromString($sPart)) {
177 4
            foreach ($xmlReader->getElements('/p:presentation/p:sldSz') as $oElement) {
178 4
                if (!($oElement instanceof \DOMElement)) {
179
                    continue;
180
                }
181 4
                $type = $oElement->getAttribute('type');
182 4
                $oLayout = $this->oPhpPresentation->getLayout();
183 4
                if ($type == DocumentLayout::LAYOUT_CUSTOM) {
184
                    $oLayout->setCX($oElement->getAttribute('cx'));
185
                    $oLayout->setCY($oElement->getAttribute('cy'));
186
                } else {
187 4
                    $oLayout->setDocumentLayout($type, true);
188 4
                    if ($oElement->getAttribute('cx') < $oElement->getAttribute('cy')) {
189
                        $oLayout->setDocumentLayout($type, false);
190
                    }
191
                }
192
            }
193
        }
194 4
    }
195
196
    /**
197
     * Read Document Properties
198
     * @param string $sPart
199
     */
200 4
    protected function loadDocumentProperties($sPart)
201
    {
202 4
        $xmlReader = new XMLReader();
203 4
        if ($xmlReader->getDomFromString($sPart)) {
204
            $arrayProperties = array(
205 4
                '/cp:coreProperties/dc:creator' => 'setCreator',
206
                '/cp:coreProperties/cp:lastModifiedBy' => 'setLastModifiedBy',
207
                '/cp:coreProperties/dc:title' => 'setTitle',
208
                '/cp:coreProperties/dc:description' => 'setDescription',
209
                '/cp:coreProperties/dc:subject' => 'setSubject',
210
                '/cp:coreProperties/cp:keywords' => 'setKeywords',
211
                '/cp:coreProperties/cp:category' => 'setCategory',
212
                '/cp:coreProperties/dcterms:created' => 'setCreated',
213
                '/cp:coreProperties/dcterms:modified' => 'setModified',
214
            );
215 4
            $oProperties = $this->oPhpPresentation->getDocumentProperties();
216 4
            foreach ($arrayProperties as $path => $property) {
217 4
                $oElement = $xmlReader->getElement($path);
218 4
                if ($oElement instanceof \DOMElement) {
219 4
                    if ($oElement->hasAttribute('xsi:type') && $oElement->getAttribute('xsi:type') == 'dcterms:W3CDTF') {
220 4
                        $oDateTime = new \DateTime();
221 4
                        $oDateTime->createFromFormat(\DateTime::W3C, $oElement->nodeValue);
222 4
                        $oProperties->{$property}($oDateTime->getTimestamp());
223
                    } else {
224 4
                        $oProperties->{$property}($oElement->nodeValue);
225
                    }
226
                }
227
            }
228
        }
229 4
    }
230
231
    /**
232
     * Read Custom Properties
233
     * @param string $sPart
234
     */
235 1
    protected function loadCustomProperties($sPart)
236
    {
237 1
        $xmlReader = new XMLReader();
238 1
        $sPart = str_replace(' xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"', '', $sPart);
239 1
        if ($xmlReader->getDomFromString($sPart)) {
240 1
            $pathMarkAsFinal = '/Properties/property[@pid="2"][@fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"][@name="_MarkAsFinal"]/vt:bool';
241 1
            if (is_object($oElement = $xmlReader->getElement($pathMarkAsFinal))) {
242 1
                if ($oElement->nodeValue == 'true') {
243 1
                    $this->oPhpPresentation->getPresentationProperties()->markAsFinal(true);
244
                }
245
            }
246
        }
247 1
    }
248
249
    /**
250
     * Read View Properties
251
     * @param string $sPart
252
     */
253 4
    protected function loadViewProperties($sPart)
254
    {
255 4
        $xmlReader = new XMLReader();
256 4
        if ($xmlReader->getDomFromString($sPart)) {
257 4
            $pathZoom = '/p:viewPr/p:slideViewPr/p:cSldViewPr/p:cViewPr/p:scale/a:sx';
258 4
            $oElement = $xmlReader->getElement($pathZoom);
259 4
            if ($oElement instanceof \DOMElement) {
260 3
                if ($oElement->hasAttribute('d') && $oElement->hasAttribute('n')) {
261 3
                    $this->oPhpPresentation->getPresentationProperties()->setZoom($oElement->getAttribute('n') / $oElement->getAttribute('d'));
262
                }
263
            }
264
        }
265 4
    }
266
267
    /**
268
     * Extract all slides
269
     * @param $sPart
270
     * @throws \Exception
271
     */
272 4
    protected function loadSlides($sPart)
273
    {
274 4
        $xmlReader = new XMLReader();
275 4
        if ($xmlReader->getDomFromString($sPart)) {
276 4
            $fileRels = 'ppt/_rels/presentation.xml.rels';
277 4
            $this->loadRels($fileRels);
278
            // Load the Masterslides
279 4
            $this->loadMasterSlides($xmlReader, $fileRels);
280
            // Continue with loading the slides
281 4
            foreach ($xmlReader->getElements('/p:presentation/p:sldIdLst/p:sldId') as $oElement) {
282 4
                if (!($oElement instanceof \DOMElement)) {
283
                    continue;
284
                }
285 4
                $rId = $oElement->getAttribute('r:id');
286 4
                $pathSlide = isset($this->arrayRels[$fileRels][$rId]) ? $this->arrayRels[$fileRels][$rId]['Target'] : '';
287 4
                if (!empty($pathSlide)) {
288 4
                    $pptSlide = $this->oZip->getFromName('ppt/' . $pathSlide);
289 4
                    if ($pptSlide !== false) {
290 4
                        $slideRels = 'ppt/slides/_rels/' . basename($pathSlide) . '.rels';
291 4
                        $this->loadRels($slideRels);
292 4
                        $this->loadSlide($pptSlide, basename($pathSlide));
293 4
                        foreach ($this->arrayRels[$slideRels] as $rel) {
294 4
                            if ($rel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide') {
295
                                $this->loadSlideNote(basename($rel['Target']), $this->oPhpPresentation->getActiveSlide());
296
                            }
297
                        }
298
                    }
299
                }
300
            }
301
        }
302 4
    }
303
304
    /**
305
     * Extract all MasterSlides
306
     * @param XMLReader $xmlReader
307
     * @param string $fileRels
308
     * @throws \Exception
309
     */
310 4
    protected function loadMasterSlides(XMLReader $xmlReader, $fileRels)
311
    {
312
        // Get all the MasterSlide Id's from the presentation.xml file
313 4
        foreach ($xmlReader->getElements('/p:presentation/p:sldMasterIdLst/p:sldMasterId') as $oElement) {
314 4
            if (!($oElement instanceof \DOMElement)) {
315
                continue;
316
            }
317 4
            $rId = $oElement->getAttribute('r:id');
318
            // Get the path to the masterslide from the array with _rels files
319 4
            $pathMasterSlide = isset($this->arrayRels[$fileRels][$rId]) ?
320 4
                $this->arrayRels[$fileRels][$rId]['Target'] : '';
321 4
            if (!empty($pathMasterSlide)) {
322 4
                $pptMasterSlide = $this->oZip->getFromName('ppt/' . $pathMasterSlide);
323 4
                if ($pptMasterSlide !== false) {
324 4
                    $this->loadRels('ppt/slideMasters/_rels/' . basename($pathMasterSlide) . '.rels');
325 4
                    $this->loadMasterSlide($pptMasterSlide, basename($pathMasterSlide));
326
                }
327
            }
328
        }
329 4
    }
330
331
    /**
332
     * Extract data from slide
333
     * @param string $sPart
334
     * @param string $baseFile
335
     * @throws \Exception
336
     */
337 4
    protected function loadSlide($sPart, $baseFile)
338
    {
339 4
        $xmlReader = new XMLReader();
340 4
        if ($xmlReader->getDomFromString($sPart)) {
341
            // Core
342 4
            $oSlide = $this->oPhpPresentation->createSlide();
343 4
            $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1);
344 4
            $oSlide->setRelsIndex('ppt/slides/_rels/' . $baseFile . '.rels');
345
346
            // Background
347 4
            $oElement = $xmlReader->getElement('/p:sld/p:cSld/p:bg/p:bgPr');
348 4
            if ($oElement instanceof \DOMElement) {
349
                $oElementColor = $xmlReader->getElement('a:solidFill/a:srgbClr', $oElement);
350
                if ($oElementColor instanceof \DOMElement) {
351
                    // Color
352
                    $oColor = new Color();
353
                    $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
354
                    // Background
355
                    $oBackground = new Slide\Background\Color();
356
                    $oBackground->setColor($oColor);
357
                    // Slide Background
358
                    $oSlide = $this->oPhpPresentation->getActiveSlide();
359
                    $oSlide->setBackground($oBackground);
360
                }
361
                $oElementColor = $xmlReader->getElement('a:solidFill/a:schemeClr', $oElement);
362
                if ($oElementColor instanceof \DOMElement) {
363
                    // Color
364
                    $oColor = new SchemeColor();
365
                    $oColor->setValue($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
366
                    // Background
367
                    $oBackground = new Slide\Background\SchemeColor();
368
                    $oBackground->setSchemeColor($oColor);
369
                    // Slide Background
370
                    $oSlide = $this->oPhpPresentation->getActiveSlide();
371
                    $oSlide->setBackground($oBackground);
372
                }
373
                $oElementImage = $xmlReader->getElement('a:blipFill/a:blip', $oElement);
374
                if ($oElementImage instanceof \DOMElement) {
375
                    $relImg = $this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'][$oElementImage->getAttribute('r:embed')];
376
                    if (is_array($relImg)) {
377
                        // File
378
                        $pathImage = 'ppt/slides/' . $relImg['Target'];
379
                        $pathImage = explode('/', $pathImage);
380
                        foreach ($pathImage as $key => $partPath) {
381
                            if ($partPath == '..') {
382
                                unset($pathImage[$key - 1]);
383
                                unset($pathImage[$key]);
384
                            }
385
                        }
386
                        $pathImage = implode('/', $pathImage);
387
                        $contentImg = $this->oZip->getFromName($pathImage);
388
389
                        $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg');
390
                        file_put_contents($tmpBkgImg, $contentImg);
391
                        // Background
392
                        $oBackground = new Slide\Background\Image();
393
                        $oBackground->setPath($tmpBkgImg);
394
                        // Slide Background
395
                        $oSlide = $this->oPhpPresentation->getActiveSlide();
396
                        $oSlide->setBackground($oBackground);
397
                    }
398
                }
399
            }
400
401
            // Shapes
402 4
            $arrayElements = $xmlReader->getElements('/p:sld/p:cSld/p:spTree/*');
403 4
            if ($arrayElements) {
404 4
                $this->loadSlideShapes($oSlide, $arrayElements, $xmlReader);
405
            }
406
407
            // Layout
408 4
            $oSlide = $this->oPhpPresentation->getActiveSlide();
409 4
            foreach ($this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'] as $valueRel) {
410 4
                if ($valueRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout') {
411 4
                    $layoutBasename = basename($valueRel['Target']);
412 4
                    if (array_key_exists($layoutBasename, $this->arraySlideLayouts)) {
413 4
                        $oSlide->setSlideLayout($this->arraySlideLayouts[$layoutBasename]);
414
                    }
415 4
                    break;
416
                }
417
            }
418
        }
419 4
    }
420
421
    /**
422
     * @param string $sPart
423
     * @param string $baseFile
424
     * @throws \Exception
425
     */
426 4
    protected function loadMasterSlide($sPart, $baseFile)
427
    {
428 4
        $xmlReader = new XMLReader();
429 4
        if ($xmlReader->getDomFromString($sPart)) {
430
            // Core
431 4
            $oSlideMaster = $this->oPhpPresentation->createMasterSlide();
432 4
            $oSlideMaster->setTextStyles(new TextStyle(false));
433 4
            $oSlideMaster->setRelsIndex('ppt/slideMasters/_rels/' . $baseFile . '.rels');
434
435
            // Background
436 4
            $oElement = $xmlReader->getElement('/p:sldMaster/p:cSld/p:bg');
437 4
            if ($oElement instanceof \DOMElement) {
438 4
                $this->loadSlideBackground($xmlReader, $oElement, $oSlideMaster);
439
            }
440
441
            // Shapes
442 4
            $arrayElements = $xmlReader->getElements('/p:sldMaster/p:cSld/p:spTree/*');
443 4
            if ($arrayElements) {
444 4
                $this->loadSlideShapes($oSlideMaster, $arrayElements, $xmlReader);
445
            }
446
            // Header & Footer
447
448
            // ColorMapping
449 4
            $colorMap = array();
450 4
            $oElement = $xmlReader->getElement('/p:sldMaster/p:clrMap');
451 4
            if ($oElement->hasAttributes()) {
452 4
                foreach ($oElement->attributes as $attr) {
453 4
                    $colorMap[$attr->nodeName] = $attr->nodeValue;
454
                }
455 4
                $oSlideMaster->colorMap->setMapping($colorMap);
456
            }
457
458
            // TextStyles
459 4
            $arrayElementTxStyles = $xmlReader->getElements('/p:sldMaster/p:txStyles/*');
460 4
            if ($arrayElementTxStyles) {
461 4
                foreach ($arrayElementTxStyles as $oElementTxStyle) {
462 4
                    $arrayElementsLvl = $xmlReader->getElements('/p:sldMaster/p:txStyles/' . $oElementTxStyle->nodeName . '/*');
463 4
                    foreach ($arrayElementsLvl as $oElementLvl) {
464 4
                        if (!($oElementLvl instanceof \DOMElement) || $oElementLvl->nodeName == 'a:extLst') {
465 1
                            continue;
466
                        }
467 4
                        $oRTParagraph = new Paragraph();
468
469 4
                        if ($oElementLvl->nodeName == 'a:defPPr') {
470 3
                            $level = 0;
471
                        } else {
472 4
                            $level = str_replace('a:lvl', '', $oElementLvl->nodeName);
473 4
                            $level = str_replace('pPr', '', $level);
474
                        }
475
476 4
                        if ($oElementLvl->hasAttribute('algn')) {
477 4
                            $oRTParagraph->getAlignment()->setHorizontal($oElementLvl->getAttribute('algn'));
478
                        }
479 4
                        if ($oElementLvl->hasAttribute('marL')) {
480 4
                            $val = $oElementLvl->getAttribute('marL');
481 4
                            $val = CommonDrawing::emuToPixels($val);
482 4
                            $oRTParagraph->getAlignment()->setMarginLeft($val);
483
                        }
484 4
                        if ($oElementLvl->hasAttribute('marR')) {
485
                            $val = $oElementLvl->getAttribute('marR');
486
                            $val = CommonDrawing::emuToPixels($val);
487
                            $oRTParagraph->getAlignment()->setMarginRight($val);
488
                        }
489 4
                        if ($oElementLvl->hasAttribute('indent')) {
490 4
                            $val = $oElementLvl->getAttribute('indent');
491 4
                            $val = CommonDrawing::emuToPixels($val);
492 4
                            $oRTParagraph->getAlignment()->setIndent($val);
493
                        }
494 4
                        $oElementLvlDefRPR = $xmlReader->getElement('a:defRPr', $oElementLvl);
495 4
                        if ($oElementLvlDefRPR instanceof \DOMElement) {
496 4
                            if ($oElementLvlDefRPR->hasAttribute('sz')) {
497 4
                                $oRTParagraph->getFont()->setSize($oElementLvlDefRPR->getAttribute('sz') / 100);
498
                            }
499 4
                            if ($oElementLvlDefRPR->hasAttribute('b') && $oElementLvlDefRPR->getAttribute('b') == 1) {
500 1
                                $oRTParagraph->getFont()->setBold(true);
501
                            }
502 4
                            if ($oElementLvlDefRPR->hasAttribute('i') && $oElementLvlDefRPR->getAttribute('i') == 1) {
503
                                $oRTParagraph->getFont()->setItalic(true);
504
                            }
505
                        }
506 4
                        $oElementSchemeColor = $xmlReader->getElement('a:defRPr/a:solidFill/a:schemeClr', $oElementLvl);
507 4
                        if ($oElementSchemeColor instanceof \DOMElement) {
508 4
                            if ($oElementSchemeColor->hasAttribute('val')) {
509 4
                                $oSchemeColor = new SchemeColor();
510 4
                                $oSchemeColor->setValue($oElementSchemeColor->getAttribute('val'));
511 4
                                $oRTParagraph->getFont()->setColor($oSchemeColor);
512
                            }
513
                        }
514
515 4
                        switch ($oElementTxStyle->nodeName) {
516 4
                            case 'p:bodyStyle':
517 4
                                $oSlideMaster->getTextStyles()->setBodyStyleAtLvl($oRTParagraph, $level);
518 4
                                break;
519 4
                            case 'p:otherStyle':
520 4
                                $oSlideMaster->getTextStyles()->setOtherStyleAtLvl($oRTParagraph, $level);
521 4
                                break;
522 4
                            case 'p:titleStyle':
523 4
                                $oSlideMaster->getTextStyles()->setTitleStyleAtLvl($oRTParagraph, $level);
524 4
                                break;
525
                        }
526
                    }
527
                }
528
            }
529
530
            // Load the theme
531 4
            foreach ($this->arrayRels[$oSlideMaster->getRelsIndex()] as $arrayRel) {
532 4
                if ($arrayRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme') {
533 4
                    $pptTheme = $this->oZip->getFromName('ppt/' . substr($arrayRel['Target'], strrpos($arrayRel['Target'], '../') + 3));
534 4
                    if ($pptTheme !== false) {
535 4
                        $this->loadTheme($pptTheme, $oSlideMaster);
536
                    }
537 4
                    break;
538
                }
539
            }
540
541
            // Load the Layoutslide
542 4
            foreach ($xmlReader->getElements('/p:sldMaster/p:sldLayoutIdLst/p:sldLayoutId') as $oElement) {
543 4
                if (!($oElement instanceof \DOMElement)) {
544
                    continue;
545
                }
546 4
                $rId = $oElement->getAttribute('r:id');
547
                // Get the path to the masterslide from the array with _rels files
548 4
                $pathLayoutSlide = isset($this->arrayRels[$oSlideMaster->getRelsIndex()][$rId]) ?
549 4
                    $this->arrayRels[$oSlideMaster->getRelsIndex()][$rId]['Target'] : '';
550 4
                if (!empty($pathLayoutSlide)) {
551 4
                    $pptLayoutSlide = $this->oZip->getFromName('ppt/' . substr($pathLayoutSlide, strrpos($pathLayoutSlide, '../') + 3));
552 4
                    if ($pptLayoutSlide !== false) {
553 4
                        $this->loadRels('ppt/slideLayouts/_rels/' . basename($pathLayoutSlide) . '.rels');
554 4
                        $oSlideMaster->addSlideLayout(
555 4
                            $this->loadLayoutSlide($pptLayoutSlide, basename($pathLayoutSlide), $oSlideMaster)
556
                        );
557
                    }
558
                }
559
            }
560
        }
561 4
    }
562
563
    /**
564
     * @param string $sPart
565
     * @param string $baseFile
566
     * @param SlideMaster $oSlideMaster
567
     * @return SlideLayout|null
568
     * @throws \Exception
569
     */
570 4
    protected function loadLayoutSlide($sPart, $baseFile, SlideMaster $oSlideMaster)
571
    {
572 4
        $xmlReader = new XMLReader();
573 4
        if ($xmlReader->getDomFromString($sPart)) {
574
            // Core
575 4
            $oSlideLayout = new SlideLayout($oSlideMaster);
576 4
            $oSlideLayout->setRelsIndex('ppt/slideLayouts/_rels/' . $baseFile . '.rels');
577
578
            // Name
579 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:cSld');
580 4
            if ($oElement instanceof \DOMElement && $oElement->hasAttribute('name')) {
581 4
                $oSlideLayout->setLayoutName($oElement->getAttribute('name'));
582
            }
583
584
            // Background
585 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:cSld/p:bg');
586 4
            if ($oElement instanceof \DOMElement) {
587 1
                $this->loadSlideBackground($xmlReader, $oElement, $oSlideLayout);
588
            }
589
590
            // ColorMapping
591 4
            $oElement = $xmlReader->getElement('/p:sldLayout/p:clrMapOvr/a:overrideClrMapping');
592 4
            if ($oElement instanceof \DOMElement && $oElement->hasAttributes()) {
593 1
                $colorMap = array();
594 1
                foreach ($oElement->attributes as $attr) {
595 1
                    $colorMap[$attr->nodeName] = $attr->nodeValue;
596
                }
597 1
                $oSlideLayout->colorMap->setMapping($colorMap);
598
            }
599
600
            // Shapes
601 4
            $oElements = $xmlReader->getElements('/p:sldLayout/p:cSld/p:spTree/*');
602 4
            if ($oElements) {
603 4
                $this->loadSlideShapes($oSlideLayout, $oElements, $xmlReader);
604
            }
605 4
            $this->arraySlideLayouts[$baseFile] = &$oSlideLayout;
606 4
            return $oSlideLayout;
607
        }
608
        return null;
609
    }
610
611
    /**
612
     * @param string $sPart
613
     * @param SlideMaster $oSlideMaster
614
     */
615 4
    protected function loadTheme($sPart, SlideMaster $oSlideMaster)
616
    {
617 4
        $xmlReader = new XMLReader();
618 4
        if ($xmlReader->getDomFromString($sPart)) {
619 4
            $oElements = $xmlReader->getElements('/a:theme/a:themeElements/a:clrScheme/*');
620 4
            if ($oElements) {
621 4
                foreach ($oElements as $oElement) {
622 4
                    $oSchemeColor = new SchemeColor();
623 4
                    $oSchemeColor->setValue(str_replace('a:', '', $oElement->tagName));
624 4
                    $colorElement = $xmlReader->getElement('*', $oElement);
625 4
                    if ($colorElement instanceof \DOMElement) {
626 4
                        if ($colorElement->hasAttribute('lastClr')) {
627 4
                            $oSchemeColor->setRGB($colorElement->getAttribute('lastClr'));
628 4
                        } elseif ($colorElement->hasAttribute('val')) {
629 4
                            $oSchemeColor->setRGB($colorElement->getAttribute('val'));
630
                        }
631
                    }
632 4
                    $oSlideMaster->addSchemeColor($oSchemeColor);
633
                }
634
            }
635
        }
636 4
    }
637
638
    /**
639
     * @param XMLReader $xmlReader
640
     * @param \DOMElement $oElement
641
     * @param AbstractSlide $oSlide
642
     * @throws \Exception
643
     */
644 4
    protected function loadSlideBackground(XMLReader $xmlReader, \DOMElement $oElement, AbstractSlide $oSlide)
645
    {
646
        // Background color
647 4
        $oElementColor = $xmlReader->getElement('p:bgPr/a:solidFill/a:srgbClr', $oElement);
648 4
        if ($oElementColor instanceof \DOMElement) {
649
            // Color
650
            $oColor = new Color();
651
            $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
652
            // Background
653
            $oBackground = new Slide\Background\Color();
654
            $oBackground->setColor($oColor);
655
            // Slide Background
656
            $oSlide->setBackground($oBackground);
657
        }
658
659
        // Background scheme color
660 4
        $oElementSchemeColor = $xmlReader->getElement('p:bgRef/a:schemeClr', $oElement);
661 4
        if ($oElementSchemeColor instanceof \DOMElement) {
662
            // Color
663 4
            $oColor = new SchemeColor();
664 4
            $oColor->setValue($oElementSchemeColor->hasAttribute('val') ? $oElementSchemeColor->getAttribute('val') : null);
665
            // Background
666 4
            $oBackground = new Slide\Background\SchemeColor();
667 4
            $oBackground->setSchemeColor($oColor);
668
            // Slide Background
669 4
            $oSlide->setBackground($oBackground);
670
        }
671
672
        // Background image
673 4
        $oElementImage = $xmlReader->getElement('p:bgPr/a:blipFill/a:blip', $oElement);
674 4
        if ($oElementImage instanceof \DOMElement) {
675
            $relImg = $this->arrayRels[$oSlide->getRelsIndex()][$oElementImage->getAttribute('r:embed')];
676
            if (is_array($relImg)) {
677
                // File
678
                $pathImage = 'ppt/slides/' . $relImg['Target'];
679
                $pathImage = explode('/', $pathImage);
680
                foreach ($pathImage as $key => $partPath) {
681
                    if ($partPath == '..') {
682
                        unset($pathImage[$key - 1]);
683
                        unset($pathImage[$key]);
684
                    }
685
                }
686
                $pathImage = implode('/', $pathImage);
687
                $contentImg = $this->oZip->getFromName($pathImage);
688
689
                $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg');
690
                file_put_contents($tmpBkgImg, $contentImg);
691
                // Background
692
                $oBackground = new Slide\Background\Image();
693
                $oBackground->setPath($tmpBkgImg);
694
                // Slide Background
695
                $oSlide->setBackground($oBackground);
696
            }
697
        }
698 4
    }
699
700
    /**
701
     * @param string $baseFile
702
     * @param Slide $oSlide
703
     * @throws \Exception
704
     */
705
    protected function loadSlideNote($baseFile, Slide $oSlide)
706
    {
707
        $sPart = $this->oZip->getFromName('ppt/notesSlides/' . $baseFile);
708
        $xmlReader = new XMLReader();
709
        if ($xmlReader->getDomFromString($sPart)) {
710
            $oNote = $oSlide->getNote();
711
712
            $arrayElements = $xmlReader->getElements('/p:notes/p:cSld/p:spTree/*');
713
            if ($arrayElements) {
714
                $this->loadSlideShapes($oNote, $arrayElements, $xmlReader);
715
            }
716
        }
717
    }
718
719
    /**
720
     * @param XMLReader $document
721
     * @param \DOMElement $node
722
     * @param AbstractSlide $oSlide
723
     * @throws \Exception
724
     */
725 3
    protected function loadShapeDrawing(XMLReader $document, \DOMElement $node, AbstractSlide $oSlide)
726
    {
727
        // Core
728 3
        $oShape = new Gd();
729 3
        $oShape->getShadow()->setVisible(false);
730
        // Variables
731 3
        $fileRels = $oSlide->getRelsIndex();
732
733 3
        $oElement = $document->getElement('p:nvPicPr/p:cNvPr', $node);
734 3
        if ($oElement instanceof \DOMElement) {
735 3
            $oShape->setName($oElement->hasAttribute('name') ? $oElement->getAttribute('name') : '');
736 3
            $oShape->setDescription($oElement->hasAttribute('descr') ? $oElement->getAttribute('descr') : '');
737
738
            // Hyperlink
739 3
            $oElementHlinkClick = $document->getElement('a:hlinkClick', $oElement);
740 3
            if (is_object($oElementHlinkClick)) {
741 1
                if ($oElementHlinkClick->hasAttribute('tooltip')) {
0 ignored issues
show
Bug introduced by
The method hasAttribute() does not exist on DOMNode. Did you maybe mean hasAttributes()?

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

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

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

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

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

Loading history...
745 1
                    $oShape->getHyperlink()->setUrl($this->arrayRels[$fileRels][$oElementHlinkClick->getAttribute('r:id')]['Target']);
746
                }
747
            }
748
        }
749
750 3
        $oElement = $document->getElement('p:blipFill/a:blip', $node);
751 3
        if ($oElement instanceof \DOMElement) {
752 3
            if ($oElement->hasAttribute('r:embed') && isset($this->arrayRels[$fileRels][$oElement->getAttribute('r:embed')]['Target'])) {
753 3
                $pathImage = 'ppt/slides/' . $this->arrayRels[$fileRels][$oElement->getAttribute('r:embed')]['Target'];
754 3
                $pathImage = explode('/', $pathImage);
755 3
                foreach ($pathImage as $key => $partPath) {
756 3
                    if ($partPath == '..') {
757 3
                        unset($pathImage[$key - 1]);
758 3
                        unset($pathImage[$key]);
759
                    }
760
                }
761 3
                $pathImage = implode('/', $pathImage);
762 3
                $imageFile = $this->oZip->getFromName($pathImage);
763 3
                if (!empty($imageFile)) {
764 3
                    $info = getimagesizefromstring($imageFile);
765 3
                    $oShape->setMimeType($info['mime']);
766 3
                    $oShape->setRenderingFunction(str_replace('/', '', $info['mime']));
767 3
                    $oShape->setImageResource(imagecreatefromstring($imageFile));
768
                }
769
            }
770
        }
771
772 3
        $oElement = $document->getElement('p:spPr', $node);
773 3
        if ($oElement instanceof \DOMElement) {
774 3
            $oFill = $this->loadStyleFill($document, $oElement);
775 3
            $oShape->setFill($oFill);
776
        }
777
778 3
        $oElement = $document->getElement('p:spPr/a:xfrm', $node);
779 3
        if ($oElement instanceof \DOMElement) {
780 3
            if ($oElement->hasAttribute('rot')) {
781 3
                $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
782
            }
783
        }
784
785 3
        $oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
786 3
        if ($oElement instanceof \DOMElement) {
787 3
            if ($oElement->hasAttribute('x')) {
788 3
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
789
            }
790 3
            if ($oElement->hasAttribute('y')) {
791 3
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
792
            }
793
        }
794
795 3
        $oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
796 3
        if ($oElement instanceof \DOMElement) {
797 3
            if ($oElement->hasAttribute('cx')) {
798 3
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
799
            }
800 3
            if ($oElement->hasAttribute('cy')) {
801 3
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
802
            }
803
        }
804
805 3
        $oElement = $document->getElement('p:spPr/a:effectLst', $node);
806 3
        if ($oElement instanceof \DOMElement) {
807 3
            $oShape->getShadow()->setVisible(true);
808
809 3
            $oSubElement = $document->getElement('a:outerShdw', $oElement);
810 3
            if ($oSubElement instanceof \DOMElement) {
811 3
                if ($oSubElement->hasAttribute('blurRad')) {
812 3
                    $oShape->getShadow()->setBlurRadius(CommonDrawing::emuToPixels($oSubElement->getAttribute('blurRad')));
813
                }
814 3
                if ($oSubElement->hasAttribute('dist')) {
815 3
                    $oShape->getShadow()->setDistance(CommonDrawing::emuToPixels($oSubElement->getAttribute('dist')));
816
                }
817 3
                if ($oSubElement->hasAttribute('dir')) {
818 3
                    $oShape->getShadow()->setDirection(CommonDrawing::angleToDegrees($oSubElement->getAttribute('dir')));
819
                }
820 3
                if ($oSubElement->hasAttribute('algn')) {
821 3
                    $oShape->getShadow()->setAlignment($oSubElement->getAttribute('algn'));
822
                }
823
            }
824
825 3
            $oSubElement = $document->getElement('a:outerShdw/a:srgbClr', $oElement);
826 3
            if ($oSubElement instanceof \DOMElement) {
827 3
                if ($oSubElement->hasAttribute('val')) {
828 3
                    $oColor = new Color();
829 3
                    $oColor->setRGB($oSubElement->getAttribute('val'));
830 3
                    $oShape->getShadow()->setColor($oColor);
831
                }
832
            }
833
834 3
            $oSubElement = $document->getElement('a:outerShdw/a:srgbClr/a:alpha', $oElement);
835 3
            if ($oSubElement instanceof \DOMElement) {
836 3
                if ($oSubElement->hasAttribute('val')) {
837 3
                    $oShape->getShadow()->setAlpha((int)$oSubElement->getAttribute('val') / 1000);
838
                }
839
            }
840
        }
841
842 3
        $oSlide->addShape($oShape);
843 3
    }
844
845
    /**
846
     * @param XMLReader $document
847
     * @param \DOMElement $node
848
     * @param AbstractSlide $oSlide
849
     * @throws \Exception
850
     */
851 4
    protected function loadShapeRichText(XMLReader $document, \DOMElement $node, $oSlide)
852
    {
853 4
        if (!$document->elementExists('p:txBody/a:p/a:r', $node)) {
854 4
            return;
855
        }
856
        // Core
857 4
        $oShape = $oSlide->createRichTextShape();
858 4
        $oShape->setParagraphs(array());
859
        // Variables
860 4
        if ($oSlide instanceof AbstractSlide) {
861 4
            $this->fileRels = $oSlide->getRelsIndex();
862
        }
863
864 4
        $oElement = $document->getElement('p:spPr/a:xfrm', $node);
865 4
        if ($oElement instanceof \DOMElement && $oElement->hasAttribute('rot')) {
866 4
            $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
867
        }
868
869 4
        $oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
870 4
        if ($oElement instanceof \DOMElement) {
871 4
            if ($oElement->hasAttribute('x')) {
872 4
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
873
            }
874 4
            if ($oElement->hasAttribute('y')) {
875 4
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
876
            }
877
        }
878
879 4
        $oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
880 4
        if ($oElement instanceof \DOMElement) {
881 4
            if ($oElement->hasAttribute('cx')) {
882 4
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
883
            }
884 4
            if ($oElement->hasAttribute('cy')) {
885 4
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
886
            }
887
        }
888
889 4
        $oElement = $document->getElement('p:nvSpPr/p:nvPr/p:ph', $node);
890 4
        if ($oElement instanceof \DOMElement) {
891 4
            if ($oElement->hasAttribute('type')) {
892 4
                $placeholder = new Placeholder($oElement->getAttribute('type'));
893 4
                $oShape->setPlaceHolder($placeholder);
894
            }
895
        }
896
897 4
        $arrayElements = $document->getElements('p:txBody/a:p', $node);
898 4
        foreach ($arrayElements as $oElement) {
899 4
            $this->loadParagraph($document, $oElement, $oShape);
900
        }
901
902 4
        if (count($oShape->getParagraphs()) > 0) {
903 4
            $oShape->setActiveParagraph(0);
904
        }
905 4
    }
906
907
    /**
908
     * @param XMLReader $document
909
     * @param \DOMElement $node
910
     * @param AbstractSlide $oSlide
911
     * @throws \Exception
912
     */
913
    protected function loadShapeTable(XMLReader $document, \DOMElement $node, AbstractSlide $oSlide)
914
    {
915
        $this->fileRels = $oSlide->getRelsIndex();
916
917
        $oShape = $oSlide->createTableShape();
918
919
        $oElement = $document->getElement('p:cNvPr', $node);
920
        if ($oElement instanceof \DOMElement) {
921
            if ($oElement->hasAttribute('name')) {
922
                $oShape->setName($oElement->getAttribute('name'));
923
            }
924
            if ($oElement->hasAttribute('descr')) {
925
                $oShape->setDescription($oElement->getAttribute('descr'));
926
            }
927
        }
928
929
        $oElement = $document->getElement('p:xfrm/a:off', $node);
930
        if ($oElement instanceof \DOMElement) {
931
            if ($oElement->hasAttribute('x')) {
932
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
933
            }
934
            if ($oElement->hasAttribute('y')) {
935
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
936
            }
937
        }
938
939
        $oElement = $document->getElement('p:xfrm/a:ext', $node);
940
        if ($oElement instanceof \DOMElement) {
941
            if ($oElement->hasAttribute('cx')) {
942
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
943
            }
944
            if ($oElement->hasAttribute('cy')) {
945
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
946
            }
947
        }
948
949
        $arrayElements = $document->getElements('a:graphic/a:graphicData/a:tbl/a:tblGrid/a:gridCol', $node);
950
        $oShape->setNumColumns($arrayElements->length);
951
        $oShape->createRow();
952
        foreach ($arrayElements as $key => $oElement) {
953
            if ($oElement instanceof \DOMElement && $oElement->getAttribute('w')) {
954
                $oShape->getRow(0)->getCell($key)->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('w')));
955
            }
956
        }
957
958
        $arrayElements = $document->getElements('a:graphic/a:graphicData/a:tbl/a:tr', $node);
959
        foreach ($arrayElements as $keyRow => $oElementRow) {
960
            if (!($oElementRow instanceof \DOMElement)) {
961
                continue;
962
            }
963
            $oRow = $oShape->getRow($keyRow, true);
964
            if (is_null($oRow)) {
965
                $oRow = $oShape->createRow();
966
            }
967
            if ($oElementRow->hasAttribute('h')) {
968
                $oRow->setHeight(CommonDrawing::emuToPixels($oElementRow->getAttribute('h')));
969
            }
970
            $arrayElementsCell = $document->getElements('a:tc', $oElementRow);
971
            foreach ($arrayElementsCell as $keyCell => $oElementCell) {
972
                if (!($oElementCell instanceof \DOMElement)) {
973
                    continue;
974
                }
975
                $oCell = $oRow->getCell($keyCell);
976
                $oCell->setParagraphs(array());
977
                if ($oElementCell->hasAttribute('gridSpan')) {
978
                    $oCell->setColSpan($oElementCell->getAttribute('gridSpan'));
979
                }
980
                if ($oElementCell->hasAttribute('rowSpan')) {
981
                    $oCell->setRowSpan($oElementCell->getAttribute('rowSpan'));
982
                }
983
984
                foreach ($document->getElements('a:txBody/a:p', $oElementCell) as $oElementPara) {
985
                    $this->loadParagraph($document, $oElementPara, $oCell);
0 ignored issues
show
Bug introduced by
It seems like $oCell defined by $oRow->getCell($keyCell) on line 975 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...
986
                }
987
988
                $oElementTcPr = $document->getElement('a:tcPr', $oElementCell);
989
                if ($oElementTcPr instanceof \DOMElement) {
990
                    $numParagraphs = count($oCell->getParagraphs());
991
                    if ($numParagraphs > 0) {
992
                        if ($oElementTcPr->hasAttribute('vert')) {
993
                            $oCell->getParagraph(0)->getAlignment()->setTextDirection($oElementTcPr->getAttribute('vert'));
994
                        }
995
                        if ($oElementTcPr->hasAttribute('anchor')) {
996
                            $oCell->getParagraph(0)->getAlignment()->setVertical($oElementTcPr->getAttribute('anchor'));
997
                        }
998
                        if ($oElementTcPr->hasAttribute('marB')) {
999
                            $oCell->getParagraph(0)->getAlignment()->setMarginBottom($oElementTcPr->getAttribute('marB'));
1000
                        }
1001
                        if ($oElementTcPr->hasAttribute('marL')) {
1002
                            $oCell->getParagraph(0)->getAlignment()->setMarginLeft($oElementTcPr->getAttribute('marL'));
1003
                        }
1004
                        if ($oElementTcPr->hasAttribute('marR')) {
1005
                            $oCell->getParagraph(0)->getAlignment()->setMarginRight($oElementTcPr->getAttribute('marR'));
1006
                        }
1007
                        if ($oElementTcPr->hasAttribute('marT')) {
1008
                            $oCell->getParagraph(0)->getAlignment()->setMarginTop($oElementTcPr->getAttribute('marT'));
1009
                        }
1010
                    }
1011
1012
                    $oFill = $this->loadStyleFill($document, $oElementTcPr);
1013
                    if ($oFill instanceof Fill) {
1014
                        $oCell->setFill($oFill);
1015
                    }
1016
1017
                    $oBorders = new Borders();
1018
                    $oElementBorderL = $document->getElement('a:lnL', $oElementTcPr);
1019
                    if ($oElementBorderL instanceof \DOMElement) {
1020
                        $this->loadStyleBorder($document, $oElementBorderL, $oBorders->getLeft());
1021
                    }
1022
                    $oElementBorderR = $document->getElement('a:lnR', $oElementTcPr);
1023
                    if ($oElementBorderR instanceof \DOMElement) {
1024
                        $this->loadStyleBorder($document, $oElementBorderR, $oBorders->getRight());
1025
                    }
1026
                    $oElementBorderT = $document->getElement('a:lnT', $oElementTcPr);
1027
                    if ($oElementBorderT instanceof \DOMElement) {
1028
                        $this->loadStyleBorder($document, $oElementBorderT, $oBorders->getTop());
1029
                    }
1030
                    $oElementBorderB = $document->getElement('a:lnB', $oElementTcPr);
1031
                    if ($oElementBorderB instanceof \DOMElement) {
1032
                        $this->loadStyleBorder($document, $oElementBorderB, $oBorders->getBottom());
1033
                    }
1034
                    $oElementBorderDiagDown = $document->getElement('a:lnTlToBr', $oElementTcPr);
1035
                    if ($oElementBorderDiagDown instanceof \DOMElement) {
1036
                        $this->loadStyleBorder($document, $oElementBorderDiagDown, $oBorders->getDiagonalDown());
1037
                    }
1038
                    $oElementBorderDiagUp = $document->getElement('a:lnBlToTr', $oElementTcPr);
1039
                    if ($oElementBorderDiagUp instanceof \DOMElement) {
1040
                        $this->loadStyleBorder($document, $oElementBorderDiagUp, $oBorders->getDiagonalUp());
1041
                    }
1042
                    $oCell->setBorders($oBorders);
1043
                }
1044
            }
1045
        }
1046
    }
1047
1048
    /**
1049
     * @param XMLReader $document
1050
     * @param \DOMElement $oElement
1051
     * @param Cell|RichText $oShape
1052
     * @throws \Exception
1053
     */
1054 4
    protected function loadParagraph(XMLReader $document, \DOMElement $oElement, $oShape)
1055
    {
1056
        // Core
1057 4
        $oParagraph = $oShape->createParagraph();
1058 4
        $oParagraph->setRichTextElements(array());
1059
1060 4
        $oSubElement = $document->getElement('a:pPr', $oElement);
1061 4
        if ($oSubElement instanceof \DOMElement) {
1062 4
            if ($oSubElement->hasAttribute('algn')) {
1063 3
                $oParagraph->getAlignment()->setHorizontal($oSubElement->getAttribute('algn'));
1064
            }
1065 4
            if ($oSubElement->hasAttribute('fontAlgn')) {
1066 3
                $oParagraph->getAlignment()->setVertical($oSubElement->getAttribute('fontAlgn'));
1067
            }
1068 4
            if ($oSubElement->hasAttribute('marL')) {
1069 3
                $oParagraph->getAlignment()->setMarginLeft(CommonDrawing::emuToPixels($oSubElement->getAttribute('marL')));
1070
            }
1071 4
            if ($oSubElement->hasAttribute('marR')) {
1072 3
                $oParagraph->getAlignment()->setMarginRight(CommonDrawing::emuToPixels($oSubElement->getAttribute('marR')));
1073
            }
1074 4
            if ($oSubElement->hasAttribute('indent')) {
1075 3
                $oParagraph->getAlignment()->setIndent(CommonDrawing::emuToPixels($oSubElement->getAttribute('indent')));
1076
            }
1077 4
            if ($oSubElement->hasAttribute('lvl')) {
1078 4
                $oParagraph->getAlignment()->setLevel($oSubElement->getAttribute('lvl'));
1079
            }
1080
1081 4
            $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NONE);
1082
1083 4
            $oElementBuFont = $document->getElement('a:buFont', $oSubElement);
1084 4
            if ($oElementBuFont instanceof \DOMElement) {
1085 3
                if ($oElementBuFont->hasAttribute('typeface')) {
1086 3
                    $oParagraph->getBulletStyle()->setBulletFont($oElementBuFont->getAttribute('typeface'));
1087
                }
1088
            }
1089 4
            $oElementBuChar = $document->getElement('a:buChar', $oSubElement);
1090 4
            if ($oElementBuChar instanceof \DOMElement) {
1091 3
                $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_BULLET);
1092 3
                if ($oElementBuChar->hasAttribute('char')) {
1093 3
                    $oParagraph->getBulletStyle()->setBulletChar($oElementBuChar->getAttribute('char'));
1094
                }
1095
            }
1096 4
            $oElementBuAutoNum = $document->getElement('a:buAutoNum', $oSubElement);
1097 4
            if ($oElementBuAutoNum instanceof \DOMElement) {
1098
                $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NUMERIC);
1099
                if ($oElementBuAutoNum->hasAttribute('type')) {
1100
                    $oParagraph->getBulletStyle()->setBulletNumericStyle($oElementBuAutoNum->getAttribute('type'));
1101
                }
1102
                if ($oElementBuAutoNum->hasAttribute('startAt') && $oElementBuAutoNum->getAttribute('startAt') != 1) {
1103
                    $oParagraph->getBulletStyle()->setBulletNumericStartAt($oElementBuAutoNum->getAttribute('startAt'));
1104
                }
1105
            }
1106 4
            $oElementBuClr = $document->getElement('a:buClr', $oSubElement);
1107 4
            if ($oElementBuClr instanceof \DOMElement) {
1108
                $oColor = new Color();
1109
                /**
1110
                 * @todo Create protected for reading Color
1111
                 */
1112
                $oElementColor = $document->getElement('a:srgbClr', $oElementBuClr);
1113
                if ($oElementColor instanceof \DOMElement) {
1114
                    $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
1115
                }
1116
                $oParagraph->getBulletStyle()->setBulletColor($oColor);
1117
            }
1118
        }
1119 4
        $arraySubElements = $document->getElements('(a:r|a:br)', $oElement);
1120 4
        foreach ($arraySubElements as $oSubElement) {
1121 4
            if ($oSubElement->tagName == 'a:br') {
1122 3
                $oParagraph->createBreak();
1123
            }
1124 4
            if ($oSubElement->tagName == 'a:r') {
1125 4
                $oElementrPr = $document->getElement('a:rPr', $oSubElement);
1126 4
                if (is_object($oElementrPr)) {
1127 4
                    $oText = $oParagraph->createTextRun();
1128
1129 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...
1130 3
                        $att = $oElementrPr->getAttribute('b');
1131 3
                        $oText->getFont()->setBold($att == 'true' || $att == '1' ? true : false);
1132
                    }
1133 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...
1134 3
                        $att = $oElementrPr->getAttribute('i');
1135 3
                        $oText->getFont()->setItalic($att == 'true' || $att == '1' ? true : false);
1136
                    }
1137 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...
1138 3
                        $oText->getFont()->setStrikethrough($oElementrPr->getAttribute('strike') == 'noStrike' ? false : true);
1139
                    }
1140 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...
1141 3
                        $oText->getFont()->setSize((int)($oElementrPr->getAttribute('sz') / 100));
1142
                    }
1143 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...
1144 3
                        $oText->getFont()->setUnderline($oElementrPr->getAttribute('u'));
1145
                    }
1146
                    // Color
1147 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...
1148 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...
1149 3
                        $oColor = new Color();
1150 3
                        $oColor->setRGB($oElementSrgbClr->getAttribute('val'));
1151 3
                        $oText->getFont()->setColor($oColor);
1152
                    }
1153
                    // Hyperlink
1154 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...
1155 4
                    if (is_object($oElementHlinkClick)) {
1156 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...
1157 3
                            $oText->getHyperlink()->setTooltip($oElementHlinkClick->getAttribute('tooltip'));
1158
                        }
1159 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...
1160 3
                            $oText->getHyperlink()->setUrl($this->arrayRels[$this->fileRels][$oElementHlinkClick->getAttribute('r:id')]['Target']);
1161
                        }
1162
                    }
1163
                    //} else {
1164
                    // $oText = $oParagraph->createText();
1165
1166 4
                    $oSubSubElement = $document->getElement('a:t', $oSubElement);
1167 4
                    $oText->setText($oSubSubElement->nodeValue);
1168
                }
1169
            }
1170
        }
1171 4
    }
1172
1173
    /**
1174
     * @param XMLReader $xmlReader
1175
     * @param \DOMElement $oElement
1176
     * @param Border $oBorder
1177
     * @throws \Exception
1178
     */
1179
    protected function loadStyleBorder(XMLReader $xmlReader, \DOMElement $oElement, Border $oBorder)
1180
    {
1181
        if ($oElement->hasAttribute('w')) {
1182
            $oBorder->setLineWidth($oElement->getAttribute('w') / 12700);
1183
        }
1184
        if ($oElement->hasAttribute('cmpd')) {
1185
            $oBorder->setLineStyle($oElement->getAttribute('cmpd'));
1186
        }
1187
1188
        $oElementNoFill = $xmlReader->getElement('a:noFill', $oElement);
1189
        if ($oElementNoFill instanceof \DOMElement && $oBorder->getLineStyle() == Border::LINE_SINGLE) {
1190
            $oBorder->setLineStyle(Border::LINE_NONE);
1191
        }
1192
1193
        $oElementColor = $xmlReader->getElement('a:solidFill/a:srgbClr', $oElement);
1194
        if ($oElementColor instanceof \DOMElement) {
1195
            $oBorder->setColor($this->loadStyleColor($xmlReader, $oElementColor));
1196
        }
1197
1198
        $oElementDashStyle = $xmlReader->getElement('a:prstDash', $oElement);
1199
        if ($oElementDashStyle instanceof \DOMElement && $oElementDashStyle->hasAttribute('val')) {
1200
            $oBorder->setDashStyle($oElementDashStyle->getAttribute('val'));
1201
        }
1202
    }
1203
1204
    /**
1205
     * @param XMLReader $xmlReader
1206
     * @param \DOMElement $oElement
1207
     * @return Color
1208
     */
1209
    protected function loadStyleColor(XMLReader $xmlReader, \DOMElement $oElement)
1210
    {
1211
        $oColor = new Color();
1212
        $oColor->setRGB($oElement->getAttribute('val'));
1213
        $oElementAlpha = $xmlReader->getElement('a:alpha', $oElement);
1214
        if ($oElementAlpha instanceof \DOMElement && $oElementAlpha->hasAttribute('val')) {
1215
            $alpha = strtoupper(dechex((($oElementAlpha->getAttribute('val') / 1000) / 100) * 255));
1216
            $oColor->setRGB($oElement->getAttribute('val'), $alpha);
1217
        }
1218
        return $oColor;
1219
    }
1220
1221
    /**
1222
     * @param XMLReader $xmlReader
1223
     * @param \DOMElement $oElement
1224
     * @return null|Fill
1225
     * @throws \Exception
1226
     */
1227 3
    protected function loadStyleFill(XMLReader $xmlReader, \DOMElement $oElement)
1228
    {
1229
        // Gradient fill
1230 3
        $oElementFill = $xmlReader->getElement('a:gradFill', $oElement);
1231 3
        if ($oElementFill instanceof \DOMElement) {
1232
            $oFill = new Fill();
1233
            $oFill->setFillType(Fill::FILL_GRADIENT_LINEAR);
1234
1235
            $oElementColor = $xmlReader->getElement('a:gsLst/a:gs[@pos="0"]/a:srgbClr', $oElementFill);
1236
            if ($oElementColor instanceof \DOMElement && $oElementColor->hasAttribute('val')) {
1237
                $oFill->setStartColor($this->loadStyleColor($xmlReader, $oElementColor));
1238
            }
1239
1240
            $oElementColor = $xmlReader->getElement('a:gsLst/a:gs[@pos="100000"]/a:srgbClr', $oElementFill);
1241
            if ($oElementColor instanceof \DOMElement && $oElementColor->hasAttribute('val')) {
1242
                $oFill->setEndColor($this->loadStyleColor($xmlReader, $oElementColor));
1243
            }
1244
1245
            $oRotation = $xmlReader->getElement('a:lin', $oElementFill);
1246
            if ($oRotation instanceof \DOMElement && $oRotation->hasAttribute('ang')) {
1247
                $oFill->setRotation(CommonDrawing::angleToDegrees($oRotation->getAttribute('ang')));
1248
            }
1249
            return $oFill;
1250
        }
1251
1252
        // Solid fill
1253 3
        $oElementFill = $xmlReader->getElement('a:solidFill', $oElement);
1254 3
        if ($oElementFill instanceof \DOMElement) {
1255
            $oFill = new Fill();
1256
            $oFill->setFillType(Fill::FILL_SOLID);
1257
1258
            $oElementColor = $xmlReader->getElement('a:srgbClr', $oElementFill);
1259
            if ($oElementColor instanceof \DOMElement) {
1260
                $oFill->setStartColor($this->loadStyleColor($xmlReader, $oElementColor));
1261
            }
1262
            return $oFill;
1263
        }
1264 3
        return null;
1265
    }
1266
1267
    /**
1268
     * @param string $fileRels
1269
     */
1270 4
    protected function loadRels($fileRels)
1271
    {
1272 4
        $sPart = $this->oZip->getFromName($fileRels);
1273 4
        if ($sPart !== false) {
1274 4
            $xmlReader = new XMLReader();
1275 4
            if ($xmlReader->getDomFromString($sPart)) {
1276 4
                foreach ($xmlReader->getElements('*') as $oNode) {
1277 4
                    if (!($oNode instanceof \DOMElement)) {
1278
                        continue;
1279
                    }
1280 4
                    $this->arrayRels[$fileRels][$oNode->getAttribute('Id')] = array(
1281 4
                        'Target' => $oNode->getAttribute('Target'),
1282 4
                        'Type' => $oNode->getAttribute('Type'),
1283
                    );
1284
                }
1285
            }
1286
        }
1287 4
    }
1288
1289
    /**
1290
     * @param $oSlide
1291
     * @param \DOMNodeList $oElements
1292
     * @param XMLReader $xmlReader
1293
     * @throws \Exception
1294
     * @internal param $baseFile
1295
     */
1296 4
    protected function loadSlideShapes($oSlide, $oElements, $xmlReader)
1297
    {
1298 4
        foreach ($oElements as $oNode) {
1299 4
            switch ($oNode->tagName) {
1300 4
                case 'p:graphicFrame':
1301
                    $this->loadShapeTable($xmlReader, $oNode, $oSlide);
1302
                    break;
1303 4
                case 'p:pic':
1304 3
                    $this->loadShapeDrawing($xmlReader, $oNode, $oSlide);
1305 3
                    break;
1306 4
                case 'p:sp':
1307 4
                    $this->loadShapeRichText($xmlReader, $oNode, $oSlide);
1308 4
                    break;
1309
                default:
1310
                    //var_export($oNode->tagName);
1311
            }
1312
        }
1313 4
    }
1314
}
1315