/framework/vendor/swift/lib/classes/Swift/KeyCache/DiskKeyCache.php

http://zoop.googlecode.com/ · PHP · 316 lines · 176 code · 23 blank · 117 comment · 22 complexity · a68e5e10fdb4d46b53f1e9ebd9ab8d71 MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of SwiftMailer.
  4. * (c) 2004-2009 Chris Corbyn
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. //@require 'Swift/KeyCache.php';
  10. //@require 'Swift/KeyCacheInputStream.php';
  11. //@require 'Swift/InputByteStream.php';
  12. //@require 'Swift/OutputByteStrean.php';
  13. //@require 'Swift/SwiftException.php';
  14. //@require 'Swift/IoException.php';
  15. /**
  16. * A KeyCache which streams to and from disk.
  17. * @package Swift
  18. * @subpackage KeyCache
  19. * @author Chris Corbyn
  20. */
  21. class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache
  22. {
  23. /** Signal to place pointer at start of file */
  24. const POSITION_START = 0;
  25. /** Signal to place pointer at end of file */
  26. const POSITION_END = 1;
  27. /**
  28. * An InputStream for cloning.
  29. * @var Swift_KeyCache_KeyCacheInputStream
  30. * @access private
  31. */
  32. private $_stream;
  33. /**
  34. * A path to write to.
  35. * @var string
  36. * @access private
  37. */
  38. private $_path;
  39. /**
  40. * Stored keys.
  41. * @var array
  42. * @access private
  43. */
  44. private $_keys = array();
  45. /**
  46. * Will be true if magic_quotes_runtime is turned on.
  47. * @var boolean
  48. * @access private
  49. */
  50. private $_quotes = false;
  51. /**
  52. * Create a new DiskKeyCache with the given $stream for cloning to make
  53. * InputByteStreams, and the given $path to save to.
  54. * @param Swift_KeyCache_KeyCacheInputStream $stream
  55. * @param string $path to save to
  56. */
  57. public function __construct(Swift_KeyCache_KeyCacheInputStream $stream, $path)
  58. {
  59. $this->_stream = $stream;
  60. $this->_path = $path;
  61. $this->_quotes = get_magic_quotes_runtime();
  62. }
  63. /**
  64. * Set a string into the cache under $itemKey for the namespace $nsKey.
  65. * @param string $nsKey
  66. * @param string $itemKey
  67. * @param string $string
  68. * @param int $mode
  69. * @throws Swift_IoException
  70. * @see MODE_WRITE, MODE_APPEND
  71. */
  72. public function setString($nsKey, $itemKey, $string, $mode)
  73. {
  74. $this->_prepareCache($nsKey);
  75. switch ($mode)
  76. {
  77. case self::MODE_WRITE:
  78. $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
  79. break;
  80. case self::MODE_APPEND:
  81. $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
  82. break;
  83. default:
  84. throw new Swift_SwiftException(
  85. 'Invalid mode [' . $mode . '] used to set nsKey='.
  86. $nsKey . ', itemKey=' . $itemKey
  87. );
  88. break;
  89. }
  90. fwrite($fp, $string);
  91. }
  92. /**
  93. * Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
  94. * @param string $nsKey
  95. * @param string $itemKey
  96. * @param Swift_OutputByteStream $os
  97. * @param int $mode
  98. * @see MODE_WRITE, MODE_APPEND
  99. * @throws Swift_IoException
  100. */
  101. public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os,
  102. $mode)
  103. {
  104. $this->_prepareCache($nsKey);
  105. switch ($mode)
  106. {
  107. case self::MODE_WRITE:
  108. $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
  109. break;
  110. case self::MODE_APPEND:
  111. $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
  112. break;
  113. default:
  114. throw new Swift_SwiftException(
  115. 'Invalid mode [' . $mode . '] used to set nsKey='.
  116. $nsKey . ', itemKey=' . $itemKey
  117. );
  118. break;
  119. }
  120. while (false !== $bytes = $os->read(8192))
  121. {
  122. fwrite($fp, $bytes);
  123. }
  124. }
  125. /**
  126. * Provides a ByteStream which when written to, writes data to $itemKey.
  127. * NOTE: The stream will always write in append mode.
  128. * @param string $nsKey
  129. * @param string $itemKey
  130. * @return Swift_InputByteStream
  131. */
  132. public function getInputByteStream($nsKey, $itemKey,
  133. Swift_InputByteStream $writeThrough = null)
  134. {
  135. $is = clone $this->_stream;
  136. $is->setKeyCache($this);
  137. $is->setNsKey($nsKey);
  138. $is->setItemKey($itemKey);
  139. if (isset($writeThrough))
  140. {
  141. $is->setWriteThroughStream($writeThrough);
  142. }
  143. return $is;
  144. }
  145. /**
  146. * Get data back out of the cache as a string.
  147. * @param string $nsKey
  148. * @param string $itemKey
  149. * @return string
  150. * @throws Swift_IoException
  151. */
  152. public function getString($nsKey, $itemKey)
  153. {
  154. $this->_prepareCache($nsKey);
  155. if ($this->hasKey($nsKey, $itemKey))
  156. {
  157. $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
  158. if ($this->_quotes)
  159. {
  160. set_magic_quotes_runtime(0);
  161. }
  162. $str = '';
  163. while (!feof($fp) && false !== $bytes = fread($fp, 8192))
  164. {
  165. $str .= $bytes;
  166. }
  167. if ($this->_quotes)
  168. {
  169. set_magic_quotes_runtime(1);
  170. }
  171. return $str;
  172. }
  173. }
  174. /**
  175. * Get data back out of the cache as a ByteStream.
  176. * @param string $nsKey
  177. * @param string $itemKey
  178. * @param Swift_InputByteStream $is to write the data to
  179. */
  180. public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
  181. {
  182. if ($this->hasKey($nsKey, $itemKey))
  183. {
  184. $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
  185. if ($this->_quotes)
  186. {
  187. set_magic_quotes_runtime(0);
  188. }
  189. while (!feof($fp) && false !== $bytes = fread($fp, 8192))
  190. {
  191. $is->write($bytes);
  192. }
  193. if ($this->_quotes)
  194. {
  195. set_magic_quotes_runtime(1);
  196. }
  197. }
  198. }
  199. /**
  200. * Check if the given $itemKey exists in the namespace $nsKey.
  201. * @param string $nsKey
  202. * @param string $itemKey
  203. * @return boolean
  204. */
  205. public function hasKey($nsKey, $itemKey)
  206. {
  207. return is_file($this->_path . '/' . $nsKey . '/' . $itemKey);
  208. }
  209. /**
  210. * Clear data for $itemKey in the namespace $nsKey if it exists.
  211. * @param string $nsKey
  212. * @param string $itemKey
  213. */
  214. public function clearKey($nsKey, $itemKey)
  215. {
  216. if ($this->hasKey($nsKey, $itemKey))
  217. {
  218. $fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
  219. fclose($fp);
  220. unlink($this->_path . '/' . $nsKey . '/' . $itemKey);
  221. }
  222. unset($this->_keys[$nsKey][$itemKey]);
  223. }
  224. /**
  225. * Clear all data in the namespace $nsKey if it exists.
  226. * @param string $nsKey
  227. */
  228. public function clearAll($nsKey)
  229. {
  230. if (array_key_exists($nsKey, $this->_keys))
  231. {
  232. foreach ($this->_keys[$nsKey] as $itemKey=>$null)
  233. {
  234. $this->clearKey($nsKey, $itemKey);
  235. }
  236. rmdir($this->_path . '/' . $nsKey);
  237. unset($this->_keys[$nsKey]);
  238. }
  239. }
  240. // -- Private methods
  241. /**
  242. * Initialize the namespace of $nsKey if needed.
  243. * @param string $nsKey
  244. * @access private
  245. */
  246. private function _prepareCache($nsKey)
  247. {
  248. $cacheDir = $this->_path . '/' . $nsKey;
  249. if (!is_dir($cacheDir))
  250. {
  251. if (!mkdir($cacheDir))
  252. {
  253. throw new Swift_IoException('Failed to create cache directory ' . $cacheDir);
  254. }
  255. $this->_keys[$nsKey] = array();
  256. }
  257. }
  258. /**
  259. * Get a file handle on the cache item.
  260. * @param string $nsKey
  261. * @param string $itemKey
  262. * @param int $position
  263. * @return resource
  264. * @access private
  265. */
  266. private function _getHandle($nsKey, $itemKey, $position)
  267. {
  268. if (!isset($this->_keys[$nsKey]) || !array_key_exists($itemKey, $this->_keys[$nsKey]))
  269. {
  270. $fp = fopen($this->_path . '/' . $nsKey . '/' . $itemKey, 'w+b');
  271. $this->_keys[$nsKey][$itemKey] = $fp;
  272. }
  273. if (self::POSITION_START == $position)
  274. {
  275. fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_SET);
  276. }
  277. else
  278. {
  279. fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_END);
  280. }
  281. return $this->_keys[$nsKey][$itemKey];
  282. }
  283. /**
  284. * Destructor.
  285. */
  286. public function __destruct()
  287. {
  288. foreach ($this->_keys as $nsKey=>$null)
  289. {
  290. $this->clearAll($nsKey);
  291. }
  292. }
  293. }