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 ##VERSION##, ##DATE## 26 */ 27 28 29/** 30 * PHPExcel_CachedObjectStorage_DiscISAM 31 * 32 * @category PHPExcel 33 * @package PHPExcel_CachedObjectStorage 34 * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) 35 */ 36class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache { 37 38 /** 39 * Name of the file for this cache 40 * 41 * @var string 42 */ 43 private $_fileName = NULL; 44 45 /** 46 * File handle for this cache file 47 * 48 * @var resource 49 */ 50 private $_fileHandle = NULL; 51 52 /** 53 * Directory/Folder where the cache file is located 54 * 55 * @var string 56 */ 57 private $_cacheDirectory = NULL; 58 59 60 /** 61 * Store cell data in cache for the current cell object if it's "dirty", 62 * and the 'nullify' the current cell object 63 * 64 * @return void 65 * @throws PHPExcel_Exception 66 */ 67 protected function _storeData() { 68 if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) { 69 $this->_currentObject->detach(); 70 71 fseek($this->_fileHandle,0,SEEK_END); 72 $offset = ftell($this->_fileHandle); 73 fwrite($this->_fileHandle, serialize($this->_currentObject)); 74 $this->_cellCache[$this->_currentObjectID] = array('ptr' => $offset, 75 'sz' => ftell($this->_fileHandle) - $offset 76 ); 77 $this->_currentCellIsDirty = false; 78 } 79 $this->_currentObjectID = $this->_currentObject = null; 80 } // function _storeData() 81 82 83 /** 84 * Add or Update a cell in cache identified by coordinate address 85 * 86 * @param string $pCoord Coordinate address of the cell to update 87 * @param PHPExcel_Cell $cell Cell to update 88 * @return PHPExcel_Cell 89 * @throws PHPExcel_Exception 90 */ 91 public function addCacheData($pCoord, PHPExcel_Cell $cell) { 92 if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { 93 $this->_storeData(); 94 } 95 96 $this->_currentObjectID = $pCoord; 97 $this->_currentObject = $cell; 98 $this->_currentCellIsDirty = true; 99 100 return $cell; 101 } // function addCacheData() 102 103 104 /** 105 * Get cell at a specific coordinate 106 * 107 * @param string $pCoord Coordinate of the cell 108 * @throws PHPExcel_Exception 109 * @return PHPExcel_Cell Cell that was found, or null if not found 110 */ 111 public function getCacheData($pCoord) { 112 if ($pCoord === $this->_currentObjectID) { 113 return $this->_currentObject; 114 } 115 $this->_storeData(); 116 117 // Check if the entry that has been requested actually exists 118 if (!isset($this->_cellCache[$pCoord])) { 119 // Return null if requested entry doesn't exist in cache 120 return null; 121 } 122 123 // Set current entry to the requested entry 124 $this->_currentObjectID = $pCoord; 125 fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']); 126 $this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz'])); 127 // Re-attach this as the cell's parent 128 $this->_currentObject->attach($this); 129 130 // Return requested entry 131 return $this->_currentObject; 132 } // function getCacheData() 133 134 135 /** 136 * Get a list of all cell addresses currently held in cache 137 * 138 * @return string[] 139 */ 140 public function getCellList() { 141 if ($this->_currentObjectID !== null) { 142 $this->_storeData(); 143 } 144 145 return parent::getCellList(); 146 } 147 148 149 /** 150 * Clone the cell collection 151 * 152 * @param PHPExcel_Worksheet $parent The new worksheet 153 * @return void 154 */ 155 public function copyCellCollection(PHPExcel_Worksheet $parent) { 156 parent::copyCellCollection($parent); 157 // Get a new id for the new file name 158 $baseUnique = $this->_getUniqueID(); 159 $newFileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; 160 // Copy the existing cell cache file 161 copy ($this->_fileName,$newFileName); 162 $this->_fileName = $newFileName; 163 // Open the copied cell cache file 164 $this->_fileHandle = fopen($this->_fileName,'a+'); 165 } // function copyCellCollection() 166 167 168 /** 169 * Clear the cell collection and disconnect from our parent 170 * 171 * @return void 172 */ 173 public function unsetWorksheetCells() { 174 if(!is_null($this->_currentObject)) { 175 $this->_currentObject->detach(); 176 $this->_currentObject = $this->_currentObjectID = null; 177 } 178 $this->_cellCache = array(); 179 180 // detach ourself from the worksheet, so that it can then delete this object successfully 181 $this->_parent = null; 182 183 // Close down the temporary cache file 184 $this->__destruct(); 185 } // function unsetWorksheetCells() 186 187 188 /** 189 * Initialise this new cell collection 190 * 191 * @param PHPExcel_Worksheet $parent The worksheet for this cell collection 192 * @param array of mixed $arguments Additional initialisation arguments 193 */ 194 public function __construct(PHPExcel_Worksheet $parent, $arguments) { 195 $this->_cacheDirectory = ((isset($arguments['dir'])) && ($arguments['dir'] !== NULL)) 196 ? $arguments['dir'] 197 : PHPExcel_Shared_File::sys_get_temp_dir(); 198 199 parent::__construct($parent); 200 if (is_null($this->_fileHandle)) { 201 $baseUnique = $this->_getUniqueID(); 202 $this->_fileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; 203 $this->_fileHandle = fopen($this->_fileName,'a+'); 204 } 205 } // function __construct() 206 207 208 /** 209 * Destroy this cell collection 210 */ 211 public function __destruct() { 212 if (!is_null($this->_fileHandle)) { 213 fclose($this->_fileHandle); 214 unlink($this->_fileName); 215 } 216 $this->_fileHandle = null; 217 } // function __destruct() 218 219} 220