5 * Copyright (c) 2006 - 2014 PHPExcel
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.
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.
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
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 ##VERSION##, ##DATE##
30 * PHPExcel_CachedObjectStorage_APC
33 * @package PHPExcel_CachedObjectStorage
34 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
36 class PHPExcel_CachedObjectStorage_APC
extends PHPExcel_CachedObjectStorage_CacheBase
implements PHPExcel_CachedObjectStorage_ICache
{
39 * Prefix used to uniquely identify cache data for this worksheet
44 private $_cachePrefix = null;
52 private $_cacheTime = 600;
56 * Store cell data in cache for the current cell object if it's "dirty",
57 * and the 'nullify' the current cell object
61 * @throws PHPExcel_Exception
63 protected function _storeData() {
64 if ($this->_currentCellIsDirty
&& !empty($this->_currentObjectID
)) {
65 $this->_currentObject
->detach();
67 if (!apc_store($this->_cachePrefix
.$this->_currentObjectID
.'.cache',serialize($this->_currentObject
),$this->_cacheTime
)) {
69 throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID
.' in APC');
71 $this->_currentCellIsDirty
= false;
73 $this->_currentObjectID
= $this->_currentObject
= null;
74 } // function _storeData()
78 * Add or Update a cell in cache identified by coordinate address
81 * @param string $pCoord Coordinate address of the cell to update
82 * @param PHPExcel_Cell $cell Cell to update
83 * @return PHPExcel_Cell
84 * @throws PHPExcel_Exception
86 public function addCacheData($pCoord, PHPExcel_Cell
$cell) {
87 if (($pCoord !== $this->_currentObjectID
) && ($this->_currentObjectID
!== null)) {
90 $this->_cellCache
[$pCoord] = true;
92 $this->_currentObjectID
= $pCoord;
93 $this->_currentObject
= $cell;
94 $this->_currentCellIsDirty
= true;
97 } // function addCacheData()
101 * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
104 * @param string $pCoord Coordinate address of the cell to check
105 * @throws PHPExcel_Exception
108 public function isDataSet($pCoord) {
109 // Check if the requested entry is the current object, or exists in the cache
110 if (parent
::isDataSet($pCoord)) {
111 if ($this->_currentObjectID
== $pCoord) {
114 // Check if the requested entry still exists in apc
115 $success = apc_fetch($this->_cachePrefix
.$pCoord.'.cache');
116 if ($success === FALSE) {
117 // Entry no longer exists in APC, so clear it from the cache array
118 parent
::deleteCacheData($pCoord);
119 throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');
124 } // function isDataSet()
128 * Get cell at a specific coordinate
131 * @param string $pCoord Coordinate of the cell
132 * @throws PHPExcel_Exception
133 * @return PHPExcel_Cell Cell that was found, or null if not found
135 public function getCacheData($pCoord) {
136 if ($pCoord === $this->_currentObjectID
) {
137 return $this->_currentObject
;
141 // Check if the entry that has been requested actually exists
142 if (parent
::isDataSet($pCoord)) {
143 $obj = apc_fetch($this->_cachePrefix
.$pCoord.'.cache');
144 if ($obj === FALSE) {
145 // Entry no longer exists in APC, so clear it from the cache array
146 parent
::deleteCacheData($pCoord);
147 throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');
150 // Return null if requested entry doesn't exist in cache
154 // Set current entry to the requested entry
155 $this->_currentObjectID
= $pCoord;
156 $this->_currentObject
= unserialize($obj);
157 // Re-attach this as the cell's parent
158 $this->_currentObject
->attach($this);
160 // Return requested entry
161 return $this->_currentObject
;
162 } // function getCacheData()
166 * Get a list of all cell addresses currently held in cache
170 public function getCellList() {
171 if ($this->_currentObjectID
!== null) {
175 return parent
::getCellList();
180 * Delete a cell in cache identified by coordinate address
183 * @param string $pCoord Coordinate address of the cell to delete
184 * @throws PHPExcel_Exception
186 public function deleteCacheData($pCoord) {
187 // Delete the entry from APC
188 apc_delete($this->_cachePrefix
.$pCoord.'.cache');
190 // Delete the entry from our cell address array
191 parent
::deleteCacheData($pCoord);
192 } // function deleteCacheData()
196 * Clone the cell collection
199 * @param PHPExcel_Worksheet $parent The new worksheet
200 * @throws PHPExcel_Exception
203 public function copyCellCollection(PHPExcel_Worksheet
$parent) {
204 parent
::copyCellCollection($parent);
205 // Get a new id for the new file name
206 $baseUnique = $this->_getUniqueID();
207 $newCachePrefix = substr(md5($baseUnique),0,8).'.';
208 $cacheList = $this->getCellList();
209 foreach($cacheList as $cellID) {
210 if ($cellID != $this->_currentObjectID
) {
211 $obj = apc_fetch($this->_cachePrefix
.$cellID.'.cache');
212 if ($obj === FALSE) {
213 // Entry no longer exists in APC, so clear it from the cache array
214 parent
::deleteCacheData($cellID);
215 throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in APC');
217 if (!apc_store($newCachePrefix.$cellID.'.cache',$obj,$this->_cacheTime
)) {
219 throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in APC');
223 $this->_cachePrefix
= $newCachePrefix;
224 } // function copyCellCollection()
228 * Clear the cell collection and disconnect from our parent
232 public function unsetWorksheetCells() {
233 if ($this->_currentObject
!== NULL) {
234 $this->_currentObject
->detach();
235 $this->_currentObject
= $this->_currentObjectID
= null;
238 // Flush the APC cache
241 $this->_cellCache
= array();
243 // detach ourself from the worksheet, so that it can then delete this object successfully
244 $this->_parent
= null;
245 } // function unsetWorksheetCells()
249 * Initialise this new cell collection
251 * @param PHPExcel_Worksheet $parent The worksheet for this cell collection
252 * @param array of mixed $arguments Additional initialisation arguments
254 public function __construct(PHPExcel_Worksheet
$parent, $arguments) {
255 $cacheTime = (isset($arguments['cacheTime'])) ?
$arguments['cacheTime'] : 600;
257 if ($this->_cachePrefix
=== NULL) {
258 $baseUnique = $this->_getUniqueID();
259 $this->_cachePrefix
= substr(md5($baseUnique),0,8).'.';
260 $this->_cacheTime
= $cacheTime;
262 parent
::__construct($parent);
264 } // function __construct()
268 * Destroy this cell collection
270 public function __destruct() {
271 $cacheList = $this->getCellList();
272 foreach($cacheList as $cellID) {
273 apc_delete($this->_cachePrefix
.$cellID.'.cache');
275 } // function __destruct()
279 * Identify whether the caching method is currently available
280 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
284 public static function cacheMethodIsAvailable() {
285 if (!function_exists('apc_store')) {
288 if (apc_sma_info() === FALSE) {