Completed
Push — develop ( 8cf911...93ccf7 )
by Adrien
33:03
created

CacheBase::isDataSet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 8
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\CachedObjectStorage;
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
abstract class CacheBase
28
{
29
    /**
30
     * Parent worksheet
31
     *
32
     * @var \PhpOffice\PhpSpreadsheet\Worksheet
33
     */
34
    protected $parent;
35
36
    /**
37
     * The currently active Cell
38
     *
39
     * @var \PhpOffice\PhpSpreadsheet\Cell
40
     */
41
    protected $currentObject = null;
42
43
    /**
44
     * Coordinate address of the currently active Cell
45
     *
46
     * @var string
47
     */
48
    protected $currentObjectID = null;
49
50
    /**
51
     * Flag indicating whether the currently active Cell requires saving
52
     *
53
     * @var bool
54
     */
55
    protected $currentCellIsDirty = true;
56
57
    /**
58
     * An array of cells or cell pointers for the worksheet cells held in this cache,
59
     *        and indexed by their coordinate address within the worksheet
60
     *
61
     * @var array of mixed
62
     */
63
    protected $cellCache = [];
64
65
    /**
66
     * Initialise this new cell collection
67
     *
68
     * @param    \PhpOffice\PhpSpreadsheet\Worksheet    $parent        The worksheet for this cell collection
69
     */
70 70
    public function __construct(\PhpOffice\PhpSpreadsheet\Worksheet $parent)
71
    {
72
        //    Set our parent worksheet.
73
        //    This is maintained within the cache controller to facilitate re-attaching it to \PhpOffice\PhpSpreadsheet\Cell objects when
74
        //        they are woken from a serialized state
75 70
        $this->parent = $parent;
76 70
    }
77
78
    /**
79
     * Return the parent worksheet for this cell collection
80
     *
81
     * @return    \PhpOffice\PhpSpreadsheet\Worksheet
82
     */
83 37
    public function getParent()
84
    {
85 37
        return $this->parent;
86
    }
87
88
    /**
89
     * Is a value set in the current \PhpOffice\PhpSpreadsheet\CachedObjectStorage\ICache for an indexed cell?
90
     *
91
     * @param    string        $pCoord        Coordinate address of the cell to check
92
     * @return    bool
93
     */
94 62
    public function isDataSet($pCoord)
95
    {
96 62
        if ($pCoord === $this->currentObjectID) {
97 57
            return true;
98
        }
99
        //    Check if the requested entry exists in the cache
100 62
        return isset($this->cellCache[$pCoord]);
101
    }
102
103
    /**
104
     * Move a cell object from one address to another
105
     *
106
     * @param    string        $fromAddress    Current address of the cell to move
107
     * @param    string        $toAddress        Destination address of the cell to move
108
     * @return    bool
109
     */
110
    public function moveCell($fromAddress, $toAddress)
111
    {
112
        if ($fromAddress === $this->currentObjectID) {
113
            $this->currentObjectID = $toAddress;
114
        }
115
        $this->currentCellIsDirty = true;
116
        if (isset($this->cellCache[$fromAddress])) {
117
            $this->cellCache[$toAddress] = &$this->cellCache[$fromAddress];
118
            unset($this->cellCache[$fromAddress]);
119
        }
120
121
        return true;
122
    }
123
124
    /**
125
     * Add or Update a cell in cache
126
     *
127
     * @param    \PhpOffice\PhpSpreadsheet\Cell    $cell        Cell to update
128
     * @throws   \PhpOffice\PhpSpreadsheet\Exception
129
     * @return   \PhpOffice\PhpSpreadsheet\Cell
130
     */
131 62
    public function updateCacheData(\PhpOffice\PhpSpreadsheet\Cell $cell)
132
    {
133 62
        return $this->addCacheData($cell->getCoordinate(), $cell);
134
    }
135
136
    /**
137
     * Delete a cell in cache identified by coordinate address
138
     *
139
     * @param    string            $pCoord        Coordinate address of the cell to delete
140
     * @throws   \PhpOffice\PhpSpreadsheet\Exception
141
     */
142 12
    public function deleteCacheData($pCoord)
143
    {
144 12
        if ($pCoord === $this->currentObjectID && !is_null($this->currentObject)) {
145
            $this->currentObject->detach();
146
            $this->currentObjectID = $this->currentObject = null;
147
        }
148
149 12
        if (is_object($this->cellCache[$pCoord])) {
150 12
            $this->cellCache[$pCoord]->detach();
151 12
            unset($this->cellCache[$pCoord]);
152
        }
153 12
        $this->currentCellIsDirty = false;
154 12
    }
155
156
    /**
157
     * Get a list of all cell addresses currently held in cache
158
     *
159
     * @return    string[]
160
     */
161 60
    public function getCellList()
162
    {
163 60
        return array_keys($this->cellCache);
164
    }
165
166
    /**
167
     * Sort the list of all cell addresses currently held in cache by row and column
168
     *
169
     * @return    string[]
170
     */
171 60
    public function getSortedCellList()
172
    {
173 60
        $sortKeys = [];
174 60
        foreach ($this->getCellList() as $coord) {
175 60
            sscanf($coord, '%[A-Z]%d', $column, $row);
0 ignored issues
show
Bug introduced by
The variable $row does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
176 60
            $sortKeys[sprintf('%09d%3s', $row, $column)] = $coord;
177
        }
178 60
        ksort($sortKeys);
179
180 60
        return array_values($sortKeys);
181
    }
182
183
    /**
184
     * Get highest worksheet column and highest row that have cell records
185
     *
186
     * @return array Highest column name and highest row number
187
     */
188 59
    public function getHighestRowAndColumn()
189
    {
190
        // Lookup highest column and highest row
191 59
        $col = ['A' => '1A'];
192 59
        $row = [1];
193 59
        foreach ($this->getCellList() as $coord) {
194 59
            sscanf($coord, '%[A-Z]%d', $c, $r);
0 ignored issues
show
Bug introduced by
The variable $r does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
195 59
            $row[$r] = $r;
196 59
            $col[$c] = strlen($c) . $c;
197
        }
198 59
        if (!empty($row)) {
199
            // Determine highest column and row
200 59
            $highestRow = max($row);
201 59
            $highestColumn = substr(max($col), 1);
202
        }
203
204
        return [
205 59
            'row' => $highestRow,
0 ignored issues
show
Bug introduced by
The variable $highestRow 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...
206 59
            'column' => $highestColumn,
0 ignored issues
show
Bug introduced by
The variable $highestColumn 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...
207
        ];
208
    }
209
210
    /**
211
     * Return the cell address of the currently active cell object
212
     *
213
     * @return    string
214
     */
215 62
    public function getCurrentAddress()
216
    {
217 62
        return $this->currentObjectID;
218
    }
219
220
    /**
221
     * Return the column address of the currently active cell object
222
     *
223
     * @return    string
224
     */
225 42
    public function getCurrentColumn()
226
    {
227 42
        sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row);
0 ignored issues
show
Bug introduced by
The variable $row does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
228
229 42
        return $column;
230
    }
231
232
    /**
233
     * Return the row address of the currently active cell object
234
     *
235
     * @return    int
236
     */
237 42
    public function getCurrentRow()
238
    {
239 42
        sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row);
0 ignored issues
show
Bug introduced by
The variable $row does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
240
241 42
        return (integer) $row;
242
    }
243
244
    /**
245
     * Get highest worksheet column
246
     *
247
     * @param   string     $row        Return the highest column for the specified row,
248
     *                                     or the highest column of any row if no row number is passed
249
     * @return  string     Highest column name
250
     */
251 10
    public function getHighestColumn($row = null)
252
    {
253 10
        if ($row == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $row of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
254 10
            $colRow = $this->getHighestRowAndColumn();
255
256 10
            return $colRow['column'];
257
        }
258
259
        $columnList = [1];
260
        foreach ($this->getCellList() as $coord) {
261
            sscanf($coord, '%[A-Z]%d', $c, $r);
0 ignored issues
show
Bug introduced by
The variable $r does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
262
            if ($r != $row) {
263
                continue;
264
            }
265
            $columnList[] = \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString($c);
266
        }
267
268
        return \PhpOffice\PhpSpreadsheet\Cell::stringFromColumnIndex(max($columnList) - 1);
269
    }
270
271
    /**
272
     * Get highest worksheet row
273
     *
274
     * @param   string     $column     Return the highest row for the specified column,
275
     *                                     or the highest row of any column if no column letter is passed
276
     * @return  int        Highest row number
277
     */
278 12
    public function getHighestRow($column = null)
279
    {
280 12
        if ($column == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $column of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
281 12
            $colRow = $this->getHighestRowAndColumn();
282
283 12
            return $colRow['row'];
284
        }
285
286
        $rowList = [0];
287
        foreach ($this->getCellList() as $coord) {
288
            sscanf($coord, '%[A-Z]%d', $c, $r);
0 ignored issues
show
Bug introduced by
The variable $r does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
289
            if ($c != $column) {
290
                continue;
291
            }
292
            $rowList[] = $r;
293
        }
294
295
        return max($rowList);
296
    }
297
298
    /**
299
     * Generate a unique ID for cache referencing
300
     *
301
     * @return string Unique Reference
302
     */
303 1
    protected function getUniqueID()
304
    {
305 1
        if (function_exists('posix_getpid')) {
306 1
            $baseUnique = posix_getpid();
307
        } else {
308
            $baseUnique = mt_rand();
309
        }
310
311 1
        return uniqid($baseUnique, true);
312
    }
313
314
    /**
315
     * Clone the cell collection
316
     *
317
     * @param  \PhpOffice\PhpSpreadsheet\Worksheet    $parent        The new worksheet that we're copying to
318
     */
319 1
    public function copyCellCollection(\PhpOffice\PhpSpreadsheet\Worksheet $parent)
320
    {
321 1
        $this->currentCellIsDirty;
322 1
        $this->storeData();
323
324 1
        $this->parent = $parent;
325 1
        if (($this->currentObject !== null) && (is_object($this->currentObject))) {
326
            $this->currentObject->attach($this);
327
        }
328 1
    }
329
330
    /**
331
     * Remove a row, deleting all cells in that row
332
     *
333
     * @param string    $row    Row number to remove
334
     */
335 12 View Code Duplication
    public function removeRow($row)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
336
    {
337 12
        foreach ($this->getCellList() as $coord) {
338 12
            sscanf($coord, '%[A-Z]%d', $c, $r);
0 ignored issues
show
Bug introduced by
The variable $r does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
339 12
            if ($r == $row) {
340 12
                $this->deleteCacheData($coord);
341
            }
342
        }
343 12
    }
344
345
    /**
346
     * Remove a column, deleting all cells in that column
347
     *
348
     * @param string    $column    Column ID to remove
349
     */
350 9 View Code Duplication
    public function removeColumn($column)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
351
    {
352 9
        foreach ($this->getCellList() as $coord) {
353 9
            sscanf($coord, '%[A-Z]%d', $c, $r);
0 ignored issues
show
Bug introduced by
The variable $r does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
354 9
            if ($c == $column) {
355 9
                $this->deleteCacheData($coord);
356
            }
357
        }
358 9
    }
359
360
    /**
361
     * Identify whether the caching method is currently available
362
     * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
363
     *
364
     * @return    bool
365
     */
366 63
    public static function cacheMethodIsAvailable()
367
    {
368 63
        return true;
369
    }
370
}
371