Completed
Pull Request — develop (#208)
by Franck
22:58 queued 12:19
created

PowerPoint2007::getInt2d()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 2
crap 2
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\XMLReader;
21
use PhpOffice\Common\Drawing as CommonDrawing;
22
use PhpOffice\Common\Microsoft\OLERead;
23
use PhpOffice\PhpPresentation\DocumentLayout;
24
use PhpOffice\PhpPresentation\PhpPresentation;
25
use PhpOffice\PhpPresentation\Shape\RichText\Paragraph;
26
use PhpOffice\PhpPresentation\Slide\AbstractSlide;
27
use PhpOffice\PhpPresentation\Shape\Placeholder;
28
use PhpOffice\PhpPresentation\Slide\Background\Image;
29
use PhpOffice\PhpPresentation\Slide\SlideLayout;
30
use PhpOffice\PhpPresentation\Slide\SlideMaster;
31
use PhpOffice\PhpPresentation\Shape\Drawing\Gd;
32
use PhpOffice\PhpPresentation\Style\Bullet;
33
use PhpOffice\PhpPresentation\Style\Color;
34
use PhpOffice\PhpPresentation\Style\SchemeColor;
35
use PhpOffice\PhpPresentation\Style\TextStyle;
36
use ZipArchive;
37
38
/**
39
 * Serialized format reader
40
 */
41
class PowerPoint2007 extends AbstractReader implements ReaderInterface
42
{
43
    /**
44
     * Output Object
45
     * @var PhpPresentation
46
     */
47
    protected $oPhpPresentation;
48
    /**
49
     * Output Object
50
     * @var \ZipArchive
51
     */
52
    protected $oZip;
53
    /**
54
     * @var array[]
55
     */
56
    protected $arrayRels = array();
57
    /**
58
     * @var SlideLayout[]
59
     */
60
    protected $arraySlideLayouts = array();
61
    /*
62
     * @var string
63
     */
64
    protected $filename;
65
66
    /**
67
     * Can the current \PhpOffice\PhpPresentation\Reader\ReaderInterface read the file?
68
     *
69
     * @param  string $pFilename
70
     * @throws \Exception
71
     * @return boolean
72
     */
73 2
    public function canRead($pFilename)
74
    {
75 2
        return $this->fileSupportsUnserializePhpPresentation($pFilename);
76
    }
77
78
    /**
79
     * Does a file support UnserializePhpPresentation ?
80
     *
81
     * @param  string $pFilename
82
     * @throws \Exception
83
     * @return boolean
84
     */
85 9
    public function fileSupportsUnserializePhpPresentation($pFilename = '')
86
    {
87
        // Check if file exists
88 9
        if (!file_exists($pFilename)) {
89 2
            throw new \Exception("Could not open " . $pFilename . " for reading! File does not exist.");
90
        }
91
92 7
        $oZip = new ZipArchive();
93
        // Is it a zip ?
94 7
        if ($oZip->open($pFilename) === true) {
95
            // Is it an OpenXML Document ?
96
            // Is it a Presentation ?
97 4
            if (is_array($oZip->statName('[Content_Types].xml')) && is_array($oZip->statName('ppt/presentation.xml'))) {
98 4
                return true;
99
            }
100
        } else {
101 3
            $oOLE = new OLERead();
102
            try {
103 3
                $oOLE->read($pFilename);
104 2
                return true;
105 1
            } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class PhpOffice\PhpPresentation\Reader\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
106
            }
107
        }
108
109
        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
            throw new \Exception("Invalid file format for PhpOffice\PhpPresentation\Reader\PowerPoint2007: " . $pFilename . ".");
124
        }
125
126 5
        return $this->loadFile($pFilename);
127
    }
128
129
    /**
130
     * Load PhpPresentation Serialized file
131
     *
132
     * @param  string $pFilename
133
     * @return \PhpOffice\PhpPresentation\PhpPresentation
134
     */
135 5
    protected function loadFile($pFilename)
136
    {
137 5
        $this->oPhpPresentation = new PhpPresentation();
138 5
        $this->oPhpPresentation->removeSlideByIndex();
139 5
        $this->oPhpPresentation->setAllMasterSlides(array());
140 5
        $this->filename = $pFilename;
141
142 5
        $this->oZip = new ZipArchive();
143
144 5
        if ($this->oZip->open($this->filename) == ZipArchive::ER_NOZIP) {
145 5
            $this->loadEncryptedFile();
146
            return $this->oPhpPresentation;
147
        }
148
149
        $docPropsCore = $this->oZip->getFromName('docProps/core.xml');
150
        if ($docPropsCore !== false) {
151
            $this->loadDocumentProperties($docPropsCore);
152
        }
153
154
        $docPropsCustom = $this->oZip->getFromName('docProps/custom.xml');
155
        if ($docPropsCustom !== false) {
156
            $this->loadCustomProperties($docPropsCustom);
157
        }
158
159
        $pptViewProps = $this->oZip->getFromName('ppt/viewProps.xml');
160
        if ($pptViewProps !== false) {
161
            $this->loadViewProperties($pptViewProps);
162
        }
163
164
        $pptPresentation = $this->oZip->getFromName('ppt/presentation.xml');
165
        if ($pptPresentation !== false) {
166
            $this->loadDocumentLayout($pptPresentation);
167
            $this->loadSlides($pptPresentation);
168
        }
169
170
        return $this->oPhpPresentation;
171
    }
172
173
    /**
174
     * Read Document Layout
175
     * @param $sPart
176
     */
177
    protected function loadDocumentLayout($sPart)
178
    {
179
        $xmlReader = new XMLReader();
180
        if ($xmlReader->getDomFromString($sPart)) {
181
            foreach ($xmlReader->getElements('/p:presentation/p:sldSz') as $oElement) {
182
                $type = $oElement->getAttribute('type');
183
                $oLayout = $this->oPhpPresentation->getLayout();
184
                if ($type == DocumentLayout::LAYOUT_CUSTOM) {
185
                    $oLayout->setCX($oElement->getAttribute('cx'));
186
                    $oLayout->setCY($oElement->getAttribute('cy'));
187
                } else {
188
                    $oLayout->setDocumentLayout($type, true);
189
                    if ($oElement->getAttribute('cx') < $oElement->getAttribute('cy')) {
190
                        $oLayout->setDocumentLayout($type, false);
191
                    }
192
                }
193
            }
194
        }
195
    }
196
197
    /**
198
     * Read Document Properties
199
     * @param string $sPart
200
     */
201
    protected function loadDocumentProperties($sPart)
202
    {
203
        $xmlReader = new XMLReader();
204
        if ($xmlReader->getDomFromString($sPart)) {
205
            $arrayProperties = array(
206
                '/cp:coreProperties/dc:creator' => 'setCreator',
207
                '/cp:coreProperties/cp:lastModifiedBy' => 'setLastModifiedBy',
208
                '/cp:coreProperties/dc:title' => 'setTitle',
209
                '/cp:coreProperties/dc:description' => 'setDescription',
210
                '/cp:coreProperties/dc:subject' => 'setSubject',
211
                '/cp:coreProperties/cp:keywords' => 'setKeywords',
212
                '/cp:coreProperties/cp:category' => 'setCategory',
213
                '/cp:coreProperties/dcterms:created' => 'setCreated',
214
                '/cp:coreProperties/dcterms:modified' => 'setModified',
215
            );
216
            $oProperties = $this->oPhpPresentation->getDocumentProperties();
217
            foreach ($arrayProperties as $path => $property) {
218
                if (is_object($oElement = $xmlReader->getElement($path))) {
219
                    if ($oElement->hasAttribute('xsi:type') && $oElement->getAttribute('xsi:type') == 'dcterms:W3CDTF') {
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...
220
                        $oDateTime = new \DateTime();
221
                        $oDateTime->createFromFormat(\DateTime::W3C, $oElement->nodeValue);
222
                        $oProperties->{$property}($oDateTime->getTimestamp());
223
                    } else {
224
                        $oProperties->{$property}($oElement->nodeValue);
225
                    }
226
                }
227
            }
228
        }
229
    }
230
231
    /**
232
     * Read Custom Properties
233
     * @param string $sPart
234
     */
235
    protected function loadCustomProperties($sPart)
236
    {
237
        $xmlReader = new XMLReader();
238
        $sPart = str_replace(' xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"', '', $sPart);
239
        if ($xmlReader->getDomFromString($sPart)) {
240
            $pathMarkAsFinal = '/Properties/property[@pid="2"][@fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"][@name="_MarkAsFinal"]/vt:bool';
241
            if (is_object($oElement = $xmlReader->getElement($pathMarkAsFinal))) {
242
                if ($oElement->nodeValue == 'true') {
243
                    $this->oPhpPresentation->getPresentationProperties()->markAsFinal(true);
244
                }
245
            }
246
        }
247
    }
248
249
    /**
250
     * Read View Properties
251
     * @param string $sPart
252
     */
253
    protected function loadViewProperties($sPart)
254
    {
255
        $xmlReader = new XMLReader();
256
        if ($xmlReader->getDomFromString($sPart)) {
257
            $pathZoom = '/p:viewPr/p:slideViewPr/p:cSldViewPr/p:cViewPr/p:scale/a:sx';
258
            if (is_object($oElement = $xmlReader->getElement($pathZoom))) {
259
                if ($oElement->hasAttribute('d') && $oElement->hasAttribute('n')) {
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...
260
                    $this->oPhpPresentation->getPresentationProperties()->setZoom($oElement->getAttribute('n') / $oElement->getAttribute('d'));
261
                }
262
            }
263
        }
264
    }
265
266
    /**
267
     * Extract all slides
268
     */
269
    protected function loadSlides($sPart)
270
    {
271
        $xmlReader = new XMLReader();
272
        if ($xmlReader->getDomFromString($sPart)) {
273
            $fileRels = 'ppt/_rels/presentation.xml.rels';
274
            $this->loadRels($fileRels);
275
            // Load the Masterslides
276
            $this->loadMasterSlides($xmlReader, $fileRels);
277
            // Continue with loading the slides
278
            foreach ($xmlReader->getElements('/p:presentation/p:sldIdLst/p:sldId') as $oElement) {
279
                $rId = $oElement->getAttribute('r:id');
280
                $pathSlide = isset($this->arrayRels[$fileRels][$rId]) ? $this->arrayRels[$fileRels][$rId]['Target'] : '';
281
                if (!empty($pathSlide)) {
282
                    $pptSlide = $this->oZip->getFromName('ppt/' . $pathSlide);
283
                    if ($pptSlide !== false) {
284
                        $this->loadRels('ppt/slides/_rels/' . basename($pathSlide) . '.rels');
285
                        $this->loadSlide($pptSlide, basename($pathSlide));
286
                    }
287
                }
288
            }
289
        }
290
    }
291
292
    /**
293
     * Extract all MasterSlides
294
     * @param XMLReader $xmlReader
295
     * @param $fileRels
296
     */
297
    protected function loadMasterSlides(XMLReader $xmlReader, $fileRels)
298
    {
299
        // Get all the MasterSlide Id's from the presentation.xml file
300
        foreach ($xmlReader->getElements('/p:presentation/p:sldMasterIdLst/p:sldMasterId') as $oElement) {
301
            $rId = $oElement->getAttribute('r:id');
302
            // Get the path to the masterslide from the array with _rels files
303
            $pathMasterSlide = isset($this->arrayRels[$fileRels][$rId]) ?
304
                $this->arrayRels[$fileRels][$rId]['Target'] : '';
305
            if (!empty($pathMasterSlide)) {
306
                $pptMasterSlide = $this->oZip->getFromName('ppt/' . $pathMasterSlide);
307
                if ($pptMasterSlide !== false) {
308
                    $this->loadRels('ppt/slideMasters/_rels/' . basename($pathMasterSlide) . '.rels');
309
                    $this->loadMasterSlide($pptMasterSlide, basename($pathMasterSlide));
310
                }
311
            }
312
        }
313
    }
314
315
    /**
316
     * Extract data from slide
317
     * @param string $sPart
318
     * @param string $baseFile
319
     */
320
    protected function loadSlide($sPart, $baseFile)
321
    {
322
        $xmlReader = new XMLReader();
323
        if ($xmlReader->getDomFromString($sPart)) {
324
            // Core
325
            $oSlide = $this->oPhpPresentation->createSlide();
326
            $this->oPhpPresentation->setActiveSlideIndex($this->oPhpPresentation->getSlideCount() - 1);
327
            $oSlide->setRelsIndex('ppt/slides/_rels/' . $baseFile . '.rels');
328
329
            // Background
330
            $oElement = $xmlReader->getElement('/p:sld/p:cSld/p:bg/p:bgPr');
331
            if ($oElement) {
332
                $oElementColor = $xmlReader->getElement('a:solidFill/a:srgbClr', $oElement);
0 ignored issues
show
Documentation introduced by
$oElement 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...
333
                if ($oElementColor) {
334
                    // Color
335
                    $oColor = new Color();
336
                    $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
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...
337
                    // Background
338
                    $oBackground = new \PhpOffice\PhpPresentation\Slide\Background\Color();
339
                    $oBackground->setColor($oColor);
340
                    // Slide Background
341
                    $oSlide = $this->oPhpPresentation->getActiveSlide();
342
                    $oSlide->setBackground($oBackground);
343
                }
344
                $oElementImage = $xmlReader->getElement('a:blipFill/a:blip', $oElement);
0 ignored issues
show
Documentation introduced by
$oElement 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...
345
                if ($oElementImage) {
346
                    $relImg = $this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'][$oElementImage->getAttribute('r:embed')];
347
                    if (is_array($relImg)) {
348
                        // File
349
                        $pathImage = 'ppt/slides/' . $relImg['Target'];
350
                        $pathImage = explode('/', $pathImage);
351
                        foreach ($pathImage as $key => $partPath) {
352
                            if ($partPath == '..') {
353
                                unset($pathImage[$key - 1]);
354
                                unset($pathImage[$key]);
355
                            }
356
                        }
357
                        $pathImage = implode('/', $pathImage);
358
                        $contentImg = $this->oZip->getFromName($pathImage);
359
360
                        $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg');
361
                        file_put_contents($tmpBkgImg, $contentImg);
362
                        // Background
363
                        $oBackground = new Image();
364
                        $oBackground->setPath($tmpBkgImg);
365
                        // Slide Background
366
                        $oSlide = $this->oPhpPresentation->getActiveSlide();
367
                        $oSlide->setBackground($oBackground);
368
                    }
369
                }
370
            }
371
372
            // Shapes
373
            foreach ($xmlReader->getElements('/p:sld/p:cSld/p:spTree/*') as $oNode) {
374
                switch ($oNode->tagName) {
375
                    case 'p:pic':
376
                        $this->loadShapeDrawing($xmlReader, $oNode, $oSlide);
377
                        break;
378
                    case 'p:sp':
379
                        $this->loadShapeRichText($xmlReader, $oNode, $oSlide);
380
                        break;
381
                    default:
382
                        //var_export($oNode->tagName);
383
                }
384
            }
385
            // Layout
386
            $oSlide = $this->oPhpPresentation->getActiveSlide();
387
            foreach ($this->arrayRels['ppt/slides/_rels/' . $baseFile . '.rels'] as $valueRel) {
388
                if ($valueRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout') {
389
                    $layoutBasename = basename($valueRel['Target']);
390
                    if (array_key_exists($layoutBasename, $this->arraySlideLayouts)) {
391
                        $oSlide->setSlideLayout($this->arraySlideLayouts[$layoutBasename]);
392
                    }
393
                    break;
394
                }
395
            }
396
        }
397
    }
398
399
    private function loadMasterSlide($sPart, $baseFile)
400
    {
401
        $xmlReader = new XMLReader();
402
        if ($xmlReader->getDomFromString($sPart)) {
403
            // Core
404
            $oSlideMaster = $this->oPhpPresentation->createMasterSlide();
405
            $oSlideMaster->setTextStyles(new TextStyle(false));
406
            $oSlideMaster->setRelsIndex('ppt/slideMasters/_rels/' . $baseFile . '.rels');
407
408
            // Background
409
            $oElement = $xmlReader->getElement('/p:sldMaster/p:cSld/p:bg');
410
            if ($oElement) {
411
                $this->loadSlideBackground($xmlReader, $oElement, $oSlideMaster);
0 ignored issues
show
Compatibility introduced by
$oElement of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
412
            }
413
414
            // Shapes
415
            $arrayElements = $xmlReader->getElements('/p:sldMaster/p:cSld/p:spTree/*');
416
            if ($arrayElements) {
417
                $this->loadSlideShapes($oSlideMaster, $arrayElements, $xmlReader);
418
            }
419
            // Header & Footer
420
421
            // ColorMapping
422
            $colorMap = array();
423
            $oElement = $xmlReader->getElement('/p:sldMaster/p:clrMap');
424
            if ($oElement->hasAttributes()) {
425
                foreach ($oElement->attributes as $attr) {
426
                    $colorMap[$attr->nodeName] = $attr->nodeValue;
427
                }
428
                $oSlideMaster->colorMap->setMapping($colorMap);
429
            }
430
431
            // TextStyles
432
            $arrayElementTxStyles = $xmlReader->getElements('/p:sldMaster/p:txStyles/*');
433
            if ($arrayElementTxStyles) {
434
                foreach ($arrayElementTxStyles as $oElementTxStyle) {
435
                    $arrayElementsLvl = $xmlReader->getElements('/p:sldMaster/p:txStyles/'.$oElementTxStyle->nodeName.'/*');
436
                    foreach ($arrayElementsLvl as $oElementLvl) {
437
                        if ($oElementLvl->nodeName == 'a:extLst') {
438
                            continue;
439
                        }
440
                        $oRTParagraph = new Paragraph();
441
442
                        if ($oElementLvl->nodeName == 'a:defPPr') {
443
                            $level = 0;
444
                        } else {
445
                            $level = str_replace('a:lvl', '', $oElementLvl->nodeName);
446
                            $level = str_replace('pPr', '', $level);
447
                        }
448
449
                        if ($oElementLvl->hasAttribute('algn')) {
450
                            $oRTParagraph->getAlignment()->setHorizontal($oElementLvl->getAttribute('algn'));
451
                        }
452
                        if ($oElementLvl->hasAttribute('marL')) {
453
                            $val = $oElementLvl->getAttribute('marL');
454
                            $val = CommonDrawing::emuToPixels($val);
455
                            $oRTParagraph->getAlignment()->setMarginLeft($val);
456
                        }
457
                        if ($oElementLvl->hasAttribute('marR')) {
458
                            $val = $oElementLvl->getAttribute('marR');
459
                            $val = CommonDrawing::emuToPixels($val);
460
                            $oRTParagraph->getAlignment()->setMarginRight($val);
461
                        }
462
                        if ($oElementLvl->hasAttribute('indent')) {
463
                            $val = $oElementLvl->getAttribute('indent');
464
                            $val = CommonDrawing::emuToPixels($val);
465
                            $oRTParagraph->getAlignment()->setIndent($val);
466
                        }
467
                        $oElementLvlDefRPR = $xmlReader->getElement('a:defRPr', $oElementLvl);
468
                        if ($oElementLvlDefRPR) {
469
                            if ($oElementLvlDefRPR->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...
470
                                $oRTParagraph->getFont()->setSize($oElementLvlDefRPR->getAttribute('sz') / 100);
471
                            }
472
                            if ($oElementLvlDefRPR->hasAttribute('b') && $oElementLvlDefRPR->getAttribute('b') == 1) {
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...
473
                                $oRTParagraph->getFont()->setBold(true);
474
                            }
475
                            if ($oElementLvlDefRPR->hasAttribute('i') && $oElementLvlDefRPR->getAttribute('i') == 1) {
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...
476
                                $oRTParagraph->getFont()->setItalic(true);
477
                            }
478
                        }
479
                        $oElementSchemeColor = $xmlReader->getElement('a:defRPr/a:solidFill/a:schemeClr', $oElementLvl);
480
                        if ($oElementSchemeColor) {
481
                            if ($oElementSchemeColor->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...
482
                                $oRTParagraph->getFont()->setColor(new SchemeColor())->getColor()->setValue($oElementSchemeColor->getAttribute('val'));
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class PhpOffice\PhpPresentation\Style\Color as the method setValue() does only exist in the following sub-classes of PhpOffice\PhpPresentation\Style\Color: PhpOffice\PhpPresentation\Style\SchemeColor. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
483
                            }
484
                        }
485
486
                        switch ($oElementTxStyle->nodeName) {
487
                            case 'p:bodyStyle':
488
                                $oSlideMaster->getTextStyles()->setBodyStyleAtLvl($oRTParagraph, $level);
489
                                break;
490
                            case 'p:otherStyle':
491
                                $oSlideMaster->getTextStyles()->setOtherStyleAtLvl($oRTParagraph, $level);
492
                                break;
493
                            case 'p:titleStyle':
494
                                $oSlideMaster->getTextStyles()->setTitleStyleAtLvl($oRTParagraph, $level);
495
                                break;
496
                        }
497
                    }
498
                }
499
            }
500
501
            // Load the theme
502
            foreach ($this->arrayRels[$oSlideMaster->getRelsIndex()] as $arrayRel) {
503
                if ($arrayRel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme') {
504
                    $pptTheme = $this->oZip->getFromName('ppt/' . substr($arrayRel['Target'], strrpos($arrayRel['Target'], '../') + 3));
505
                    if ($pptTheme !== false) {
506
                        $this->loadTheme($pptTheme, $oSlideMaster);
507
                    }
508
                    break;
509
                }
510
            }
511
512
            // Load the Layoutslide
513
            foreach ($xmlReader->getElements('/p:sldMaster/p:sldLayoutIdLst/p:sldLayoutId') as $oElement) {
514
                $rId = $oElement->getAttribute('r:id');
515
                // Get the path to the masterslide from the array with _rels files
516
                $pathLayoutSlide = isset($this->arrayRels[$oSlideMaster->getRelsIndex()][$rId]) ?
517
                    $this->arrayRels[$oSlideMaster->getRelsIndex()][$rId]['Target'] : '';
518
                if (!empty($pathLayoutSlide)) {
519
                    $pptLayoutSlide = $this->oZip->getFromName('ppt/' . substr($pathLayoutSlide, strrpos($pathLayoutSlide, '../') + 3));
520
                    if ($pptLayoutSlide !== false) {
521
                        $this->loadRels('ppt/slideLayouts/_rels/' . basename($pathLayoutSlide) . '.rels');
522
                        $oSlideMaster->addSlideLayout(
523
                            $this->loadLayoutSlide($pptLayoutSlide, basename($pathLayoutSlide), $oSlideMaster)
524
                        );
525
                    }
526
                }
527
            }
528
        }
529
    }
530
531
    private function loadLayoutSlide($sPart, $baseFile, SlideMaster $oSlideMaster)
532
    {
533
        $xmlReader = new XMLReader();
534
        if ($xmlReader->getDomFromString($sPart)) {
535
            // Core
536
            $oSlideLayout = new SlideLayout($oSlideMaster);
537
            $oSlideLayout->setRelsIndex('ppt/slideLayouts/_rels/' . $baseFile . '.rels');
538
539
            // Name
540
            $oElement = $xmlReader->getElement('/p:sldLayout/p:cSld');
541
            if ($oElement && $oElement->hasAttribute('name')) {
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...
542
                $oSlideLayout->setLayoutName($oElement->getAttribute('name'));
543
            }
544
545
            // Background
546
            $oElement = $xmlReader->getElement('/p:sldLayout/p:cSld/p:bg');
547
            if ($oElement) {
548
                $this->loadSlideBackground($xmlReader, $oElement, $oSlideLayout);
0 ignored issues
show
Compatibility introduced by
$oElement of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
549
            }
550
551
            // ColorMapping
552
            $oElement = $xmlReader->getElement('/p:sldLayout/p:clrMapOvr/a:overrideClrMapping');
553
            if ($oElement && $oElement->hasAttributes()) {
554
                $colorMap = array();
555
                foreach ($oElement->attributes as $attr) {
556
                    $colorMap[$attr->nodeName] = $attr->nodeValue;
557
                }
558
                $oSlideLayout->colorMap->setMapping($colorMap);
559
            }
560
561
            // Shapes
562
            $oElements = $xmlReader->getElements('/p:sldLayout/p:cSld/p:spTree/*');
563
            if ($oElements) {
564
                $this->loadSlideShapes($oSlideLayout, $oElements, $xmlReader);
565
            }
566
            $this->arraySlideLayouts[$baseFile] = &$oSlideLayout;
567
            return $oSlideLayout;
568
        }
569
        return null;
570
    }
571
572
    /**
573
     * @param string $sPart
574
     * @param SlideMaster $oSlideMaster
575
     */
576
    private function loadTheme($sPart, SlideMaster $oSlideMaster)
577
    {
578
        $xmlReader = new XMLReader();
579
        if ($xmlReader->getDomFromString($sPart)) {
580
            $oElements = $xmlReader->getElements('/a:theme/a:themeElements/a:clrScheme/*');
581
            if ($oElements) {
582
                foreach ($oElements as $oElement) {
583
                    $oSchemeColor = new SchemeColor();
584
                    $oSchemeColor->setValue(str_replace('a:', '', $oElement->tagName));
585
                    $colorElement = $xmlReader->getElement('*', $oElement);
586
                    if ($colorElement) {
587
                        if ($colorElement->hasAttribute('lastClr')) {
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...
588
                            $oSchemeColor->setRGB($colorElement->getAttribute('lastClr'));
589
                        } elseif ($colorElement->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...
590
                            $oSchemeColor->setRGB($colorElement->getAttribute('val'));
591
                        }
592
                    }
593
                    $oSlideMaster->addSchemeColor($oSchemeColor);
594
                }
595
            }
596
        }
597
    }
598
599
    /**
600
     * @param XMLReader $xmlReader
601
     * @param \DOMElement $oElement
602
     * @param AbstractSlide $oSlide
603
     */
604
    private function loadSlideBackground(XMLReader $xmlReader, \DOMElement $oElement, AbstractSlide $oSlide)
605
    {
606
        // Background color
607
        $oElementColor = $xmlReader->getElement('p:bgPr/a:solidFill/a:srgbClr', $oElement);
608
        if ($oElementColor) {
609
            // Color
610
            $oColor = new Color();
611
            $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
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...
612
            // Background
613
            $oBackground = new \PhpOffice\PhpPresentation\Slide\Background\Color();
614
            $oBackground->setColor($oColor);
615
            // Slide Background
616
            $oSlide->setBackground($oBackground);
617
        }
618
619
        // Background scheme color
620
        $oElementSchemeColor = $xmlReader->getElement('p:bgRef/a:schemeClr', $oElement);
621
        if ($oElementSchemeColor) {
622
            // Color
623
            $oColor = new SchemeColor();
624
            $oColor->setValue($oElementSchemeColor->hasAttribute('val') ? $oElementSchemeColor->getAttribute('val') : null);
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...
625
            // Background
626
            $oBackground = new \PhpOffice\PhpPresentation\Slide\Background\SchemeColor();
627
            $oBackground->setSchemeColor($oColor);
628
            // Slide Background
629
            $oSlide->setBackground($oBackground);
630
        }
631
632
        // Background image
633
        $oElementImage = $xmlReader->getElement('p:bgPr/a:blipFill/a:blip', $oElement);
634
        if ($oElementImage) {
635
            $relImg = $this->arrayRels[$oSlide->getRelsIndex()][$oElementImage->getAttribute('r:embed')];
636
            if (is_array($relImg)) {
637
                // File
638
                $pathImage = 'ppt/slides/' . $relImg['Target'];
639
                $pathImage = explode('/', $pathImage);
640
                foreach ($pathImage as $key => $partPath) {
641
                    if ($partPath == '..') {
642
                        unset($pathImage[$key - 1]);
643
                        unset($pathImage[$key]);
644
                    }
645
                }
646
                $pathImage = implode('/', $pathImage);
647
                $contentImg = $this->oZip->getFromName($pathImage);
648
649
                $tmpBkgImg = tempnam(sys_get_temp_dir(), 'PhpPresentationReaderPpt2007Bkg');
650
                file_put_contents($tmpBkgImg, $contentImg);
651
                // Background
652
                $oBackground = new Image();
653
                $oBackground->setPath($tmpBkgImg);
654
                // Slide Background
655
                $oSlide->setBackground($oBackground);
656
            }
657
        }
658
    }
659
660
    /**
661
     *
662
     * @param XMLReader $document
663
     * @param \DOMElement $node
664
     * @param AbstractSlide $oSlide
665
     */
666
    protected function loadShapeDrawing(XMLReader $document, \DOMElement $node, AbstractSlide $oSlide)
667
    {
668
        // Core
669
        $oShape = new Gd();
670
        $oShape->getShadow()->setVisible(false);
671
        // Variables
672
        $fileRels = $oSlide->getRelsIndex();
673
674
        $oElement = $document->getElement('p:nvPicPr/p:cNvPr', $node);
675
        if ($oElement) {
676
            $oShape->setName($oElement->hasAttribute('name') ? $oElement->getAttribute('name') : '');
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...
677
            $oShape->setDescription($oElement->hasAttribute('descr') ? $oElement->getAttribute('descr') : '');
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...
678
        }
679
680
        $oElement = $document->getElement('p:blipFill/a:blip', $node);
681
        if ($oElement) {
682
            if ($oElement->hasAttribute('r:embed') && isset($this->arrayRels[$fileRels][$oElement->getAttribute('r:embed')]['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...
683
                $pathImage = 'ppt/slides/' . $this->arrayRels[$fileRels][$oElement->getAttribute('r:embed')]['Target'];
684
                $pathImage = explode('/', $pathImage);
685
                foreach ($pathImage as $key => $partPath) {
686
                    if ($partPath == '..') {
687
                        unset($pathImage[$key - 1]);
688
                        unset($pathImage[$key]);
689
                    }
690
                }
691
                $pathImage = implode('/', $pathImage);
692
                $imageFile = $this->oZip->getFromName($pathImage);
693
                if (!empty($imageFile)) {
694
                    $oShape->setImageResource(imagecreatefromstring($imageFile));
695
                }
696
            }
697
        }
698
699
        $oElement = $document->getElement('p:spPr/a:xfrm', $node);
700
        if ($oElement) {
701
            if ($oElement->hasAttribute('rot')) {
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...
702
                $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
703
            }
704
        }
705
706
        $oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
707
        if ($oElement) {
708
            if ($oElement->hasAttribute('x')) {
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...
709
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
710
            }
711
            if ($oElement->hasAttribute('y')) {
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...
712
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
713
            }
714
        }
715
716
        $oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
717
        if ($oElement) {
718
            if ($oElement->hasAttribute('cx')) {
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...
719
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
720
            }
721
            if ($oElement->hasAttribute('cy')) {
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...
722
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
723
            }
724
        }
725
726
        $oElement = $document->getElement('p:spPr/a:effectLst', $node);
727
        if ($oElement) {
728
            $oShape->getShadow()->setVisible(true);
729
730
            $oSubElement = $document->getElement('a:outerShdw', $oElement);
0 ignored issues
show
Documentation introduced by
$oElement 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...
731
            if ($oSubElement) {
732
                if ($oSubElement->hasAttribute('blurRad')) {
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...
733
                    $oShape->getShadow()->setBlurRadius(CommonDrawing::emuToPixels($oSubElement->getAttribute('blurRad')));
734
                }
735
                if ($oSubElement->hasAttribute('dist')) {
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...
736
                    $oShape->getShadow()->setDistance(CommonDrawing::emuToPixels($oSubElement->getAttribute('dist')));
737
                }
738
                if ($oSubElement->hasAttribute('dir')) {
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...
739
                    $oShape->getShadow()->setDirection(CommonDrawing::angleToDegrees($oSubElement->getAttribute('dir')));
740
                }
741
                if ($oSubElement->hasAttribute('algn')) {
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
                    $oShape->getShadow()->setAlignment($oSubElement->getAttribute('algn'));
743
                }
744
            }
745
746
            $oSubElement = $document->getElement('a:outerShdw/a:srgbClr', $oElement);
0 ignored issues
show
Documentation introduced by
$oElement 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...
747
            if ($oSubElement) {
748
                if ($oSubElement->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...
749
                    $oColor = new Color();
750
                    $oColor->setRGB($oSubElement->getAttribute('val'));
751
                    $oShape->getShadow()->setColor($oColor);
752
                }
753
            }
754
755
            $oSubElement = $document->getElement('a:outerShdw/a:srgbClr/a:alpha', $oElement);
0 ignored issues
show
Documentation introduced by
$oElement 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...
756
            if ($oSubElement) {
757
                if ($oSubElement->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...
758
                    $oShape->getShadow()->setAlpha((int)$oSubElement->getAttribute('val') / 1000);
759
                }
760
            }
761
        }
762
763
        $oSlide->addShape($oShape);
764
    }
765
766
    /**
767
     * @param XMLReader $document
768
     * @param \DOMElement $node
769
     * @param AbstractSlide $oSlide
770
     * @throws \Exception
771
     */
772
    protected function loadShapeRichText(XMLReader $document, \DOMElement $node, AbstractSlide $oSlide)
773
    {
774
        // Core
775
        $oShape = $oSlide->createRichTextShape();
776
        $oShape->setParagraphs(array());
777
        // Variables
778
        $fileRels = $oSlide->getRelsIndex();
779
780
        $oElement = $document->getElement('p:spPr/a:xfrm', $node);
781
        if ($oElement && $oElement->hasAttribute('rot')) {
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...
782
            $oShape->setRotation(CommonDrawing::angleToDegrees($oElement->getAttribute('rot')));
783
        }
784
785
        $oElement = $document->getElement('p:spPr/a:xfrm/a:off', $node);
786
        if ($oElement) {
787
            if ($oElement->hasAttribute('x')) {
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...
788
                $oShape->setOffsetX(CommonDrawing::emuToPixels($oElement->getAttribute('x')));
789
            }
790
            if ($oElement->hasAttribute('y')) {
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...
791
                $oShape->setOffsetY(CommonDrawing::emuToPixels($oElement->getAttribute('y')));
792
            }
793
        }
794
795
        $oElement = $document->getElement('p:spPr/a:xfrm/a:ext', $node);
796
        if ($oElement) {
797
            if ($oElement->hasAttribute('cx')) {
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...
798
                $oShape->setWidth(CommonDrawing::emuToPixels($oElement->getAttribute('cx')));
799
            }
800
            if ($oElement->hasAttribute('cy')) {
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...
801
                $oShape->setHeight(CommonDrawing::emuToPixels($oElement->getAttribute('cy')));
802
            }
803
        }
804
805
        $oElement = $document->getElement('p:nvSpPr/p:nvPr/p:ph', $node);
806
        if ($oElement) {
807
            if ($oElement->hasAttribute('type')) {
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...
808
                $placeholder = new Placeholder($oElement->getAttribute('type'));
809
                $oShape->setPlaceHolder($placeholder);
810
            }
811
        }
812
813
        $arrayElements = $document->getElements('p:txBody/a:p', $node);
814
        foreach ($arrayElements as $oElement) {
815
            // Core
816
            $oParagraph = $oShape->createParagraph();
817
            $oParagraph->setRichTextElements(array());
818
819
            $oSubElement = $document->getElement('a:pPr', $oElement);
820
            if ($oSubElement) {
821
                if ($oSubElement->hasAttribute('algn')) {
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...
822
                    $oParagraph->getAlignment()->setHorizontal($oSubElement->getAttribute('algn'));
823
                }
824
                if ($oSubElement->hasAttribute('fontAlgn')) {
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...
825
                    $oParagraph->getAlignment()->setVertical($oSubElement->getAttribute('fontAlgn'));
826
                }
827
                if ($oSubElement->hasAttribute('marL')) {
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...
828
                    $oParagraph->getAlignment()->setMarginLeft(CommonDrawing::emuToPixels($oSubElement->getAttribute('marL')));
829
                }
830
                if ($oSubElement->hasAttribute('marR')) {
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...
831
                    $oParagraph->getAlignment()->setMarginRight(CommonDrawing::emuToPixels($oSubElement->getAttribute('marR')));
832
                }
833
                if ($oSubElement->hasAttribute('indent')) {
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...
834
                    $oParagraph->getAlignment()->setIndent(CommonDrawing::emuToPixels($oSubElement->getAttribute('indent')));
835
                }
836
                if ($oSubElement->hasAttribute('lvl')) {
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...
837
                    $oParagraph->getAlignment()->setLevel($oSubElement->getAttribute('lvl'));
838
                }
839
840
                $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NONE);
841
842
                $oElementBuFont = $document->getElement('a:buFont', $oSubElement);
0 ignored issues
show
Documentation introduced by
$oSubElement 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...
843
                if ($oElementBuFont) {
844
                    if ($oElementBuFont->hasAttribute('typeface')) {
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...
845
                        $oParagraph->getBulletStyle()->setBulletFont($oElementBuFont->getAttribute('typeface'));
846
                    }
847
                }
848
                $oElementBuChar = $document->getElement('a:buChar', $oSubElement);
0 ignored issues
show
Documentation introduced by
$oSubElement 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...
849
                if ($oElementBuChar) {
850
                    $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_BULLET);
851
                    if ($oElementBuChar->hasAttribute('char')) {
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...
852
                        $oParagraph->getBulletStyle()->setBulletChar($oElementBuChar->getAttribute('char'));
853
                    }
854
                }
855
                $oElementBuAutoNum = $document->getElement('a:buAutoNum', $oSubElement);
0 ignored issues
show
Documentation introduced by
$oSubElement 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...
856
                if ($oElementBuAutoNum) {
857
                    $oParagraph->getBulletStyle()->setBulletType(Bullet::TYPE_NUMERIC);
858
                    if ($oElementBuAutoNum->hasAttribute('type')) {
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...
859
                        $oParagraph->getBulletStyle()->setBulletNumericStyle($oElementBuAutoNum->getAttribute('type'));
860
                    }
861
                    if ($oElementBuAutoNum->hasAttribute('startAt') && $oElementBuAutoNum->getAttribute('startAt') != 1) {
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...
862
                        $oParagraph->getBulletStyle()->setBulletNumericStartAt($oElementBuAutoNum->getAttribute('startAt'));
863
                    }
864
                }
865
                $oElementBuClr = $document->getElement('a:buClr', $oSubElement);
0 ignored issues
show
Documentation introduced by
$oSubElement 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...
866
                if ($oElementBuClr) {
867
                    $oColor = new Color();
868
                    /**
869
                     * @todo Create protected for reading Color
870
                     */
871
                    $oElementColor = $document->getElement('a:srgbClr', $oElementBuClr);
0 ignored issues
show
Documentation introduced by
$oElementBuClr 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...
872
                    if ($oElementColor) {
873
                        $oColor->setRGB($oElementColor->hasAttribute('val') ? $oElementColor->getAttribute('val') : null);
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...
874
                    }
875
                    $oParagraph->getBulletStyle()->setBulletColor($oColor);
876
                }
877
            }
878
            $arraySubElements = $document->getElements('(a:r|a:br)', $oElement);
879
            foreach ($arraySubElements as $oSubElement) {
880
                if ($oSubElement->tagName == 'a:br') {
881
                    $oParagraph->createBreak();
882
                }
883
                if ($oSubElement->tagName == 'a:r') {
884
                    $oElementrPr = $document->getElement('a:rPr', $oSubElement);
885
                    if (is_object($oElementrPr)) {
886
                        $oText = $oParagraph->createTextRun();
887
888
                        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...
889
                            $oText->getFont()->setBold($oElementrPr->getAttribute('b') == 'true' ? true : false);
890
                        }
891
                        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...
892
                            $oText->getFont()->setItalic($oElementrPr->getAttribute('i') == 'true' ? true : false);
893
                        }
894
                        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...
895
                            $oText->getFont()->setStrikethrough($oElementrPr->getAttribute('strike') == 'noStrike' ? false : true);
896
                        }
897
                        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...
898
                            $oText->getFont()->setSize((int)($oElementrPr->getAttribute('sz') / 100));
899
                        }
900
                        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...
901
                            $oText->getFont()->setUnderline($oElementrPr->getAttribute('u'));
902
                        }
903
                        // Color
904
                        $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...
905
                        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...
906
                            $oColor = new Color();
907
                            $oColor->setRGB($oElementSrgbClr->getAttribute('val'));
908
                            $oText->getFont()->setColor($oColor);
909
                        }
910
                        // Hyperlink
911
                        $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...
912
                        if (is_object($oElementHlinkClick)) {
913
                            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...
914
                                $oText->getHyperlink()->setTooltip($oElementHlinkClick->getAttribute('tooltip'));
915
                            }
916
                            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...
917
                                $oText->getHyperlink()->setUrl($this->arrayRels[$fileRels][$oElementHlinkClick->getAttribute('r:id')]['Target']);
918
                            }
919
                        }
920
                        //} else {
921
                        // $oText = $oParagraph->createText();
922
923
                        $oSubSubElement = $document->getElement('a:t', $oSubElement);
924
                        $oText->setText($oSubSubElement->nodeValue);
925
                    }
926
                }
927
            }
928
        }
929
930
        if (count($oShape->getParagraphs()) > 0) {
931
            $oShape->setActiveParagraph(0);
932
        }
933
    }
934
935
    /**
936
     *
937
     * @param string $fileRels
938
     * @return string
939
     */
940
    protected function loadRels($fileRels)
941
    {
942
        $sPart = $this->oZip->getFromName($fileRels);
943
        if ($sPart !== false) {
944
            $xmlReader = new XMLReader();
945
            if ($xmlReader->getDomFromString($sPart)) {
946
                foreach ($xmlReader->getElements('*') as $oNode) {
947
                    $this->arrayRels[$fileRels][$oNode->getAttribute('Id')] = array(
948
                        'Target' => $oNode->getAttribute('Target'),
949
                        'Type' => $oNode->getAttribute('Type'),
950
                    );
951
                }
952
            }
953
        }
954
    }
955
956
    /**
957
     * @param $oSlide
958
     * @param $oElements
959
     * @param $xmlReader
960
     * @internal param $baseFile
961
     */
962
    private function loadSlideShapes($oSlide, $oElements, $xmlReader)
963
    {
964
        foreach ($oElements as $oNode) {
965
            switch ($oNode->tagName) {
966
                case 'p:pic':
967
                    $this->loadShapeDrawing($xmlReader, $oNode, $oSlide);
968
                    break;
969
                case 'p:sp':
970
                    $this->loadShapeRichText($xmlReader, $oNode, $oSlide);
971
                    break;
972
                default:
973
                    //var_export($oNode->tagName);
974
            }
975
        }
976
    }
977
978 5
    protected function loadEncryptedFile()
0 ignored issues
show
Coding Style Naming introduced by
The variable $CSPName is not named in camelCase.

This check marks variable names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
979
    {
980
        //return false;
981 5
        $oOLE = new OLERead();
982 5
        $oOLE->read($this->filename);
983
984 1
        $oStreamEncrypted = $oOLE->getStream($oOLE->encryptedPackage);
0 ignored issues
show
Bug introduced by
The property encryptedPackage does not seem to exist in PhpOffice\Common\Microsoft\OLERead.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
985
        $pos = 0;
986
        $size = self::getInt4d($oStreamEncrypted, $pos);
987
        $pos += 8;
988
        $data = '';
989
        for ($inc = 0 ; $inc < $size ; $inc++) {
0 ignored issues
show
Coding Style introduced by
Space found before first semicolon of FOR loop
Loading history...
Coding Style introduced by
Space found before second semicolon of FOR loop
Loading history...
990
            $data .= pack('v', self::getInt1d($oStreamEncrypted, $pos + $inc));
991
        }
992
993
        $oStream = $oOLE->getStream($oOLE->encryptionInfo);
0 ignored issues
show
Bug introduced by
The property encryptionInfo does not seem to exist in PhpOffice\Common\Microsoft\OLERead.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
994
        $pos = 0;
995
        // EncryptionVersionInfo
996
        $vMajor = self::getInt2d($oStream, $pos);
0 ignored issues
show
Unused Code introduced by
$vMajor is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
997
        $pos += 2;
998
        $vMinor = self::getInt2d($oStream, $pos);
0 ignored issues
show
Unused Code introduced by
$vMinor is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
999
        $pos += 2;
1000
        // EncryptionHeader.Flags
1001
        $pos += 4;
1002
        // EncryptionHeaderSize
1003
        $size = self::getInt4d($oStream, $pos);
1004
        $pos += 4;
1005
        echo 'EncryptionHeaderSize : ' . $size. '<br />'; //
1006
1007
        // EncryptionHeader
1008
        // EncryptionHeader > Flags
1009
        $flags = self::getInt4d($oStream, $pos);
1010
        echo 'EncryptionHeader > Flags > fCryptoAPI : ' . (($flags >> 2) & bindec('1')). '<br />'; //
1011
        echo 'EncryptionHeader > Flags > fDocProps : ' . (($flags >> 3) & bindec('1')). '<br />'; //
1012
        echo 'EncryptionHeader > Flags > fExternal : ' . (($flags >> 4) & bindec('1')). '<br />'; //
1013
        echo 'EncryptionHeader > Flags > fAES : ' . (($flags >> 5) & bindec('1')). '<br />'; //
1014
        $pos += 4;
1015
        $size -= 4;
1016
        // EncryptionHeader > SizeExtra
1017
        $sizeExtra = self::getInt4d($oStream, $pos);
1018
        echo 'EncryptionHeader > SizeExtra : '.$sizeExtra. '<br />';
1019
        $pos += 4;
1020
        $size -= 4;
1021
        // EncryptionHeader > AlgID
1022
        $algID = self::getInt4d($oStream, $pos);
1023
        echo 'EncryptionHeader > AlgID :'.$algID.' ('.hexdec('0x00006801').' = 0x00006801 = RC4) -  ('.hexdec('0x0000660E').' = 0x0000660E = AES-128) - ('.hexdec('0x0000660F').' = 0x0000660F = AES-192) - ('.hexdec('0x00006610').' = 0x00006610 = AES-256)'. '<br />';
1024
        $pos += 4;
1025
        $size -= 4;
1026
        // EncryptionHeader > AlgIDHash
1027
        $algIDHash = self::getInt4d($oStream, $pos);
1028
        echo 'EncryptionHeader > AlgIDHash : '.$algIDHash. ' ('.hexdec('0x00008004').' = 0x00008004 = SHA1)'. '<br />';
1029
        $pos += 4;
1030
        $size -= 4;
1031
        // EncryptionHeader > KeySize
1032
        $keySize = self::getInt4d($oStream, $pos);
1033
        echo 'EncryptionHeader > KeySize : '.$keySize.  ' ('.hexdec('0x00000080').' = 0x00000080 = AES-128) - ('.hexdec('0x000000C0').' = 0x000000C0 = AES-192) - ('.hexdec('0x00000100').' = 0x00000100 = AES-256)'. '<br />';
1034
        $pos += 4;
1035
        $size -= 4;
1036
        // EncryptionHeader > ProviderType
1037
        $providerType = self::getInt4d($oStream, $pos);
1038
        echo 'EncryptionHeader > ProviderType : '.$providerType. ' ('.hexdec('0x00000018').' = 0x00000018)'. '<br />';
1039
        $pos += 4;
1040
        $size -= 4;
1041
        // EncryptionHeader > Reserved1
1042
        $pos += 4;
1043
        $size -= 4;
1044
        // EncryptionHeader > Reserved2
1045
        $pos += 4;
1046
        $size -= 4;
1047
        // EncryptionHeader > CSPName
1048
        $CSPName = '';
1049
        for ($inc = 0 ; $inc <= $size ; $inc += 2) {
0 ignored issues
show
Coding Style introduced by
Space found before first semicolon of FOR loop
Loading history...
Coding Style introduced by
Space found before second semicolon of FOR loop
Loading history...
1050
            $chr = self::getInt2d($oStream, $pos);
1051
            $pos += 2;
1052
            if ($chr == 0) {
1053
                break;
1054
            }
1055
            $CSPName .= chr($chr);
1056
        }
1057
        echo 'EncryptionHeader > CSPName : '.$CSPName. '<br />';
1058
        // EncryptionVerifier
1059
        // EncryptionVerifier > SaltSize
1060
        $saltSize = self::getInt4d($oStream, $pos);
1061
        echo 'EncryptionVerifier > SaltSize : '.$saltSize.' ('.hexdec('0x00000010').' = 0x00000010)';
1062
        hex_dump($saltSize);
1063
        $pos += 4;
1064
        // EncryptionVerifier > Salt
1065
        $salt = '';
1066
        for ($inc = 0 ; $inc < 16 ; $inc ++) {
0 ignored issues
show
Coding Style introduced by
Space found before first semicolon of FOR loop
Loading history...
Coding Style introduced by
Space found before second semicolon of FOR loop
Loading history...
1067
            $salt .= pack('v', self::getInt1d($oStream, $pos));
1068
            $pos += 1;
1069
        }
1070
        echo 'EncryptionVerifier > Salt : ';
1071
        hex_dump($salt);
1072
        // EncryptionVerifier > EncryptedVerifier
1073
        $encryptedVerifier = '';
1074
        for ($inc = 0 ; $inc < 16 ; $inc ++) {
0 ignored issues
show
Coding Style introduced by
Space found before first semicolon of FOR loop
Loading history...
Coding Style introduced by
Space found before second semicolon of FOR loop
Loading history...
1075
            $encryptedVerifier .= pack('v', self::getInt1d($oStream, $pos));
1076
            $pos += 1;
1077
        }
1078
        echo 'EncryptionVerifier > EncryptedVerifier : ';
1079
        hex_dump($encryptedVerifier);
1080
        // EncryptionVerifier > VerifierHashSize
1081
        $verifierHashSize = self::getInt4d($oStream, $pos);
1082
        echo 'EncryptionVerifier > VerifierHashSize ('.hexdec('0x00000010').' = 0x00000010) :';
1083
        hex_dump($verifierHashSize);
1084
        $pos += 4;
1085
        // EncryptionVerifier > EncryptedVerifierHash
1086
        // mon cas : AES donc 32
1087
        echo 'EncryptionVerifier > EncryptedVerifierHash :';
1088
        $encryptedVerifierHash = '';
1089
        for ($inc = 0 ; $inc < 32 ; $inc ++) {
0 ignored issues
show
Coding Style introduced by
Space found before first semicolon of FOR loop
Loading history...
Coding Style introduced by
Space found before second semicolon of FOR loop
Loading history...
1090
            $encryptedVerifierHash .= pack('v', self::getInt1d($oStream, $pos));
1091
            $pos += 1;
1092
        }
1093
        hex_dump($encryptedVerifierHash);
1094
1095
        // https://github.com/doy/spreadsheet-parsexlsx/pull/37/files#diff-e61fbe6112ca2b7a3c08a4ea62d74ffeR1314
1096
1097
        // https://msdn.microsoft.com/en-us/library/dd925430(v=office.12).aspx
1098
        // H0 = H(salt + password)
1099
        $hash = $salt . iconv("ISO-8859-1", "UTF-16LE", $this->getPassword());
1100
        echo 'Hash (length : '.strlen($hash).')';
1101
        hex_dump($hash);
1102
        for($inc = 0 ; $inc < 50000 ; $inc++) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FOR keyword; 0 found
Loading history...
Coding Style introduced by
Space found before first semicolon of FOR loop
Loading history...
Coding Style introduced by
Space found before second semicolon of FOR loop
Loading history...
1103
            $hash = sha1(pack('L', $inc).$hash, true);
1104
        }
1105
        echo 'Hash (length : '.strlen($hash).')';
1106
        hex_dump($hash);
1107
        //  Hn = H(iterator + Hn-1)
1108
        $hash = sha1($hash . 0x00000000, true);
1109
        echo 'Hash (length : '.strlen($hash).')';
1110
        hex_dump($hash);
1111
1112
        $keySize /=8;
1113
1114
        $x36 = '';
1115
        for($inc = 0 ; $inc < 64 ; $inc++) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FOR keyword; 0 found
Loading history...
Coding Style introduced by
Space found before first semicolon of FOR loop
Loading history...
Coding Style introduced by
Space found before second semicolon of FOR loop
Loading history...
1116
            $x36 .= pack('H*', '36');
1117
        }
1118
        echo 'x36 (length : '.strlen($x36).')';
1119
        hex_dump($x36);
1120
1121
        $x1 = ($x36 ^ $hash);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $x1. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1122
        echo 'Hash = $x36 xor $hash (length : '.strlen($x1).')';
1123
        hex_dump($x1);
1124
1125
        if (strlen($x1) >= $keySize) {
1126
            $hash = substr($x1, 0, $keySize);
1127
        } else {
1128
            $x5C = '';
1129
            for($inc = 0 ; $inc < 64 ; $inc++) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FOR keyword; 0 found
Loading history...
Coding Style introduced by
Space found before first semicolon of FOR loop
Loading history...
Coding Style introduced by
Space found before second semicolon of FOR loop
Loading history...
1130
                $x5C .= pack('H*', '5C');
1131
            }
1132
            echo '$x5C (length : '.strlen($x5C).')';
1133
            hex_dump($x5C);
1134
1135
            $x2 = ($x5C ^ $hash);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $x2. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1136
            echo '$x1 = $x5C xor $hash (length : '.strlen($x2).')';
1137
            hex_dump($x2);
1138
1139
            $hash = substr($x1.$x2, 0, $keySize);
1140
        }
1141
1142
        echo 'Final hash (length : '.strlen($hash).')';
1143
        hex_dump($hash);
1144
        // https://msdn.microsoft.com/en-us/library/dd926426(v=office.12).aspx
1145
        $verifier = openssl_decrypt($encryptedVerifier, 'AES-128-ECB', $hash, 0, '');
1146
        echo 'Verifier :';
1147
        hex_dump($verifier);
1148
        $verifierHash = openssl_decrypt($encryptedVerifierHash, 'AES-128-ECB', $hash, 0, '');
1149
        echo 'VerifierHash :';
1150
        hex_dump($verifierHash);
1151
1152
        $verifierHash0 = sha1($verifier, true);
1153
        echo 'VerifierHash :';
1154
        hex_dump($verifierHash);
1155
        echo 'VerifierHash sha1($verifier, true):';
1156
        hex_dump($verifierHash0);
1157
    }
1158
1159
    /**
1160
     * Read 8-bit unsigned integer
1161
     *
1162
     * @param string $data
1163
     * @param int $pos
1164
     * @return int
1165
     */
1166
    public static function getInt1d($data, $pos)
1167
    {
1168
        return ord($data[$pos]);
1169
    }
1170
1171
    /**
1172
     * Read 16-bit unsigned integer
1173
     *
1174
     * @param string $data
1175
     * @param int $pos
1176
     * @return int
1177
     */
1178
    public static function getInt2d($data, $pos)
1179
    {
1180
        return ord($data[$pos]) | (ord($data[$pos+1]) << 8);
1181
    }
1182
1183
    /**
1184
     * Read 32-bit signed integer
1185
     *
1186
     * @param string $data
1187
     * @param int $pos
1188
     * @return int
1189
     */
1190
    public static function getInt4d($data, $pos)
1191
    {
1192
        // FIX: represent numbers correctly on 64-bit system
1193
        // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
1194
        // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
1195
        $or24 = ord($data[$pos + 3]);
1196
        if ($or24 >= 128) {
1197
            // negative number
1198
            $ord24 = -abs((256 - $or24) << 24);
1199
        } else {
1200
            $ord24 = ($or24 & 127) << 24;
1201
        }
1202
        return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $ord24;
1203
    }
1204
}
1205