ea536910847998553047c249f96c2da91369003c
[tine20] / tine20 / Calendar / Frontend / Json.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Calendar
6  * @subpackage  Frontend
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @author      Cornelius Weiss <c.weiss@metaways.de>
9  * @copyright   Copyright (c) 2007-2013 Metaways Infosystems GmbH (http://www.metaways.de)
10  */
11
12 /**
13  * json interface for calendar
14  * 
15  * @package     Calendar
16  * @subpackage  Frontend
17  */
18 class Calendar_Frontend_Json extends Tinebase_Frontend_Json_Abstract
19 {
20     /**
21      * app name
22      * 
23      * @var string
24      */
25     protected $_applicationName = 'Calendar';
26     
27     /**
28      * creates an exception instance of a recurring event
29      *
30      * NOTE: deleting persistent exceptions is done via a normal delete action
31      *       and handled in the controller
32      * 
33      * @param  array       $recordData
34      * @param  bool        $deleteInstance
35      * @param  bool        $deleteAllFollowing
36      * @param  bool        $checkBusyConflicts
37      * @return array       exception Event | updated baseEvent
38      * 
39      * @todo replace $_allFollowing param with $range
40      * @deprecated replace with create/update/delete
41      */
42     public function createRecurException($recordData, $deleteInstance, $deleteAllFollowing, $checkBusyConflicts = FALSE)
43     {
44         $event = new Calendar_Model_Event(array(), TRUE);
45         $event->setFromJsonInUsersTimezone($recordData);
46         
47         $returnEvent = Calendar_Controller_Event::getInstance()->createRecurException($event, $deleteInstance, $deleteAllFollowing, $checkBusyConflicts);
48         
49         return $this->getEvent($returnEvent->getId());
50     }
51     
52     /**
53      * deletes existing events
54      *
55      * @param array $_ids
56      * @param string $range
57      * @return string
58      */
59     public function deleteEvents($ids, $range = Calendar_Model_Event::RANGE_THIS)
60     {
61         return $this->_delete($ids, Calendar_Controller_Event::getInstance(), array($range));
62     }
63     
64     /**
65      * deletes existing resources
66      *
67      * @param array $_ids 
68      * @return string
69      */
70     public function deleteResources($ids)
71     {
72         return $this->_delete($ids, Calendar_Controller_Resource::getInstance());
73     }
74     
75     /**
76      * deletes a recur series
77      *
78      * @param  array $recordData
79      * @return void
80      */
81     public function deleteRecurSeries($recordData)
82     {
83         $event = new Calendar_Model_Event(array(), TRUE);
84         $event->setFromJsonInUsersTimezone($recordData);
85         
86         Calendar_Controller_Event::getInstance()->deleteRecurSeries($event);
87         return array('success' => true);
88     }
89     
90     /**
91      * Return a single event
92      *
93      * @param   string $id
94      * @return  array record data
95      */
96     public function getEvent($id)
97     {
98         return $this->_get($id, Calendar_Controller_Event::getInstance());
99     }
100     
101     /**
102      * Returns registry data of the calendar.
103      *
104      * @return mixed array 'variable name' => 'data'
105      * 
106      * @todo move exception handling (no default calender found) to another place?
107      */
108     public function getRegistryData()
109     {
110         $defaultCalendarId = Tinebase_Core::getPreference('Calendar')->getValue(Calendar_Preference::DEFAULTCALENDAR);
111         try {
112             $defaultCalendarArray = Tinebase_Container::getInstance()->getContainerById($defaultCalendarId)->toArray();
113             $defaultCalendarArray['account_grants'] = Tinebase_Container::getInstance()->getGrantsOfAccount(Tinebase_Core::getUser(), $defaultCalendarId)->toArray();
114         } catch (Exception $e) {
115             // remove default cal pref
116             Tinebase_Core::getPreference('Calendar')->deleteUserPref(Calendar_Preference::DEFAULTCALENDAR);
117             $defaultCalendarArray = array();
118         }
119         
120         return array(
121             // registry setting is called defaultContainer to be compatible to the other apps
122             'defaultContainer' => $defaultCalendarArray
123         );
124     }
125     
126     /**
127      * Return a single resouece
128      *
129      * @param   string $id
130      * @return  array record data
131      */
132     public function getResource($id)
133     {
134         return $this->_get($id, Calendar_Controller_Resource::getInstance());
135     }
136     
137     /**
138      * Search for events matching given arguments
139      *
140      * @param  array $_filter
141      * @param  array $_paging
142      * @return array
143      */
144     public function searchEvents($filter, $paging)
145     {
146         $controller = Calendar_Controller_Event::getInstance();
147         
148         $decodedPagination = is_array($paging) ? $paging : Zend_Json::decode($paging);
149         $pagination = new Tinebase_Model_Pagination($decodedPagination);
150         $clientFilter = $filter = $this->_decodeFilter($filter, 'Calendar_Model_EventFilter');
151
152         // find out if fixed calendars should be used
153         $fixedCalendars = Calendar_Config::getInstance()->get(Calendar_Config::FIXED_CALENDARS, new Tinebase_Config_Struct(array()))->toArray();
154         $useFixedCalendars = is_array($fixedCalendars) && ! empty($fixedCalendars);
155         
156         $periodFilter = $filter->getFilter('period');
157         
158         // add period filter per default to prevent endless search
159         if (! $periodFilter) {
160             $now = Tinebase_DateTime::now()->setTime(0,0,0);
161             $inAmonth = clone $now;
162             $inAmonth->addMonth(1);
163             $periodFilter = new Calendar_Model_PeriodFilter(array('field' => 'period', 'operator' => 'within', 'value' => array("from" => $now, "until" => $inAmonth)));
164             // periodFilter will be added to fixed filter when using fixed calendars
165             if (! $useFixedCalendars) {
166                 $filter->addFilter($periodFilter);
167             }
168         }
169         
170         // add fixed calendar on demand
171         if ($useFixedCalendars) {
172             $fixed = new Calendar_Model_EventFilter(array(), 'AND');
173             $fixed->addFilter( new Tinebase_Model_Filter_Text('container_id', 'in', $fixedCalendars));
174             
175             $fixed->addFilter($periodFilter);
176             
177             $og = new Calendar_Model_EventFilter(array(), 'OR');
178             $og->addFilterGroup($fixed);
179             $og->addFilterGroup($clientFilter);
180             
181             $filter = new Calendar_Model_EventFilter(array(), 'AND');
182             $filter->addFilterGroup($og);
183         }
184         
185         $records = $controller->search($filter, $pagination, FALSE);
186         
187         $result = $this->_multipleRecordsToJson($records, $clientFilter, $pagination);
188         
189         return array(
190             'results'       => $result,
191             'totalcount'    => count($result),
192             'filter'        => $clientFilter->toArray(TRUE),
193         );
194     }
195     
196     /**
197      * Search for resources matching given arguments
198      *
199      * @param  array $_filter
200      * @param  array $_paging
201      * @return array
202      */
203     public function searchResources($filter, $paging)
204     {
205         return $this->_search($filter, $paging, Calendar_Controller_Resource::getInstance(), 'Calendar_Model_ResourceFilter');
206     }
207     
208     /**
209      * creates/updates an event / recur
210      *
211      * @param   array   $recordData
212      * @param   bool    $checkBusyConflicts
213      * @param   string  $range
214      * @return  array   created/updated event
215      */
216     public function saveEvent($recordData, $checkBusyConflicts = FALSE, $range = Calendar_Model_Event::RANGE_THIS)
217     {
218         return $this->_save($recordData, Calendar_Controller_Event::getInstance(), 'Event', 'id', array($checkBusyConflicts, $range));
219     }
220     
221     /**
222      * creates/updates a Resource
223      *
224      * @param   array   $recordData
225      * @return  array   created/updated Resource
226      */
227     public function saveResource($recordData)
228     {
229         $recordData['grants'] = new Tinebase_Record_RecordSet('Tinebase_Model_Grants', $recordData['grants']);
230         
231         return $this->_save($recordData, Calendar_Controller_Resource::getInstance(), 'Resource');
232     }
233     
234     /**
235      * sets attendee status for an attender on the given event
236      * 
237      * NOTE: for recur events we implicitly create an exceptions on demand
238      *
239      * @param  array         $eventData
240      * @param  array         $attenderData
241      * @param  string        $authKey
242      * @return array         complete event
243      */
244     public function setAttenderStatus($eventData, $attenderData, $authKey)
245     {
246         $event    = new Calendar_Model_Event($eventData);
247         $attender = new Calendar_Model_Attender($attenderData);
248         
249         Calendar_Controller_Event::getInstance()->attenderStatusUpdate($event, $attender, $authKey);
250         
251         return $this->getEvent($event->getId());
252     }
253     
254     /**
255      * updated a recur series
256      *
257      * @param  array $recordData
258      * @param  bool  $checkBusyConflicts
259      * @noparamyet  JSONstring $returnPeriod NOT IMPLEMENTED YET
260      * @return array 
261      */
262     public function updateRecurSeries($recordData, $checkBusyConflicts = FALSE /*, $returnPeriod*/)
263     {
264         $recurInstance = new Calendar_Model_Event(array(), TRUE);
265         $recurInstance->setFromJsonInUsersTimezone($recordData);
266         
267         //if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(print_r($recurInstance->toArray(), true));
268         
269         $baseEvent = Calendar_Controller_Event::getInstance()->updateRecurSeries($recurInstance, $checkBusyConflicts);
270         
271         return $this->getEvent($baseEvent->getId());
272     }
273     
274     /**
275      * prepares an iMIP (RFC 6047) Message
276      * 
277      * @param array $iMIP
278      * @return array prepared iMIP part
279      */
280     public function iMIPPrepare($iMIP)
281     {
282         $iMIPMessage = $iMIP instanceof Calendar_Model_iMIP ? $iMIP : new Calendar_Model_iMIP($iMIP);
283         $iMIPFrontend = new Calendar_Frontend_iMIP();
284         
285         $iMIPMessage->preconditionsChecked = FALSE;
286         $iMIPFrontend->prepareComponent($iMIPMessage);
287         $iMIPMessage->setTimezone(Tinebase_Core::get(Tinebase_Core::USERTIMEZONE));
288         return $iMIPMessage->toArray();
289     }
290     
291     /**
292      * process an iMIP (RFC 6047) Message
293      * 
294      * @param array  $iMIP
295      * @param string $status
296      * @return array prepared iMIP part
297      */
298     public function iMIPProcess($iMIP, $status=null)
299     {
300         $iMIPMessage = new Calendar_Model_iMIP($iMIP);
301         $iMIPFrontend = new Calendar_Frontend_iMIP();
302         
303         $iMIPFrontend->process($iMIPMessage, $status);
304         
305         return $this->iMIPPrepare($iMIPMessage);
306     }
307 }