Subversion Repositories eFlore/Applications.cel

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2388 jpm 1
<?php
2
/**
3
 * PHPExcel
4
 *
5
 * Copyright (c) 2006 - 2013 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 - 2013 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_Memcache
31
 *
32
 * @category   PHPExcel
33
 * @package    PHPExcel_CachedObjectStorage
34
 * @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)
35
 */
36
class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {
37
 
38
	/**
39
	 * Prefix used to uniquely identify cache data for this worksheet
40
	 *
41
	 * @var string
42
	 */
43
	private $_cachePrefix = null;
44
 
45
	/**
46
	 * Cache timeout
47
	 *
48
	 * @var integer
49
	 */
50
	private $_cacheTime = 600;
51
 
52
	/**
53
	 * Memcache interface
54
	 *
55
	 * @var resource
56
	 */
57
	private $_memcache = 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) {
69
			$this->_currentObject->detach();
70
 
71
			$obj = serialize($this->_currentObject);
72
			if (!$this->_memcache->replace($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) {
73
				if (!$this->_memcache->add($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) {
74
					$this->__destruct();
75
					throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in MemCache');
76
				}
77
			}
78
			$this->_currentCellIsDirty = false;
79
		}
80
		$this->_currentObjectID = $this->_currentObject = null;
81
	}	//	function _storeData()
82
 
83
 
84
    /**
85
     * Add or Update a cell in cache identified by coordinate address
86
     *
87
     * @param	string			$pCoord		Coordinate address of the cell to update
88
     * @param	PHPExcel_Cell	$cell		Cell to update
89
	 * @return	void
90
     * @throws	PHPExcel_Exception
91
     */
92
	public function addCacheData($pCoord, PHPExcel_Cell $cell) {
93
		if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {
94
			$this->_storeData();
95
		}
96
		$this->_cellCache[$pCoord] = true;
97
 
98
		$this->_currentObjectID = $pCoord;
99
		$this->_currentObject = $cell;
100
		$this->_currentCellIsDirty = true;
101
 
102
		return $cell;
103
	}	//	function addCacheData()
104
 
105
 
106
	/**
107
	 * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
108
	 *
109
	 * @param	string		$pCoord		Coordinate address of the cell to check
110
	 * @return	void
111
	 * @return	boolean
112
	 */
113
	public function isDataSet($pCoord) {
114
		//	Check if the requested entry is the current object, or exists in the cache
115
		if (parent::isDataSet($pCoord)) {
116
			if ($this->_currentObjectID == $pCoord) {
117
				return true;
118
			}
119
			//	Check if the requested entry still exists in Memcache
120
			$success = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache');
121
			if ($success === false) {
122
				//	Entry no longer exists in Memcache, so clear it from the cache array
123
				parent::deleteCacheData($pCoord);
124
				throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache');
125
			}
126
			return true;
127
		}
128
		return false;
129
	}	//	function isDataSet()
130
 
131
 
132
	/**
133
     * Get cell at a specific coordinate
134
     *
135
     * @param 	string 			$pCoord		Coordinate of the cell
136
     * @throws 	PHPExcel_Exception
137
     * @return 	PHPExcel_Cell 	Cell that was found, or null if not found
138
     */
139
	public function getCacheData($pCoord) {
140
		if ($pCoord === $this->_currentObjectID) {
141
			return $this->_currentObject;
142
		}
143
		$this->_storeData();
144
 
145
		//	Check if the entry that has been requested actually exists
146
		if (parent::isDataSet($pCoord)) {
147
			$obj = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache');
148
			if ($obj === false) {
149
				//	Entry no longer exists in Memcache, so clear it from the cache array
150
				parent::deleteCacheData($pCoord);
151
				throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache');
152
			}
153
		} else {
154
			//	Return null if requested entry doesn't exist in cache
155
			return null;
156
		}
157
 
158
		//	Set current entry to the requested entry
159
		$this->_currentObjectID = $pCoord;
160
		$this->_currentObject = unserialize($obj);
161
        //    Re-attach this as the cell's parent
162
        $this->_currentObject->attach($this);
163
 
164
		//	Return requested entry
165
		return $this->_currentObject;
166
	}	//	function getCacheData()
167
 
168
 
169
	/**
170
	 * Get a list of all cell addresses currently held in cache
171
	 *
172
	 * @return  array of string
173
	 */
174
	public function getCellList() {
175
		if ($this->_currentObjectID !== null) {
176
			$this->_storeData();
177
		}
178
 
179
		return parent::getCellList();
180
	}
181
 
182
 
183
    /**
184
     * Delete a cell in cache identified by coordinate address
185
     *
186
     * @param	string			$pCoord		Coordinate address of the cell to delete
187
     * @throws	PHPExcel_Exception
188
     */
189
	public function deleteCacheData($pCoord) {
190
		//	Delete the entry from Memcache
191
		$this->_memcache->delete($this->_cachePrefix.$pCoord.'.cache');
192
 
193
		//	Delete the entry from our cell address array
194
		parent::deleteCacheData($pCoord);
195
	}	//	function deleteCacheData()
196
 
197
 
198
	/**
199
	 * Clone the cell collection
200
	 *
201
	 * @param	PHPExcel_Worksheet	$parent		The new worksheet
202
	 * @return	void
203
	 */
204
	public function copyCellCollection(PHPExcel_Worksheet $parent) {
205
		parent::copyCellCollection($parent);
206
		//	Get a new id for the new file name
207
		$baseUnique = $this->_getUniqueID();
208
		$newCachePrefix = substr(md5($baseUnique),0,8).'.';
209
		$cacheList = $this->getCellList();
210
		foreach($cacheList as $cellID) {
211
			if ($cellID != $this->_currentObjectID) {
212
				$obj = $this->_memcache->get($this->_cachePrefix.$cellID.'.cache');
213
				if ($obj === false) {
214
					//	Entry no longer exists in Memcache, so clear it from the cache array
215
					parent::deleteCacheData($cellID);
216
					throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in MemCache');
217
				}
218
				if (!$this->_memcache->add($newCachePrefix.$cellID.'.cache',$obj,NULL,$this->_cacheTime)) {
219
					$this->__destruct();
220
					throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in MemCache');
221
				}
222
			}
223
		}
224
		$this->_cachePrefix = $newCachePrefix;
225
	}	//	function copyCellCollection()
226
 
227
 
228
	/**
229
	 * Clear the cell collection and disconnect from our parent
230
	 *
231
	 * @return	void
232
	 */
233
	public function unsetWorksheetCells() {
234
		if(!is_null($this->_currentObject)) {
235
			$this->_currentObject->detach();
236
			$this->_currentObject = $this->_currentObjectID = null;
237
		}
238
 
239
		//	Flush the Memcache cache
240
		$this->__destruct();
241
 
242
		$this->_cellCache = array();
243
 
244
		//	detach ourself from the worksheet, so that it can then delete this object successfully
245
		$this->_parent = null;
246
	}	//	function unsetWorksheetCells()
247
 
248
 
249
	/**
250
	 * Initialise this new cell collection
251
	 *
252
	 * @param	PHPExcel_Worksheet	$parent		The worksheet for this cell collection
253
	 * @param	array of mixed		$arguments	Additional initialisation arguments
254
	 */
255
	public function __construct(PHPExcel_Worksheet $parent, $arguments) {
256
		$memcacheServer	= (isset($arguments['memcacheServer']))	? $arguments['memcacheServer']	: 'localhost';
257
		$memcachePort	= (isset($arguments['memcachePort']))	? $arguments['memcachePort']	: 11211;
258
		$cacheTime		= (isset($arguments['cacheTime']))		? $arguments['cacheTime']		: 600;
259
 
260
		if (is_null($this->_cachePrefix)) {
261
			$baseUnique = $this->_getUniqueID();
262
			$this->_cachePrefix = substr(md5($baseUnique),0,8).'.';
263
 
264
			//	Set a new Memcache object and connect to the Memcache server
265
			$this->_memcache = new Memcache();
266
			if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) {
267
				throw new PHPExcel_Exception('Could not connect to MemCache server at '.$memcacheServer.':'.$memcachePort);
268
			}
269
			$this->_cacheTime = $cacheTime;
270
 
271
			parent::__construct($parent);
272
		}
273
	}	//	function __construct()
274
 
275
 
276
	/**
277
	 * Memcache error handler
278
	 *
279
	 * @param	string	$host		Memcache server
280
	 * @param	integer	$port		Memcache port
281
     * @throws	PHPExcel_Exception
282
	 */
283
	public function failureCallback($host, $port) {
284
		throw new PHPExcel_Exception('memcache '.$host.':'.$port.' failed');
285
	}
286
 
287
 
288
	/**
289
	 * Destroy this cell collection
290
	 */
291
	public function __destruct() {
292
		$cacheList = $this->getCellList();
293
		foreach($cacheList as $cellID) {
294
			$this->_memcache->delete($this->_cachePrefix.$cellID.'.cache');
295
		}
296
	}	//	function __destruct()
297
 
298
	/**
299
	 * Identify whether the caching method is currently available
300
	 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build
301
	 *
302
	 * @return	boolean
303
	 */
304
	public static function cacheMethodIsAvailable() {
305
		if (!function_exists('memcache_add')) {
306
			return false;
307
		}
308
 
309
		return true;
310
	}
311
 
312
}