%PDF- %PDF-
| Direktori : /www/varak.net/mail2.varak.net_old/libraries/afterlogic/DAV/CalDAV/Backend/ |
| Current File : /www/varak.net/mail2.varak.net_old/libraries/afterlogic/DAV/CalDAV/Backend/PDO.php |
<?php
/*
* Copyright 2004-2014, AfterLogic Corp.
* Licensed under AGPLv3 license or AfterLogic license
* if commercial version of the product was purchased.
* See the LICENSE file for a full license statement.
*/
namespace afterlogic\DAV\CalDAV\Backend;
use afterlogic\DAV\Constants;
class PDO extends \Sabre\CalDAV\Backend\PDO implements \Sabre\CalDAV\Backend\SharingSupport
{
/**
* The table name that will be used for calendar shares
*
* @var string
*/
protected $calendarSharesTableName;
/**
* The table name that will be used for principals
*
* @var string
*/
protected $principalsTableName;
/**
* The table name that will be used for notifications
*
* @var string
*/
protected $notificationsTableName;
/**
* @var string
*/
protected $dBPrefix;
/**
* List of properties for the calendar shares table
* This list maps exactly to the field names in the db table
*/
public $sharesProperties = array(
'calendarid',
'member',
'status',
'readonly',
'summary',
'displayname',
'color'
);
/**
* Creates the backend
*/
public function __construct()
{
$oPdo = \CApi::GetPDO();
$sDbPrefix = \CApi::GetSettings()->GetConf('Common/DBPrefix');
$this->dBPrefix = $sDbPrefix;
parent::__construct($oPdo, $sDbPrefix.Constants::T_CALENDARS, $sDbPrefix.Constants::T_CALENDAROBJECTS);
$this->calendarSharesTableName = $sDbPrefix.Constants::T_CALENDARSHARES;
$this->principalsTableName = $sDbPrefix.Constants::T_PRINCIPALS;
$this->notificationsTableName = $sDbPrefix.Constants::T_NOTIFICATIONS;
}
/**
* Setter method for the calendarShares table name
*/
public function setCalendarSharesTableName($name)
{
$this->calendarSharesTableName = $name;
}
/**
* 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);
}
public function deleteCalendarShares($calendarId) {
$stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarSharesTableName.' WHERE calendarid = ?');
$stmt->execute(array($calendarId));
}
/**
* Updates the list of shares.
*
* The first array is a list of people that are to be added to the
* calendar.
*
* Every element in the add array has the following properties:
* * href - A url. Usually a mailto: address
* * commonname - Usually a first and last name, or false
* * summary - A description of the share, can also be false
* * readOnly - A boolean value
*
* Every element in the remove array is just the address string.
*
* Note that if the calendar is currently marked as 'not shared' by and
* this method is called, the calendar should be 'upgraded' to a shared
* calendar.
*
* @param mixed $mCalendarId
* @param array $aAdd
* @param array $aRemove
* @return void
*/
public function updateShares($mCalendarId, array $aAdd, array $aRemove = array())
{
$bAddResult = true;
$bRemoveResult = true;
if(count($aAdd)>0)
{
foreach ($aAdd as $aAddItem)
{
$aFieldNames = array();
$aFields = array();
$aFieldNames[] = 'calendarid';
$aFields[':calendarid'] = $mCalendarId;
// get the principal based on the supplied email address
$aPrincipal = \afterlogic\DAV\Utils::getPrincipalByEmail($aAddItem['href']);
$aFieldNames[] = 'member';
$aFields[':member'] = $aPrincipal['id'];
$aFieldNames[] = 'status';
$aFields[':status'] = \Sabre\CalDAV\SharingPlugin::STATUS_NORESPONSE;
// check we have all the required fields
foreach($this->sharesProperties as $sField)
{
if(isset($aAddItem[$sField]))
{
$aFieldNames[] = $sField;
$aFields[':'.$sField] = $aAddItem[$sField];
}
}
$stmt = $this->pdo->prepare("SELECT calendarid FROM ".$this->calendarSharesTableName." WHERE calendarid = ? and member = ?");
$stmt->execute(array($mCalendarId, $aPrincipal['id']));
if (count($stmt->fetchAll()) === 0)
{
$stmt = $this->pdo->prepare("INSERT INTO ".$this->calendarSharesTableName." (".implode(', ', $aFieldNames).") VALUES (".implode(', ',array_keys($aFields)).")");
$bAddResult = $stmt->execute($aFields);
}
else
{
$aUpdateFields = array();
foreach ($aFieldNames as $sFieldName)
{
$aUpdateFields[] = $sFieldName . '= :'. $sFieldName;
}
$stmt = $this->pdo->prepare("UPDATE ".$this->calendarSharesTableName." SET ".implode(', ', $aUpdateFields)." WHERE calendarid = :calendarid and member = :member");
$bAddResult = $stmt->execute($aFields);
}
if (isset($aAddItem['displayname'], $aAddItem['summary']))
{
$stmt = $this->pdo->prepare("UPDATE " . $this->calendarTableName . " SET displayname = ?, description = ? WHERE id = ?");
$newValues['displayname'] = $aAddItem['displayname'];
$newValues['description'] = $aAddItem['summary'];
$newValues['id'] = $mCalendarId;
$stmt->execute(array_values($newValues));
}
}
}
// are we removing any shares?
if(count($aRemove)>0)
{
$aParams = array($mCalendarId);
$aMembers = array();
foreach($aRemove as $sRemoveItem)
{
// get the principalid
$oPrincipal = \afterlogic\DAV\Utils::getPrincipalByEmail($sRemoveItem);
$aMembers[] = $oPrincipal['id'];
}
$aParams[] = implode(',', $aMembers);
$stmt = $this->pdo->prepare("DELETE FROM ".$this->calendarSharesTableName." WHERE calendarid = ? and member IN (?)");
$bRemoveResult = $stmt->execute($aParams);
}
$stmt = $this->pdo->prepare("UPDATE " . $this->calendarTableName . " SET ctag = ctag + 1 WHERE id = ?");
$stmt->execute(array($mCalendarId));
return $bAddResult && $bRemoveResult;
}
/**
* Returns the list of people whom this calendar is shared with.
*
* Every element in this array should have the following properties:
* * href - Often a mailto: address
* * commonname - Optional, for example a first + last name
* * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
* * readOnly - boolean
* * summary - Optional, a description for the share
*
* @return array
*/
public function getShares($mCalendarId) {
// $fields = implode(', ', $this->sharesProperties);
$stmt = $this->pdo->prepare("SELECT * FROM ".$this->calendarSharesTableName." AS calendarShares LEFT JOIN ".$this->principalsTableName." AS principals ON calendarShares.member = principals.id WHERE calendarShares.calendarid = ? ORDER BY calendarShares.calendarid ASC");
$stmt->execute(array($mCalendarId));
$aShares = array();
while($aRow = $stmt->fetch(\PDO::FETCH_ASSOC))
{
$aShare = array(
'calendarid'=>$aRow['calendarid'],
'principalpath' => $aRow['uri'],
'readOnly'=>$aRow['readonly'],
'summary'=>$aRow['summary'],
'href'=>$aRow['email'],
'commonName' => $aRow['displayname'],
'displayname'=>$aRow['displayname'],
'status'=>$aRow['status'],
'color'=>$aRow['color']
);
// add it to main array
$aShares[] = $aShare;
}
return $aShares;
}
protected function getCalendarFields()
{
$aFields = array_values($this->propertyMap);
$aFields[] = 'id';
$aFields[] = 'uri';
$aFields[] = 'ctag';
$aFields[] = 'components';
$aFields[] = 'principaluri';
$aFields[] = 'transparent';
// Making fields a comma-delimited list
return implode(', ', $aFields);
}
/**
* Returns a list of calendars for a principal.
*
* Every project is an array with the following keys:
* * id, a unique id that will be used by other functions to modify the
* calendar. This can be the same as the uri or a database key.
* * uri, which the basename of the uri with which the calendar is
* accessed.
* * principaluri. The owner of the calendar. Almost always the same as
* principalUri passed to this method.
*
* Furthermore it can contain webdav properties in clark notation. A very
* common one is '{DAV:}displayname'.
*
* MODIFIED: THIS METHOD NOW NEEDS TO BE ABLE TO RETRIEVE SHARED CALENDARS
*
* @param string $principalUri
* @return array
*/
public function getCalendarsForUser($principalUri) {
$aCalendars = $this->getOwnCalendarsForUser($principalUri);
$aSharedCalendars = $this->getSharedCalendarsForUser($principalUri);
$aSharedToAllCalendars = $this->getSharedCalendarsForUser(\afterlogic\DAV\Utils::getTenantPrincipalUri($principalUri));
foreach ($aSharedToAllCalendars as $iKey => $aSharedToAllCalendar)
{
if (isset($aCalendars[$iKey]))
{
$aSharedToAllCalendar['{http://sabredav.org/ns}read-only'] = false;
}
$aCalendars[$iKey] = $aSharedToAllCalendar;
}
foreach ($aSharedCalendars as $iKey => $aSharedCalendar)
{
if (isset($aCalendars[$iKey]))
{
$aSharedCalendar['{http://sabredav.org/ns}read-only'] = false;
}
$aCalendars[$iKey] = $aSharedCalendar;
}
return array_merge($aCalendars, $aSharedCalendars);
}
protected function getOwnCalendarsForUser($principalUri)
{
$sFields = $this->getCalendarFields();
$oStmt = $this->pdo->prepare("SELECT " . $sFields . " FROM ".$this->calendarTableName." WHERE principaluri = ? ORDER BY calendarorder ASC");
$oStmt->execute(array($principalUri));
$aCalendars = array();
while($aRows = $oStmt->fetch(\PDO::FETCH_ASSOC))
{
$aComponents = array();
if ($aRows['components'])
{
$aComponents = explode(',', $aRows['components']);
}
$aCalendar = array(
'id' => $aRows['id'],
'uri' => $aRows['uri'],
'principaluri' => $aRows['principaluri'],
'{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => $aRows['ctag']?$aRows['ctag']:'0',
'{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new \Sabre\CalDAV\Property\SupportedCalendarComponentSet($aComponents),
'{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' => new \Sabre\CalDAV\Property\ScheduleCalendarTransp($aRows['transparent']?'transparent':'opaque'),
);
foreach($this->propertyMap as $xmlName=>$dbName)
{
$aCalendar[$xmlName] = $aRows[$dbName];
}
$aCalendars[$aCalendar['id']] = $aCalendar;
}
return $aCalendars;
}
protected function getSharedCalendarsForUser($sPrincipalUri, $bSharedToAll = false)
{
$aCalendars = array();
$sTenantPrincipalUri = null;
if (!$sPrincipalUri)
{
return $aCalendars;
}
if ($sPrincipalUri)
{
if ($bSharedToAll)
{
$sTenantPrincipalUri = $sPrincipalUri;
$sPrincipalUri = \afterlogic\DAV\Utils::getTenantPrincipalUri($sPrincipalUri);
}
$sFields = $this->getCalendarFields();
$sShareFields = implode(', ', $this->sharesProperties);
$oPrincipalBackend = \afterlogic\DAV\Backends::Principal();
$aPrincipal = $oPrincipalBackend->getPrincipalByPath($sPrincipalUri);
if ($aPrincipal)
{
$oStmt = $this->pdo->prepare("SELECT " . $sShareFields . " FROM ".$this->calendarSharesTableName." WHERE member = ?");
$oStmt->execute(array($aPrincipal['id']));
$aRows = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
foreach ($aRows as $aRow)
{
// get the original calendar
$oCalStmt = $this->pdo->prepare("SELECT " . $sFields . " FROM ".$this->calendarTableName." WHERE id = ? ORDER BY calendarorder ASC LIMIT 1");
$oCalStmt->execute(array($aRow['calendarid']));
while($calRow = $oCalStmt->fetch(\PDO::FETCH_ASSOC))
{
$aComponents = array();
if ($calRow['components'])
{
$aComponents = explode(',', $calRow['components']);
}
$aCalendar = array(
'id' => $calRow['id'],
'uri' => $calRow['uri'],
'principaluri' => $bSharedToAll ? $sTenantPrincipalUri : $sPrincipalUri,
'{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => $calRow['ctag'] ? $calRow['ctag'] : '0',
'{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new \Sabre\CalDAV\Property\SupportedCalendarComponentSet($aComponents),
'{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' => new \Sabre\CalDAV\Property\ScheduleCalendarTransp($calRow['transparent'] ? 'transparent' : 'opaque'),
);
// some specific properies for shared calendars
$aCalendar['{http://calendarserver.org/ns/}shared-url'] = $calRow['uri'];
$aCalendar['{http://sabredav.org/ns}owner-principal'] = $calRow['principaluri'];
$aCalendar['{http://sabredav.org/ns}read-only'] = $aRow['readonly'];
$aCalendar['{http://calendarserver.org/ns/}summary'] = $aRow['summary'];
foreach($this->propertyMap as $xmlName=>$dbName)
{
if($xmlName == '{DAV:}displayname')
{
$aCalendar[$xmlName] = $calRow['displayname'];//$aRow['displayname'] == null ? $calRow['displayname'] : $aRow['displayname'];
}
elseif($xmlName == '{http://apple.com/ns/ical/}calendar-color')
{
$aCalendar[$xmlName] = $aRow['color'] == null ? $calRow['calendarcolor'] : $aRow['color'];
}
else
{
$aCalendar[$xmlName] = $calRow[$dbName];
}
}
$aCalendars[$aCalendar['id']] = $aCalendar;
}
}
}
}
return $aCalendars;
}
/**
* This method is called when a user replied to a request to share.
*
* If the user chose to accept the share, this method should return the
* newly created calendar url.
*
* @param string href The sharee who is replying (often a mailto: address)
* @param int status One of the SharingPlugin::STATUS_* constants
* @param string $calendarUri The url to the calendar thats being shared
* @param string $inReplyTo The unique id this message is a response to
* @param string $summary A description of the reply
* @return null|string
*/
public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) {}
/**
* Marks this calendar as published.
*
* Publishing a calendar should automatically create a read-only, public,
* subscribable calendar.
*
* @param bool $value
* @return void
*/
public function setPublishStatus($calendarId, $value) {}
/**
* Returns a list of notifications for a given principal url.
*
* The returned array should only consist of implementations of
* \Sabre\CalDAV\Notifications\INotificationType.
*
* @param string $principalUri
* @return array
*/
public function getNotificationsForPrincipal($principalUri)
{
$aNotifications = array();
/*
// get ALL notifications for the user NB. Any read or out of date notifications should be already deleted.
$stmt = $this->pdo->prepare("SELECT * FROM ".$this->notificationsTableName." WHERE principaluri = ? ORDER BY dtstamp ASC");
$stmt->execute(array($principalUri));
while($aRow = $stmt->fetch(\PDO::FETCH_ASSOC))
{
// we need to return the correct type of notification
switch($aRow['notification'])
{
case 'Invite':
$aValues = array();
// sort out the required data
if($aRow['id'])
{
$aValues['id'] = $aRow['id'];
}
if($aRow['etag'])
{
$aValues['etag'] = $aRow['etag'];
}
if($aRow['principaluri'])
{
$aValues['href'] = $aRow['principaluri'];
}
if($aRow['dtstamp'])
{
$aValues['dtstamp'] = $aRow['dtstamp'];
}
if($aRow['type'])
{
$aValues['type'] = $aRow['type'];
}
if($aRow['readonly'])
{
$aValues['readOnly'] = $aRow['readonly'];
}
if($aRow['hosturl'])
{
$aValues['hosturl'] = $aRow['hosturl'];
}
if($aRow['organizer'])
{
$aValues['organizer'] = $aRow['organizer'];
}
if($aRow['commonname'])
{
$aValues['commonName'] = $aRow['commonname'];
}
if($aRow['firstname'])
{
$aValues['firstname'] = $aRow['firstname'];
}
if($aRow['lastname'])
{
$aValues['lastname'] = $aRow['lastname'];
}
if($aRow['summary'])
{
$aValues['summary'] = $aRow['summary'];
}
$aNotifications[] = new \Sabre\CalDAV\Notifications\Notification\Invite($aValues);
break;
case 'InviteReply':
break;
case 'SystemStatus':
break;
}
}
*/
return $aNotifications;
}
/**
* This deletes a specific notifcation.
*
* This may be called by a client once it deems a notification handled.
*
* @param string $sPrincipalUri
* @param \Sabre\CalDAV\Notifications\INotificationType $oNotification
* @return void
*/
public function deleteNotification($sPrincipalUri, \Sabre\CalDAV\Notifications\INotificationType $oNotification){ }
}