PageRenderTime 23ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/imr/horde
PHP | 305 lines | 172 code | 24 blank | 109 comment | 15 complexity | 930d75f614b9704df280fa445b7de1d9 MD5 | raw file
  1. <?php
  2. /**
  3. * Handles synchronization of the list query cache.
  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. * Handles synchronization of the list query cache.
  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_Query_List_Cache_Synchronization
  28. {
  29. /**
  30. * The IMAP driver to query the backend.
  31. *
  32. * @var Horde_Kolab_Storage_Driver
  33. */
  34. private $_driver;
  35. /**
  36. * The factory for folder types.
  37. *
  38. * @var Horde_Kolab_Storage_Folder_Types
  39. */
  40. private $_folder_types;
  41. /**
  42. * Handles default folders.
  43. *
  44. * @var Horde_Kolab_Storage_List_Query_List_Defaults
  45. */
  46. private $_defaults;
  47. /**
  48. * The list cache.
  49. *
  50. * @var Horde_Kolab_Storage_List_Cache
  51. */
  52. private $_cache;
  53. /**
  54. * Constructor.
  55. *
  56. * @param Horde_Kolab_Storage_Driver $driver The driver to access the backend.
  57. * @param Horde_Kolab_Storage_Folder_Types $types Handler of folder types.
  58. */
  59. public function __construct(Horde_Kolab_Storage_Driver $driver,
  60. Horde_Kolab_Storage_Folder_Types $types,
  61. Horde_Kolab_Storage_List_Query_List_Defaults $defaults)
  62. {
  63. $this->_driver = $driver;
  64. $this->_folder_types = $types;
  65. $this->_defaults = $defaults;
  66. }
  67. /**
  68. * Set the list cache.
  69. *
  70. * @param Horde_Kolab_Storage_List_Cache $cache The reference to the cache
  71. * that should reveive any updates.
  72. */
  73. public function setCache($cache)
  74. {
  75. $this->_cache = $cache;
  76. }
  77. /**
  78. * Synchronize the query data with the information from the backend.
  79. */
  80. public function synchronize()
  81. {
  82. $this->_synchronize(
  83. $this->_driver->getNamespace(),
  84. $this->_driver->listFolders(),
  85. $this->_driver->listAnnotation(
  86. Horde_Kolab_Storage_List_Query_List::ANNOTATION_FOLDER_TYPE
  87. )
  88. );
  89. }
  90. /**
  91. * Synchronize based on the given folder list.
  92. *
  93. * @param Horde_Kolab_Storage_List_Cache $cache The reference to the cache
  94. * that should reveive the update.
  95. * @param Horde_Kolab_Storage_Folder_Namespace $namespace The namespace handler
  96. * @param array $folder_list The list of folders.
  97. * @param array $annotation The list of folder annotations.
  98. *
  99. * @return NULL
  100. */
  101. public function _synchronize(Horde_Kolab_Storage_Folder_Namespace $namespace,
  102. $folder_list,
  103. $annotations)
  104. {
  105. $folders = array();
  106. $owners = array();
  107. $types = array();
  108. $by_type = array();
  109. $mail_type = $this->_folder_types->create('mail');
  110. $this->_defaults->reset();
  111. foreach ($folder_list as $folder) {
  112. $folder = strval($folder);
  113. if (!isset($annotations[$folder])) {
  114. $type = $mail_type;
  115. } else {
  116. $type = $this->_folder_types->create($annotations[$folder]);
  117. }
  118. $folder_type = $type->getType();
  119. $owner = $namespace->getOwner($folder);
  120. $owners[$folder] = $owner;
  121. $types[$folder] = $type->getType();
  122. $data = new Horde_Kolab_Storage_Folder_Data(
  123. $folder, $type, $namespace
  124. );
  125. $dataset = $data->toArray();
  126. $folders[$folder] = $dataset;
  127. $by_type[$folder_type][$folder] = $dataset;
  128. if ($folders[$folder]['default']) {
  129. $this->_defaults->rememberDefault(
  130. $folder,
  131. $folder_type,
  132. $owner,
  133. $folders[$folder]['namespace'] == Horde_Kolab_Storage_Folder_Namespace::PERSONAL
  134. );
  135. }
  136. }
  137. $this->_cache->store($folder_list, $annotations);
  138. if (!$this->_cache->hasNamespace()) {
  139. $this->_cache->setNamespace(serialize($namespace));
  140. }
  141. $this->_cache->setQuery(Horde_Kolab_Storage_List_Query_List_Cache::TYPES, $types);
  142. $this->_cache->setQuery(Horde_Kolab_Storage_List_Query_List_Cache::FOLDERS, $folders);
  143. $this->_cache->setQuery(Horde_Kolab_Storage_List_Query_List_Cache::OWNERS, $owners);
  144. $this->_cache->setQuery(Horde_Kolab_Storage_List_Query_List_Cache::BY_TYPE, $by_type);
  145. $this->_cache->setQuery(
  146. Horde_Kolab_Storage_List_Query_List_Cache::DEFAULTS,
  147. $this->_defaults->getDefaults()
  148. );
  149. $this->_cache->setQuery(
  150. Horde_Kolab_Storage_List_Query_List_Cache::PERSONAL_DEFAULTS,
  151. $this->_defaults->getPersonalDefaults()
  152. );
  153. $this->_cache->save();
  154. }
  155. /**
  156. * Update the listener after creating a new folder.
  157. *
  158. * @param string $folder The path of the folder that has been created.
  159. * @param string $type An optional type for the folder.
  160. *
  161. * @return NULL
  162. */
  163. public function updateAfterCreateFolder($folder, $type = null)
  164. {
  165. if (!$this->_cache->hasNamespace()) {
  166. // Cache not synchronized yet.
  167. return;
  168. }
  169. $folder_list = $this->_cache->getFolders();
  170. $folder_list[] = $folder;
  171. $annotations = $this->_cache->getFolderTypes();
  172. if ($type !== null) {
  173. $annotations[$folder] = $type;
  174. }
  175. $namespace = unserialize($this->_cache->getNamespace());
  176. $this->_synchronize($namespace, $folder_list, $annotations);
  177. }
  178. /**
  179. * Update the listener after deleting folder.
  180. *
  181. * @param string $folder The path of the folder that has been deleted.
  182. *
  183. * @return NULL
  184. */
  185. public function updateAfterDeleteFolder($folder)
  186. {
  187. if (!$this->_cache->hasNamespace()) {
  188. // Cache not synchronized yet.
  189. return;
  190. }
  191. $folder_list = $this->_cache->getFolders();
  192. $folder_list = array_diff($folder_list, array($folder));
  193. $annotations = $this->_cache->getFolderTypes();
  194. if (isset($annotations[$folder])) {
  195. unset($annotations[$folder]);
  196. }
  197. $namespace = unserialize($this->_cache->getNamespace());
  198. $this->_synchronize($namespace, $folder_list, $annotations);
  199. }
  200. /**
  201. * Update the listener after renaming a folder.
  202. *
  203. * @param string $old The old path of the folder.
  204. * @param string $new The new path of the folder.
  205. *
  206. * @return NULL
  207. */
  208. public function updateAfterRenameFolder($old, $new)
  209. {
  210. if (!$this->_cache->hasNamespace()) {
  211. // Cache not synchronized yet.
  212. return;
  213. }
  214. $folder_list = $this->_cache->getFolders();
  215. $folder_list = array_diff($folder_list, array($old));
  216. $folder_list[] = $new;
  217. $annotations = $this->_cache->getFolderTypes();
  218. if (isset($annotations[$old])) {
  219. $annotations[$new] = $annotations[$old];
  220. unset($annotations[$old]);
  221. }
  222. $namespace = unserialize($this->_cache->getNamespace());
  223. $this->_synchronize($namespace, $folder_list, $annotations);
  224. }
  225. /**
  226. * Set the specified folder as default for its current type.
  227. *
  228. * @param array $folder The folder data.
  229. * @param string|boolean $previous The previous default folder or false if there was none.
  230. */
  231. public function setDefault($folder, $previous = false)
  232. {
  233. if (!$this->_cache->hasNamespace()) {
  234. // Cache not synchronized yet.
  235. return;
  236. }
  237. if ($folder['namespace'] !== Horde_Kolab_Storage_Folder_Namespace::PERSONAL) {
  238. throw new Horde_Kolab_Storage_List_Exception(
  239. sprintf(
  240. "Unable to mark %s as a default folder. It is not within your personal namespace!",
  241. $folder['folder']
  242. )
  243. );
  244. }
  245. $annotations = $this->_cache->getFolderTypes();
  246. if (!isset($annotations[$folder['folder']])) {
  247. throw new Horde_Kolab_Storage_List_Exception(
  248. sprintf(
  249. "The folder %s has no Kolab type. It cannot be marked as 'default' folder!",
  250. $folder['folder']
  251. )
  252. );
  253. }
  254. if ($previous) {
  255. $this->_driver->setAnnotation(
  256. $previous,
  257. Horde_Kolab_Storage_List_Query_List::ANNOTATION_FOLDER_TYPE,
  258. $folder['type']
  259. );
  260. $annotations[$previous] = $folder['type'];
  261. }
  262. $this->_driver->setAnnotation(
  263. $folder['folder'],
  264. Horde_Kolab_Storage_List_Query_List::ANNOTATION_FOLDER_TYPE,
  265. $folder['type'] . '.default'
  266. );
  267. $annotations[$folder['folder']] = $folder['type'] . '.default';
  268. $folder_list = $this->_cache->getFolders();
  269. $namespace = unserialize($this->_cache->getNamespace());
  270. $this->_synchronize($namespace, $folder_list, $annotations);
  271. }
  272. /**
  273. * Return any default folder duplicates.
  274. *
  275. * @return array The list of duplicate default folders accessible to the current user.
  276. */
  277. public function getDuplicateDefaults()
  278. {
  279. return $this->_defaults->getDuplicates();
  280. }
  281. }