Completed
Push — develop ( e1f81f...539a89 )
by Adrien
16:11
created

Gnumeric::parseRichText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace PhpSpreadsheet\Reader;
4
5
/**
6
 * Copyright (c) 2006 - 2016 PhpSpreadsheet
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
 *
22
 * @category   PhpSpreadsheet
23
 * @copyright  Copyright (c) 2006 - 2016 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
24
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
25
 * @version    ##VERSION##, ##DATE##
26
 */
27
class Gnumeric extends BaseReader implements IReader
28
{
29
    /**
30
     * Formats
31
     *
32
     * @var array
33
     */
34
    private $styles = array();
0 ignored issues
show
Unused Code introduced by
The property $styles is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
35
36
    /**
37
     * Shared Expressions
38
     *
39
     * @var array
40
     */
41
    private $expressions = array();
42
43
    private $referenceHelper = null;
44
45
    /**
46
     * Create a new Gnumeric
47
     */
48
    public function __construct()
49
    {
50
        $this->readFilter     = new DefaultReadFilter();
51
        $this->referenceHelper = \PhpSpreadsheet\ReferenceHelper::getInstance();
52
    }
53
54
    /**
55
     * Can the current IReader read the file?
56
     *
57
     * @param     string         $pFilename
58
     * @return     boolean
59
     * @throws Exception
60
     */
61
    public function canRead($pFilename)
62
    {
63
        // Check if file exists
64
        if (!file_exists($pFilename)) {
65
            throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
66
        }
67
68
        // Check if gzlib functions are available
69
        if (!function_exists('gzread')) {
70
            throw new Exception("gzlib library is not enabled");
71
        }
72
73
        // Read signature data (first 3 bytes)
74
        $fh = fopen($pFilename, 'r');
75
        $data = fread($fh, 2);
76
        fclose($fh);
77
78
        if ($data != chr(0x1F).chr(0x8B)) {
79
            return false;
80
        }
81
82
        return true;
83
    }
84
85
    /**
86
     * Reads names of the worksheets from a file, without parsing the whole file to a PhpSpreadsheet object
87
     *
88
     * @param   string         $pFilename
89
     * @throws  Exception
90
     */
91
    public function listWorksheetNames($pFilename)
92
    {
93
        // Check if file exists
94
        if (!file_exists($pFilename)) {
95
            throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
96
        }
97
98
        $xml = new XMLReader();
99
        $xml->xml($this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, \PhpSpreadsheet\Settings::getLibXmlLoaderOptions());
100
        $xml->setParserProperty(2, true);
101
102
        $worksheetNames = array();
103
        while ($xml->read()) {
104 View Code Duplication
            if ($xml->name == 'gnm:SheetName' && $xml->nodeType == XMLReader::ELEMENT) {
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...
105
                $xml->read();    //    Move onto the value node
106
                $worksheetNames[] = (string) $xml->value;
107
            } elseif ($xml->name == 'gnm:Sheets') {
108
                //    break out of the loop once we've got our sheet names rather than parse the entire file
109
                break;
110
            }
111
        }
112
113
        return $worksheetNames;
114
    }
115
116
    /**
117
     * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
118
     *
119
     * @param   string     $pFilename
120
     * @throws   Exception
121
     */
122
    public function listWorksheetInfo($pFilename)
123
    {
124
        // Check if file exists
125
        if (!file_exists($pFilename)) {
126
            throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
127
        }
128
129
        $xml = new XMLReader();
130
        $xml->xml($this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, \PhpSpreadsheet\Settings::getLibXmlLoaderOptions());
131
        $xml->setParserProperty(2, true);
132
133
        $worksheetInfo = array();
134
        while ($xml->read()) {
135
            if ($xml->name == 'gnm:Sheet' && $xml->nodeType == XMLReader::ELEMENT) {
136
                $tmpInfo = array(
137
                    'worksheetName' => '',
138
                    'lastColumnLetter' => 'A',
139
                    'lastColumnIndex' => 0,
140
                    'totalRows' => 0,
141
                    'totalColumns' => 0,
142
                );
143
144
                while ($xml->read()) {
145
                    if ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) {
146
                        $xml->read();    //    Move onto the value node
147
                        $tmpInfo['worksheetName'] = (string) $xml->value;
148
                    } elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) {
149
                        $xml->read();    //    Move onto the value node
150
                        $tmpInfo['lastColumnIndex'] = (int) $xml->value;
151
                        $tmpInfo['totalColumns'] = (int) $xml->value + 1;
152 View Code Duplication
                    } elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) {
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...
153
                        $xml->read();    //    Move onto the value node
154
                        $tmpInfo['totalRows'] = (int) $xml->value + 1;
155
                        break;
156
                    }
157
                }
158
                $tmpInfo['lastColumnLetter'] = \PhpSpreadsheet\Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
159
                $worksheetInfo[] = $tmpInfo;
160
            }
161
        }
162
163
        return $worksheetInfo;
164
    }
165
166
    private function gzfileGetContents($filename)
167
    {
168
        $file = @gzopen($filename, 'rb');
169
        if ($file !== false) {
170
            $data = '';
171
            while (!gzeof($file)) {
172
                $data .= gzread($file, 1024);
173
            }
174
            gzclose($file);
175
        }
176
        return $data;
0 ignored issues
show
Bug introduced by
The variable $data 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...
177
    }
178
179
    /**
180
     * Loads PhpSpreadsheet from file
181
     *
182
     * @param     string         $pFilename
183
     * @return     PhpSpreadsheet
184
     * @throws     Exception
185
     */
186
    public function load($pFilename)
187
    {
188
        // Create new PhpSpreadsheet
189
        $spreadsheet = new PhpSpreadsheet();
190
191
        // Load into this instance
192
        return $this->loadIntoExisting($pFilename, $spreadsheet);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->loadIntoEx...ilename, $spreadsheet); (PhpSpreadsheet\Spreadsheet) is incompatible with the return type declared by the interface PhpSpreadsheet\Reader\IReader::load of type 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...
193
    }
194
195
    /**
196
     * Loads PhpSpreadsheet from file into PhpSpreadsheet instance
197
     *
198
     * @param     string         $pFilename
199
     * @param    \PhpSpreadsheet\Spreadsheet    $spreadsheet
200
     * @return     PhpSpreadsheet
201
     * @throws     Exception
202
     */
203
    public function loadIntoExisting($pFilename, \PhpSpreadsheet\Spreadsheet $spreadsheet)
204
    {
205
        // Check if file exists
206
        if (!file_exists($pFilename)) {
207
            throw new Exception("Could not open " . $pFilename . " for reading! File does not exist.");
208
        }
209
210
        $timezoneObj = new DateTimeZone('Europe/London');
0 ignored issues
show
Unused Code introduced by
$timezoneObj 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...
211
        $GMT = new DateTimeZone('UTC');
0 ignored issues
show
Unused Code introduced by
$GMT 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...
212
213
        $gFileData = $this->gzfileGetContents($pFilename);
214
215
//        echo '<pre>';
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
216
//        echo htmlentities($gFileData,ENT_QUOTES,'UTF-8');
217
//        echo '</pre><hr />';
218
//
219
        $xml = simplexml_load_string($this->securityScan($gFileData), 'SimpleXMLElement', \PhpSpreadsheet\Settings::getLibXmlLoaderOptions());
220
        $namespacesMeta = $xml->getNamespaces(true);
221
222
//        var_dump($namespacesMeta);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
223
//
224
        $gnmXML = $xml->children($namespacesMeta['gnm']);
225
226
        $docProps = $spreadsheet->getProperties();
227
        //    Document Properties are held differently, depending on the version of Gnumeric
228
        if (isset($namespacesMeta['office'])) {
229
            $officeXML = $xml->children($namespacesMeta['office']);
230
            $officeDocXML = $officeXML->{'document-meta'};
231
            $officeDocMetaXML = $officeDocXML->meta;
232
233
            foreach ($officeDocMetaXML as $officePropertyData) {
234
                $officePropertyDC = array();
235
                if (isset($namespacesMeta['dc'])) {
236
                    $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
237
                }
238
                foreach ($officePropertyDC as $propertyName => $propertyValue) {
239
                    $propertyValue = (string) $propertyValue;
240
                    switch ($propertyName) {
241
                        case 'title':
242
                            $docProps->setTitle(trim($propertyValue));
243
                            break;
244
                        case 'subject':
245
                            $docProps->setSubject(trim($propertyValue));
246
                            break;
247
                        case 'creator':
248
                            $docProps->setCreator(trim($propertyValue));
249
                            $docProps->setLastModifiedBy(trim($propertyValue));
250
                            break;
251 View Code Duplication
                        case 'date':
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...
252
                            $creationDate = strtotime(trim($propertyValue));
253
                            $docProps->setCreated($creationDate);
0 ignored issues
show
Documentation introduced by
$creationDate is of type integer, but the function expects a object<PhpSpreadsheet\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...
254
                            $docProps->setModified($creationDate);
0 ignored issues
show
Documentation introduced by
$creationDate is of type integer, but the function expects a object<PhpSpreadsheet\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...
255
                            break;
256
                        case 'description':
257
                            $docProps->setDescription(trim($propertyValue));
258
                            break;
259
                    }
260
                }
261
                $officePropertyMeta = array();
262
                if (isset($namespacesMeta['meta'])) {
263
                    $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
264
                }
265
                foreach ($officePropertyMeta as $propertyName => $propertyValue) {
266
                    $attributes = $propertyValue->attributes($namespacesMeta['meta']);
267
                    $propertyValue = (string) $propertyValue;
268
                    switch ($propertyName) {
269
                        case 'keyword':
270
                            $docProps->setKeywords(trim($propertyValue));
271
                            break;
272
                        case 'initial-creator':
273
                            $docProps->setCreator(trim($propertyValue));
274
                            $docProps->setLastModifiedBy(trim($propertyValue));
275
                            break;
276 View Code Duplication
                        case 'creation-date':
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...
277
                            $creationDate = strtotime(trim($propertyValue));
278
                            $docProps->setCreated($creationDate);
0 ignored issues
show
Documentation introduced by
$creationDate is of type integer, but the function expects a object<PhpSpreadsheet\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...
279
                            $docProps->setModified($creationDate);
0 ignored issues
show
Documentation introduced by
$creationDate is of type integer, but the function expects a object<PhpSpreadsheet\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...
280
                            break;
281
                        case 'user-defined':
282
                            list(, $attrName) = explode(':', $attributes['name']);
283
                            switch ($attrName) {
284
                                case 'publisher':
285
                                    $docProps->setCompany(trim($propertyValue));
286
                                    break;
287
                                case 'category':
288
                                    $docProps->setCategory(trim($propertyValue));
289
                                    break;
290
                                case 'manager':
291
                                    $docProps->setManager(trim($propertyValue));
292
                                    break;
293
                            }
294
                            break;
295
                    }
296
                }
297
            }
298
        } elseif (isset($gnmXML->Summary)) {
299
            foreach ($gnmXML->Summary->Item as $summaryItem) {
300
                $propertyName = $summaryItem->name;
301
                $propertyValue = $summaryItem->{'val-string'};
302
                switch ($propertyName) {
303
                    case 'title':
304
                        $docProps->setTitle(trim($propertyValue));
305
                        break;
306
                    case 'comments':
307
                        $docProps->setDescription(trim($propertyValue));
308
                        break;
309
                    case 'keywords':
310
                        $docProps->setKeywords(trim($propertyValue));
311
                        break;
312
                    case 'category':
313
                        $docProps->setCategory(trim($propertyValue));
314
                        break;
315
                    case 'manager':
316
                        $docProps->setManager(trim($propertyValue));
317
                        break;
318
                    case 'author':
319
                        $docProps->setCreator(trim($propertyValue));
320
                        $docProps->setLastModifiedBy(trim($propertyValue));
321
                        break;
322
                    case 'company':
323
                        $docProps->setCompany(trim($propertyValue));
324
                        break;
325
                }
326
            }
327
        }
328
329
        $worksheetID = 0;
330
        foreach ($gnmXML->Sheets->Sheet as $sheet) {
331
            $worksheetName = (string) $sheet->Name;
332
//            echo '<b>Worksheet: ', $worksheetName,'</b><br />';
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
333
            if ((isset($this->loadSheetsOnly)) && (!in_array($worksheetName, $this->loadSheetsOnly))) {
334
                continue;
335
            }
336
337
            $maxRow = $maxCol = 0;
338
339
            // Create new Worksheet
340
            $spreadsheet->createSheet();
341
            $spreadsheet->setActiveSheetIndex($worksheetID);
342
            //    Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula
343
            //        cells... during the load, all formulae should be correct, and we're simply bringing the worksheet
344
            //        name in line with the formula, not the reverse
345
            $spreadsheet->getActiveSheet()->setTitle($worksheetName, false);
346
347
            if ((!$this->readDataOnly) && (isset($sheet->PrintInformation))) {
348
                if (isset($sheet->PrintInformation->Margins)) {
349
                    foreach ($sheet->PrintInformation->Margins->children('gnm', true) as $key => $margin) {
350
                        $marginAttributes = $margin->attributes();
351
                        $marginSize = 72 / 100;    //    Default
352
                        switch ($marginAttributes['PrefUnit']) {
353
                            case 'mm':
354
                                $marginSize = intval($marginAttributes['Points']) / 100;
355
                                break;
356
                        }
357
                        switch ($key) {
358
                            case 'top':
359
                                $spreadsheet->getActiveSheet()->getPageMargins()->setTop($marginSize);
360
                                break;
361
                            case 'bottom':
362
                                $spreadsheet->getActiveSheet()->getPageMargins()->setBottom($marginSize);
363
                                break;
364
                            case 'left':
365
                                $spreadsheet->getActiveSheet()->getPageMargins()->setLeft($marginSize);
366
                                break;
367
                            case 'right':
368
                                $spreadsheet->getActiveSheet()->getPageMargins()->setRight($marginSize);
369
                                break;
370
                            case 'header':
371
                                $spreadsheet->getActiveSheet()->getPageMargins()->setHeader($marginSize);
372
                                break;
373
                            case 'footer':
374
                                $spreadsheet->getActiveSheet()->getPageMargins()->setFooter($marginSize);
375
                                break;
376
                        }
377
                    }
378
                }
379
            }
380
381
            foreach ($sheet->Cells->Cell as $cell) {
382
                $cellAttributes = $cell->attributes();
383
                $row = (int) $cellAttributes->Row + 1;
384
                $column = (int) $cellAttributes->Col;
385
386
                if ($row > $maxRow) {
387
                    $maxRow = $row;
388
                }
389
                if ($column > $maxCol) {
390
                    $maxCol = $column;
391
                }
392
393
                $column = \PhpSpreadsheet\Cell::stringFromColumnIndex($column);
394
395
                // Read cell?
396
                if ($this->getReadFilter() !== null) {
397
                    if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) {
398
                        continue;
399
                    }
400
                }
401
402
                $ValueType = $cellAttributes->ValueType;
403
                $ExprID = (string) $cellAttributes->ExprID;
404
//                echo 'Cell ', $column, $row,'<br />';
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% 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...
405
//                echo 'Type is ', $ValueType,'<br />';
406
//                echo 'Value is ', $cell,'<br />';
407
                $type = \PhpSpreadsheet\Cell\DataType::TYPE_FORMULA;
408
                if ($ExprID > '') {
409
                    if (((string) $cell) > '') {
410
                        $this->expressions[$ExprID] = array(
411
                            'column'    => $cellAttributes->Col,
412
                            'row'        => $cellAttributes->Row,
413
                            'formula'    => (string) $cell
414
                        );
415
//                        echo 'NEW EXPRESSION ', $ExprID,'<br />';
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
416
                    } else {
417
                        $expression = $this->expressions[$ExprID];
418
419
                        $cell = $this->referenceHelper->updateFormulaReferences(
420
                            $expression['formula'],
421
                            'A1',
422
                            $cellAttributes->Col - $expression['column'],
423
                            $cellAttributes->Row - $expression['row'],
424
                            $worksheetName
425
                        );
426
//                        echo 'SHARED EXPRESSION ', $ExprID,'<br />';
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
427
//                        echo 'New Value is ', $cell,'<br />';
428
                    }
429
                    $type = \PhpSpreadsheet\Cell\DataType::TYPE_FORMULA;
430
                } else {
431
                    switch ($ValueType) {
432
                        case '10':        //    NULL
433
                            $type = \PhpSpreadsheet\Cell\DataType::TYPE_NULL;
434
                            break;
435
                        case '20':        //    Boolean
436
                            $type = \PhpSpreadsheet\Cell\DataType::TYPE_BOOL;
437
                            $cell = ($cell == 'TRUE') ? true: false;
438
                            break;
439
                        case '30':        //    Integer
440
                            $cell = intval($cell);
441
                            // Excel 2007+ doesn't differentiate between integer and float, so set the value and dropthru to the next (numeric) case
442
                        case '40':        //    Float
443
                            $type = \PhpSpreadsheet\Cell\DataType::TYPE_NUMERIC;
444
                            break;
445
                        case '50':        //    Error
446
                            $type = \PhpSpreadsheet\Cell\DataType::TYPE_ERROR;
447
                            break;
448
                        case '60':        //    String
449
                            $type = \PhpSpreadsheet\Cell\DataType::TYPE_STRING;
450
                            break;
451
                        case '70':        //    Cell Range
452
                        case '80':        //    Array
453
                    }
454
                }
455
                $spreadsheet->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell, $type);
456
            }
457
458
            if ((!$this->readDataOnly) && (isset($sheet->Objects))) {
459
                foreach ($sheet->Objects->children('gnm', true) as $key => $comment) {
460
                    $commentAttributes = $comment->attributes();
461
                    //    Only comment objects are handled at the moment
462
                    if ($commentAttributes->Text) {
463
                        $spreadsheet->getActiveSheet()->getComment((string)$commentAttributes->ObjectBound)->setAuthor((string)$commentAttributes->Author)->setText($this->parseRichText((string)$commentAttributes->Text));
464
                    }
465
                }
466
            }
467
//            echo '$maxCol=', $maxCol,'; $maxRow=', $maxRow,'<br />';
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% 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...
468
//
469
            foreach ($sheet->Styles->StyleRegion as $styleRegion) {
470
                $styleAttributes = $styleRegion->attributes();
471
                if (($styleAttributes['startRow'] <= $maxRow) &&
472
                    ($styleAttributes['startCol'] <= $maxCol)) {
473
                    $startColumn = \PhpSpreadsheet\Cell::stringFromColumnIndex((int) $styleAttributes['startCol']);
474
                    $startRow = $styleAttributes['startRow'] + 1;
475
476
                    $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol'];
477
                    $endColumn = \PhpSpreadsheet\Cell::stringFromColumnIndex($endColumn);
478
                    $endRow = ($styleAttributes['endRow'] > $maxRow) ? $maxRow : $styleAttributes['endRow'];
479
                    $endRow += 1;
480
                    $cellRange = $startColumn.$startRow.':'.$endColumn.$endRow;
481
//                    echo $cellRange,'<br />';
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% 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...
482
483
                    $styleAttributes = $styleRegion->Style->attributes();
484
//                    var_dump($styleAttributes);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
485
//                    echo '<br />';
486
487
                    //    We still set the number format mask for date/time values, even if readDataOnly is true
488
                    if ((!$this->readDataOnly) ||
489
                        (\PhpSpreadsheet\Shared\Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) {
490
                        $styleArray = array();
491
                        $styleArray['numberformat']['code'] = (string) $styleAttributes['Format'];
492
                        //    If readDataOnly is false, we set all formatting information
493
                        if (!$this->readDataOnly) {
494
                            switch ($styleAttributes['HAlign']) {
495
                                case '1':
496
                                    $styleArray['alignment']['horizontal'] = \PhpSpreadsheet\Style\Alignment::HORIZONTAL_GENERAL;
497
                                    break;
498
                                case '2':
499
                                    $styleArray['alignment']['horizontal'] = \PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT;
500
                                    break;
501
                                case '4':
502
                                    $styleArray['alignment']['horizontal'] = \PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT;
503
                                    break;
504
                                case '8':
505
                                    $styleArray['alignment']['horizontal'] = \PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER;
506
                                    break;
507
                                case '16':
508
                                case '64':
509
                                    $styleArray['alignment']['horizontal'] = \PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER_CONTINUOUS;
510
                                    break;
511
                                case '32':
512
                                    $styleArray['alignment']['horizontal'] = \PhpSpreadsheet\Style\Alignment::HORIZONTAL_JUSTIFY;
513
                                    break;
514
                            }
515
516
                            switch ($styleAttributes['VAlign']) {
517
                                case '1':
518
                                    $styleArray['alignment']['vertical'] = \PhpSpreadsheet\Style\Alignment::VERTICAL_TOP;
519
                                    break;
520
                                case '2':
521
                                    $styleArray['alignment']['vertical'] = \PhpSpreadsheet\Style\Alignment::VERTICAL_BOTTOM;
522
                                    break;
523
                                case '4':
524
                                    $styleArray['alignment']['vertical'] = \PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER;
525
                                    break;
526
                                case '8':
527
                                    $styleArray['alignment']['vertical'] = \PhpSpreadsheet\Style\Alignment::VERTICAL_JUSTIFY;
528
                                    break;
529
                            }
530
531
                            $styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? true : false;
532
                            $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? true : false;
533
                            $styleArray['alignment']['indent'] = (intval($styleAttributes["Indent"]) > 0) ? $styleAttributes["indent"] : 0;
534
535
                            $RGB = self::parseGnumericColour($styleAttributes["Fore"]);
536
                            $styleArray['font']['color']['rgb'] = $RGB;
537
                            $RGB = self::parseGnumericColour($styleAttributes["Back"]);
538
                            $shade = $styleAttributes["Shade"];
539
                            if (($RGB != '000000') || ($shade != '0')) {
540
                                $styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB;
541
                                $RGB2 = self::parseGnumericColour($styleAttributes["PatternColor"]);
542
                                $styleArray['fill']['endcolor']['rgb'] = $RGB2;
543
                                switch ($shade) {
544
                                    case '1':
545
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_SOLID;
546
                                        break;
547
                                    case '2':
548
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_GRADIENT_LINEAR;
549
                                        break;
550
                                    case '3':
551
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_GRADIENT_PATH;
552
                                        break;
553
                                    case '4':
554
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_DARKDOWN;
555
                                        break;
556
                                    case '5':
557
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_DARKGRAY;
558
                                        break;
559
                                    case '6':
560
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_DARKGRID;
561
                                        break;
562
                                    case '7':
563
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_DARKHORIZONTAL;
564
                                        break;
565
                                    case '8':
566
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_DARKTRELLIS;
567
                                        break;
568
                                    case '9':
569
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_DARKUP;
570
                                        break;
571
                                    case '10':
572
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_DARKVERTICAL;
573
                                        break;
574
                                    case '11':
575
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_GRAY0625;
576
                                        break;
577
                                    case '12':
578
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_GRAY125;
579
                                        break;
580
                                    case '13':
581
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_LIGHTDOWN;
582
                                        break;
583
                                    case '14':
584
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_LIGHTGRAY;
585
                                        break;
586
                                    case '15':
587
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_LIGHTGRID;
588
                                        break;
589
                                    case '16':
590
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_LIGHTHORIZONTAL;
591
                                        break;
592
                                    case '17':
593
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_LIGHTTRELLIS;
594
                                        break;
595
                                    case '18':
596
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_LIGHTUP;
597
                                        break;
598
                                    case '19':
599
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_LIGHTVERTICAL;
600
                                        break;
601
                                    case '20':
602
                                        $styleArray['fill']['type'] = \PhpSpreadsheet\Style\Fill::FILL_PATTERN_MEDIUMGRAY;
603
                                        break;
604
                                }
605
                            }
606
607
                            $fontAttributes = $styleRegion->Style->Font->attributes();
608
//                            var_dump($fontAttributes);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
609
//                            echo '<br />';
610
                            $styleArray['font']['name'] = (string) $styleRegion->Style->Font;
611
                            $styleArray['font']['size'] = intval($fontAttributes['Unit']);
612
                            $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? true : false;
613
                            $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? true : false;
614
                            $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? true : false;
615
                            switch ($fontAttributes['Underline']) {
616
                                case '1':
617
                                    $styleArray['font']['underline'] = \PhpSpreadsheet\Style\Font::UNDERLINE_SINGLE;
618
                                    break;
619
                                case '2':
620
                                    $styleArray['font']['underline'] = \PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLE;
621
                                    break;
622
                                case '3':
623
                                    $styleArray['font']['underline'] = \PhpSpreadsheet\Style\Font::UNDERLINE_SINGLEACCOUNTING;
624
                                    break;
625
                                case '4':
626
                                    $styleArray['font']['underline'] = \PhpSpreadsheet\Style\Font::UNDERLINE_DOUBLEACCOUNTING;
627
                                    break;
628
                                default:
629
                                    $styleArray['font']['underline'] = \PhpSpreadsheet\Style\Font::UNDERLINE_NONE;
630
                                    break;
631
                            }
632
                            switch ($fontAttributes['Script']) {
633
                                case '1':
634
                                    $styleArray['font']['superScript'] = true;
635
                                    break;
636
                                case '-1':
637
                                    $styleArray['font']['subScript'] = true;
638
                                    break;
639
                            }
640
641
                            if (isset($styleRegion->Style->StyleBorder)) {
642 View Code Duplication
                                if (isset($styleRegion->Style->StyleBorder->Top)) {
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...
643
                                    $styleArray['borders']['top'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes());
644
                                }
645 View Code Duplication
                                if (isset($styleRegion->Style->StyleBorder->Bottom)) {
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...
646
                                    $styleArray['borders']['bottom'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes());
647
                                }
648 View Code Duplication
                                if (isset($styleRegion->Style->StyleBorder->Left)) {
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...
649
                                    $styleArray['borders']['left'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes());
650
                                }
651 View Code Duplication
                                if (isset($styleRegion->Style->StyleBorder->Right)) {
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...
652
                                    $styleArray['borders']['right'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes());
653
                                }
654
                                if ((isset($styleRegion->Style->StyleBorder->Diagonal)) && (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}))) {
655
                                    $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes());
656
                                    $styleArray['borders']['diagonaldirection'] = \PhpSpreadsheet\Style\Borders::DIAGONAL_BOTH;
657
                                } elseif (isset($styleRegion->Style->StyleBorder->Diagonal)) {
658
                                    $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes());
659
                                    $styleArray['borders']['diagonaldirection'] = \PhpSpreadsheet\Style\Borders::DIAGONAL_UP;
660
                                } elseif (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'})) {
661
                                    $styleArray['borders']['diagonal'] = self::parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes());
662
                                    $styleArray['borders']['diagonaldirection'] = \PhpSpreadsheet\Style\Borders::DIAGONAL_DOWN;
663
                                }
664
                            }
665
                            if (isset($styleRegion->Style->HyperLink)) {
666
                                //    TO DO
667
                                $hyperlink = $styleRegion->Style->HyperLink->attributes();
0 ignored issues
show
Unused Code introduced by
$hyperlink 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...
668
                            }
669
                        }
670
//                        var_dump($styleArray);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
671
//                        echo '<br />';
672
                        $spreadsheet->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray);
673
                    }
674
                }
675
            }
676
677
            if ((!$this->readDataOnly) && (isset($sheet->Cols))) {
678
                //    Column Widths
679
                $columnAttributes = $sheet->Cols->attributes();
680
                $defaultWidth = $columnAttributes['DefaultSizePts']  / 5.4;
681
                $c = 0;
682
                foreach ($sheet->Cols->ColInfo as $columnOverride) {
683
                    $columnAttributes = $columnOverride->attributes();
684
                    $column = $columnAttributes['No'];
685
                    $columnWidth = $columnAttributes['Unit']  / 5.4;
686
                    $hidden = ((isset($columnAttributes['Hidden'])) && ($columnAttributes['Hidden'] == '1')) ? true : false;
687
                    $columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1;
688
                    while ($c < $column) {
689
                        $spreadsheet->getActiveSheet()->getColumnDimension(\PhpSpreadsheet\Cell::stringFromColumnIndex($c))->setWidth($defaultWidth);
690
                        ++$c;
691
                    }
692
                    while (($c < ($column+$columnCount)) && ($c <= $maxCol)) {
693
                        $spreadsheet->getActiveSheet()->getColumnDimension(\PhpSpreadsheet\Cell::stringFromColumnIndex($c))->setWidth($columnWidth);
694
                        if ($hidden) {
695
                            $spreadsheet->getActiveSheet()->getColumnDimension(\PhpSpreadsheet\Cell::stringFromColumnIndex($c))->setVisible(false);
696
                        }
697
                        ++$c;
698
                    }
699
                }
700
                while ($c <= $maxCol) {
701
                    $spreadsheet->getActiveSheet()->getColumnDimension(\PhpSpreadsheet\Cell::stringFromColumnIndex($c))->setWidth($defaultWidth);
702
                    ++$c;
703
                }
704
            }
705
706
            if ((!$this->readDataOnly) && (isset($sheet->Rows))) {
707
                //    Row Heights
708
                $rowAttributes = $sheet->Rows->attributes();
709
                $defaultHeight = $rowAttributes['DefaultSizePts'];
710
                $r = 0;
711
712
                foreach ($sheet->Rows->RowInfo as $rowOverride) {
713
                    $rowAttributes = $rowOverride->attributes();
714
                    $row = $rowAttributes['No'];
715
                    $rowHeight = $rowAttributes['Unit'];
716
                    $hidden = ((isset($rowAttributes['Hidden'])) && ($rowAttributes['Hidden'] == '1')) ? true : false;
717
                    $rowCount = (isset($rowAttributes['Count'])) ? $rowAttributes['Count'] : 1;
718
                    while ($r < $row) {
719
                        ++$r;
720
                        $spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);
721
                    }
722
                    while (($r < ($row+$rowCount)) && ($r < $maxRow)) {
723
                        ++$r;
724
                        $spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($rowHeight);
725
                        if ($hidden) {
726
                            $spreadsheet->getActiveSheet()->getRowDimension($r)->setVisible(false);
727
                        }
728
                    }
729
                }
730
                while ($r < $maxRow) {
731
                    ++$r;
732
                    $spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);
733
                }
734
            }
735
736
            //    Handle Merged Cells in this worksheet
737
            if (isset($sheet->MergedRegions)) {
738
                foreach ($sheet->MergedRegions->Merge as $mergeCells) {
739
                    if (strpos($mergeCells, ':') !== false) {
740
                        $spreadsheet->getActiveSheet()->mergeCells($mergeCells);
741
                    }
742
                }
743
            }
744
745
            $worksheetID++;
746
        }
747
748
        //    Loop through definedNames (global named ranges)
749
        if (isset($gnmXML->Names)) {
750
            foreach ($gnmXML->Names->Name as $namedRange) {
751
                $name = (string) $namedRange->name;
752
                $range = (string) $namedRange->value;
753
                if (stripos($range, '#REF!') !== false) {
754
                    continue;
755
                }
756
757
                $range = explode('!', $range);
758
                $range[0] = trim($range[0], "'");
759
                if ($worksheet = $spreadsheet->getSheetByName($range[0])) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $worksheet is correct as $spreadsheet->getSheetByName($range[0]) (which targets PhpSpreadsheet\Spreadsheet::getSheetByName()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
760
                    $extractedRange = str_replace('$', '', $range[1]);
761
                    $spreadsheet->addNamedRange(new \PhpSpreadsheet\NamedRange($name, $worksheet, $extractedRange));
762
                }
763
            }
764
        }
765
766
        // Return
767
        return $spreadsheet;
768
    }
769
770
    private static function parseBorderAttributes($borderAttributes)
771
    {
772
        $styleArray = array();
773
        if (isset($borderAttributes["Color"])) {
774
            $styleArray['color']['rgb'] = self::parseGnumericColour($borderAttributes["Color"]);
775
        }
776
777
        switch ($borderAttributes["Style"]) {
778
            case '0':
779
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_NONE;
780
                break;
781
            case '1':
782
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_THIN;
783
                break;
784
            case '2':
785
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_MEDIUM;
786
                break;
787
            case '3':
788
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_SLANTDASHDOT;
789
                break;
790
            case '4':
791
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_DASHED;
792
                break;
793
            case '5':
794
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_THICK;
795
                break;
796
            case '6':
797
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_DOUBLE;
798
                break;
799
            case '7':
800
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_DOTTED;
801
                break;
802
            case '8':
803
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_MEDIUMDASHED;
804
                break;
805
            case '9':
806
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_DASHDOT;
807
                break;
808
            case '10':
809
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_MEDIUMDASHDOT;
810
                break;
811
            case '11':
812
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_DASHDOTDOT;
813
                break;
814
            case '12':
815
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_MEDIUMDASHDOTDOT;
816
                break;
817
            case '13':
818
                $styleArray['style'] = \PhpSpreadsheet\Style\Border::BORDER_MEDIUMDASHDOTDOT;
819
                break;
820
        }
821
        return $styleArray;
822
    }
823
824
    private function parseRichText($is = '')
825
    {
826
        $value = new \PhpSpreadsheet\RichText();
827
        $value->createText($is);
828
829
        return $value;
830
    }
831
832
    private static function parseGnumericColour($gnmColour)
833
    {
834
        list($gnmR, $gnmG, $gnmB) = explode(':', $gnmColour);
835
        $gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2);
836
        $gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2);
837
        $gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2);
838
        return $gnmR . $gnmG . $gnmB;
839
    }
840
}
841