Completed
Push — develop ( 5e03e2...c8a8fd )
by Adrien
28:49
created

Xlsx::load()   F

Complexity

Conditions 379
Paths > 20000

Size

Total Lines 1507
Code Lines 962

Duplication

Lines 140
Ratio 9.29 %

Code Coverage

Tests 652
CRAP Score 4422.4869

Importance

Changes 0
Metric Value
cc 379
eloc 962
nc 983248
nop 1
dl 140
loc 1507
ccs 652
cts 937
cp 0.6958
crap 4422.4869
rs 2
c 0
b 0
f 0

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
namespace PhpOffice\PhpSpreadsheet\Reader;
4
5
use PhpOffice\PhpSpreadsheet\Shared\File;
6
7
/**
8
 * Copyright (c) 2006 - 2016 PhpSpreadsheet
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
 *
24
 * @category   PhpSpreadsheet
25
 * @copyright  Copyright (c) 2006 - 2016 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
26
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
27
 */
28
class Xlsx extends BaseReader implements IReader
29
{
30
    /**
31
     * ReferenceHelper instance
32
     *
33
     * @var \PhpOffice\PhpSpreadsheet\ReferenceHelper
34
     */
35
    private $referenceHelper = null;
36
37
    /**
38
     * Xlsx\Theme instance
39
     *
40
     * @var Xlsx\Theme
41
     */
42
    private static $theme = null;
43
44
    /**
45
     * Create a new Xlsx Reader instance
46
     */
47 10
    public function __construct()
48
    {
49 10
        $this->readFilter = new DefaultReadFilter();
50 10
        $this->referenceHelper = \PhpOffice\PhpSpreadsheet\ReferenceHelper::getInstance();
51 10
    }
52
53
    /**
54
     * Can the current IReader read the file?
55
     *
56
     * @param    string         $pFilename
57
     * @throws   Exception
58
     * @return   bool
59
     */
60 5
    public function canRead($pFilename)
61
    {
62 5
        File::assertFile($pFilename);
63
64 5
        $zipClass = \PhpOffice\PhpSpreadsheet\Settings::getZipClass();
65
66
        // Check if zip class exists
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
67
//        if (!class_exists($zipClass, false)) {
68
//            throw new Exception($zipClass . " library is not enabled");
69
//        }
70
71 5
        $xl = false;
72
        // Load file
73 5
        $zip = new $zipClass();
74 5
        if ($zip->open($pFilename) === true) {
75
            // check if it is an OOXML archive
76 5
            $rels = simplexml_load_string(
77 5
                $this->securityScan(
78 5
                    $this->getFromZipArchive($zip, '_rels/.rels')
79
                ),
80 5
                'SimpleXMLElement',
81 5
                \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
82
            );
83 5
            if ($rels !== false) {
84 5
                foreach ($rels->Relationship as $rel) {
85 5
                    switch ($rel['Type']) {
86 5
                        case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
87 5
                            if (basename($rel['Target']) == 'workbook.xml') {
88 5
                                $xl = true;
89
                            }
90 5
                            break;
91
                    }
92
                }
93
            }
94 5
            $zip->close();
95
        }
96
97 5
        return $xl;
98
    }
99
100
    /**
101
     * Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object
102
     *
103
     * @param    string         $pFilename
104
     * @throws   Exception
105
     */
106 1
    public function listWorksheetNames($pFilename)
107
    {
108 1
        File::assertFile($pFilename);
109
110 1
        $worksheetNames = [];
111
112 1
        $zipClass = \PhpOffice\PhpSpreadsheet\Settings::getZipClass();
113
114 1
        $zip = new $zipClass();
115 1
        $zip->open($pFilename);
116
117
        //    The files we're looking at here are small enough that simpleXML is more efficient than XMLReader
118 1
        $rels = simplexml_load_string(
119 1
            $this->securityScan(
120 1
                $this->getFromZipArchive($zip, '_rels/.rels'),
121 1
                'SimpleXMLElement',
0 ignored issues
show
Unused Code introduced by
The call to Xlsx::securityScan() has too many arguments starting with 'SimpleXMLElement'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
122 1
                \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
123
            )
124
        ); //~ http://schemas.openxmlformats.org/package/2006/relationships");
125 1
        foreach ($rels->Relationship as $rel) {
126 1
            switch ($rel['Type']) {
127 1
                case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
128 1
                    $xmlWorkbook = simplexml_load_string(
129 1
                        $this->securityScan(
130 1
                            $this->getFromZipArchive($zip, "{$rel['Target']}"),
131 1
                            'SimpleXMLElement',
0 ignored issues
show
Unused Code introduced by
The call to Xlsx::securityScan() has too many arguments starting with 'SimpleXMLElement'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
132 1
                            \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
133
                        )
134
                    ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
135
136 1
                    if ($xmlWorkbook->sheets) {
137 1
                        foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
138
                            // Check if sheet should be skipped
139 1
                            $worksheetNames[] = (string) $eleSheet['name'];
140
                        }
141
                    }
142
            }
143
        }
144
145 1
        $zip->close();
146
147 1
        return $worksheetNames;
148
    }
149
150
    /**
151
     * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
152
     *
153
     * @param   string     $pFilename
154
     * @throws  Exception
155
     */
156 1
    public function listWorksheetInfo($pFilename)
157
    {
158 1
        File::assertFile($pFilename);
159
160 1
        $worksheetInfo = [];
161
162 1
        $zipClass = \PhpOffice\PhpSpreadsheet\Settings::getZipClass();
163
164 1
        $zip = new $zipClass();
165 1
        $zip->open($pFilename);
166
167 1
        $rels = simplexml_load_string(
168
            //~ http://schemas.openxmlformats.org/package/2006/relationships"
169 1
            $this->securityScan($this->getFromZipArchive($zip, '_rels/.rels')),
170 1
            'SimpleXMLElement',
171 1
            \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
172
        );
173 1
        foreach ($rels->Relationship as $rel) {
174 1
            if ($rel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument') {
175 1
                $dir = dirname($rel['Target']);
176 1
                $relsWorkbook = simplexml_load_string(
177
                    //~ http://schemas.openxmlformats.org/package/2006/relationships"
178 1
                    $this->securityScan(
179 1
                        $this->getFromZipArchive($zip, "$dir/_rels/" . basename($rel['Target']) . '.rels')
180
                    ),
181 1
                    'SimpleXMLElement',
182 1
                    \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
183
                );
184 1
                $relsWorkbook->registerXPathNamespace('rel', 'http://schemas.openxmlformats.org/package/2006/relationships');
185
186 1
                $worksheets = [];
187 1
                foreach ($relsWorkbook->Relationship as $ele) {
188 1
                    if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet') {
189 1
                        $worksheets[(string) $ele['Id']] = $ele['Target'];
190
                    }
191
                }
192
193 1
                $xmlWorkbook = simplexml_load_string(
194
                    //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
195 1
                    $this->securityScan(
196 1
                        $this->getFromZipArchive($zip, "{$rel['Target']}")
197
                    ),
198 1
                    'SimpleXMLElement',
199 1
                    \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
200
                );
201 1
                if ($xmlWorkbook->sheets) {
202 1
                    $dir = dirname($rel['Target']);
203 1
                    foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
204
                        $tmpInfo = [
205 1
                            'worksheetName' => (string) $eleSheet['name'],
206 1
                            'lastColumnLetter' => 'A',
207 1
                            'lastColumnIndex' => 0,
208 1
                            'totalRows' => 0,
209 1
                            'totalColumns' => 0,
210
                        ];
211
212 1
                        $fileWorksheet = $worksheets[(string) self::getArrayItem($eleSheet->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'), 'id')];
213
214 1
                        $xml = new \XMLReader();
215 1
                        $res = $xml->xml(
0 ignored issues
show
Unused Code introduced by
$res 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...
216 1
                            $this->securityScanFile(
217 1
                                'zip://' . \PhpOffice\PhpSpreadsheet\Shared\File::realpath($pFilename) . '#' . "$dir/$fileWorksheet"
218
                            ),
219 1
                            null,
220 1
                            \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
221
                        );
222 1
                        $xml->setParserProperty(2, true);
223
224 1
                        $currCells = 0;
225 1
                        while ($xml->read()) {
226 1
                            if ($xml->name == 'row' && $xml->nodeType == \XMLReader::ELEMENT) {
227 1
                                $row = $xml->getAttribute('r');
228 1
                                $tmpInfo['totalRows'] = $row;
229 1
                                $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
230 1
                                $currCells = 0;
231 1
                            } elseif ($xml->name == 'c' && $xml->nodeType == \XMLReader::ELEMENT) {
232 1
                                ++$currCells;
233
                            }
234
                        }
235 1
                        $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'], $currCells);
236 1
                        $xml->close();
237
238 1
                        $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
239 1
                        $tmpInfo['lastColumnLetter'] = \PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
240
241 1
                        $worksheetInfo[] = $tmpInfo;
242
                    }
243
                }
244
            }
245
        }
246
247 1
        $zip->close();
248
249 1
        return $worksheetInfo;
250
    }
251
252 1
    private static function castToBoolean($c)
253
    {
254 1
        $value = isset($c->v) ? (string) $c->v : null;
255 1
        if ($value == '0') {
256
            return false;
257 1
        } elseif ($value == '1') {
258 1
            return true;
259
        } else {
260
            return (bool) $c->v;
261
        }
262
263
        return $value;
0 ignored issues
show
Unused Code introduced by
return $value; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
264
    }
265
266
    private static function castToError($c)
267
    {
268
        return isset($c->v) ? (string) $c->v : null;
269
    }
270
271 5
    private static function castToString($c)
272
    {
273 5
        return isset($c->v) ? (string) $c->v : null;
274
    }
275
276 3
    private function castToFormula($c, $r, &$cellDataType, &$value, &$calculatedValue, &$sharedFormulas, $castBaseType)
277
    {
278 3
        $cellDataType = 'f';
279 3
        $value = "={$c->f}";
280 3
        $calculatedValue = self::$castBaseType($c);
281
282
        // Shared formula?
283 3
        if (isset($c->f['t']) && strtolower((string) $c->f['t']) == 'shared') {
284 1
            $instance = (string) $c->f['si'];
285
286 1
            if (!isset($sharedFormulas[(string) $c->f['si']])) {
287 1
                $sharedFormulas[$instance] = ['master' => $r, 'formula' => $value];
288
            } else {
289 1
                $master = \PhpOffice\PhpSpreadsheet\Cell::coordinateFromString($sharedFormulas[$instance]['master']);
290 1
                $current = \PhpOffice\PhpSpreadsheet\Cell::coordinateFromString($r);
291
292 1
                $difference = [0, 0];
293 1
                $difference[0] = \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString($current[0]) - \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString($master[0]);
294 1
                $difference[1] = $current[1] - $master[1];
295
296 1
                $value = $this->referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]);
297
            }
298
        }
299 3
    }
300
301 10
    private function getFromZipArchive($archive, $fileName = '')
302
    {
303
        // Root-relative paths
304 10
        if (strpos($fileName, '//') !== false) {
305
            $fileName = substr($fileName, strpos($fileName, '//') + 1);
306
        }
307 10
        $fileName = \PhpOffice\PhpSpreadsheet\Shared\File::realpath($fileName);
308
309
        // Sadly, some 3rd party xlsx generators don't use consistent case for filenaming
310
        //    so we need to load case-insensitively from the zip file
311
312
        // Apache POI fixes
313 10
        $contents = $archive->getFromIndex(
314 10
            $archive->locateName($fileName, \ZipArchive::FL_NOCASE)
315
        );
316 10
        if ($contents === false) {
317
            $contents = $archive->getFromIndex(
318
                $archive->locateName(substr($fileName, 1), \ZipArchive::FL_NOCASE)
319
            );
320
        }
321
322 10
        return $contents;
323
    }
324
325
    /**
326
     * Loads Spreadsheet from file
327
     *
328
     * @param     string         $pFilename
329
     * @throws    Exception
330
     * @return    Spreadsheet
331
     */
332 8
    public function load($pFilename)
333
    {
334 8
        File::assertFile($pFilename);
335
336
        // Initialisations
337 8
        $excel = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
338 8
        $excel->removeSheetByIndex(0);
339 8
        if (!$this->readDataOnly) {
340 8
            $excel->removeCellStyleXfByIndex(0); // remove the default style
341 8
            $excel->removeCellXfByIndex(0); // remove the default style
342
        }
343
344 8
        $zipClass = \PhpOffice\PhpSpreadsheet\Settings::getZipClass();
345
346 8
        $zip = new $zipClass();
347 8
        $zip->open($pFilename);
348
349
        //    Read the theme first, because we need the colour scheme when reading the styles
350 8
        $wbRels = simplexml_load_string(
351
            //~ http://schemas.openxmlformats.org/package/2006/relationships"
352 8
            $this->securityScan($this->getFromZipArchive($zip, 'xl/_rels/workbook.xml.rels')),
353 8
            'SimpleXMLElement',
354 8
            \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
355
        );
356 8
        foreach ($wbRels->Relationship as $rel) {
357 8
            switch ($rel['Type']) {
358 8
                case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme':
359 8
                    $themeOrderArray = ['lt1', 'dk1', 'lt2', 'dk2'];
360 8
                    $themeOrderAdditional = count($themeOrderArray);
361
362 8
                    $xmlTheme = simplexml_load_string(
363 8
                        $this->securityScan($this->getFromZipArchive($zip, "xl/{$rel['Target']}")),
364 8
                        'SimpleXMLElement',
365 8
                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
366
                    );
367 8
                    if (is_object($xmlTheme)) {
368 8
                        $xmlThemeName = $xmlTheme->attributes();
369 8
                        $xmlTheme = $xmlTheme->children('http://schemas.openxmlformats.org/drawingml/2006/main');
370 8
                        $themeName = (string) $xmlThemeName['name'];
371
372 8
                        $colourScheme = $xmlTheme->themeElements->clrScheme->attributes();
373 8
                        $colourSchemeName = (string) $colourScheme['name'];
374 8
                        $colourScheme = $xmlTheme->themeElements->clrScheme->children('http://schemas.openxmlformats.org/drawingml/2006/main');
375
376 8
                        $themeColours = [];
377 8
                        foreach ($colourScheme as $k => $xmlColour) {
378 8
                            $themePos = array_search($k, $themeOrderArray);
379 8
                            if ($themePos === false) {
380 8
                                $themePos = $themeOrderAdditional++;
381
                            }
382 8
                            if (isset($xmlColour->sysClr)) {
383 8
                                $xmlColourData = $xmlColour->sysClr->attributes();
384 8
                                $themeColours[$themePos] = $xmlColourData['lastClr'];
385
                            } elseif (isset($xmlColour->srgbClr)) {
386 8
                                $xmlColourData = $xmlColour->srgbClr->attributes();
387 8
                                $themeColours[$themePos] = $xmlColourData['val'];
388
                            }
389
                        }
390 8
                        self::$theme = new Xlsx\Theme($themeName, $colourSchemeName, $themeColours);
391
                    }
392 8
                    break;
393
            }
394
        }
395
396 8
        $rels = simplexml_load_string(
397
            //~ http://schemas.openxmlformats.org/package/2006/relationships"
398 8
            $this->securityScan($this->getFromZipArchive($zip, '_rels/.rels')),
399 8
            'SimpleXMLElement',
400 8
            \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
401
        );
402 8
        foreach ($rels->Relationship as $rel) {
403 8
            switch ($rel['Type']) {
404 8
                case 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties':
405 8
                    $xmlCore = simplexml_load_string(
406 8
                        $this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")),
407 8
                        'SimpleXMLElement',
408 8
                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
409
                    );
410 8
                    if (is_object($xmlCore)) {
411 8
                        $xmlCore->registerXPathNamespace('dc', 'http://purl.org/dc/elements/1.1/');
412 8
                        $xmlCore->registerXPathNamespace('dcterms', 'http://purl.org/dc/terms/');
413 8
                        $xmlCore->registerXPathNamespace('cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties');
414 8
                        $docProps = $excel->getProperties();
415 8
                        $docProps->setCreator((string) self::getArrayItem($xmlCore->xpath('dc:creator')));
416 8
                        $docProps->setLastModifiedBy((string) self::getArrayItem($xmlCore->xpath('cp:lastModifiedBy')));
417 8
                        $docProps->setCreated(strtotime(self::getArrayItem($xmlCore->xpath('dcterms:created')))); //! respect xsi:type
0 ignored issues
show
Documentation introduced by
strtotime(self::getArray...th('dcterms:created'))) is of type integer, but the function expects a object<PhpOffice\PhpSpre...Document\datetime>|null.

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...
418 8
                        $docProps->setModified(strtotime(self::getArrayItem($xmlCore->xpath('dcterms:modified')))); //! respect xsi:type
0 ignored issues
show
Documentation introduced by
strtotime(self::getArray...h('dcterms:modified'))) is of type integer, but the function expects a object<PhpOffice\PhpSpre...Document\datetime>|null.

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...
419 8
                        $docProps->setTitle((string) self::getArrayItem($xmlCore->xpath('dc:title')));
420 8
                        $docProps->setDescription((string) self::getArrayItem($xmlCore->xpath('dc:description')));
421 8
                        $docProps->setSubject((string) self::getArrayItem($xmlCore->xpath('dc:subject')));
422 8
                        $docProps->setKeywords((string) self::getArrayItem($xmlCore->xpath('cp:keywords')));
423 8
                        $docProps->setCategory((string) self::getArrayItem($xmlCore->xpath('cp:category')));
424
                    }
425 8
                    break;
426 8
                case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties':
427 8
                    $xmlCore = simplexml_load_string(
428 8
                        $this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")),
429 8
                        'SimpleXMLElement',
430 8
                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
431
                    );
432 8
                    if (is_object($xmlCore)) {
433 8
                        $docProps = $excel->getProperties();
434 8
                        if (isset($xmlCore->Company)) {
435 7
                            $docProps->setCompany((string) $xmlCore->Company);
436
                        }
437 8
                        if (isset($xmlCore->Manager)) {
438 5
                            $docProps->setManager((string) $xmlCore->Manager);
439
                        }
440
                    }
441 8
                    break;
442 8
                case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties':
443 1
                    $xmlCore = simplexml_load_string(
444 1
                        $this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")),
445 1
                        'SimpleXMLElement',
446 1
                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
447
                    );
448 1
                    if (is_object($xmlCore)) {
449 1
                        $docProps = $excel->getProperties();
450 1
                        foreach ($xmlCore as $xmlProperty) {
451 1
                            $cellDataOfficeAttributes = $xmlProperty->attributes();
452 1
                            if (isset($cellDataOfficeAttributes['name'])) {
453 1
                                $propertyName = (string) $cellDataOfficeAttributes['name'];
454 1
                                $cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');
455 1
                                $attributeType = $cellDataOfficeChildren->getName();
456 1
                                $attributeValue = (string) $cellDataOfficeChildren->{$attributeType};
457 1
                                $attributeValue = \PhpOffice\PhpSpreadsheet\Document\Properties::convertProperty($attributeValue, $attributeType);
458 1
                                $attributeType = \PhpOffice\PhpSpreadsheet\Document\Properties::convertPropertyType($attributeType);
459 1
                                $docProps->setCustomProperty($propertyName, $attributeValue, $attributeType);
460
                            }
461
                        }
462
                    }
463 1
                    break;
464
                //Ribbon
465 8
                case 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility':
466
                    $customUI = $rel['Target'];
467
                    if (!is_null($customUI)) {
468
                        $this->readRibbon($excel, $customUI, $zip);
469
                    }
470
                    break;
471 8
                case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
472 8
                    $dir = dirname($rel['Target']);
473 8
                    $relsWorkbook = simplexml_load_string(
474
                        //~ http://schemas.openxmlformats.org/package/2006/relationships"
475 8
                        $this->securityScan($this->getFromZipArchive($zip, "$dir/_rels/" . basename($rel['Target']) . '.rels')),
476 8
                        'SimpleXMLElement',
477 8
                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
478
                    );
479 8
                    $relsWorkbook->registerXPathNamespace('rel', 'http://schemas.openxmlformats.org/package/2006/relationships');
480
481 8
                    $sharedStrings = [];
482 8
                    $xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']"));
483 8
                    $xmlStrings = simplexml_load_string(
484
                        //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
485 8
                        $this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")),
486 8
                        'SimpleXMLElement',
487 8
                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
488
                    );
489 8
                    if (isset($xmlStrings) && isset($xmlStrings->si)) {
490 8
                        foreach ($xmlStrings->si as $val) {
491 8
                            if (isset($val->t)) {
492 8
                                $sharedStrings[] = \PhpOffice\PhpSpreadsheet\Shared\StringHelper::controlCharacterOOXML2PHP((string) $val->t);
493
                            } elseif (isset($val->r)) {
494 8
                                $sharedStrings[] = $this->parseRichText($val);
495
                            }
496
                        }
497
                    }
498
499 8
                    $worksheets = [];
500 8
                    $macros = $customUI = null;
0 ignored issues
show
Unused Code introduced by
$customUI 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...
501 8
                    foreach ($relsWorkbook->Relationship as $ele) {
502 8
                        switch ($ele['Type']) {
503 8
                            case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet':
504 8
                                $worksheets[(string) $ele['Id']] = $ele['Target'];
505 8
                                break;
506
                            // a vbaProject ? (: some macros)
507 8
                            case 'http://schemas.microsoft.com/office/2006/relationships/vbaProject':
508
                                $macros = $ele['Target'];
509 8
                                break;
510
                        }
511
                    }
512
513 8
                    if (!is_null($macros)) {
514
                        $macrosCode = $this->getFromZipArchive($zip, 'xl/vbaProject.bin'); //vbaProject.bin always in 'xl' dir and always named vbaProject.bin
515
                        if ($macrosCode !== false) {
516
                            $excel->setMacrosCode($macrosCode);
517
                            $excel->setHasMacros(true);
518
                            //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir
519
                            $Certificate = $this->getFromZipArchive($zip, 'xl/vbaProjectSignature.bin');
520
                            if ($Certificate !== false) {
521
                                $excel->setMacrosCertificate($Certificate);
522
                            }
523
                        }
524
                    }
525 8
                    $styles = [];
526 8
                    $cellStyles = [];
527 8
                    $xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']"));
528 8
                    $xmlStyles = simplexml_load_string(
529
                        //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
530 8
                        $this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")),
531 8
                        'SimpleXMLElement',
532 8
                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
533
                    );
534 8
                    $numFmts = null;
535 8
                    if ($xmlStyles && $xmlStyles->numFmts[0]) {
536 5
                        $numFmts = $xmlStyles->numFmts[0];
537
                    }
538 8
                    if (isset($numFmts) && ($numFmts !== null)) {
539 5
                        $numFmts->registerXPathNamespace('sml', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
540
                    }
541 8
                    if (!$this->readDataOnly && $xmlStyles) {
542 8
                        foreach ($xmlStyles->cellXfs->xf as $xf) {
543 8
                            $numFmt = \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_GENERAL;
544
545 8
                            if ($xf['numFmtId']) {
546 8
                                if (isset($numFmts)) {
547 5
                                    $tmpNumFmt = self::getArrayItem($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]"));
548
549 5
                                    if (isset($tmpNumFmt['formatCode'])) {
550 2
                                        $numFmt = (string) $tmpNumFmt['formatCode'];
551
                                    }
552
                                }
553
554
                                // We shouldn't override any of the built-in MS Excel values (values below id 164)
555
                                //  But there's a lot of naughty homebrew xlsx writers that do use "reserved" id values that aren't actually used
556
                                //  So we make allowance for them rather than lose formatting masks
557 8
                                if ((int) $xf['numFmtId'] < 164 &&
558 8
                                    \PhpOffice\PhpSpreadsheet\Style\NumberFormat::builtInFormatCode((int) $xf['numFmtId']) !== '') {
559 8
                                    $numFmt = \PhpOffice\PhpSpreadsheet\Style\NumberFormat::builtInFormatCode((int) $xf['numFmtId']);
560
                                }
561
                            }
562 8
                            $quotePrefix = false;
563 8
                            if (isset($xf['quotePrefix'])) {
564
                                $quotePrefix = (boolean) $xf['quotePrefix'];
565
                            }
566
567
                            $style = (object) [
568 8
                                'numFmt' => $numFmt,
569 8
                                'font' => $xmlStyles->fonts->font[intval($xf['fontId'])],
570 8
                                'fill' => $xmlStyles->fills->fill[intval($xf['fillId'])],
571 8
                                'border' => $xmlStyles->borders->border[intval($xf['borderId'])],
572 8
                                'alignment' => $xf->alignment,
573 8
                                'protection' => $xf->protection,
574 8
                                'quotePrefix' => $quotePrefix,
575
                            ];
576 8
                            $styles[] = $style;
577
578
                            // add style to cellXf collection
579 8
                            $objStyle = new \PhpOffice\PhpSpreadsheet\Style();
580 8
                            self::readStyle($objStyle, $style);
581 8
                            $excel->addCellXf($objStyle);
582
                        }
583
584 8
                        foreach ($xmlStyles->cellStyleXfs->xf as $xf) {
585 8
                            $numFmt = \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_GENERAL;
586 8
                            if ($numFmts && $xf['numFmtId']) {
587 5
                                $tmpNumFmt = self::getArrayItem($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]"));
588 5
                                if (isset($tmpNumFmt['formatCode'])) {
589
                                    $numFmt = (string) $tmpNumFmt['formatCode'];
590 5
                                } elseif ((int) $xf['numFmtId'] < 165) {
591 5
                                    $numFmt = \PhpOffice\PhpSpreadsheet\Style\NumberFormat::builtInFormatCode((int) $xf['numFmtId']);
592
                                }
593
                            }
594
595
                            $cellStyle = (object) [
596 8
                                'numFmt' => $numFmt,
597 8
                                'font' => $xmlStyles->fonts->font[intval($xf['fontId'])],
598 8
                                'fill' => $xmlStyles->fills->fill[intval($xf['fillId'])],
599 8
                                'border' => $xmlStyles->borders->border[intval($xf['borderId'])],
600 8
                                'alignment' => $xf->alignment,
601 8
                                'protection' => $xf->protection,
602 8
                                'quotePrefix' => $quotePrefix,
0 ignored issues
show
Bug introduced by
The variable $quotePrefix does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
603
                            ];
604 8
                            $cellStyles[] = $cellStyle;
605
606
                            // add style to cellStyleXf collection
607 8
                            $objStyle = new \PhpOffice\PhpSpreadsheet\Style();
608 8
                            self::readStyle($objStyle, $cellStyle);
609 8
                            $excel->addCellStyleXf($objStyle);
610
                        }
611
                    }
612
613 8
                    $dxfs = [];
614 8
                    if (!$this->readDataOnly && $xmlStyles) {
615
                        //    Conditional Styles
616 8
                        if ($xmlStyles->dxfs) {
617 8
                            foreach ($xmlStyles->dxfs->dxf as $dxf) {
618
                                $style = new \PhpOffice\PhpSpreadsheet\Style(false, true);
619
                                self::readStyle($style, $dxf);
620
                                $dxfs[] = $style;
621
                            }
622
                        }
623
                        //    Cell Styles
624 8
                        if ($xmlStyles->cellStyles) {
625 8
                            foreach ($xmlStyles->cellStyles->cellStyle as $cellStyle) {
626 8
                                if (intval($cellStyle['builtinId']) == 0) {
627 8
                                    if (isset($cellStyles[intval($cellStyle['xfId'])])) {
628
                                        // Set default style
629 8
                                        $style = new \PhpOffice\PhpSpreadsheet\Style();
630 8
                                        self::readStyle($style, $cellStyles[intval($cellStyle['xfId'])]);
631
632
                                        // normal style, currently not using it for anything
633
                                    }
634
                                }
635
                            }
636
                        }
637
                    }
638
639 8
                    $xmlWorkbook = simplexml_load_string(
640
                        //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
641 8
                        $this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")),
642 8
                        'SimpleXMLElement',
643 8
                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
644
                    );
645
646
                    // Set base date
647 8
                    if ($xmlWorkbook->workbookPr) {
648 8
                        \PhpOffice\PhpSpreadsheet\Shared\Date::setExcelCalendar(\PhpOffice\PhpSpreadsheet\Shared\Date::CALENDAR_WINDOWS_1900);
649 8
                        if (isset($xmlWorkbook->workbookPr['date1904'])) {
650
                            if (self::boolean((string) $xmlWorkbook->workbookPr['date1904'])) {
651
                                \PhpOffice\PhpSpreadsheet\Shared\Date::setExcelCalendar(\PhpOffice\PhpSpreadsheet\Shared\Date::CALENDAR_MAC_1904);
652
                            }
653
                        }
654
                    }
655
656 8
                    $sheetId = 0; // keep track of new sheet id in final workbook
657 8
                    $oldSheetId = -1; // keep track of old sheet id in final workbook
658 8
                    $countSkippedSheets = 0; // keep track of number of skipped sheets
659 8
                    $mapSheetId = []; // mapping of sheet ids from old to new
660
661 8
                    $charts = $chartDetails = [];
662
663 8
                    if ($xmlWorkbook->sheets) {
664 8
                        foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
665 8
                            ++$oldSheetId;
666
667
                            // Check if sheet should be skipped
668 8
                            if (isset($this->loadSheetsOnly) && !in_array((string) $eleSheet['name'], $this->loadSheetsOnly)) {
669
                                ++$countSkippedSheets;
670
                                $mapSheetId[$oldSheetId] = null;
671
                                continue;
672
                            }
673
674
                            // Map old sheet id in original workbook to new sheet id.
675
                            // They will differ if loadSheetsOnly() is being used
676 8
                            $mapSheetId[$oldSheetId] = $oldSheetId - $countSkippedSheets;
677
678
                            // Load sheet
679 8
                            $docSheet = $excel->createSheet();
680
                            //    Use false for $updateFormulaCellReferences to prevent adjustment of worksheet
681
                            //        references in formula cells... during the load, all formulae should be correct,
682
                            //        and we're simply bringing the worksheet name in line with the formula, not the
683
                            //        reverse
684 8
                            $docSheet->setTitle((string) $eleSheet['name'], false);
685 8
                            $fileWorksheet = $worksheets[(string) self::getArrayItem($eleSheet->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'), 'id')];
686 8
                            $xmlSheet = simplexml_load_string(
687
                                //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"
688 8
                                $this->securityScan($this->getFromZipArchive($zip, "$dir/$fileWorksheet")),
689 8
                                'SimpleXMLElement',
690 8
                                \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
691
                            );
692
693 8
                            $sharedFormulas = [];
694
695 8
                            if (isset($eleSheet['state']) && (string) $eleSheet['state'] != '') {
696
                                $docSheet->setSheetState((string) $eleSheet['state']);
697
                            }
698
699 8
                            if (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) {
700 8 View Code Duplication
                                if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
701
                                    $docSheet->getSheetView()->setZoomScale(intval($xmlSheet->sheetViews->sheetView['zoomScale']));
702
                                }
703 8 View Code Duplication
                                if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
704
                                    $docSheet->getSheetView()->setZoomScaleNormal(intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']));
705
                                }
706 8
                                if (isset($xmlSheet->sheetViews->sheetView['view'])) {
707
                                    $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']);
708
                                }
709 8 View Code Duplication
                                if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
710 5
                                    $docSheet->setShowGridLines(self::boolean((string) $xmlSheet->sheetViews->sheetView['showGridLines']));
711
                                }
712 8 View Code Duplication
                                if (isset($xmlSheet->sheetViews->sheetView['showRowColHeaders'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
713 5
                                    $docSheet->setShowRowColHeaders(self::boolean((string) $xmlSheet->sheetViews->sheetView['showRowColHeaders']));
714
                                }
715 8 View Code Duplication
                                if (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
716
                                    $docSheet->setRightToLeft(self::boolean((string) $xmlSheet->sheetViews->sheetView['rightToLeft']));
717
                                }
718 8
                                if (isset($xmlSheet->sheetViews->sheetView->pane)) {
719 1
                                    if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) {
720 1
                                        $docSheet->freezePane((string) $xmlSheet->sheetViews->sheetView->pane['topLeftCell']);
721
                                    } else {
722
                                        $xSplit = 0;
723
                                        $ySplit = 0;
724
725 View Code Duplication
                                        if (isset($xmlSheet->sheetViews->sheetView->pane['xSplit'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
726
                                            $xSplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['xSplit']);
727
                                        }
728
729 View Code Duplication
                                        if (isset($xmlSheet->sheetViews->sheetView->pane['ySplit'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
730
                                            $ySplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['ySplit']);
731
                                        }
732
733
                                        $docSheet->freezePaneByColumnAndRow($xSplit, $ySplit);
734
                                    }
735
                                }
736
737 8
                                if (isset($xmlSheet->sheetViews->sheetView->selection)) {
738 8
                                    if (isset($xmlSheet->sheetViews->sheetView->selection['sqref'])) {
739 8
                                        $sqref = (string) $xmlSheet->sheetViews->sheetView->selection['sqref'];
740 8
                                        $sqref = explode(' ', $sqref);
741 8
                                        $sqref = $sqref[0];
742 8
                                        $docSheet->setSelectedCells($sqref);
743
                                    }
744
                                }
745
                            }
746
747 8
                            if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) {
748 2
                                if (isset($xmlSheet->sheetPr->tabColor['rgb'])) {
749 2
                                    $docSheet->getTabColor()->setARGB((string) $xmlSheet->sheetPr->tabColor['rgb']);
750
                                }
751
                            }
752 8
                            if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr['codeName'])) {
753
                                $docSheet->setCodeName((string) $xmlSheet->sheetPr['codeName']);
754
                            }
755 8
                            if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) {
756 5 View Code Duplication
                                if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
757 5
                                    !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) {
758
                                    $docSheet->setShowSummaryRight(false);
759
                                } else {
760 5
                                    $docSheet->setShowSummaryRight(true);
761
                                }
762
763 5 View Code Duplication
                                if (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
764 5
                                    !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryBelow'])) {
765
                                    $docSheet->setShowSummaryBelow(false);
766
                                } else {
767 5
                                    $docSheet->setShowSummaryBelow(true);
768
                                }
769
                            }
770
771 8
                            if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) {
772
                                if (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) &&
773
                                    !self::boolean((string) $xmlSheet->sheetPr->pageSetUpPr['fitToPage'])) {
774
                                    $docSheet->getPageSetup()->setFitToPage(false);
775
                                } else {
776
                                    $docSheet->getPageSetup()->setFitToPage(true);
777
                                }
778
                            }
779
780 8
                            if (isset($xmlSheet->sheetFormatPr)) {
781 8
                                if (isset($xmlSheet->sheetFormatPr['customHeight']) &&
782 8
                                    self::boolean((string) $xmlSheet->sheetFormatPr['customHeight']) &&
783 8
                                    isset($xmlSheet->sheetFormatPr['defaultRowHeight'])) {
784
                                    $docSheet->getDefaultRowDimension()->setRowHeight((float) $xmlSheet->sheetFormatPr['defaultRowHeight']);
785
                                }
786 8
                                if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) {
787
                                    $docSheet->getDefaultColumnDimension()->setWidth((float) $xmlSheet->sheetFormatPr['defaultColWidth']);
788
                                }
789 8
                                if (isset($xmlSheet->sheetFormatPr['zeroHeight']) &&
790 8
                                    ((string) $xmlSheet->sheetFormatPr['zeroHeight'] == '1')) {
791
                                    $docSheet->getDefaultRowDimension()->setZeroHeight(true);
792
                                }
793
                            }
794
795 8
                            if (isset($xmlSheet->cols) && !$this->readDataOnly) {
796 5
                                foreach ($xmlSheet->cols->col as $col) {
797 5
                                    for ($i = intval($col['min']) - 1; $i < intval($col['max']); ++$i) {
798 5
                                        if ($col['style'] && !$this->readDataOnly) {
799 3
                                            $docSheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex($i))->setXfIndex(intval($col['style']));
800
                                        }
801 5
                                        if (self::boolean($col['hidden'])) {
802 1
                                            $docSheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex($i))->setVisible(false);
803
                                        }
804 5
                                        if (self::boolean($col['collapsed'])) {
805 1
                                            $docSheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex($i))->setCollapsed(true);
806
                                        }
807 5
                                        if ($col['outlineLevel'] > 0) {
808 1
                                            $docSheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col['outlineLevel']));
809
                                        }
810 5
                                        $docSheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex($i))->setWidth(floatval($col['width']));
811
812 5
                                        if (intval($col['max']) == 16384) {
813
                                            break;
814
                                        }
815
                                    }
816
                                }
817
                            }
818
819 8
                            if (isset($xmlSheet->printOptions) && !$this->readDataOnly) {
820 5
                                if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) {
821 5
                                    $docSheet->setShowGridlines(true);
822
                                }
823 5
                                if (self::boolean((string) $xmlSheet->printOptions['gridLines'])) {
824
                                    $docSheet->setPrintGridlines(true);
825
                                }
826 5
                                if (self::boolean((string) $xmlSheet->printOptions['horizontalCentered'])) {
827
                                    $docSheet->getPageSetup()->setHorizontalCentered(true);
828
                                }
829 5
                                if (self::boolean((string) $xmlSheet->printOptions['verticalCentered'])) {
830
                                    $docSheet->getPageSetup()->setVerticalCentered(true);
831
                                }
832
                            }
833
834 8
                            if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) {
835 8
                                foreach ($xmlSheet->sheetData->row as $row) {
836 8
                                    if ($row['ht'] && !$this->readDataOnly) {
837 1
                                        $docSheet->getRowDimension(intval($row['r']))->setRowHeight(floatval($row['ht']));
838
                                    }
839 8
                                    if (self::boolean($row['hidden']) && !$this->readDataOnly) {
840
                                        $docSheet->getRowDimension(intval($row['r']))->setVisible(false);
841
                                    }
842 8
                                    if (self::boolean($row['collapsed'])) {
843
                                        $docSheet->getRowDimension(intval($row['r']))->setCollapsed(true);
844
                                    }
845 8
                                    if ($row['outlineLevel'] > 0) {
846
                                        $docSheet->getRowDimension(intval($row['r']))->setOutlineLevel(intval($row['outlineLevel']));
847
                                    }
848 8 View Code Duplication
                                    if ($row['s'] && !$this->readDataOnly) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
849
                                        $docSheet->getRowDimension(intval($row['r']))->setXfIndex(intval($row['s']));
850
                                    }
851
852 8
                                    foreach ($row->c as $c) {
853 8
                                        $r = (string) $c['r'];
854 8
                                        $cellDataType = (string) $c['t'];
855 8
                                        $value = null;
856 8
                                        $calculatedValue = null;
857
858
                                        // Read cell?
859 8
                                        if ($this->getReadFilter() !== null) {
860 8
                                            $coordinates = \PhpOffice\PhpSpreadsheet\Cell::coordinateFromString($r);
861
862 8
                                            if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) {
863 1
                                                continue;
864
                                            }
865
                                        }
866
867
                                        // Read cell!
868
                                        switch ($cellDataType) {
869 8
                                            case 's':
870 8
                                                if ((string) $c->v != '') {
871 8
                                                    $value = $sharedStrings[intval($c->v)];
872
873 8
                                                    if ($value instanceof \PhpOffice\PhpSpreadsheet\RichText) {
874 8
                                                        $value = clone $value;
875
                                                    }
876
                                                } else {
877
                                                    $value = '';
878
                                                }
879 8
                                                break;
880 6
                                            case 'b':
881 1
                                                if (!isset($c->f)) {
882 1
                                                    $value = self::castToBoolean($c);
883
                                                } else {
884
                                                    // Formula
885
                                                    $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToBoolean');
886
                                                    if (isset($c->f['t'])) {
887
                                                        $att = [];
0 ignored issues
show
Unused Code introduced by
$att 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...
888
                                                        $att = $c->f;
889
                                                        $docSheet->getCell($r)->setFormulaAttributes($att);
890
                                                    }
891
                                                }
892 1
                                                break;
893 5 View Code Duplication
                                            case 'inlineStr':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
894 2
                                                if (isset($c->f)) {
895
                                                    $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError');
896
                                                } else {
897 2
                                                    $value = $this->parseRichText($c->is);
898
                                                }
899 2
                                                break;
900 5 View Code Duplication
                                            case 'e':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
901
                                                if (!isset($c->f)) {
902
                                                    $value = self::castToError($c);
903
                                                } else {
904
                                                    // Formula
905
                                                    $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError');
906
                                                }
907
                                                break;
908
                                            default:
909 5
                                                if (!isset($c->f)) {
910 5
                                                    $value = self::castToString($c);
911
                                                } else {
912
                                                    // Formula
913 3
                                                    $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToString');
914
                                                }
915 5
                                                break;
916
                                        }
917
918
                                        // Check for numeric values
919 8
                                        if (is_numeric($value) && $cellDataType != 's') {
920 5
                                            if ($value == (int) $value) {
921 5
                                                $value = (int) $value;
922
                                            } elseif ($value == (float) $value) {
923
                                                $value = (float) $value;
924
                                            } elseif ($value == (double) $value) {
925
                                                $value = (double) $value;
926
                                            }
927
                                        }
928
929
                                        // Rich text?
930 8
                                        if ($value instanceof \PhpOffice\PhpSpreadsheet\RichText && $this->readDataOnly) {
931
                                            $value = $value->getPlainText();
932
                                        }
933
934 8
                                        $cell = $docSheet->getCell($r);
935
                                        // Assign value
936 8
                                        if ($cellDataType != '') {
937 8
                                            $cell->setValueExplicit($value, $cellDataType);
938
                                        } else {
939 5
                                            $cell->setValue($value);
940
                                        }
941 8
                                        if ($calculatedValue !== null) {
942 3
                                            $cell->setCalculatedValue($calculatedValue);
943
                                        }
944
945
                                        // Style information?
946 8 View Code Duplication
                                        if ($c['s'] && !$this->readDataOnly) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
947
                                            // no style index means 0, it seems
948 5
                                            $cell->setXfIndex(isset($styles[intval($c['s'])]) ?
949 8
                                                intval($c['s']) : 0);
950
                                        }
951
                                    }
952
                                }
953
                            }
954
955 8
                            $conditionals = [];
956 8
                            if (!$this->readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) {
957
                                foreach ($xmlSheet->conditionalFormatting as $conditional) {
958
                                    foreach ($conditional->cfRule as $cfRule) {
959
                                        if (((string) $cfRule['type'] == \PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_NONE || (string) $cfRule['type'] == \PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_CELLIS || (string) $cfRule['type'] == \PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_CONTAINSTEXT || (string) $cfRule['type'] == \PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_EXPRESSION) && isset($dxfs[intval($cfRule['dxfId'])])) {
960
                                            $conditionals[(string) $conditional['sqref']][intval($cfRule['priority'])] = $cfRule;
961
                                        }
962
                                    }
963
                                }
964
965
                                foreach ($conditionals as $ref => $cfRules) {
966
                                    ksort($cfRules);
967
                                    $conditionalStyles = [];
968
                                    foreach ($cfRules as $cfRule) {
969
                                        $objConditional = new \PhpOffice\PhpSpreadsheet\Style\Conditional();
970
                                        $objConditional->setConditionType((string) $cfRule['type']);
971
                                        $objConditional->setOperatorType((string) $cfRule['operator']);
972
973
                                        if ((string) $cfRule['text'] != '') {
974
                                            $objConditional->setText((string) $cfRule['text']);
975
                                        }
976
977
                                        if (count($cfRule->formula) > 1) {
978
                                            foreach ($cfRule->formula as $formula) {
979
                                                $objConditional->addCondition((string) $formula);
980
                                            }
981
                                        } else {
982
                                            $objConditional->addCondition((string) $cfRule->formula);
983
                                        }
984
                                        $objConditional->setStyle(clone $dxfs[intval($cfRule['dxfId'])]);
985
                                        $conditionalStyles[] = $objConditional;
986
                                    }
987
988
                                    // Extract all cell references in $ref
989
                                    $cellBlocks = explode(' ', str_replace('$', '', strtoupper($ref)));
990
                                    foreach ($cellBlocks as $cellBlock) {
991
                                        $docSheet->getStyle($cellBlock)->setConditionalStyles($conditionalStyles);
992
                                    }
993
                                }
994
                            }
995
996 8
                            $aKeys = ['sheet', 'objects', 'scenarios', 'formatCells', 'formatColumns', 'formatRows', 'insertColumns', 'insertRows', 'insertHyperlinks', 'deleteColumns', 'deleteRows', 'selectLockedCells', 'sort', 'autoFilter', 'pivotTables', 'selectUnlockedCells'];
997 8
                            if (!$this->readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
998 5
                                foreach ($aKeys as $key) {
999 5
                                    $method = 'set' . ucfirst($key);
1000 5
                                    $docSheet->getProtection()->$method(self::boolean((string) $xmlSheet->sheetProtection[$key]));
1001
                                }
1002
                            }
1003
1004 8
                            if (!$this->readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {
1005 5
                                $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection['password'], true);
1006 5
                                if ($xmlSheet->protectedRanges->protectedRange) {
1007 2
                                    foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) {
1008 2
                                        $docSheet->protectCells((string) $protectedRange['sqref'], (string) $protectedRange['password'], true);
1009
                                    }
1010
                                }
1011
                            }
1012
1013 8
                            if ($xmlSheet && $xmlSheet->autoFilter && !$this->readDataOnly) {
1014
                                $autoFilterRange = (string) $xmlSheet->autoFilter['ref'];
1015
                                if (strpos($autoFilterRange, ':') !== false) {
1016
                                    $autoFilter = $docSheet->getAutoFilter();
1017
                                    $autoFilter->setRange($autoFilterRange);
1018
1019
                                    foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) {
1020
                                        $column = $autoFilter->getColumnByOffset((integer) $filterColumn['colId']);
1021
                                        //    Check for standard filters
1022
                                        if ($filterColumn->filters) {
1023
                                            $column->setFilterType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER);
1024
                                            $filters = $filterColumn->filters;
1025
                                            if ((isset($filters['blank'])) && ($filters['blank'] == 1)) {
1026
                                                //    Operator is undefined, but always treated as EQUAL
1027
                                                $column->createRule()->setRule(null, '')->setRuleType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_FILTER);
1028
                                            }
1029
                                            //    Standard filters are always an OR join, so no join rule needs to be set
1030
                                            //    Entries can be either filter elements
1031 View Code Duplication
                                            foreach ($filters->filter as $filterRule) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1032
                                                //    Operator is undefined, but always treated as EQUAL
1033
                                                $column->createRule()->setRule(null, (string) $filterRule['val'])->setRuleType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_FILTER);
1034
                                            }
1035
                                            //    Or Date Group elements
1036
                                            foreach ($filters->dateGroupItem as $dateGroupItem) {
1037
                                                $column->createRule()->setRule(
1038
                                                    //    Operator is undefined, but always treated as EQUAL
1039
                                                    null,
1040
                                                    [
1041
                                                        'year' => (string) $dateGroupItem['year'],
1042
                                                        'month' => (string) $dateGroupItem['month'],
1043
                                                        'day' => (string) $dateGroupItem['day'],
1044
                                                        'hour' => (string) $dateGroupItem['hour'],
1045
                                                        'minute' => (string) $dateGroupItem['minute'],
1046
                                                        'second' => (string) $dateGroupItem['second'],
1047
                                                    ],
1048
                                                    (string) $dateGroupItem['dateTimeGrouping']
1049
                                                )
1050
                                                ->setRuleType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP);
1051
                                            }
1052
                                        }
1053
                                        //    Check for custom filters
1054
                                        if ($filterColumn->customFilters) {
1055
                                            $column->setFilterType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER);
1056
                                            $customFilters = $filterColumn->customFilters;
1057
                                            //    Custom filters can an AND or an OR join;
1058
                                            //        and there should only ever be one or two entries
1059
                                            if ((isset($customFilters['and'])) && ($customFilters['and'] == 1)) {
1060
                                                $column->setJoin(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND);
1061
                                            }
1062 View Code Duplication
                                            foreach ($customFilters->customFilter as $filterRule) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1063
                                                $column->createRule()->setRule(
1064
                                                    (string) $filterRule['operator'],
1065
                                                    (string) $filterRule['val']
1066
                                                )
1067
                                                ->setRuleType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);
1068
                                            }
1069
                                        }
1070
                                        //    Check for dynamic filters
1071
                                        if ($filterColumn->dynamicFilter) {
1072
                                            $column->setFilterType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);
1073
                                            //    We should only ever have one dynamic filter
1074
                                            foreach ($filterColumn->dynamicFilter as $filterRule) {
1075
                                                $column->createRule()->setRule(
1076
                                                    //    Operator is undefined, but always treated as EQUAL
1077
                                                    null,
1078
                                                    (string) $filterRule['val'],
1079
                                                    (string) $filterRule['type']
1080
                                                )
1081
                                                ->setRuleType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);
1082
                                                if (isset($filterRule['val'])) {
1083
                                                    $column->setAttribute('val', (string) $filterRule['val']);
1084
                                                }
1085
                                                if (isset($filterRule['maxVal'])) {
1086
                                                    $column->setAttribute('maxVal', (string) $filterRule['maxVal']);
1087
                                                }
1088
                                            }
1089
                                        }
1090
                                        //    Check for dynamic filters
1091
                                        if ($filterColumn->top10) {
1092
                                            $column->setFilterType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER);
1093
                                            //    We should only ever have one top10 filter
1094
                                            foreach ($filterColumn->top10 as $filterRule) {
1095
                                                $column->createRule()->setRule(
1096
                                                    (((isset($filterRule['percent'])) && ($filterRule['percent'] == 1))
1097
                                                        ? \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT
1098
                                                        : \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE
1099
                                                    ),
1100
                                                    (string) $filterRule['val'],
1101
                                                    (((isset($filterRule['top'])) && ($filterRule['top'] == 1))
1102
                                                        ? \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP
1103
                                                        : \PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM
1104
                                                    )
1105
                                                )
1106
                                                ->setRuleType(\PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_TOPTENFILTER);
1107
                                            }
1108
                                        }
1109
                                    }
1110
                                }
1111
                            }
1112
1113 8
                            if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->readDataOnly) {
1114 4
                                foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) {
1115 4
                                    $mergeRef = (string) $mergeCell['ref'];
1116 4
                                    if (strpos($mergeRef, ':') !== false) {
1117 4
                                        $docSheet->mergeCells((string) $mergeCell['ref']);
1118
                                    }
1119
                                }
1120
                            }
1121
1122 8
                            if ($xmlSheet && $xmlSheet->pageMargins && !$this->readDataOnly) {
1123 8
                                $docPageMargins = $docSheet->getPageMargins();
1124 8
                                $docPageMargins->setLeft(floatval($xmlSheet->pageMargins['left']));
1125 8
                                $docPageMargins->setRight(floatval($xmlSheet->pageMargins['right']));
1126 8
                                $docPageMargins->setTop(floatval($xmlSheet->pageMargins['top']));
1127 8
                                $docPageMargins->setBottom(floatval($xmlSheet->pageMargins['bottom']));
1128 8
                                $docPageMargins->setHeader(floatval($xmlSheet->pageMargins['header']));
1129 8
                                $docPageMargins->setFooter(floatval($xmlSheet->pageMargins['footer']));
1130
                            }
1131
1132 8
                            if ($xmlSheet && $xmlSheet->pageSetup && !$this->readDataOnly) {
1133 8
                                $docPageSetup = $docSheet->getPageSetup();
1134
1135 8
                                if (isset($xmlSheet->pageSetup['orientation'])) {
1136 8
                                    $docPageSetup->setOrientation((string) $xmlSheet->pageSetup['orientation']);
1137
                                }
1138 8
                                if (isset($xmlSheet->pageSetup['paperSize'])) {
1139 8
                                    $docPageSetup->setPaperSize(intval($xmlSheet->pageSetup['paperSize']));
1140
                                }
1141 8
                                if (isset($xmlSheet->pageSetup['scale'])) {
1142 5
                                    $docPageSetup->setScale(intval($xmlSheet->pageSetup['scale']), false);
1143
                                }
1144 8 View Code Duplication
                                if (isset($xmlSheet->pageSetup['fitToHeight']) && intval($xmlSheet->pageSetup['fitToHeight']) >= 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1145 5
                                    $docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup['fitToHeight']), false);
1146
                                }
1147 8 View Code Duplication
                                if (isset($xmlSheet->pageSetup['fitToWidth']) && intval($xmlSheet->pageSetup['fitToWidth']) >= 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1148 5
                                    $docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup['fitToWidth']), false);
1149
                                }
1150 8
                                if (isset($xmlSheet->pageSetup['firstPageNumber']) && isset($xmlSheet->pageSetup['useFirstPageNumber']) &&
1151 8
                                    self::boolean((string) $xmlSheet->pageSetup['useFirstPageNumber'])) {
1152
                                    $docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup['firstPageNumber']));
1153
                                }
1154
                            }
1155
1156 8
                            if ($xmlSheet && $xmlSheet->headerFooter && !$this->readDataOnly) {
1157 5
                                $docHeaderFooter = $docSheet->getHeaderFooter();
1158
1159 5 View Code Duplication
                                if (isset($xmlSheet->headerFooter['differentOddEven']) &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1160 5
                                    self::boolean((string) $xmlSheet->headerFooter['differentOddEven'])) {
1161
                                    $docHeaderFooter->setDifferentOddEven(true);
1162
                                } else {
1163 5
                                    $docHeaderFooter->setDifferentOddEven(false);
1164
                                }
1165 5 View Code Duplication
                                if (isset($xmlSheet->headerFooter['differentFirst']) &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1166 5
                                    self::boolean((string) $xmlSheet->headerFooter['differentFirst'])) {
1167
                                    $docHeaderFooter->setDifferentFirst(true);
1168
                                } else {
1169 5
                                    $docHeaderFooter->setDifferentFirst(false);
1170
                                }
1171 5 View Code Duplication
                                if (isset($xmlSheet->headerFooter['scaleWithDoc']) &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1172 5
                                    !self::boolean((string) $xmlSheet->headerFooter['scaleWithDoc'])) {
1173
                                    $docHeaderFooter->setScaleWithDocument(false);
1174
                                } else {
1175 5
                                    $docHeaderFooter->setScaleWithDocument(true);
1176
                                }
1177 5 View Code Duplication
                                if (isset($xmlSheet->headerFooter['alignWithMargins']) &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1178 5
                                    !self::boolean((string) $xmlSheet->headerFooter['alignWithMargins'])) {
1179 1
                                    $docHeaderFooter->setAlignWithMargins(false);
1180
                                } else {
1181 4
                                    $docHeaderFooter->setAlignWithMargins(true);
1182
                                }
1183
1184 5
                                $docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader);
1185 5
                                $docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter);
1186 5
                                $docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader);
1187 5
                                $docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter);
1188 5
                                $docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader);
1189 5
                                $docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter);
1190
                            }
1191
1192 8
                            if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->readDataOnly) {
1193
                                foreach ($xmlSheet->rowBreaks->brk as $brk) {
1194
                                    if ($brk['man']) {
1195
                                        $docSheet->setBreak("A$brk[id]", \PhpOffice\PhpSpreadsheet\Worksheet::BREAK_ROW);
1196
                                    }
1197
                                }
1198
                            }
1199 8
                            if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->readDataOnly) {
1200
                                foreach ($xmlSheet->colBreaks->brk as $brk) {
1201
                                    if ($brk['man']) {
1202
                                        $docSheet->setBreak(\PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex((string) $brk['id']) . '1', \PhpOffice\PhpSpreadsheet\Worksheet::BREAK_COLUMN);
1203
                                    }
1204
                                }
1205
                            }
1206
1207 8
                            if ($xmlSheet && $xmlSheet->dataValidations && !$this->readDataOnly) {
1208
                                foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) {
1209
                                    // Uppercase coordinate
1210
                                    $range = strtoupper($dataValidation['sqref']);
1211
                                    $rangeSet = explode(' ', $range);
1212
                                    foreach ($rangeSet as $range) {
1213
                                        $stRange = $docSheet->shrinkRangeToFit($range);
1214
1215
                                        // Extract all cell references in $range
1216
                                        foreach (\PhpOffice\PhpSpreadsheet\Cell::extractAllCellReferencesInRange($stRange) as $reference) {
1217
                                            // Create validation
1218
                                            $docValidation = $docSheet->getCell($reference)->getDataValidation();
1219
                                            $docValidation->setType((string) $dataValidation['type']);
1220
                                            $docValidation->setErrorStyle((string) $dataValidation['errorStyle']);
1221
                                            $docValidation->setOperator((string) $dataValidation['operator']);
1222
                                            $docValidation->setAllowBlank($dataValidation['allowBlank'] != 0);
1223
                                            $docValidation->setShowDropDown($dataValidation['showDropDown'] == 0);
1224
                                            $docValidation->setShowInputMessage($dataValidation['showInputMessage'] != 0);
1225
                                            $docValidation->setShowErrorMessage($dataValidation['showErrorMessage'] != 0);
1226
                                            $docValidation->setErrorTitle((string) $dataValidation['errorTitle']);
1227
                                            $docValidation->setError((string) $dataValidation['error']);
1228
                                            $docValidation->setPromptTitle((string) $dataValidation['promptTitle']);
1229
                                            $docValidation->setPrompt((string) $dataValidation['prompt']);
1230
                                            $docValidation->setFormula1((string) $dataValidation->formula1);
1231
                                            $docValidation->setFormula2((string) $dataValidation->formula2);
1232
                                        }
1233
                                    }
1234
                                }
1235
                            }
1236
1237
                            // Add hyperlinks
1238 8
                            $hyperlinks = [];
1239 8
                            if (!$this->readDataOnly) {
1240
                                // Locate hyperlink relations
1241 8
                                if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
1242 8
                                    $relsWorksheet = simplexml_load_string(
1243
                                        //~ http://schemas.openxmlformats.org/package/2006/relationships"
1244 8
                                        $this->securityScan(
1245 8
                                            $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
1246
                                        ),
1247 8
                                        'SimpleXMLElement',
1248 8
                                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1249
                                    );
1250 8
                                    foreach ($relsWorksheet->Relationship as $ele) {
1251 5
                                        if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink') {
1252 5
                                            $hyperlinks[(string) $ele['Id']] = (string) $ele['Target'];
1253
                                        }
1254
                                    }
1255
                                }
1256
1257
                                // Loop through hyperlinks
1258 8
                                if ($xmlSheet && $xmlSheet->hyperlinks) {
1259 2
                                    foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) {
1260
                                        // Link url
1261 2
                                        $linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
1262
1263 2
                                        foreach (\PhpOffice\PhpSpreadsheet\Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) {
1264 2
                                            $cell = $docSheet->getCell($cellReference);
1265 2
                                            if (isset($linkRel['id'])) {
1266 2
                                                $hyperlinkUrl = $hyperlinks[(string) $linkRel['id']];
1267 2
                                                if (isset($hyperlink['location'])) {
1268
                                                    $hyperlinkUrl .= '#' . (string) $hyperlink['location'];
1269
                                                }
1270 2
                                                $cell->getHyperlink()->setUrl($hyperlinkUrl);
1271 2
                                            } elseif (isset($hyperlink['location'])) {
1272 2
                                                $cell->getHyperlink()->setUrl('sheet://' . (string) $hyperlink['location']);
1273
                                            }
1274
1275
                                            // Tooltip
1276 2
                                            if (isset($hyperlink['tooltip'])) {
1277 2
                                                $cell->getHyperlink()->setTooltip((string) $hyperlink['tooltip']);
1278
                                            }
1279
                                        }
1280
                                    }
1281
                                }
1282
                            }
1283
1284
                            // Add comments
1285 8
                            $comments = [];
1286 8
                            $vmlComments = [];
1287 8
                            if (!$this->readDataOnly) {
1288
                                // Locate comment relations
1289 8
                                if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
1290 8
                                    $relsWorksheet = simplexml_load_string(
1291
                                        //~ http://schemas.openxmlformats.org/package/2006/relationships"
1292 8
                                        $this->securityScan(
1293 8
                                            $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
1294
                                        ),
1295 8
                                        'SimpleXMLElement',
1296 8
                                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1297
                                    );
1298 8
                                    foreach ($relsWorksheet->Relationship as $ele) {
1299 5
                                        if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments') {
1300 2
                                            $comments[(string) $ele['Id']] = (string) $ele['Target'];
1301
                                        }
1302 5
                                        if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing') {
1303 5
                                            $vmlComments[(string) $ele['Id']] = (string) $ele['Target'];
1304
                                        }
1305
                                    }
1306
                                }
1307
1308
                                // Loop through comments
1309 8
                                foreach ($comments as $relName => $relPath) {
1310
                                    // Load comments file
1311 2
                                    $relPath = \PhpOffice\PhpSpreadsheet\Shared\File::realpath(dirname("$dir/$fileWorksheet") . '/' . $relPath);
1312 2
                                    $commentsFile = simplexml_load_string(
1313 2
                                        $this->securityScan($this->getFromZipArchive($zip, $relPath)),
1314 2
                                        'SimpleXMLElement',
1315 2
                                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1316
                                    );
1317
1318
                                    // Utility variables
1319 2
                                    $authors = [];
1320
1321
                                    // Loop through authors
1322 2
                                    foreach ($commentsFile->authors->author as $author) {
1323 2
                                        $authors[] = (string) $author;
1324
                                    }
1325
1326
                                    // Loop through contents
1327 2
                                    foreach ($commentsFile->commentList->comment as $comment) {
1328 2
                                        if (!empty($comment['authorId'])) {
1329
                                            $docSheet->getComment((string) $comment['ref'])->setAuthor($authors[(string) $comment['authorId']]);
1330
                                        }
1331 2
                                        $docSheet->getComment((string) $comment['ref'])->setText($this->parseRichText($comment->text));
1332
                                    }
1333
                                }
1334
1335
                                // Loop through VML comments
1336 8
                                foreach ($vmlComments as $relName => $relPath) {
1337
                                    // Load VML comments file
1338 2
                                    $relPath = \PhpOffice\PhpSpreadsheet\Shared\File::realpath(dirname("$dir/$fileWorksheet") . '/' . $relPath);
1339 2
                                    $vmlCommentsFile = simplexml_load_string(
1340 2
                                        $this->securityScan($this->getFromZipArchive($zip, $relPath)),
1341 2
                                        'SimpleXMLElement',
1342 2
                                        \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1343
                                    );
1344 2
                                    $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
1345
1346 2
                                    $shapes = $vmlCommentsFile->xpath('//v:shape');
1347 2
                                    foreach ($shapes as $shape) {
1348 2
                                        $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
1349
1350 2
                                        if (isset($shape['style'])) {
1351 2
                                            $style = (string) $shape['style'];
1352 2
                                            $fillColor = strtoupper(substr((string) $shape['fillcolor'], 1));
1353 2
                                            $column = null;
1354 2
                                            $row = null;
1355
1356 2
                                            $clientData = $shape->xpath('.//x:ClientData');
1357 2
                                            if (is_array($clientData) && !empty($clientData)) {
1358 2
                                                $clientData = $clientData[0];
1359
1360 2
                                                if (isset($clientData['ObjectType']) && (string) $clientData['ObjectType'] == 'Note') {
1361 2
                                                    $temp = $clientData->xpath('.//x:Row');
1362 2
                                                    if (is_array($temp)) {
1363 2
                                                        $row = $temp[0];
1364
                                                    }
1365
1366 2
                                                    $temp = $clientData->xpath('.//x:Column');
1367 2
                                                    if (is_array($temp)) {
1368 2
                                                        $column = $temp[0];
1369
                                                    }
1370
                                                }
1371
                                            }
1372
1373 2
                                            if (($column !== null) && ($row !== null)) {
1374
                                                // Set comment properties
1375 2
                                                $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1);
1376 2
                                                $comment->getFillColor()->setRGB($fillColor);
1377
1378
                                                // Parse style
1379 2
                                                $styleArray = explode(';', str_replace(' ', '', $style));
1380 2
                                                foreach ($styleArray as $stylePair) {
1381 2
                                                    $stylePair = explode(':', $stylePair);
1382
1383 2
                                                    if ($stylePair[0] == 'margin-left') {
1384 2
                                                        $comment->setMarginLeft($stylePair[1]);
1385
                                                    }
1386 2
                                                    if ($stylePair[0] == 'margin-top') {
1387 2
                                                        $comment->setMarginTop($stylePair[1]);
1388
                                                    }
1389 2
                                                    if ($stylePair[0] == 'width') {
1390 2
                                                        $comment->setWidth($stylePair[1]);
1391
                                                    }
1392 2
                                                    if ($stylePair[0] == 'height') {
1393 2
                                                        $comment->setHeight($stylePair[1]);
1394
                                                    }
1395 2
                                                    if ($stylePair[0] == 'visibility') {
1396 2
                                                        $comment->setVisible($stylePair[1] == 'visible');
1397
                                                    }
1398
                                                }
1399
                                            }
1400
                                        }
1401
                                    }
1402
                                }
1403
1404
                                // Header/footer images
1405 8
                                if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->readDataOnly) {
1406
                                    if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
1407
                                        $relsWorksheet = simplexml_load_string(
1408
                                            //~ http://schemas.openxmlformats.org/package/2006/relationships"
1409
                                            $this->securityScan(
1410
                                                $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
1411
                                            ),
1412
                                            'SimpleXMLElement',
1413
                                            \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1414
                                        );
1415
                                        $vmlRelationship = '';
1416
1417
                                        foreach ($relsWorksheet->Relationship as $ele) {
1418
                                            if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing') {
1419
                                                $vmlRelationship = self::dirAdd("$dir/$fileWorksheet", $ele['Target']);
1420
                                            }
1421
                                        }
1422
1423
                                        if ($vmlRelationship != '') {
1424
                                            // Fetch linked images
1425
                                            $relsVML = simplexml_load_string(
1426
                                                //~ http://schemas.openxmlformats.org/package/2006/relationships"
1427
                                                $this->securityScan(
1428
                                                    $this->getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')
1429
                                                ),
1430
                                                'SimpleXMLElement',
1431
                                                \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1432
                                            );
1433
                                            $drawings = [];
1434 View Code Duplication
                                            foreach ($relsVML->Relationship as $ele) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1435
                                                if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') {
1436
                                                    $drawings[(string) $ele['Id']] = self::dirAdd($vmlRelationship, $ele['Target']);
1437
                                                }
1438
                                            }
1439
1440
                                            // Fetch VML document
1441
                                            $vmlDrawing = simplexml_load_string(
1442
                                                $this->securityScan($this->getFromZipArchive($zip, $vmlRelationship)),
1443
                                                'SimpleXMLElement',
1444
                                                \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1445
                                            );
1446
                                            $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
1447
1448
                                            $hfImages = [];
1449
1450
                                            $shapes = $vmlDrawing->xpath('//v:shape');
1451
                                            foreach ($shapes as $idx => $shape) {
1452
                                                $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');
1453
                                                $imageData = $shape->xpath('//v:imagedata');
1454
                                                $imageData = $imageData[$idx];
1455
1456
                                                $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office');
1457
                                                $style = self::toCSSArray((string) $shape['style']);
1458
1459
                                                $hfImages[(string) $shape['id']] = new \PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing();
1460
                                                if (isset($imageData['title'])) {
1461
                                                    $hfImages[(string) $shape['id']]->setName((string) $imageData['title']);
1462
                                                }
1463
1464
                                                $hfImages[(string) $shape['id']]->setPath('zip://' . \PhpOffice\PhpSpreadsheet\Shared_File::realpath($pFilename) . '#' . $drawings[(string) $imageData['relid']], false);
1465
                                                $hfImages[(string) $shape['id']]->setResizeProportional(false);
1466
                                                $hfImages[(string) $shape['id']]->setWidth($style['width']);
1467
                                                $hfImages[(string) $shape['id']]->setHeight($style['height']);
1468
                                                if (isset($style['margin-left'])) {
1469
                                                    $hfImages[(string) $shape['id']]->setOffsetX($style['margin-left']);
1470
                                                }
1471
                                                $hfImages[(string) $shape['id']]->setOffsetY($style['margin-top']);
1472
                                                $hfImages[(string) $shape['id']]->setResizeProportional(true);
1473
                                            }
1474
1475
                                            $docSheet->getHeaderFooter()->setImages($hfImages);
1476
                                        }
1477
                                    }
1478
                                }
1479
                            }
1480
1481
                            // TODO: Autoshapes from twoCellAnchors!
1482 8
                            if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) {
1483 8
                                $relsWorksheet = simplexml_load_string(
1484
                                    //~ http://schemas.openxmlformats.org/package/2006/relationships"
1485 8
                                    $this->securityScan(
1486 8
                                        $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')
1487
                                    ),
1488 8
                                    'SimpleXMLElement',
1489 8
                                    \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1490
                                );
1491 8
                                $drawings = [];
1492 8 View Code Duplication
                                foreach ($relsWorksheet->Relationship as $ele) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1493 5
                                    if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing') {
1494 5
                                        $drawings[(string) $ele['Id']] = self::dirAdd("$dir/$fileWorksheet", $ele['Target']);
1495
                                    }
1496
                                }
1497 8
                                if ($xmlSheet->drawing && !$this->readDataOnly) {
1498 3
                                    foreach ($xmlSheet->drawing as $drawing) {
1499 3
                                        $fileDrawing = $drawings[(string) self::getArrayItem($drawing->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'), 'id')];
1500 3
                                        $relsDrawing = simplexml_load_string(
1501
                                            //~ http://schemas.openxmlformats.org/package/2006/relationships"
1502 3
                                            $this->securityScan(
1503 3
                                                $this->getFromZipArchive($zip, dirname($fileDrawing) . '/_rels/' . basename($fileDrawing) . '.rels')
1504
                                            ),
1505 3
                                            'SimpleXMLElement',
1506 3
                                            \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1507
                                        );
1508 3
                                        $images = [];
1509
1510 3
                                        if ($relsDrawing && $relsDrawing->Relationship) {
1511 3
                                            foreach ($relsDrawing->Relationship as $ele) {
1512 3
                                                if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') {
1513 3
                                                    $images[(string) $ele['Id']] = self::dirAdd($fileDrawing, $ele['Target']);
1514 1
                                                } elseif ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart') {
1515 1
                                                    if ($this->includeCharts) {
1516 1
                                                        $charts[self::dirAdd($fileDrawing, $ele['Target'])] = [
1517 1
                                                            'id' => (string) $ele['Id'],
1518 3
                                                            'sheet' => $docSheet->getTitle(),
1519
                                                        ];
1520
                                                    }
1521
                                                }
1522
                                            }
1523
                                        }
1524 3
                                        $xmlDrawing = simplexml_load_string(
1525 3
                                            $this->securityScan($this->getFromZipArchive($zip, $fileDrawing)),
1526 3
                                            'SimpleXMLElement',
1527 3
                                            \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1528 3
                                        )->children('http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
1529
1530 3
                                        if ($xmlDrawing->oneCellAnchor) {
1531 2
                                            foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) {
1532 2
                                                if ($oneCellAnchor->pic->blipFill) {
1533 2
                                                    $blip = $oneCellAnchor->pic->blipFill->children('http://schemas.openxmlformats.org/drawingml/2006/main')->blip;
1534 2
                                                    $xfrm = $oneCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->xfrm;
1535 2
                                                    $outerShdw = $oneCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->effectLst->outerShdw;
1536 2
                                                    $objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
1537 2
                                                    $objDrawing->setName((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name'));
1538 2
                                                    $objDrawing->setDescription((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'descr'));
1539 2
                                                    $objDrawing->setPath(
1540 2
                                                        'zip://' . \PhpOffice\PhpSpreadsheet\Shared\File::realpath($pFilename) . '#' .
1541 2
                                                        $images[(string) self::getArrayItem(
1542 2
                                                            $blip->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'),
1543 2
                                                            'embed'
1544
                                                        )],
1545 2
                                                        false
1546
                                                    );
1547 2
                                                    $objDrawing->setCoordinates(\PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1));
1548 2
                                                    $objDrawing->setOffsetX(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($oneCellAnchor->from->colOff));
1549 2
                                                    $objDrawing->setOffsetY(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($oneCellAnchor->from->rowOff));
1550 2
                                                    $objDrawing->setResizeProportional(false);
1551 2
                                                    $objDrawing->setWidth(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cx')));
1552 2
                                                    $objDrawing->setHeight(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cy')));
1553 2
                                                    if ($xfrm) {
1554 2
                                                        $objDrawing->setRotation(\PhpOffice\PhpSpreadsheet\Shared\Drawing::angleToDegrees(self::getArrayItem($xfrm->attributes(), 'rot')));
1555
                                                    }
1556 2 View Code Duplication
                                                    if ($outerShdw) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1557 2
                                                        $shadow = $objDrawing->getShadow();
1558 2
                                                        $shadow->setVisible(true);
1559 2
                                                        $shadow->setBlurRadius(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUTopixels(self::getArrayItem($outerShdw->attributes(), 'blurRad')));
1560 2
                                                        $shadow->setDistance(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUTopixels(self::getArrayItem($outerShdw->attributes(), 'dist')));
1561 2
                                                        $shadow->setDirection(\PhpOffice\PhpSpreadsheet\Shared\Drawing::angleToDegrees(self::getArrayItem($outerShdw->attributes(), 'dir')));
1562 2
                                                        $shadow->setAlignment((string) self::getArrayItem($outerShdw->attributes(), 'algn'));
1563 2
                                                        $shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), 'val'));
1564 2
                                                        $shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), 'val') / 1000);
1565
                                                    }
1566 2
                                                    $objDrawing->setWorksheet($docSheet);
1567
                                                } else {
1568
                                                    //    ? Can charts be positioned with a oneCellAnchor ?
1569
                                                    $coordinates = \PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1);
0 ignored issues
show
Unused Code introduced by
$coordinates 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...
1570
                                                    $offsetX = \PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($oneCellAnchor->from->colOff);
0 ignored issues
show
Unused Code introduced by
$offsetX 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...
1571
                                                    $offsetY = \PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($oneCellAnchor->from->rowOff);
0 ignored issues
show
Unused Code introduced by
$offsetY 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...
1572
                                                    $width = \PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cx'));
0 ignored issues
show
Unused Code introduced by
$width 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...
1573 2
                                                    $height = \PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cy'));
0 ignored issues
show
Unused Code introduced by
$height 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...
1574
                                                }
1575
                                            }
1576
                                        }
1577 3
                                        if ($xmlDrawing->twoCellAnchor) {
1578 1
                                            foreach ($xmlDrawing->twoCellAnchor as $twoCellAnchor) {
1579 1
                                                if ($twoCellAnchor->pic->blipFill) {
1580 1
                                                    $blip = $twoCellAnchor->pic->blipFill->children('http://schemas.openxmlformats.org/drawingml/2006/main')->blip;
1581 1
                                                    $xfrm = $twoCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->xfrm;
1582 1
                                                    $outerShdw = $twoCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->effectLst->outerShdw;
1583 1
                                                    $objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
1584 1
                                                    $objDrawing->setName((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name'));
1585 1
                                                    $objDrawing->setDescription((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'descr'));
1586 1
                                                    $objDrawing->setPath(
1587 1
                                                        'zip://' . \PhpOffice\PhpSpreadsheet\Shared\File::realpath($pFilename) . '#' .
1588 1
                                                        $images[(string) self::getArrayItem(
1589 1
                                                            $blip->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'),
1590 1
                                                            'embed'
1591
                                                        )],
1592 1
                                                        false
1593
                                                    );
1594 1
                                                    $objDrawing->setCoordinates(\PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1));
1595 1
                                                    $objDrawing->setOffsetX(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($twoCellAnchor->from->colOff));
1596 1
                                                    $objDrawing->setOffsetY(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($twoCellAnchor->from->rowOff));
1597 1
                                                    $objDrawing->setResizeProportional(false);
1598
1599 1
                                                    if ($xfrm) {
1600 1
                                                        $objDrawing->setWidth(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels(self::getArrayItem($xfrm->ext->attributes(), 'cx')));
1601 1
                                                        $objDrawing->setHeight(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels(self::getArrayItem($xfrm->ext->attributes(), 'cy')));
1602 1
                                                        $objDrawing->setRotation(\PhpOffice\PhpSpreadsheet\Shared\Drawing::angleToDegrees(self::getArrayItem($xfrm->attributes(), 'rot')));
1603
                                                    }
1604 1 View Code Duplication
                                                    if ($outerShdw) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1605
                                                        $shadow = $objDrawing->getShadow();
1606
                                                        $shadow->setVisible(true);
1607
                                                        $shadow->setBlurRadius(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUTopixels(self::getArrayItem($outerShdw->attributes(), 'blurRad')));
1608
                                                        $shadow->setDistance(\PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUTopixels(self::getArrayItem($outerShdw->attributes(), 'dist')));
1609
                                                        $shadow->setDirection(\PhpOffice\PhpSpreadsheet\Shared\Drawing::angleToDegrees(self::getArrayItem($outerShdw->attributes(), 'dir')));
1610
                                                        $shadow->setAlignment((string) self::getArrayItem($outerShdw->attributes(), 'algn'));
1611
                                                        $shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), 'val'));
1612
                                                        $shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), 'val') / 1000);
1613
                                                    }
1614 1
                                                    $objDrawing->setWorksheet($docSheet);
1615 1
                                                } elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) {
1616 1
                                                    $fromCoordinate = \PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1);
1617 1
                                                    $fromOffsetX = \PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($twoCellAnchor->from->colOff);
1618 1
                                                    $fromOffsetY = \PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($twoCellAnchor->from->rowOff);
1619 1
                                                    $toCoordinate = \PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1);
1620 1
                                                    $toOffsetX = \PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($twoCellAnchor->to->colOff);
1621 1
                                                    $toOffsetY = \PhpOffice\PhpSpreadsheet\Shared\Drawing::EMUToPixels($twoCellAnchor->to->rowOff);
1622 1
                                                    $graphic = $twoCellAnchor->graphicFrame->children('http://schemas.openxmlformats.org/drawingml/2006/main')->graphic;
1623 1
                                                    $chartRef = $graphic->graphicData->children('http://schemas.openxmlformats.org/drawingml/2006/chart')->chart;
1624 1
                                                    $thisChart = (string) $chartRef->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
1625
1626 1
                                                    $chartDetails[$docSheet->getTitle() . '!' . $thisChart] = [
1627 1
                                                        'fromCoordinate' => $fromCoordinate,
1628 1
                                                        'fromOffsetX' => $fromOffsetX,
1629 1
                                                        'fromOffsetY' => $fromOffsetY,
1630 1
                                                        'toCoordinate' => $toCoordinate,
1631 1
                                                        'toOffsetX' => $toOffsetX,
1632 1
                                                        'toOffsetY' => $toOffsetY,
1633 3
                                                        'worksheetTitle' => $docSheet->getTitle(),
1634
                                                    ];
1635
                                                }
1636
                                            }
1637
                                        }
1638
                                    }
1639
                                }
1640
                            }
1641
1642
                            // Loop through definedNames
1643 8
                            if ($xmlWorkbook->definedNames) {
1644 5
                                foreach ($xmlWorkbook->definedNames->definedName as $definedName) {
1645
                                    // Extract range
1646 1
                                    $extractedRange = (string) $definedName;
1647 1 View Code Duplication
                                    if (($spos = strpos($extractedRange, '!')) !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1648 1
                                        $extractedRange = substr($extractedRange, 0, $spos) . str_replace('$', '', substr($extractedRange, $spos));
1649
                                    } else {
1650
                                        $extractedRange = str_replace('$', '', $extractedRange);
1651
                                    }
1652
1653
                                    // Valid range?
1654 1
                                    if (stripos((string) $definedName, '#REF!') !== false || $extractedRange == '') {
1655
                                        continue;
1656
                                    }
1657
1658
                                    // Some definedNames are only applicable if we are on the same sheet...
1659 1
                                    if ((string) $definedName['localSheetId'] != '' && (string) $definedName['localSheetId'] == $sheetId) {
1660
                                        // Switch on type
1661 1
                                        switch ((string) $definedName['name']) {
1662 1
                                            case '_xlnm._FilterDatabase':
1663
                                                if ((string) $definedName['hidden'] !== '1') {
1664
                                                    $extractedRange = explode(',', $extractedRange);
1665
                                                    foreach ($extractedRange as $range) {
1666
                                                        $autoFilterRange = $range;
1667
                                                        if (strpos($autoFilterRange, ':') !== false) {
1668
                                                            $docSheet->getAutoFilter()->setRange($autoFilterRange);
1669
                                                        }
1670
                                                    }
1671
                                                }
1672
                                                break;
1673 1
                                            case '_xlnm.Print_Titles':
1674
                                                // Split $extractedRange
1675 1
                                                $extractedRange = explode(',', $extractedRange);
1676
1677
                                                // Set print titles
1678 1
                                                foreach ($extractedRange as $range) {
1679 1
                                                    $matches = [];
1680 1
                                                    $range = str_replace('$', '', $range);
1681
1682
                                                    // check for repeating columns, e g. 'A:A' or 'A:D'
1683 1
                                                    if (preg_match('/!?([A-Z]+)\:([A-Z]+)$/', $range, $matches)) {
1684
                                                        $docSheet->getPageSetup()->setColumnsToRepeatAtLeft([$matches[1], $matches[2]]);
1685 1
                                                    } elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) {
1686
                                                        // check for repeating rows, e.g. '1:1' or '1:5'
1687 1
                                                        $docSheet->getPageSetup()->setRowsToRepeatAtTop([$matches[1], $matches[2]]);
1688
                                                    }
1689
                                                }
1690 1
                                                break;
1691
                                            case '_xlnm.Print_Area':
1692
                                                $rangeSets = preg_split("/'(.*?)'(?:![A-Z0-9]+:[A-Z0-9]+,?)/", $extractedRange, PREG_SPLIT_NO_EMPTY);
1693
                                                $newRangeSets = [];
1694
                                                foreach ($rangeSets as $rangeSet) {
1695
                                                    $range = explode('!', $rangeSet); // FIXME: what if sheetname contains exclamation mark?
1696
                                                    $rangeSet = isset($range[1]) ? $range[1] : $range[0];
1697
                                                    if (strpos($rangeSet, ':') === false) {
1698
                                                        $rangeSet = $rangeSet . ':' . $rangeSet;
1699
                                                    }
1700
                                                    $newRangeSets[] = str_replace('$', '', $rangeSet);
1701
                                                }
1702
                                                $docSheet->getPageSetup()->setPrintArea(implode(',', $newRangeSets));
1703
                                                break;
1704
1705
                                            default:
1706 1
                                                break;
1707
                                        }
1708
                                    }
1709
                                }
1710
                            }
1711
1712
                            // Next sheet id
1713 8
                            ++$sheetId;
1714
                        }
1715
1716
                        // Loop through definedNames
1717 8
                        if ($xmlWorkbook->definedNames) {
1718 5
                            foreach ($xmlWorkbook->definedNames->definedName as $definedName) {
1719
                                // Extract range
1720 1
                                $extractedRange = (string) $definedName;
1721 1 View Code Duplication
                                if (($spos = strpos($extractedRange, '!')) !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1722 1
                                    $extractedRange = substr($extractedRange, 0, $spos) . str_replace('$', '', substr($extractedRange, $spos));
1723
                                } else {
1724
                                    $extractedRange = str_replace('$', '', $extractedRange);
1725
                                }
1726
1727
                                // Valid range?
1728 1
                                if (stripos((string) $definedName, '#REF!') !== false || $extractedRange == '') {
1729
                                    continue;
1730
                                }
1731
1732
                                // Some definedNames are only applicable if we are on the same sheet...
1733 1
                                if ((string) $definedName['localSheetId'] != '') {
1734
                                    // Local defined name
1735
                                    // Switch on type
1736 1
                                    switch ((string) $definedName['name']) {
1737 1
                                        case '_xlnm._FilterDatabase':
1738 1
                                        case '_xlnm.Print_Titles':
1739
                                        case '_xlnm.Print_Area':
1740 1
                                            break;
1741
                                        default:
1742
                                            if ($mapSheetId[(integer) $definedName['localSheetId']] !== null) {
1743
                                                $range = explode('!', (string) $definedName);
1744
                                                if (count($range) == 2) {
1745
                                                    $range[0] = str_replace("''", "'", $range[0]);
1746
                                                    $range[0] = str_replace("'", '', $range[0]);
1747
                                                    if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) {
1748
                                                        $extractedRange = str_replace('$', '', $range[1]);
1749
                                                        $scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]);
0 ignored issues
show
Bug introduced by
The variable $docSheet does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1750
                                                        $excel->addNamedRange(new \PhpOffice\PhpSpreadsheet\NamedRange((string) $definedName['name'], $worksheet, $extractedRange, true, $scope));
1751
                                                    }
1752
                                                }
1753
                                            }
1754 1
                                            break;
1755
                                    }
1756
                                } elseif (!isset($definedName['localSheetId'])) {
1757
                                    // "Global" definedNames
1758
                                    $locatedSheet = null;
1759
                                    $extractedSheetName = '';
0 ignored issues
show
Unused Code introduced by
$extractedSheetName 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...
1760
                                    if (strpos((string) $definedName, '!') !== false) {
1761
                                        // Extract sheet name
1762
                                        $extractedSheetName = \PhpOffice\PhpSpreadsheet\Worksheet::extractSheetTitle((string) $definedName, true);
1763
                                        $extractedSheetName = $extractedSheetName[0];
1764
1765
                                        // Locate sheet
1766
                                        $locatedSheet = $excel->getSheetByName($extractedSheetName);
1767
1768
                                        // Modify range
1769
                                        $range = explode('!', $extractedRange);
1770
                                        $extractedRange = isset($range[1]) ? $range[1] : $range[0];
1771
                                    }
1772
1773
                                    if ($locatedSheet !== null) {
1774 1
                                        $excel->addNamedRange(new \PhpOffice\PhpSpreadsheet\NamedRange((string) $definedName['name'], $locatedSheet, $extractedRange, false));
1775
                                    }
1776
                                }
1777
                            }
1778
                        }
1779
                    }
1780
1781 8
                    if ((!$this->readDataOnly) || (!empty($this->loadSheetsOnly))) {
1782
                        // active sheet index
1783 8
                        $activeTab = intval($xmlWorkbook->bookViews->workbookView['activeTab']); // refers to old sheet index
1784
1785
                        // keep active sheet index if sheet is still loaded, else first sheet is set as the active
1786 8
                        if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) {
1787 8
                            $excel->setActiveSheetIndex($mapSheetId[$activeTab]);
1788
                        } else {
1789
                            if ($excel->getSheetCount() == 0) {
1790
                                $excel->createSheet();
1791
                            }
1792
                            $excel->setActiveSheetIndex(0);
1793
                        }
1794
                    }
1795 8
                    break;
1796
            }
1797
        }
1798
1799 8
        if (!$this->readDataOnly) {
1800 8
            $contentTypes = simplexml_load_string(
1801 8
                $this->securityScan(
1802 8
                    $this->getFromZipArchive($zip, '[Content_Types].xml')
1803
                ),
1804 8
                'SimpleXMLElement',
1805 8
                \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1806
            );
1807 8
            foreach ($contentTypes->Override as $contentType) {
1808 8
                switch ($contentType['ContentType']) {
1809 8
                    case 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml':
1810 1
                        if ($this->includeCharts) {
1811 1
                            $chartEntryRef = ltrim($contentType['PartName'], '/');
1812 1
                            $chartElements = simplexml_load_string(
1813 1
                                $this->securityScan(
1814 1
                                    $this->getFromZipArchive($zip, $chartEntryRef)
1815
                                ),
1816 1
                                'SimpleXMLElement',
1817 1
                                \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
1818
                            );
1819 1
                            $objChart = \PhpOffice\PhpSpreadsheet\Reader\Xlsx\Chart::readChart($chartElements, basename($chartEntryRef, '.xml'));
1820
1821 1
                            if (isset($charts[$chartEntryRef])) {
1822 1
                                $chartPositionRef = $charts[$chartEntryRef]['sheet'] . '!' . $charts[$chartEntryRef]['id'];
1823 1
                                if (isset($chartDetails[$chartPositionRef])) {
1824 1
                                    $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart);
1825 1
                                    $objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet']));
1826 1
                                    $objChart->setTopLeftPosition($chartDetails[$chartPositionRef]['fromCoordinate'], $chartDetails[$chartPositionRef]['fromOffsetX'], $chartDetails[$chartPositionRef]['fromOffsetY']);
1827 8
                                    $objChart->setBottomRightPosition($chartDetails[$chartPositionRef]['toCoordinate'], $chartDetails[$chartPositionRef]['toOffsetX'], $chartDetails[$chartPositionRef]['toOffsetY']);
1828
                                }
1829
                            }
1830
                        }
1831
                }
1832
            }
1833
        }
1834
1835 8
        $zip->close();
1836
1837 8
        return $excel;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $excel; (PhpOffice\PhpSpreadsheet\Spreadsheet) is incompatible with the return type declared by the interface PhpOffice\PhpSpreadsheet\Reader\IReader::load of type PhpOffice\PhpSpreadsheet\Reader\PhpSpreadsheet.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1838
    }
1839
1840 8
    private static function readColor($color, $background = false)
1841
    {
1842 8
        if (isset($color['rgb'])) {
1843 7
            return (string) $color['rgb'];
1844 4
        } elseif (isset($color['indexed'])) {
1845 3
            return \PhpOffice\PhpSpreadsheet\Style\Color::indexedColor($color['indexed'] - 7, $background)->getARGB();
1846 3
        } elseif (isset($color['theme'])) {
1847 3
            if (self::$theme !== null) {
1848 3
                $returnColour = self::$theme->getColourByIndex((int) $color['theme']);
1849 3
                if (isset($color['tint'])) {
1850
                    $tintAdjust = (float) $color['tint'];
1851
                    $returnColour = \PhpOffice\PhpSpreadsheet\Style\Color::changeBrightness($returnColour, $tintAdjust);
1852
                }
1853
1854 3
                return 'FF' . $returnColour;
1855
            }
1856
        }
1857
1858
        if ($background) {
1859
            return 'FFFFFFFF';
1860
        }
1861
1862
        return 'FF000000';
1863
    }
1864
1865
    /**
1866
     * @param \PhpOffice\PhpSpreadsheet\Style $docStyle
1867
     * @param \stdClass|\SimpleXMLElement $style
1868
     */
1869 8
    private static function readStyle(\PhpOffice\PhpSpreadsheet\Style $docStyle, $style)
1870
    {
1871 8
        $docStyle->getNumberFormat()->setFormatCode($style->numFmt);
1872
1873
        // font
1874 8
        if (isset($style->font)) {
1875 8
            $docStyle->getFont()->setName((string) $style->font->name['val']);
1876 8
            $docStyle->getFont()->setSize((string) $style->font->sz['val']);
1877 8 View Code Duplication
            if (isset($style->font->b)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1878 7
                $docStyle->getFont()->setBold(!isset($style->font->b['val']) || self::boolean((string) $style->font->b['val']));
1879
            }
1880 8 View Code Duplication
            if (isset($style->font->i)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1881 5
                $docStyle->getFont()->setItalic(!isset($style->font->i['val']) || self::boolean((string) $style->font->i['val']));
1882
            }
1883 8 View Code Duplication
            if (isset($style->font->strike)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1884 5
                $docStyle->getFont()->setStrikethrough(!isset($style->font->strike['val']) || self::boolean((string) $style->font->strike['val']));
1885
            }
1886 8
            $docStyle->getFont()->getColor()->setARGB(self::readColor($style->font->color));
1887
1888 8 View Code Duplication
            if (isset($style->font->u) && !isset($style->font->u['val'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1889
                $docStyle->getFont()->setUnderline(\PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE);
1890 8
            } elseif (isset($style->font->u) && isset($style->font->u['val'])) {
1891 5
                $docStyle->getFont()->setUnderline((string) $style->font->u['val']);
1892
            }
1893
1894 8 View Code Duplication
            if (isset($style->font->vertAlign) && isset($style->font->vertAlign['val'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1895
                $vertAlign = strtolower((string) $style->font->vertAlign['val']);
1896
                if ($vertAlign == 'superscript') {
1897
                    $docStyle->getFont()->setSuperScript(true);
1898
                }
1899
                if ($vertAlign == 'subscript') {
1900
                    $docStyle->getFont()->setSubScript(true);
1901
                }
1902
            }
1903
        }
1904
1905
        // fill
1906 8
        if (isset($style->fill)) {
1907 8
            if ($style->fill->gradientFill) {
1908 2
                $gradientFill = $style->fill->gradientFill[0];
1909 2
                if (!empty($gradientFill['type'])) {
1910 2
                    $docStyle->getFill()->setFillType((string) $gradientFill['type']);
1911
                }
1912 2
                $docStyle->getFill()->setRotation(floatval($gradientFill['degree']));
1913 2
                $gradientFill->registerXPathNamespace('sml', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
1914 2
                $docStyle->getFill()->getStartColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color));
1915 2
                $docStyle->getFill()->getEndColor()->setARGB(self::readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color));
1916 8
            } elseif ($style->fill->patternFill) {
1917 8
                $patternType = (string) $style->fill->patternFill['patternType'] != '' ? (string) $style->fill->patternFill['patternType'] : 'solid';
1918 8
                $docStyle->getFill()->setFillType($patternType);
1919 8
                if ($style->fill->patternFill->fgColor) {
1920 3
                    $docStyle->getFill()->getStartColor()->setARGB(self::readColor($style->fill->patternFill->fgColor, true));
1921
                } else {
1922 8
                    $docStyle->getFill()->getStartColor()->setARGB('FF000000');
1923
                }
1924 8
                if ($style->fill->patternFill->bgColor) {
1925 3
                    $docStyle->getFill()->getEndColor()->setARGB(self::readColor($style->fill->patternFill->bgColor, true));
1926
                }
1927
            }
1928
        }
1929
1930
        // border
1931 8
        if (isset($style->border)) {
1932 8
            $diagonalUp = self::boolean((string) $style->border['diagonalUp']);
1933 8
            $diagonalDown = self::boolean((string) $style->border['diagonalDown']);
1934 8
            if (!$diagonalUp && !$diagonalDown) {
1935 8
                $docStyle->getBorders()->setDiagonalDirection(\PhpOffice\PhpSpreadsheet\Style\Borders::DIAGONAL_NONE);
1936
            } elseif ($diagonalUp && !$diagonalDown) {
1937
                $docStyle->getBorders()->setDiagonalDirection(\PhpOffice\PhpSpreadsheet\Style\Borders::DIAGONAL_UP);
1938
            } elseif (!$diagonalUp && $diagonalDown) {
1939
                $docStyle->getBorders()->setDiagonalDirection(\PhpOffice\PhpSpreadsheet\Style\Borders::DIAGONAL_DOWN);
1940
            } else {
1941
                $docStyle->getBorders()->setDiagonalDirection(\PhpOffice\PhpSpreadsheet\Style\Borders::DIAGONAL_BOTH);
1942
            }
1943 8
            self::readBorder($docStyle->getBorders()->getLeft(), $style->border->left);
1944 8
            self::readBorder($docStyle->getBorders()->getRight(), $style->border->right);
1945 8
            self::readBorder($docStyle->getBorders()->getTop(), $style->border->top);
1946 8
            self::readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom);
1947 8
            self::readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal);
1948
        }
1949
1950
        // alignment
1951 8
        if (isset($style->alignment)) {
1952 8
            $docStyle->getAlignment()->setHorizontal((string) $style->alignment['horizontal']);
1953 8
            $docStyle->getAlignment()->setVertical((string) $style->alignment['vertical']);
1954
1955 8
            $textRotation = 0;
1956 8
            if ((int) $style->alignment['textRotation'] <= 90) {
1957 8
                $textRotation = (int) $style->alignment['textRotation'];
1958
            } elseif ((int) $style->alignment['textRotation'] > 90) {
1959
                $textRotation = 90 - (int) $style->alignment['textRotation'];
1960
            }
1961
1962 8
            $docStyle->getAlignment()->setTextRotation(intval($textRotation));
1963 8
            $docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment['wrapText']));
1964 8
            $docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment['shrinkToFit']));
1965 8
            $docStyle->getAlignment()->setIndent(intval((string) $style->alignment['indent']) > 0 ? intval((string) $style->alignment['indent']) : 0);
1966 8
            $docStyle->getAlignment()->setReadorder(intval((string) $style->alignment['readingOrder']) > 0 ? intval((string) $style->alignment['readingOrder']) : 0);
1967
        }
1968
1969
        // protection
1970 8
        if (isset($style->protection)) {
1971 8 View Code Duplication
            if (isset($style->protection['locked'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1972 2
                if (self::boolean((string) $style->protection['locked'])) {
1973
                    $docStyle->getProtection()->setLocked(\PhpOffice\PhpSpreadsheet\Style\Protection::PROTECTION_PROTECTED);
1974
                } else {
1975 2
                    $docStyle->getProtection()->setLocked(\PhpOffice\PhpSpreadsheet\Style\Protection::PROTECTION_UNPROTECTED);
1976
                }
1977
            }
1978
1979 8 View Code Duplication
            if (isset($style->protection['hidden'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1980
                if (self::boolean((string) $style->protection['hidden'])) {
1981
                    $docStyle->getProtection()->setHidden(\PhpOffice\PhpSpreadsheet\Style\Protection::PROTECTION_PROTECTED);
1982
                } else {
1983
                    $docStyle->getProtection()->setHidden(\PhpOffice\PhpSpreadsheet\Style\Protection::PROTECTION_UNPROTECTED);
1984
                }
1985
            }
1986
        }
1987
1988
        // top-level style settings
1989 8
        if (isset($style->quotePrefix)) {
1990 8
            $docStyle->setQuotePrefix($style->quotePrefix);
1991
        }
1992 8
    }
1993
1994 8
    private static function readBorder($docBorder, $eleBorder)
1995
    {
1996 8
        if (isset($eleBorder['style'])) {
1997 2
            $docBorder->setBorderStyle((string) $eleBorder['style']);
1998
        }
1999 8
        if (isset($eleBorder->color)) {
2000 2
            $docBorder->getColor()->setARGB(self::readColor($eleBorder->color));
2001
        }
2002 8
    }
2003
2004 3
    private function parseRichText($is = null)
2005
    {
2006 3
        $value = new \PhpOffice\PhpSpreadsheet\RichText();
2007
2008 3
        if (isset($is->t)) {
2009
            $value->createText(\PhpOffice\PhpSpreadsheet\Shared\StringHelper::controlCharacterOOXML2PHP((string) $is->t));
2010
        } else {
2011 3
            if (is_object($is->r)) {
2012 3
                foreach ($is->r as $run) {
2013 3
                    if (!isset($run->rPr)) {
2014 3
                        $objText = $value->createText(\PhpOffice\PhpSpreadsheet\Shared\StringHelper::controlCharacterOOXML2PHP((string) $run->t));
0 ignored issues
show
Unused Code introduced by
$objText 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...
2015
                    } else {
2016 3
                        $objText = $value->createTextRun(\PhpOffice\PhpSpreadsheet\Shared\StringHelper::controlCharacterOOXML2PHP((string) $run->t));
2017
2018 3 View Code Duplication
                        if (isset($run->rPr->rFont['val'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2019 3
                            $objText->getFont()->setName((string) $run->rPr->rFont['val']);
2020
                        }
2021 3
                        if (isset($run->rPr->sz['val'])) {
2022 3
                            $objText->getFont()->setSize((string) $run->rPr->sz['val']);
2023
                        }
2024 3
                        if (isset($run->rPr->color)) {
2025 3
                            $objText->getFont()->setColor(new \PhpOffice\PhpSpreadsheet\Style\Color(self::readColor($run->rPr->color)));
2026
                        }
2027 3 View Code Duplication
                        if ((isset($run->rPr->b['val']) && self::boolean((string) $run->rPr->b['val'])) ||
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2028 3
                            (isset($run->rPr->b) && !isset($run->rPr->b['val']))) {
2029 3
                            $objText->getFont()->setBold(true);
2030
                        }
2031 3 View Code Duplication
                        if ((isset($run->rPr->i['val']) && self::boolean((string) $run->rPr->i['val'])) ||
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2032 3
                            (isset($run->rPr->i) && !isset($run->rPr->i['val']))) {
2033 2
                            $objText->getFont()->setItalic(true);
2034
                        }
2035 3 View Code Duplication
                        if (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign['val'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2036
                            $vertAlign = strtolower((string) $run->rPr->vertAlign['val']);
2037
                            if ($vertAlign == 'superscript') {
2038
                                $objText->getFont()->setSuperScript(true);
2039
                            }
2040
                            if ($vertAlign == 'subscript') {
2041
                                $objText->getFont()->setSubScript(true);
2042
                            }
2043
                        }
2044 3 View Code Duplication
                        if (isset($run->rPr->u) && !isset($run->rPr->u['val'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2045
                            $objText->getFont()->setUnderline(\PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE);
2046 3
                        } elseif (isset($run->rPr->u) && isset($run->rPr->u['val'])) {
2047 2
                            $objText->getFont()->setUnderline((string) $run->rPr->u['val']);
2048
                        }
2049 3 View Code Duplication
                        if ((isset($run->rPr->strike['val']) && self::boolean((string) $run->rPr->strike['val'])) ||
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2050 3
                            (isset($run->rPr->strike) && !isset($run->rPr->strike['val']))) {
2051 3
                            $objText->getFont()->setStrikethrough(true);
2052
                        }
2053
                    }
2054
                }
2055
            }
2056
        }
2057
2058 3
        return $value;
2059
    }
2060
2061
    /**
2062
     * @param \PhpOffice\PhpSpreadsheet\Spreadsheet $excel
2063
     */
2064
    private function readRibbon(\PhpOffice\PhpSpreadsheet\Spreadsheet $excel, $customUITarget, $zip)
2065
    {
2066
        $baseDir = dirname($customUITarget);
2067
        $nameCustomUI = basename($customUITarget);
2068
        // get the xml file (ribbon)
2069
        $localRibbon = $this->getFromZipArchive($zip, $customUITarget);
2070
        $customUIImagesNames = [];
2071
        $customUIImagesBinaries = [];
2072
        // something like customUI/_rels/customUI.xml.rels
2073
        $pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels';
2074
        $dataRels = $this->getFromZipArchive($zip, $pathRels);
2075
        if ($dataRels) {
2076
            // exists and not empty if the ribbon have some pictures (other than internal MSO)
2077
            $UIRels = simplexml_load_string(
2078
                $this->securityScan($dataRels),
2079
                'SimpleXMLElement',
2080
                \PhpOffice\PhpSpreadsheet\Settings::getLibXmlLoaderOptions()
2081
            );
2082
            if ($UIRels) {
2083
                // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image
2084
                foreach ($UIRels->Relationship as $ele) {
2085
                    if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') {
2086
                        // an image ?
2087
                        $customUIImagesNames[(string) $ele['Id']] = (string) $ele['Target'];
2088
                        $customUIImagesBinaries[(string) $ele['Target']] = $this->getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']);
2089
                    }
2090
                }
2091
            }
2092
        }
2093
        if ($localRibbon) {
2094
            $excel->setRibbonXMLData($customUITarget, $localRibbon);
2095
            if (count($customUIImagesNames) > 0 && count($customUIImagesBinaries) > 0) {
2096
                $excel->setRibbonBinObjects($customUIImagesNames, $customUIImagesBinaries);
2097
            } else {
2098
                $excel->setRibbonBinObjects(null);
2099
            }
2100
        } else {
2101
            $excel->setRibbonXMLData(null);
2102
            $excel->setRibbonBinObjects(null);
2103
        }
2104
    }
2105
2106 9
    private static function getArrayItem($array, $key = 0)
2107
    {
2108 9
        return isset($array[$key]) ? $array[$key] : null;
2109
    }
2110
2111 3
    private static function dirAdd($base, $add)
2112
    {
2113 3
        return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add");
2114
    }
2115
2116
    private static function toCSSArray($style)
2117
    {
2118
        $style = str_replace(["\r", "\n"], '', $style);
2119
2120
        $temp = explode(';', $style);
2121
        $style = [];
2122
        foreach ($temp as $item) {
2123
            $item = explode(':', $item);
2124
2125
            if (strpos($item[1], 'px') !== false) {
2126
                $item[1] = str_replace('px', '', $item[1]);
2127
            }
2128 View Code Duplication
            if (strpos($item[1], 'pt') !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2129
                $item[1] = str_replace('pt', '', $item[1]);
2130
                $item[1] = \PhpOffice\PhpSpreadsheet\Shared\Font::fontSizeToPixels($item[1]);
2131
            }
2132 View Code Duplication
            if (strpos($item[1], 'in') !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2133
                $item[1] = str_replace('in', '', $item[1]);
2134
                $item[1] = \PhpOffice\PhpSpreadsheet\Shared\Font::inchSizeToPixels($item[1]);
2135
            }
2136 View Code Duplication
            if (strpos($item[1], 'cm') !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2137
                $item[1] = str_replace('cm', '', $item[1]);
2138
                $item[1] = \PhpOffice\PhpSpreadsheet\Shared\Font::centimeterSizeToPixels($item[1]);
2139
            }
2140
2141
            $style[$item[0]] = $item[1];
2142
        }
2143
2144
        return $style;
2145
    }
2146
2147 8
    private static function boolean($value = null)
2148
    {
2149 8
        if (is_object($value)) {
2150 1
            $value = (string) $value;
2151
        }
2152 8
        if (is_numeric($value)) {
2153 6
            return (bool) $value;
2154
        }
2155
2156 8
        return $value === 'true' || $value === 'TRUE';
2157
    }
2158
}
2159