PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/framework/Kolab_Storage/lib/Horde/Kolab/Storage/List/Cache.php

https://github.com/imr/horde
PHP | 421 lines | 190 code | 37 blank | 194 comment | 21 complexity | 0b3c0e54efc63a6eb517b4aaa3620b00 MD5 | raw file
  1. <?php
  2. /**
  3. * A cache backend for Kolab storage list handlers.
  4. *
  5. * PHP version 5
  6. *
  7. * @category Kolab
  8. * @package Kolab_Storage
  9. * @author Gunnar Wrobel <wrobel@pardus.de>
  10. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  11. * @link http://pear.horde.org/index.php?package=Kolab_Storage
  12. */
  13. /**
  14. * A cache backend for Kolab storage list handlers.
  15. *
  16. * Copyright 2010-2014 Horde LLC (http://www.horde.org/)
  17. *
  18. * See the enclosed file COPYING for license information (LGPL). If you
  19. * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  20. *
  21. * @category Kolab
  22. * @package Kolab_Storage
  23. * @author Gunnar Wrobel <wrobel@pardus.de>
  24. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  25. * @link http://pear.horde.org/index.php?package=Kolab_Storage
  26. */
  27. class Horde_Kolab_Storage_List_Cache
  28. {
  29. /** Key for the folder list. */
  30. const FOLDERS = 'F';
  31. /** Key for the type list. */
  32. const TYPES = 'T';
  33. /** Key for the namespace data. */
  34. const NAME_SPACE = 'N';
  35. /** Key for the backend capabilities. */
  36. const SUPPORT = 'C';
  37. /** Holds query results. */
  38. const QUERIES = 'Q';
  39. /** Holds long term cache data. */
  40. const LONG_TERM = 'L';
  41. /** Key for the last time the list was synchronized. */
  42. const SYNC = 'S';
  43. /** Key for the cache format version. */
  44. const VERSION = 'V';
  45. /** Key for the connection ID associated with this list cache. */
  46. const ID = 'I';
  47. /** Holds the version number of the cache format. */
  48. const FORMAT_VERSION = '1';
  49. /**
  50. * The core cache driver.
  51. *
  52. * @var Horde_Kolab_Storage_Cache
  53. */
  54. private $_cache;
  55. /**
  56. * List parameters that will be recorded in the cache.
  57. *
  58. * @var array
  59. */
  60. private $_parameters;
  61. /**
  62. * List ID.
  63. *
  64. * @var string
  65. */
  66. private $_list_id;
  67. /**
  68. * The list data.
  69. *
  70. * @var array
  71. */
  72. private $_data = false;
  73. /**
  74. * Constructor.
  75. *
  76. * @param Horde_Kolab_Storage_Cache $cache The core cache driver.
  77. * @param array $parameters Connection parameters that
  78. * are only recorded and have
  79. * no further impact.
  80. */
  81. public function __construct(Horde_Kolab_Storage_Cache $cache,
  82. $parameters = array())
  83. {
  84. $this->_cache = $cache;
  85. $this->_parameters = $parameters;
  86. $this->_setListId();
  87. }
  88. /**
  89. * Compose the list key.
  90. */
  91. private function _setListId()
  92. {
  93. foreach (array('host', 'port', 'user') as $key) {
  94. $this->_cache->requireParameter($this->_parameters, 'list', $key);
  95. }
  96. ksort($this->_parameters);
  97. $this->_list_id = md5(serialize($this->_parameters));
  98. }
  99. /**
  100. * Return the ID for the list cache.
  101. *
  102. * @return string The unique ID for the list used when caching it.
  103. */
  104. public function getListId()
  105. {
  106. if ($this->_list_id === null) {
  107. throw new Horde_Kolab_Storage_Exception(
  108. 'You must set the ID of the list cache!'
  109. );
  110. }
  111. return $this->_list_id;
  112. }
  113. /**
  114. * Retrieve the cached list data.
  115. *
  116. * @return mixed The data of the object.
  117. */
  118. private function _load()
  119. {
  120. if ($this->_data === false) {
  121. $this->_data = unserialize($this->_cache->loadList($this->getListId()));
  122. if (!is_array($this->_data)
  123. || !isset($this->_data[self::SYNC])
  124. || !isset($this->_data[self::VERSION])
  125. || $this->_data[self::VERSION] != self::FORMAT_VERSION) {
  126. $this->_data = array();
  127. }
  128. }
  129. }
  130. /**
  131. * Cache the list data.
  132. *
  133. * @return NULL
  134. */
  135. public function save()
  136. {
  137. $this->_cache->storeList($this->getListId(), serialize($this->_data));
  138. }
  139. /**
  140. * Check if the cache has been initialized.
  141. *
  142. * @return boolean True if cache data is available.
  143. */
  144. public function isInitialized()
  145. {
  146. $this->_load();
  147. return !empty($this->_data);
  148. }
  149. /**
  150. * Returns the last sync stamp.
  151. *
  152. * @return string The last sync stamp.
  153. */
  154. public function getStamp()
  155. {
  156. $this->_load();
  157. if (isset($this->_data[self::SYNC])) {
  158. return $this->_data[self::SYNC];
  159. }
  160. return 0;
  161. }
  162. /**
  163. * Returns the list of folders from the cache.
  164. *
  165. * @return array The list of folders, represented as a list of strings.
  166. */
  167. public function getFolders()
  168. {
  169. $this->_load();
  170. if (isset($this->_data[self::FOLDERS])) {
  171. return $this->_data[self::FOLDERS];
  172. } else {
  173. throw new Horde_Kolab_Storage_Exception(
  174. sprintf('Missing cache data (Key: %s). Synchronize first!', self::FOLDERS)
  175. );
  176. }
  177. }
  178. /**
  179. * Returns if the folder type annotation is stored in the cache.
  180. *
  181. * @return boolean True if the type annotation is available.
  182. */
  183. public function hasFolderTypes()
  184. {
  185. $this->_load();
  186. if (isset($this->_data[self::TYPES])) {
  187. return true;
  188. }
  189. return false;
  190. }
  191. /**
  192. * Returns the folder type annotation from the cache.
  193. *
  194. * @return array The list folder types with the folder names as key and the
  195. * folder type as values.
  196. */
  197. public function getFolderTypes()
  198. {
  199. if ($this->hasFolderTypes()) {
  200. return $this->_data[self::TYPES];
  201. } else {
  202. throw new Horde_Kolab_Storage_Exception(
  203. sprintf('Missing cache data (Key: %s). Synchronize first!', self::TYPES)
  204. );
  205. }
  206. }
  207. /**
  208. * Returns if the namespace information is available.
  209. *
  210. * @return boolean True if the information exists in the cache.
  211. */
  212. public function hasNamespace()
  213. {
  214. $this->_load();
  215. return isset($this->_data[self::NAME_SPACE]);
  216. }
  217. /**
  218. * Return namespace information.
  219. *
  220. * @return mixed The namespace data.
  221. */
  222. public function getNamespace()
  223. {
  224. if ($this->hasNamespace()) {
  225. return $this->_data[self::NAME_SPACE];
  226. } else {
  227. throw new Horde_Kolab_Storage_Exception(
  228. 'Missing namespace data. Synchronize first!'
  229. );
  230. }
  231. }
  232. /**
  233. * Set namespace information.
  234. *
  235. * @param mixed $data The namespace data.
  236. *
  237. * @return NULL
  238. */
  239. public function setNamespace($data)
  240. {
  241. $this->_load();
  242. $this->_data[self::NAME_SPACE] = $data;
  243. }
  244. /**
  245. * Has the capability support already been cached?
  246. *
  247. * @return boolean True if the value is already in the cache.
  248. */
  249. public function issetSupport($capability)
  250. {
  251. $this->_load();
  252. return isset($this->_data[self::SUPPORT][$capability]);
  253. }
  254. /**
  255. * Has the list support for the requested capability?
  256. *
  257. * @param string $capability The name of the requested capability.
  258. *
  259. * @return boolean True if the backend supports the requested capability.
  260. */
  261. public function hasSupport($capability)
  262. {
  263. if ($this->issetSupport($capability)) {
  264. return $this->_data[self::SUPPORT][$capability];
  265. } else {
  266. throw new Horde_Kolab_Storage_Exception(
  267. 'Missing support data. Synchronize first!'
  268. );
  269. }
  270. }
  271. /**
  272. * Set if the list supports the given capability.
  273. *
  274. * @param string $capability The name of the requested capability.
  275. * @param boolean $flag True if the capability is supported.
  276. *
  277. * @return NULL
  278. */
  279. public function setSupport($capability, $flag)
  280. {
  281. $this->_load();
  282. $this->_data[self::SUPPORT][$capability] = $flag;
  283. }
  284. /**
  285. * Is the specified query data available in the cache?
  286. *
  287. * @param string $key The query key.
  288. *
  289. * @return boolean True in case cached data is available.
  290. */
  291. public function hasQuery($key)
  292. {
  293. $this->_load();
  294. return isset($this->_data[self::QUERIES][$key]);
  295. }
  296. /**
  297. * Return query information.
  298. *
  299. * @param string $key The query key.
  300. *
  301. * @return mixed The query data.
  302. */
  303. public function getQuery($key)
  304. {
  305. if ($this->hasQuery($key)) {
  306. return $this->_data[self::QUERIES][$key];
  307. } else {
  308. throw new Horde_Kolab_Storage_Exception(
  309. sprintf('Missing query cache data (Key: %s). Synchronize first!', $key)
  310. );
  311. }
  312. }
  313. /**
  314. * Set query information.
  315. *
  316. * @param string $key The query key.
  317. * @param mixed $data The query data.
  318. *
  319. * @return NULL
  320. */
  321. public function setQuery($key, $data)
  322. {
  323. $this->_load();
  324. $this->_data[self::QUERIES][$key] = $data;
  325. }
  326. /**
  327. * Is the specified long term data available in the cache?
  328. *
  329. * @param string $key The long term key.
  330. *
  331. * @return boolean True in case cached data is available.
  332. */
  333. public function hasLongTerm($key)
  334. {
  335. $this->_load();
  336. return isset($this->_data[self::LONG_TERM][$key]);
  337. }
  338. /**
  339. * Return long term information.
  340. *
  341. * @param string $key The long term key.
  342. *
  343. * @return mixed The long term data.
  344. */
  345. public function getLongTerm($key)
  346. {
  347. if ($this->hasLongTerm($key)) {
  348. return $this->_data[self::LONG_TERM][$key];
  349. } else {
  350. throw new Horde_Kolab_Storage_Exception(
  351. sprintf('Missing long term cache data (Key: %s). Synchronize first!', $key)
  352. );
  353. }
  354. }
  355. /**
  356. * Set long term information.
  357. *
  358. * @param string $key The long term key.
  359. * @param mixed $data The long term data.
  360. *
  361. * @return NULL
  362. */
  363. public function setLongTerm($key, $data)
  364. {
  365. $this->_load();
  366. $this->_data[self::LONG_TERM][$key] = $data;
  367. }
  368. /**
  369. * Store the folder list and folder type annotations in the cache.
  370. *
  371. * @return NULL
  372. */
  373. public function store(array $folders = null, array $types = null)
  374. {
  375. $this->_load();
  376. $this->_data[self::QUERIES] = array();
  377. $this->_data[self::FOLDERS] = $folders;
  378. $this->_data[self::TYPES] = $types;
  379. $this->_data[self::VERSION] = self::FORMAT_VERSION;
  380. $this->_data[self::ID] = serialize($this->_parameters);
  381. $this->_data[self::SYNC] = pack('Nn', time(), mt_rand());
  382. }
  383. }