cleanup remove tabs
[tine20] / tine20 / Tasks / Frontend / WebDAV / Container.php
1 <?php
2
3 use Sabre\DAV;
4 use Sabre\DAVACL;
5 use Sabre\CalDAV;
6 use Sabre\VObject;
7
8 /**
9  * Tine 2.0
10  *
11  * @package     Tasks
12  * @subpackage  Frontend
13  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
14  * @author      Lars Kneschke <l.kneschke@metaways.de>
15  * @copyright   Copyright (c) 2011-2013 Metaways Infosystems GmbH (http://www.metaways.de)
16  */
17
18 /**
19  * class to handle task containers in CalDAV tree
20  *
21  * @package     Tasks
22  * @subpackage  Frontend
23  */
24 class Tasks_Frontend_WebDAV_Container extends Tinebase_WebDav_Container_Abstract implements CalDAV\ICalendar
25 {
26     protected $_applicationName = 'Tasks';
27
28     protected $_model = 'Task';
29
30     protected $_suffix = '.ics';
31
32     /**
33      * Performs a calendar-query on the contents of this calendar.
34      *
35      * The calendar-query is defined in RFC4791 : CalDAV. Using the
36      * calendar-query it is possible for a client to request a specific set of
37      * object, based on contents of iCalendar properties, date-ranges and
38      * iCalendar component types (VTODO, VEVENT).
39      *
40      * This method should just return a list of (relative) urls that match this
41      * query.
42      *
43      * The list of filters are specified as an array. The exact array is
44      * documented by \Sabre\CalDAV\CalendarQueryParser.
45      *
46      * @param array $filters
47      * @return array
48      */
49     public function calendarQuery(array $filters)
50     {
51         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(
52             __METHOD__ . '::' . __LINE__ . ' filters ' . print_r($filters, true));
53
54         //var_dump($filters['comp-filters'][0]);
55
56         $filterArray = array(
57             array(
58                 'field'    => 'container_id',
59                 'operator' => 'equals',
60                 'value'    => $this->_container->getId()
61             )
62         );
63
64         /*if (isset($filters['comp-filters']) && isset($filters['comp-filters'][0]['time-range'])) {
65             if (isset($filters['comp-filters'][0]['time-range']['start'])) {
66                 $filterArray[] = array(
67                     'field' => 'period', 
68                     'operator' => 'within', 
69                     'value' => array(
70                         'from'  => $filters['comp-filters'][0]['time-range']['start'],
71                         'until' => $filters['comp-filters'][0]['time-range']['end']
72                     )
73                 );
74             }
75         }*/
76         
77         $filterClass = $this->_application->name . '_Model_' . $this->_model . 'Filter';
78         $filter = new $filterClass($filterArray);
79
80         /**
81          * see http://forge.tine20.org/mantisbt/view.php?id=5122
82          * we must use action 'sync' and not 'get' as
83          * otherwise the calendar also return events the user only can see because of freebusy
84          */
85         $ids = $this->_getController()->search($filter, null, false, true, 'sync');
86
87         return $ids;
88     }
89
90     /**
91      * (non-PHPdoc)
92      * @see Sabre\DAV\Collection::getChild()
93      */
94     public function getChild($_name)
95     {
96         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(
97             __METHOD__ . '::' . __LINE__ .' FLAAAAAAAAA aplicacao:' . $this->_application->name . ' modelo:' . $this->_model .' Nome: ' . $_name);
98
99         $modelName = $this->_application->name . '_Model_' . $this->_model;
100
101         if ($_name instanceof $modelName) {
102             $object = $_name;
103         } else {
104             $filterClass = $this->_application->name . '_Model_' . $this->_model . 'Filter';
105             $filter = new $filterClass(array(
106                 array(
107                     'field'     => 'container_id',
108                     'operator'  => 'equals',
109                     'value'     => $this->_container->id
110                 ),
111                 array('condition' => 'OR', 'filters' => array(
112                     array(
113                         'field'     => 'id',
114                         'operator'  => 'equals',
115                         'value'     => $this->_getIdFromName($_name)
116                     ),
117                     array(
118                         'field'     => 'uid',
119                         'operator'  => 'equals',
120                         'value'     => $this->_getIdFromName($_name)
121                     )
122                 ))
123             ));
124             $object = $this->_getController()->search($filter, null, false, false, 'sync')->getFirstRecord();
125
126             if ($object == null) {
127                 throw new DAV\Exception\NotFound('Object not found');
128             }
129         }
130
131         $httpRequest = new Sabre\HTTP\Request();
132
133         // lie about existance of event of request is a PUT request from an ATTENDEE for an already existing event 
134         // to prevent ugly (and not helpful) error messages on the client
135         if (isset($_SERVER['REQUEST_METHOD']) && $httpRequest->getMethod() == 'PUT' && $httpRequest->getHeader('If-None-Match') === '*') {
136             if (
137                 $object->organizer != Tinebase_Core::getUser()->getId() && 
138                 Calendar_Model_Attender::getOwnAttender($object->attendee) !== null
139             ) {
140                 throw new DAV\Exception\NotFound('Object not found');
141             }
142         }
143         
144         $objectClass = $this->_application->name . '_Frontend_WebDAV_' . $this->_model;
145
146         return new $objectClass($this->_container, $object);
147     }
148
149     /**
150      * Returns an array with all the child nodes
151      *
152      * @return Sabre\DAV\INode[]
153      */
154     public function getChildren()
155     {
156         $filterClass = $this->_application->name . '_Model_' . $this->_model . 'Filter';
157         $filter = new $filterClass(array(
158             array(
159                 'field'     => 'container_id',
160                 'operator'  => 'equals',
161                 'value'     => $this->_container->getId()
162             ),
163             array(
164                 'field'     => 'period', 
165                 'operator'  => 'within', 
166                 'value'     => array(
167                     'from'  => Tinebase_DateTime::now()->subWeek(4),
168                     'until' => Tinebase_DateTime::now()->addYear(4)
169                 )
170             )
171         ));
172
173         /**
174          * see http://forge.tine20.org/mantisbt/view.php?id=5122
175          * we must use action 'sync' and not 'get' as
176          * otherwise the calendar also return events the user only can see because of freebusy
177          */
178         $objects = $this->_getController()->search($filter, null, false, false, 'sync');
179
180         $children = array();
181
182         foreach ($objects as $object) {
183             $children[] = $this->getChild($object);
184         }
185
186         return $children;
187     }
188     
189     /**
190      * Returns the list of properties
191      *
192      * @param array $requestedProperties
193      * @return array
194      */
195     public function getProperties($requestedProperties) 
196     {
197         $displayName = $this->_container->type == Tinebase_Model_Container::TYPE_SHARED ? $this->_container->name . ' (shared)' : $this->_container->name;
198
199         $ctags = Tinebase_Container::getInstance()->getContentSequence($this->_container);
200
201         $properties = array(
202             '{http://calendarserver.org/ns/}getctag' => $ctags ? $ctags : 1,
203             'id'                => $this->_container->getId(),
204             'uri'               => $this->_useIdAsName == true ? $this->_container->getId() : $this->_container->name,
205             '{DAV:}resource-id' => 'urn:uuid:' . $this->_container->getId(),
206             '{DAV:}owner'       => new DAVACL\Property\Principal(DAVACL\Property\Principal::HREF, 'principals/users/' . Tinebase_Core::getUser()->contact_id),
207             #'principaluri'      => $principalUri,
208             '{DAV:}displayname' => $displayName,
209             '{http://apple.com/ns/ical/}calendar-color' => (empty($this->_container->color)) ? '#000000' : $this->_container->color,
210             
211             '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Property\SupportedCalendarComponentSet(array('VTODO')),
212             '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-data'          => new CalDAV\Property\SupportedCalendarData(),
213             '{' . CalDAV\Plugin::NS_CALDAV . '}calendar-description'             => 'Tasks ' . $displayName,
214             '{' . CalDAV\Plugin::NS_CALDAV . '}calendar-timezone'                => $this->_getCalendarVTimezone()
215         );
216         
217         if (!empty(Tinebase_Core::getUser()->accountEmailAddress)) {
218             $properties['{' . CalDAV\Plugin::NS_CALDAV . '}calendar-user-address-set'] = new DAV\Property\HrefList(array('mailto:' . Tinebase_Core::getUser()->accountEmailAddress), false); 
219         }
220         
221         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . print_r($properties, true));
222         
223         $response = array();
224
225         foreach($requestedProperties as $prop) {
226             if (isset($properties[$prop])) {
227                 $response[$prop] = $properties[$prop];
228             }
229         }
230         
231         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . print_r($response, true));
232         
233         return $response;
234     }
235 }