DiscISAM.php 6.8 KB

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