mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-08-29 18:26:05 +00:00
Under development.
This commit is contained in:
parent
6fee9fcb02
commit
1f5961e1b1
@ -6,9 +6,12 @@
|
||||
* @subpackage Resource
|
||||
* @author Andrew McMillan <andrew@mcmillan.net.nz>
|
||||
* @copyright Morphoss Ltd
|
||||
* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later
|
||||
* @license http://gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once('AwlQuery.php');
|
||||
|
||||
|
||||
/**
|
||||
* A class for things to do with a DAV Resource
|
||||
*
|
||||
@ -56,6 +59,16 @@ class DAVResource
|
||||
*/
|
||||
private $_is_principal;
|
||||
|
||||
/**
|
||||
* @var True if this resource is a calendar collection
|
||||
*/
|
||||
private $_is_calendar;
|
||||
|
||||
/**
|
||||
* @var True if this resource is an addressbook collection
|
||||
*/
|
||||
private $_is_addressbook;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param mixed $parameters If null, an empty Resourced is created.
|
||||
@ -65,10 +78,15 @@ class DAVResource
|
||||
function __construct( $parameters = null ) {
|
||||
$this->_is_principal = false;
|
||||
$this->_is_collection = false;
|
||||
$this->_is_calendar = false;
|
||||
$this->_is_addressbook = false;
|
||||
if ( isset($parameters) && is_object($parameters) ) {
|
||||
$this->FromRow($parameters);
|
||||
}
|
||||
else if ( isset($parameters) && is_array($parameters) ) {
|
||||
if ( isset($parameters['path']) ) {
|
||||
$this->FromPath($parameters['path']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,6 +112,117 @@ class DAVResource
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise from a path
|
||||
* @param object $inpath The path to populate the resource data from
|
||||
*/
|
||||
function FromPath($inpath) {
|
||||
global $c;
|
||||
|
||||
$this->path = rawurldecode($inpath);
|
||||
|
||||
/** Allow a path like .../username/calendar.ics to translate into the calendar URL */
|
||||
if ( preg_match( '#^(/[^/]+/[^/]+).ics$#', $this->path, $matches ) ) {
|
||||
$this->path = $matches[1]. '/';
|
||||
}
|
||||
|
||||
/** strip doubled slashes */
|
||||
if ( strstr($this->path,'//') ) $this->path = preg_replace( '#//+#', '/', $this->path);
|
||||
|
||||
$this->FindCollection();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the collection associated with this resource.
|
||||
*/
|
||||
function FindCollection() {
|
||||
/**
|
||||
* RFC4918, 8.3: Identifiers for collections SHOULD end in '/'
|
||||
* - also discussed at more length in 5.2
|
||||
*
|
||||
* So we look for a collection which matches one of the following URLs:
|
||||
* - The exact request.
|
||||
* - If the exact request, doesn't end in '/', then the request URL with a '/' appended
|
||||
* - The request URL truncated to the last '/'
|
||||
* The collection URL for this request is therefore the longest row in the result, so we
|
||||
* can "... ORDER BY LENGTH(dav_name) DESC LIMIT 1"
|
||||
*/
|
||||
$this->collection = (object) array(
|
||||
'collection_id' => -1,
|
||||
'type' => 'unknown',
|
||||
'is_calendar' => false, 'is_principal' => false, 'is_addressbook' => false, 'resourcetypes' => '<DAV::collection/>',
|
||||
|
||||
);
|
||||
|
||||
$sql = "SELECT * FROM collection WHERE dav_name = :raw_path ";
|
||||
$params = array( ':raw_path' => $this->path);
|
||||
if ( !preg_match( '#/$#', $this->path ) ) {
|
||||
$sql .= ' OR dav_name = :up_to_slash OR dav_name = :plus_slash'
|
||||
$params[':up_to_slash'] = preg_replace( '#[^/]*$#', '', $this->path);
|
||||
$params[':plus_slash'] = $this->path."/";
|
||||
}
|
||||
$sql .= "ORDER BY LENGTH(dav_name) DESC LIMIT 1";
|
||||
$qry = new AwlQuery( $sql, $params );
|
||||
if ( $qry->Exec('caldav') && $qry->rows == 1 && ($row = $qry->Fetch()) ) {
|
||||
$this->collection = $row;
|
||||
$this->collection = $row;
|
||||
if ( $row->is_calendar == 't' ) $this->collection->type = 'calendar';
|
||||
else if ( $row->is_addressbook == 't' ) $this->collection->type = 'addressbook';
|
||||
else $this->collection->type = 'collection';
|
||||
}
|
||||
else if ( preg_match( '#^((/[^/]+/)\.(in|out)/)[^/]*$#', $this->path, $matches ) ) {
|
||||
// The request is for a scheduling inbox or outbox (or something inside one) and we should auto-create it
|
||||
$params = array( ':user_no' => $session->user_no, ':parent_container' => $matches[2], ':dav_name' => $matches[1] );
|
||||
$params['displayname'] = $session->fullname . ($matches[3] == 'in' ? ' Inbox' : ' Outbox');
|
||||
$this->collection_type = 'schedule-'. $matches[3]. 'box';
|
||||
$params['resourcetypes'] = sprintf('<DAV::collection/><urn:ietf:params:xml:ns:caldav:%s/>', $this->collection_type );
|
||||
$sql = <<<EOSQL
|
||||
INSERT INTO collection ( user_no, parent_container, dav_name, dav_displayname, is_calendar, created, modified, dav_etag, resourcetypes )
|
||||
VALUES( :user_no, :parent_container, :dav_name, :dav_displayname, FALSE, current_timestamp, current_timestamp, '1', :resourcetypes )
|
||||
EOSQL;
|
||||
$qry = new AwlQuery( $sql, $params );
|
||||
$qry->Exec('caldav');
|
||||
dbg_error_log( "caldav", "Created new collection as '$displayname'." );
|
||||
|
||||
$qry = new AwlQuery( "SELECT * FROM collection WHERE user_no = :user_no AND dav_name = :dav_name", $params );
|
||||
if ( $qry->Exec('caldav') && $qry->rows == 1 && ($row = $qry->Fetch()) ) {
|
||||
$this->collection = $row;
|
||||
$this->collection->type = $this->collection_type;
|
||||
}
|
||||
}
|
||||
else if ( preg_match( '#^((/[^/]+/)calendar-proxy-(read|write))/?[^/]*$#', $this->path, $matches ) ) {
|
||||
$this->collection_type = 'proxy';
|
||||
$this->_is_proxy_request = true;
|
||||
$this->proxy_type = $matches[3];
|
||||
$this->collection_path = $matches[1].'/';
|
||||
}
|
||||
else if ( $this->options['allow_by_email'] && preg_match( '#^/(\S+@\S+[.]\S+)/?$#', $this->path) ) {
|
||||
/** @TODO: we should deprecate this now that Evolution 2.27 can do scheduling extensions */
|
||||
$this->collection_id = -1;
|
||||
$this->collection_type = 'email';
|
||||
$this->collection_path = $this->path;
|
||||
$this->_is_principal = true;
|
||||
}
|
||||
else if ( preg_match( '#^(/[^/]+)/?$#', $this->path, $matches) || preg_match( '#^(/principals/[^/]+/[^/]+)/?$#', $this->path, $matches) ) {
|
||||
$this->collection_id = -1;
|
||||
$this->collection_path = $matches[1].'/'; // Enforce trailling '/'
|
||||
$this->collection_type = 'principal';
|
||||
$this->_is_principal = true;
|
||||
if ( preg_match( '#^(/principals/[^/]+/[^/]+)/?$#', $this->path, $matches) ) {
|
||||
// Force a depth of 0 on these, which are at the wrong URL.
|
||||
$this->depth = 0;
|
||||
}
|
||||
}
|
||||
else if ( $this->path == '/' ) {
|
||||
$this->collection_id = -1;
|
||||
$this->collection_path = '/';
|
||||
$this->collection_type = 'root';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return general server-related properties for this URL
|
||||
*/
|
||||
@ -107,11 +236,11 @@ class DAVResource
|
||||
switch( $tag ) {
|
||||
case 'DAV::href':
|
||||
$prop->NewElement('href', ConstructURL($this->dav_name) );
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'DAV::getcontenttype':
|
||||
$prop->NewElement('getcontenttype', $this->contenttype );
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'DAV::resourcetype':
|
||||
$prop->NewElement('resourcetype', $this->resourcetype );
|
||||
@ -139,7 +268,7 @@ class DAVResource
|
||||
// // After a careful reading of RFC3744 we see that this must be the principal-URL of the owner
|
||||
// $reply->DAVElement( $prop, 'owner', $reply->href( $this->principal_url) ) );
|
||||
// break;
|
||||
|
||||
|
||||
// Empty tag responses.
|
||||
case 'DAV::alternate-URI-set':
|
||||
case 'DAV::getcontentlength':
|
||||
@ -226,7 +355,7 @@ class DAVResource
|
||||
}
|
||||
return $elements;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Render XML for this resource
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user