1: <?php
2: /**
3: * PHPExcel
4: *
5: * Copyright (c) 2006 - 2014 PHPExcel
6: *
7: * This library is free software; you can redistribute it and/or
8: * modify it under the terms of the GNU Lesser General Public
9: * License as published by the Free Software Foundation; either
10: * version 2.1 of the License, or (at your option) any later version.
11: *
12: * This library is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * Lesser General Public License for more details.
16: *
17: * You should have received a copy of the GNU Lesser General Public
18: * License along with this library; if not, write to the Free Software
19: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20: *
21: * @category PHPExcel
22: * @package PHPExcel_CachedObjectStorage
23: * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24: * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
25: * @version 1.8.0, 2014-03-02
26: */
27:
28:
29: /**
30: * PHPExcel_CachedObjectStorage_CacheBase
31: *
32: * @category PHPExcel
33: * @package PHPExcel_CachedObjectStorage
34: * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
35: */
36: abstract class PHPExcel_CachedObjectStorage_CacheBase {
37:
38: /**
39: * Parent worksheet
40: *
41: * @var PHPExcel_Worksheet
42: */
43: protected $_parent;
44:
45: /**
46: * The currently active Cell
47: *
48: * @var PHPExcel_Cell
49: */
50: protected $_currentObject = null;
51:
52: /**
53: * Coordinate address of the currently active Cell
54: *
55: * @var string
56: */
57: protected $_currentObjectID = null;
58:
59:
60: /**
61: * Flag indicating whether the currently active Cell requires saving
62: *
63: * @var boolean
64: */
65: protected $_currentCellIsDirty = true;
66:
67: /**
68: * An array of cells or cell pointers for the worksheet cells held in this cache,
69: * and indexed by their coordinate address within the worksheet
70: *
71: * @var array of mixed
72: */
73: protected $_cellCache = array();
74:
75:
76: /**
77: * Initialise this new cell collection
78: *
79: * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
80: */
81: public function __construct(PHPExcel_Worksheet $parent) {
82: // Set our parent worksheet.
83: // This is maintained within the cache controller to facilitate re-attaching it to PHPExcel_Cell objects when
84: // they are woken from a serialized state
85: $this->_parent = $parent;
86: } // function __construct()
87:
88:
89: /**
90: * Return the parent worksheet for this cell collection
91: *
92: * @return PHPExcel_Worksheet
93: */
94: public function getParent()
95: {
96: return $this->_parent;
97: }
98:
99: /**
100: * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
101: *
102: * @param string $pCoord Coordinate address of the cell to check
103: * @return boolean
104: */
105: public function isDataSet($pCoord) {
106: if ($pCoord === $this->_currentObjectID) {
107: return true;
108: }
109: // Check if the requested entry exists in the cache
110: return isset($this->_cellCache[$pCoord]);
111: } // function isDataSet()
112:
113:
114: /**
115: * Move a cell object from one address to another
116: *
117: * @param string $fromAddress Current address of the cell to move
118: * @param string $toAddress Destination address of the cell to move
119: * @return boolean
120: */
121: public function moveCell($fromAddress, $toAddress) {
122: if ($fromAddress === $this->_currentObjectID) {
123: $this->_currentObjectID = $toAddress;
124: }
125: $this->_currentCellIsDirty = true;
126: if (isset($this->_cellCache[$fromAddress])) {
127: $this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress];
128: unset($this->_cellCache[$fromAddress]);
129: }
130:
131: return TRUE;
132: } // function moveCell()
133:
134:
135: /**
136: * Add or Update a cell in cache
137: *
138: * @param PHPExcel_Cell $cell Cell to update
139: * @return void
140: * @throws PHPExcel_Exception
141: */
142: public function updateCacheData(PHPExcel_Cell $cell) {
143: return $this->addCacheData($cell->getCoordinate(),$cell);
144: } // function updateCacheData()
145:
146:
147: /**
148: * Delete a cell in cache identified by coordinate address
149: *
150: * @param string $pCoord Coordinate address of the cell to delete
151: * @throws PHPExcel_Exception
152: */
153: public function deleteCacheData($pCoord) {
154: if ($pCoord === $this->_currentObjectID) {
155: $this->_currentObject->detach();
156: $this->_currentObjectID = $this->_currentObject = null;
157: }
158:
159: if (is_object($this->_cellCache[$pCoord])) {
160: $this->_cellCache[$pCoord]->detach();
161: unset($this->_cellCache[$pCoord]);
162: }
163: $this->_currentCellIsDirty = false;
164: } // function deleteCacheData()
165:
166:
167: /**
168: * Get a list of all cell addresses currently held in cache
169: *
170: * @return array of string
171: */
172: public function getCellList() {
173: return array_keys($this->_cellCache);
174: } // function getCellList()
175:
176:
177: /**
178: * Sort the list of all cell addresses currently held in cache by row and column
179: *
180: * @return void
181: */
182: public function getSortedCellList() {
183: $sortKeys = array();
184: foreach ($this->getCellList() as $coord) {
185: sscanf($coord,'%[A-Z]%d', $column, $row);
186: $sortKeys[sprintf('%09d%3s',$row,$column)] = $coord;
187: }
188: ksort($sortKeys);
189:
190: return array_values($sortKeys);
191: } // function sortCellList()
192:
193:
194:
195: /**
196: * Get highest worksheet column and highest row that have cell records
197: *
198: * @return array Highest column name and highest row number
199: */
200: public function getHighestRowAndColumn()
201: {
202: // Lookup highest column and highest row
203: $col = array('A' => '1A');
204: $row = array(1);
205: foreach ($this->getCellList() as $coord) {
206: sscanf($coord,'%[A-Z]%d', $c, $r);
207: $row[$r] = $r;
208: $col[$c] = strlen($c).$c;
209: }
210: if (!empty($row)) {
211: // Determine highest column and row
212: $highestRow = max($row);
213: $highestColumn = substr(max($col),1);
214: }
215:
216: return array( 'row' => $highestRow,
217: 'column' => $highestColumn
218: );
219: }
220:
221:
222: /**
223: * Return the cell address of the currently active cell object
224: *
225: * @return string
226: */
227: public function getCurrentAddress()
228: {
229: return $this->_currentObjectID;
230: }
231:
232: /**
233: * Return the column address of the currently active cell object
234: *
235: * @return string
236: */
237: public function getCurrentColumn()
238: {
239: sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row);
240: return $column;
241: }
242:
243: /**
244: * Return the row address of the currently active cell object
245: *
246: * @return string
247: */
248: public function getCurrentRow()
249: {
250: sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row);
251: return $row;
252: }
253:
254: /**
255: * Get highest worksheet column
256: *
257: * @param string $row Return the highest column for the specified row,
258: * or the highest column of any row if no row number is passed
259: * @return string Highest column name
260: */
261: public function getHighestColumn($row = null)
262: {
263: if ($row == null) {
264: $colRow = $this->getHighestRowAndColumn();
265: return $colRow['column'];
266: }
267:
268: $columnList = array(1);
269: foreach ($this->getCellList() as $coord) {
270: sscanf($coord,'%[A-Z]%d', $c, $r);
271: if ($r != $row) {
272: continue;
273: }
274: $columnList[] = PHPExcel_Cell::columnIndexFromString($c);
275: }
276: return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1);
277: }
278:
279: /**
280: * Get highest worksheet row
281: *
282: * @param string $column Return the highest row for the specified column,
283: * or the highest row of any column if no column letter is passed
284: * @return int Highest row number
285: */
286: public function getHighestRow($column = null)
287: {
288: if ($column == null) {
289: $colRow = $this->getHighestRowAndColumn();
290: return $colRow['row'];
291: }
292:
293: $rowList = array(0);
294: foreach ($this->getCellList() as $coord) {
295: sscanf($coord,'%[A-Z]%d', $c, $r);
296: if ($c != $column) {
297: continue;
298: }
299: $rowList[] = $r;
300: }
301:
302: return max($rowList);
303: }
304:
305:
306: /**
307: * Generate a unique ID for cache referencing
308: *
309: * @return string Unique Reference
310: */
311: protected function _getUniqueID() {
312: if (function_exists('posix_getpid')) {
313: $baseUnique = posix_getpid();
314: } else {
315: $baseUnique = mt_rand();
316: }
317: return uniqid($baseUnique,true);
318: }
319:
320: /**
321: * Clone the cell collection
322: *
323: * @param PHPExcel_Worksheet $parent The new worksheet
324: * @return void
325: */
326: public function copyCellCollection(PHPExcel_Worksheet $parent) {
327: $this->_currentCellIsDirty;
328: $this->_storeData();
329:
330: $this->_parent = $parent;
331: if (($this->_currentObject !== NULL) && (is_object($this->_currentObject))) {
332: $this->_currentObject->attach($this);
333: }
334: } // function copyCellCollection()
335:
336:
337: /**
338: * Identify whether the caching method is currently available
339: * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
340: *
341: * @return boolean
342: */
343: public static function cacheMethodIsAvailable() {
344: return true;
345: }
346:
347: }
348: