1<?php
2/**
3 * Copyright 2012-2017 Horde LLC (http://www.horde.org/)
4 *
5 * See the enclosed file COPYING for license information (LGPL). If you
6 * did not receive this file, see http://www.horde.org/licenses/lgpl21.
7 *
8 * @category Kolab
9 * @package  Kolab_Storage
10 * @author   Gunnar Wrobel <wrobel@pardus.de>
11 * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
12 */
13
14/**
15 * Manages and provides the toolset available for dealing with the list of
16 * Kolab folders.
17 *
18 * @category Kolab
19 * @package  Kolab_Storage
20 * @author   Gunnar Wrobel <wrobel@pardus.de>
21 * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
22 */
23class Horde_Kolab_Storage_List_Tools
24{
25    /** Identifies the basic list query */
26    const QUERY_BASE  = 'List';
27
28    /** Identifies the ACL query */
29    const QUERY_ACL   = 'Acl';
30
31    /** Identifies the share query */
32    const QUERY_SHARE = 'Share';
33
34    /** The collection of list queries currently supported */
35    private static $_supported_queries = array(
36        self::QUERY_BASE,
37        self::QUERY_ACL,
38        self::QUERY_SHARE
39    );
40
41    /**
42     * The driver for accessing the Kolab storage system.
43     *
44     * @var Horde_Kolab_Storage_Driver
45     */
46    private $_driver;
47
48    /**
49     * The Kolab Storage data cache.
50     *
51     * @var Horde_Kolab_Storage_Cache
52     */
53    private $_cache;
54
55    /**
56     * The list specific cache.
57     *
58     * @var Horde_Kolab_Storage_List_Cache
59     */
60    private $_list_cache;
61
62    /**
63     * A logger.
64     *
65     * @var Horde_Log_Logger
66     */
67    private $_logger;
68
69    /**
70     * Parameters for constructing the various tools.
71     *
72     * @var array
73     */
74    private $_params;
75
76    /**
77     * The handler for list manipulations.
78     *
79     * @var Horde_Kolab_Storage_List_Manipulation
80     */
81    private $_manipulation;
82
83    /**
84     * The handler for synchronizing with the backend.
85     *
86     * @var Horde_Kolab_Storage_List_Synchronization
87     */
88    private $_synchronization;
89
90    /**
91     * The queries currently registered.
92     *
93     * @var array
94     */
95    private $_queries;
96
97    /**
98     * Constructor.
99     *
100     * @param Horde_Kolab_Storage_Driver $driver  The backend driver.
101     * @param Horde_Kolab_Storage_Cache  $cache   The cache.
102     * @param Horde_Log_Logger           $logger  A logger.
103     * @param array                      $params
104     */
105    public function __construct(Horde_Kolab_Storage_Driver $driver,
106                                Horde_Kolab_Storage_Cache $cache,
107                                $logger,
108                                $params = array())
109    {
110        $this->_driver = $driver;
111        $this->_cache  = $cache;
112        $this->_logger = $logger;
113        $this->_params = $params;
114        $this->_prepareManipulationHandler();
115        $this->_prepareSynchronizationHandler();
116        $this->_prepareListCache();
117        $this->_prepareQueries();
118    }
119
120    /**
121     * Setup for the manipulation handler.
122     */
123    private function _prepareManipulationHandler()
124    {
125        $manipulation = new Horde_Kolab_Storage_List_Manipulation_Base($this->_driver);
126        if (isset($this->_params['log'])
127            && (in_array('debug', $this->_params['log'])
128                || in_array('list_manipulation', $this->_params['log']))) {
129            $manipulation = new Horde_Kolab_Storage_List_Manipulation_Decorator_Log(
130                $manipulation, $this->_logger
131            );
132        }
133        $this->_manipulation = $manipulation;
134    }
135
136    /**
137     * Setup for the synchronization handler.
138     */
139    private function _prepareSynchronizationHandler()
140    {
141        $synchronization = new Horde_Kolab_Storage_List_Synchronization_Base($this->_driver);
142        if (isset($this->_params['log'])
143            && (in_array('debug', $this->_params['log'])
144                || in_array('list_synchronization', $this->_params['log']))) {
145            $synchronization = new Horde_Kolab_Storage_List_Synchronization_Decorator_Log(
146                $synchronization, $this->_logger
147            );
148        }
149        $this->_synchronization = $synchronization;
150    }
151
152    /**
153     * Setup the list cache.
154     */
155    private function _prepareListCache()
156    {
157        $this->_list_cache = new Horde_Kolab_Storage_List_Cache(
158            $this->_cache, $this->_driver->getParameters()
159        );
160    }
161
162    /**
163     * Setup the queries.
164     */
165    private function _prepareQueries()
166    {
167        if (isset($this->_params['queries']['list'])) {
168            $query_list = array_keys($this->_params['queries']['list']);
169        } else {
170            $query_list = array(self::QUERY_BASE);
171        }
172        foreach ($query_list as $query) {
173            $method = '_prepare' . $query . 'Query';
174            if (isset($this->_params['queries']['list'][$query])) {
175                $this->{$method}($this->_params['queries']['list'][$query]);
176            } else {
177                $this->{$method}();
178            }
179        }
180    }
181
182    /**
183     * Prepare the general list query.
184     *
185     * @param array $params Query specific configuration parameters.
186     */
187    private function _prepareListQuery($params = null)
188    {
189        if (!empty($params['defaults_bail'])) {
190            $defaults = new Horde_Kolab_Storage_List_Query_List_Defaults_Bail();
191        } else {
192            $defaults = new Horde_Kolab_Storage_List_Query_List_Defaults_Log(
193                $this->_logger
194            );
195        }
196        if (empty($params['cache'])) {
197            $this->_queries[self::QUERY_BASE] = new Horde_Kolab_Storage_List_Query_List_Base(
198                $this->_driver,
199                new Horde_Kolab_Storage_Folder_Types(),
200                $defaults
201            );
202        } else {
203            $this->_queries[self::QUERY_BASE] = new Horde_Kolab_Storage_List_Query_List_Cache(
204                new Horde_Kolab_Storage_List_Query_List_Cache_Synchronization(
205                    $this->_driver,
206                    new Horde_Kolab_Storage_Folder_Types(),
207                    $defaults
208                ),
209                $this->_list_cache
210            );
211            $this->_synchronization->registerListener($this->_queries[self::QUERY_BASE]);
212            $this->_manipulation->registerListener($this->_queries[self::QUERY_BASE]);
213        }
214    }
215
216    /**
217     * Prepare the ACL query.
218     *
219     * @param array $params Query specific configuration parameters.
220     */
221    private function _prepareAclQuery($params = null)
222    {
223        $this->_queries[self::QUERY_ACL] = new Horde_Kolab_Storage_List_Query_Acl_Base(
224            $this->_driver
225        );
226        if (!empty($params['cache'])) {
227            $this->_queries[self::QUERY_ACL] = new Horde_Kolab_Storage_List_Query_Acl_Cache(
228                $this->_queries[self::QUERY_ACL], $this->_list_cache
229            );
230            $this->_synchronization->registerListener($this->_queries[self::QUERY_ACL]);
231            $this->_manipulation->registerListener($this->_queries[self::QUERY_ACL]);
232        }
233    }
234
235    /**
236     * Prepare the query for shares.
237     *
238     * @param array $params Query specific configuration parameters.
239     */
240    private function _prepareShareQuery($params = null)
241    {
242        $this->_queries[self::QUERY_SHARE] = new Horde_Kolab_Storage_List_Query_Share_Base(
243            $this->_driver
244        );
245        if (!empty($params['cache'])) {
246            $this->_queries[self::QUERY_SHARE] = new Horde_Kolab_Storage_List_Query_Share_Cache(
247                $this->_queries[self::QUERY_SHARE], $this->_list_cache
248            );
249            $this->_synchronization->registerListener($this->_queries[self::QUERY_SHARE]);
250            $this->_manipulation->registerListener($this->_queries[self::QUERY_SHARE]);
251        }
252    }
253
254    /**
255     * Return the ID of the underlying connection.
256     *
257     * @return string The connection ID.
258     */
259    public function getId()
260    {
261        return $this->_driver->getId();
262    }
263
264    /**
265     * Return the namespace handler for the underlying connection.
266     *
267     * @return Horde_Kolab_Storage_Folder_Namespace The namespace handler.
268     */
269    public function getNamespace()
270    {
271        return $this->_driver->getNamespace();
272    }
273
274    /**
275     * Return the handler for list manipulations.
276     */
277    public function getListManipulation()
278    {
279        return $this->_manipulation;
280    }
281
282    /**
283     * Return the handler for list synchronizations.
284     */
285    public function getListSynchronization()
286    {
287        return $this->_synchronization;
288    }
289
290    /**
291     * Return a query object.
292     *
293     * @param string $type The query type that should be returned.
294     */
295    public function getQuery($type = null)
296    {
297        if ($type === null) {
298            $type = self::QUERY_BASE;
299        }
300        if (!in_array($type, self::$_supported_queries)) {
301            throw new Horde_Kolab_Storage_List_Exception(
302                sprintf("Queries of type '%s' are not supported!", $type)
303            );
304        }
305        if (!isset($this->_queries[$type])) {
306            throw new Horde_Kolab_Storage_List_Exception(
307                sprintf("No query of type '%s' registered!", $type)
308            );
309        }
310        return $this->_queries[$type];
311    }
312}
313
314