Esempio n. 1
0
    function setUp()
    {
        if (!SABRE_HASSQLITE) {
            $this->markTestSkipped('SQLite driver is not available');
        }
        if (file_exists(SABRE_TEMPDIR . '/testdb.sqlite')) {
            unlink(SABRE_TEMPDIR . '/testdb.sqlite');
        }
        $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/testdb.sqlite');
        $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        $pdo->exec(<<<SQL
CREATE TABLE simple_calendars (
    id INTEGER PRIMARY KEY ASC NOT NULL,
    uri TEXT NOT NULL,
    principaluri TEXT NOT NULL
)
SQL
);
        $pdo->exec(<<<SQL
CREATE TABLE simple_calendarobjects (
    id INTEGER PRIMARY KEY ASC NOT NULL,
    calendarid INT UNSIGNED NOT NULL,
    uri TEXT NOT NULL,
    calendardata TEXT
);
SQL
);
        $this->pdo = $pdo;
    }
Esempio n. 2
0
 function testMkCalendarEmptyBodySucceed()
 {
     $request = new HTTP\Request('MKCALENDAR', '/calendars/user1/NEWCALENDAR');
     $request->setBody('');
     $this->server->httpRequest = $request;
     $this->server->exec();
     $this->assertEquals(201, $this->response->status, 'Invalid response code received. Full response body: ' . $this->response->body);
     $calendars = $this->caldavBackend->getCalendarsForUser('principals/user1');
     $this->assertEquals(3, count($calendars));
     $newCalendar = null;
     foreach ($calendars as $calendar) {
         if ($calendar['uri'] === 'NEWCALENDAR') {
             $newCalendar = $calendar;
             break;
         }
     }
     $this->assertInternalType('array', $newCalendar);
     $keys = ['uri' => 'NEWCALENDAR', 'id' => null, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => null];
     foreach ($keys as $key => $value) {
         $this->assertArrayHasKey($key, $newCalendar);
         if (is_null($value)) {
             continue;
         }
         $this->assertEquals($value, $newCalendar[$key]);
     }
     $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
     $this->assertTrue($newCalendar[$sccs] instanceof Xml\Property\SupportedCalendarComponentSet);
     $this->assertEquals(['VEVENT', 'VTODO'], $newCalendar[$sccs]->getValue());
 }
Esempio n. 3
0
 /**
  * Creates the backend
  *
  * @param \PDO $pdo
  * @param string $calendarTableName
  * @param string $calendarObjectTableName
  */
 public function __construct(\PDO $pdo, $calendarTableName = 'calendars', $principalsTableName = 'principals', $calendarObjectTableName = 'calendarobjects', $calendarSharesTableName = 'calendarShares', $notificationsTableName = 'notifications')
 {
     parent::__construct($pdo, $calendarTableName, $calendarObjectTableName);
     $this->calendarSharesTableName = $calendarSharesTableName;
     $this->principalsTableName = $principalsTableName;
     $this->notificationsTableName = $notificationsTableName;
 }
Esempio n. 4
0
    /**
     * Returns the list of people whom a calendar is shared with.
     *
     * Every item in the returned list must be a Sharee object with at
     * least the following properties set:
     *   $href
     *   $shareAccess
     *   $inviteStatus
     *
     * and optionally:
     *   $properties
     *
     * @param mixed $calendarId
     * @return \Sabre\DAV\Xml\Element\Sharee[]
     */
    function getInvites($calendarId)
    {
        if (!is_array($calendarId)) {
            throw new \InvalidArgumentException('The value passed to getInvites() is expected to be an array with a calendarId and an instanceId');
        }
        list($calendarId, $instanceId) = $calendarId;
        $query = <<<SQL
SELECT
    principaluri,
    access,
    share_href,
    share_displayname,
    share_invitestatus
FROM {$this->calendarInstancesTableName}
WHERE
    calendarid = ?
SQL;
        $stmt = $this->pdo->prepare($query);
        $stmt->execute([$calendarId]);
        $result = [];
        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
            $result[] = new Sharee(['href' => isset($row['share_href']) ? $row['share_href'] : \Sabre\HTTP\encodePath($row['principaluri']), 'access' => (int) $row['access'], 'inviteStatus' => (int) $row['share_invitestatus'], 'properties' => !empty($row['share_displayname']) ? ['{DAV:}displayname' => $row['share_displayname']] : [], 'principal' => $row['principaluri']]);
        }
        return $result;
    }
Esempio n. 5
0
 /**
  * Performs a calendar-query on the contents of this calendar.
  *
  * The calendar-query is defined in RFC4791 : CalDAV. Using the
  * calendar-query it is possible for a client to request a specific set of
  * object, based on contents of iCalendar properties, date-ranges and
  * iCalendar component types (VTODO, VEVENT).
  *
  * This method should just return a list of (relative) urls that match this
  * query.
  *
  * The list of filters are specified as an array. The exact array is
  * documented by \Sabre\CalDAV\CalendarQueryParser.
  *
  * Note that it is extremely likely that getCalendarObject for every path
  * returned from this method will be called almost immediately after. You
  * may want to anticipate this to speed up these requests.
  *
  * This method provides a default implementation, which parses *all* the
  * iCalendar objects in the specified calendar.
  *
  * This default may well be good enough for personal use, and calendars
  * that aren't very large. But if you anticipate high usage, big calendars
  * or high loads, you are strongly adviced to optimize certain paths.
  *
  * The best way to do so is override this method and to optimize
  * specifically for 'common filters'.
  *
  * Requests that are extremely common are:
  *   * requests for just VEVENTS
  *   * requests for just VTODO
  *   * requests with a time-range-filter on a VEVENT.
  *
  * ..and combinations of these requests. It may not be worth it to try to
  * handle every possible situation and just rely on the (relatively
  * easy to use) CalendarQueryValidator to handle the rest.
  *
  * Note that especially time-range-filters may be difficult to parse. A
  * time-range filter specified on a VEVENT must for instance also handle
  * recurrence rules correctly.
  * A good example of how to interprete all these filters can also simply
  * be found in \Sabre\CalDAV\CalendarQueryFilter. This class is as correct
  * as possible, so it gives you a good idea on what type of stuff you need
  * to think of.
  *
  * This specific implementation (for the PDO) backend optimizes filters on
  * specific components, and VEVENT time-ranges.
  *
  * @param string $calendarId
  * @param array $filters
  * @return array
  */
 public function calendarQuery($calendarId, array $filters)
 {
     $result = array();
     $validator = new \Sabre\CalDAV\CalendarQueryValidator();
     $componentType = null;
     $requirePostFilter = true;
     $timeRange = null;
     // if no filters were specified, we don't need to filter after a query
     if (!$filters['prop-filters'] && !$filters['comp-filters']) {
         $requirePostFilter = false;
     }
     // Figuring out if there's a component filter
     if (count($filters['comp-filters']) > 0 && !$filters['comp-filters'][0]['is-not-defined']) {
         $componentType = $filters['comp-filters'][0]['name'];
         // Checking if we need post-filters
         if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['time-range'] && !$filters['comp-filters'][0]['prop-filters']) {
             $requirePostFilter = false;
         }
         // There was a time-range filter
         if ($componentType == 'VEVENT' && isset($filters['comp-filters'][0]['time-range'])) {
             $timeRange = $filters['comp-filters'][0]['time-range'];
             // If start time OR the end time is not specified, we can do a
             // 100% accurate mysql query.
             if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['prop-filters'] && (!$timeRange['start'] || !$timeRange['end'])) {
                 $requirePostFilter = false;
             }
         }
     }
     if ($requirePostFilter) {
         $query = "SELECT uri, calendardata FROM " . $this->calendarObjectTableName . " WHERE calendarid = :calendarid";
     } else {
         $query = "SELECT uri FROM " . $this->calendarObjectTableName . " WHERE calendarid = :calendarid";
     }
     $values = array('calendarid' => $calendarId);
     if ($componentType) {
         $query .= " AND componenttype = :componenttype";
         $values['componenttype'] = $componentType;
     }
     if ($timeRange && $timeRange['start']) {
         $query .= " AND lastoccurence > :startdate";
         $values['startdate'] = $timeRange['start']->getTimeStamp();
     }
     if ($timeRange && $timeRange['end']) {
         $query .= " AND firstoccurence < :enddate";
         $values['enddate'] = $timeRange['end']->getTimeStamp();
     }
     $stmt = $this->pdo->prepare($query);
     $stmt->execute($values);
     $result = array();
     while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
         if ($requirePostFilter) {
             if (!$this->validateFilterForObject($row, $filters)) {
                 continue;
             }
         }
         $result[] = $row['uri'];
     }
     return $result;
 }
Esempio n. 6
0
 function setup()
 {
     if (!SABRE_HASSQLITE) {
         $this->markTestSkipped('SQLite driver is not available');
     }
     if (file_exists(SABRE_TEMPDIR . '/testdb.sqlite')) {
         unlink(SABRE_TEMPDIR . '/testdb.sqlite');
     }
     $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/testdb.sqlite');
     $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
     // Yup this is definitely not 'fool proof', but good enough for now.
     $queries = explode(';', file_get_contents(__DIR__ . '/../../../../examples/sql/sqlite.calendars.sql'));
     foreach ($queries as $query) {
         $pdo->exec($query);
     }
     $this->pdo = $pdo;
 }
Esempio n. 7
0
 /**
  * Delete a calendar and all it's objects 
  * 
  * @param string $calendarId 
  * @return void
  */
 public function deleteCalendar($calendarId)
 {
     parent::deleteCalendar($calendarId);
     $this->deleteCalendarShares($calendarId);
 }
Esempio n. 8
0
 /**
  * Delete a calendar and all it's objects 
  * 
  * @param string $calendarId 
  * @return void
  */
 public function deleteCalendar($calendarId)
 {
     \CApi::Log('deleteCalendar', \ELogLevel::Full, 'del-');
     parent::deleteCalendar($calendarId);
     $this->deleteCalendarShares($calendarId);
 }
Esempio n. 9
0
 /**
  * Creates a new scheduling object. This should land in a users' inbox.
  *
  * @param string $principalUri
  * @param string $objectUri
  * @param string $objectData
  * @return void
  */
 function createSchedulingObject($principalUri, $objectUri, $objectData)
 {
     $stmt = $this->pdo->prepare('INSERT INTO ' . $this->schedulingObjectTableName . ' (principaluri, calendardata, uri, lastmodified, etag, size) VALUES (?, ?, ?, ?, ?, ?)');
     $stmt->execute([$principalUri, $objectData, $objectUri, time(), md5($objectData), strlen($objectData)]);
 }
Esempio n. 10
0
 function testSchedulingMethods()
 {
     $backend = new PDO($this->pdo);
     $calData = "BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n";
     $backend->createSchedulingObject('principals/user1', 'schedule1.ics', $calData);
     $expected = ['calendardata' => $calData, 'uri' => 'schedule1.ics', 'etag' => '"' . md5($calData) . '"', 'size' => strlen($calData)];
     $result = $backend->getSchedulingObject('principals/user1', 'schedule1.ics');
     foreach ($expected as $k => $v) {
         $this->assertArrayHasKey($k, $result);
         $this->assertEquals($v, $result[$k]);
     }
     $results = $backend->getSchedulingObjects('principals/user1');
     $this->assertEquals(1, count($results));
     $result = $results[0];
     foreach ($expected as $k => $v) {
         $this->assertEquals($v, $result[$k]);
     }
     $backend->deleteSchedulingObject('principals/user1', 'schedule1.ics');
     $result = $backend->getSchedulingObject('principals/user1', 'schedule1.ics');
     $this->assertNull($result);
 }
Esempio n. 11
0
 /**
  * @expectedException \Sabre\DAV\Exception\NotImplemented
  */
 function testSetPublishStatus()
 {
     $backend = new PDO($this->pdo);
     $backend->setPublishStatus([1, 1], true);
 }
Esempio n. 12
0
 function testCalendarQueryTimeRangeNoEnd()
 {
     $backend = new PDO($this->pdo);
     $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
     $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
     $backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
     $filters = array('name' => 'VCALENDAR', 'comp-filters' => array(array('name' => 'VEVENT', 'comp-filters' => array(), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => array('start' => new \DateTime('20120102'), 'end' => null))), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => null);
     $this->assertEquals(array("event2"), $backend->calendarQuery(1, $filters));
 }
Esempio n. 13
0
 /**
  * Deletes an existing calendar object.
  *
  * The object uri is only the basename, or filename and not a full path.
  *
  * @param string $calendarId
  * @param string $objectUri
  * @return void
  */
 function deleteCalendarObject($calendarId, $objectUri)
 {
     $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
     $stmt->execute([$calendarId, $objectUri]);
 }