mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 16:48:49 +01:00
basic managed attachment support, tested with iCal from OS X mountain lion
This commit is contained in:
parent
3bdc5577d8
commit
1752f7defd
@ -7,7 +7,7 @@
|
|||||||
* @package calendar
|
* @package calendar
|
||||||
* @subpackage groupdav
|
* @subpackage groupdav
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @copyright (c) 2007-12 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2007-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1019,8 +1019,7 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
{
|
{
|
||||||
if ($this->debug) error_log(__METHOD__."() importVCal($eventId) returned false");
|
if ($this->debug) error_log(__METHOD__."() importVCal($eventId) returned false");
|
||||||
}
|
}
|
||||||
// we should not return an etag here, as we never store the ical byte-by-byte
|
header('ETag: "'.$this->get_etag($eventId).'"');
|
||||||
//header('ETag: "'.$this->get_etag($eventId).'"');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1318,6 +1317,18 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
return $event;
|
return $event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update etag, ctag and sync-token to reflect changed attachments
|
||||||
|
*
|
||||||
|
* @param array|string|int $entry array with entry data from read, or id
|
||||||
|
*/
|
||||||
|
public function update_tags($entry)
|
||||||
|
{
|
||||||
|
if (!is_array($entry)) $entry = $this->read($entry);
|
||||||
|
|
||||||
|
$this->bo->update($entry, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query ctag for calendar
|
* Query ctag for calendar
|
||||||
*
|
*
|
||||||
@ -1453,6 +1464,7 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
{
|
{
|
||||||
$handler = new calendar_ical();
|
$handler = new calendar_ical();
|
||||||
$handler->setSupportedFields('GroupDAV',$this->agent);
|
$handler->setSupportedFields('GroupDAV',$this->agent);
|
||||||
|
$handler->supportedFields['attachments'] = true; // enabling attachments
|
||||||
if ($this->debug > 1) error_log("ical Handler called: " . $this->agent);
|
if ($this->debug > 1) error_log("ical Handler called: " . $this->agent);
|
||||||
return $handler;
|
return $handler;
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
'RECURRENCE-ID' => 'recurrence',
|
'RECURRENCE-ID' => 'recurrence',
|
||||||
'SEQUENCE' => 'etag',
|
'SEQUENCE' => 'etag',
|
||||||
'STATUS' => 'status',
|
'STATUS' => 'status',
|
||||||
|
'ATTACH' => 'attachments',
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!is_array($this->supportedFields)) $this->setSupportedFields();
|
if (!is_array($this->supportedFields)) $this->setSupportedFields();
|
||||||
@ -789,6 +790,31 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'ATTACH':
|
||||||
|
static $url_prefix;
|
||||||
|
if (!isset($url_prefix))
|
||||||
|
{
|
||||||
|
$url_prefix = '';
|
||||||
|
if ($GLOBALS['egw_info']['server']['webserver_url'][0] == '/')
|
||||||
|
{
|
||||||
|
$url_prefix = ($_SERVER['HTTPS'] ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach(egw_vfs::find(egw_link::vfs_path('calendar', $event['id'], '', true), array(
|
||||||
|
'type' => 'F',
|
||||||
|
'need_mime' => true,
|
||||||
|
), true) as $path => $stat)
|
||||||
|
{
|
||||||
|
$attributes['ATTACH'][] = $url_prefix.egw::link(egw_vfs::download_url($path));
|
||||||
|
$parameters['ATTACH'][] = array(
|
||||||
|
'MANAGED-ID' => groupdav::path2managed_id($path),
|
||||||
|
'FMTTYP' => $stat['mime'],
|
||||||
|
'SIZE' => $stat['size'],
|
||||||
|
'FILENAME' => egw_vfs::basename($path),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (isset($this->clientProperties[$icalFieldName]['Size']))
|
if (isset($this->clientProperties[$icalFieldName]['Size']))
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* @package infolog
|
* @package infolog
|
||||||
* @subpackage groupdav
|
* @subpackage groupdav
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @copyright (c) 2007-12 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2007-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -569,6 +569,18 @@ class infolog_groupdav extends groupdav_handler
|
|||||||
return $retval;
|
return $retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update etag, ctag and sync-token to reflect changed attachments
|
||||||
|
*
|
||||||
|
* @param array|string|int $entry array with entry data from read, or id
|
||||||
|
*/
|
||||||
|
public function update_tags($entry)
|
||||||
|
{
|
||||||
|
if (!is_array($entry)) $entry = $this->read($entry);
|
||||||
|
|
||||||
|
$this->bo->write($entry, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for infolog_ical::importVTODO to implement infolog-cat-action
|
* Callback for infolog_ical::importVTODO to implement infolog-cat-action
|
||||||
*
|
*
|
||||||
@ -664,6 +676,19 @@ class infolog_groupdav extends groupdav_handler
|
|||||||
return $this->bo->read(array(self::$path_attr => $id, "info_status!='deleted'"),false,'server');
|
return $this->bo->read(array(self::$path_attr => $id, "info_status!='deleted'"),false,'server');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get id from entry-array returned by read()
|
||||||
|
*
|
||||||
|
* Reimplemented because id uses key 'info_id'
|
||||||
|
*
|
||||||
|
* @param int|string|array $entry
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
function get_id($entry)
|
||||||
|
{
|
||||||
|
return is_array($entry) ? $entry['info_id'] : $entry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if user has the neccessary rights on a task / infolog entry
|
* Check if user has the neccessary rights on a task / infolog entry
|
||||||
*
|
*
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* @package api
|
* @package api
|
||||||
* @subpackage groupdav
|
* @subpackage groupdav
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @copyright (c) 2007-12 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2007-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -325,6 +325,8 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
$dav[] = 'calendarserver-principal-property-search';
|
$dav[] = 'calendarserver-principal-property-search';
|
||||||
// required by iOS & OS X iCal to show private checkbox (X-CALENDARSERVER-ACCESS: CONFIDENTIAL on VCALENDAR)
|
// required by iOS & OS X iCal to show private checkbox (X-CALENDARSERVER-ACCESS: CONFIDENTIAL on VCALENDAR)
|
||||||
$dav[] = 'calendarserver-private-events';
|
$dav[] = 'calendarserver-private-events';
|
||||||
|
// managed attachments
|
||||||
|
$dav[] = 'calendar-managed-attachments';
|
||||||
// other capabilities calendarserver announces
|
// other capabilities calendarserver announces
|
||||||
//$dav[] = 'calendar-schedule';
|
//$dav[] = 'calendar-schedule';
|
||||||
//$dav[] = 'calendar-availability';
|
//$dav[] = 'calendar-availability';
|
||||||
@ -1185,6 +1187,20 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
$_GET['add-member'] = ''; // otherwise we give no Location header
|
$_GET['add-member'] = ''; // otherwise we give no Location header
|
||||||
return $this->PUT($options);
|
return $this->PUT($options);
|
||||||
}
|
}
|
||||||
|
if ($this->debug) error_log(__METHOD__.'('.array2string($options).')');
|
||||||
|
|
||||||
|
$this->_parse_path($options['path'],$id,$app,$user);
|
||||||
|
|
||||||
|
if (($handler = self::app_handler($app)))
|
||||||
|
{
|
||||||
|
// managed attachments
|
||||||
|
if (isset($_GET['action']) && substr($_GET['action'], 0, 11) === 'attachment-')
|
||||||
|
{
|
||||||
|
return $this->managed_attachements($options, $id, $handler, $_GET['action']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method_exists($handler, 'post'))
|
||||||
|
{
|
||||||
// read the content in a string, if a stream is given
|
// read the content in a string, if a stream is given
|
||||||
if (isset($options['stream']))
|
if (isset($options['stream']))
|
||||||
{
|
{
|
||||||
@ -1194,17 +1210,168 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
$options['content'] .= fread($options['stream'],8192);
|
$options['content'] .= fread($options['stream'],8192);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->debug) error_log(__METHOD__.'('.array2string($options).')');
|
|
||||||
|
|
||||||
$this->_parse_path($options['path'],$id,$app,$user);
|
|
||||||
|
|
||||||
if (($handler = self::app_handler($app)) && method_exists($handler, 'post'))
|
|
||||||
{
|
|
||||||
return $handler->post($options,$id,$user);
|
return $handler->post($options,$id,$user);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return '501 Not Implemented';
|
return '501 Not Implemented';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP header containing managed id
|
||||||
|
*/
|
||||||
|
const MANAGED_ID_HEADER = 'Cal-Managed-ID';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add, update or remove attachments
|
||||||
|
*
|
||||||
|
* @param array &$options
|
||||||
|
* @param string|int $id
|
||||||
|
* @param groupdav_handler $handler
|
||||||
|
* @param string $action 'attachment-add', 'attachment-update', 'attachment-remove'
|
||||||
|
* @return string http status
|
||||||
|
*
|
||||||
|
* @todo support for rid parameter
|
||||||
|
* @todo managed-id does NOT change on update
|
||||||
|
* @todo updates of attachments through vfs need to call $handler->update_tags($id) too
|
||||||
|
* @todo stripping attachments added via PUT direct and make them managed ones (urls are NOT yet supported too)
|
||||||
|
* @todo update of attachments via PUT on calendar resource (not sure if I want delete), allows to re-user managed-ids ...
|
||||||
|
*/
|
||||||
|
protected function managed_attachements(&$options, $id, groupdav_handler $handler, $action)
|
||||||
|
{
|
||||||
|
error_log(__METHOD__."(path=$options[path], id=$id, ..., action=$action) _GET=".array2string($_GET));
|
||||||
|
$entry = $handler->_common_get_put_delete('GET', $options, $id);
|
||||||
|
|
||||||
|
if (!is_array($entry))
|
||||||
|
{
|
||||||
|
return $entry ? $entry : "404 Not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!egw_link::file_access($handler->app, $entry['id'], EGW_ACL_EDIT))
|
||||||
|
{
|
||||||
|
return '403 Forbidden';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($action)
|
||||||
|
{
|
||||||
|
case 'attachment-add':
|
||||||
|
if (isset($this->_SERVER['HTTP_CONTENT_DISPOSITION']) &&
|
||||||
|
substr($this->_SERVER['HTTP_CONTENT_DISPOSITION'], 0, 10) === 'attachment' &&
|
||||||
|
preg_match('/filename="?([^";]+)/', $this->_SERVER['HTTP_CONTENT_DISPOSITION'], $matches))
|
||||||
|
{
|
||||||
|
$filename = $matches[1];
|
||||||
|
$parts = explode('.', $filename);
|
||||||
|
$ext = '.'.array_pop($parts);
|
||||||
|
$filename = implode('.', $parts);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$filename = 'attachment';
|
||||||
|
if (isset($options['content_type']) && ($ext = mime_magic::mime2ext($options['content_type'])))
|
||||||
|
{
|
||||||
|
$ext = '.'.$ext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ext = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for($i = 1; $i < 100; ++$i)
|
||||||
|
{
|
||||||
|
$path = egw_link::vfs_path($handler->app, $handler->get_id($entry), $filename.($i > 1 ? '-'.$i : '').$ext, true);
|
||||||
|
if (!egw_vfs::stat($path)) break;
|
||||||
|
}
|
||||||
|
if (!($to = egw_vfs::fopen($path, 'w')) ||
|
||||||
|
isset($options['stream']) && ($copied=stream_copy_to_stream($options['stream'], $to)) === false ||
|
||||||
|
isset($options['content']) && ($copied=fwrite($to, $options['content'])) === false)
|
||||||
|
{
|
||||||
|
return '403 Forbidden';
|
||||||
|
}
|
||||||
|
fclose($to);
|
||||||
|
error_log(__METHOD__."() content-type=$options[content_type], filename=$filename, ext=$ext: $path created $copied bytes copied");
|
||||||
|
$ret = '201 Created';
|
||||||
|
header(self::MANAGED_ID_HEADER.': '.self::path2managed_id($path));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'attachment-remove':
|
||||||
|
case 'attachment-update':
|
||||||
|
if (empty($_GET['managed-id']) || !($path = self::managed_id2path($_GET['managed-id'], $app, $id)))
|
||||||
|
{
|
||||||
|
return '404 Not found';
|
||||||
|
}
|
||||||
|
if ($action == 'attachment-remove')
|
||||||
|
{
|
||||||
|
if (!egw_vfs::unlink($path))
|
||||||
|
{
|
||||||
|
return '403 Forbidden';
|
||||||
|
}
|
||||||
|
$ret = '204 No content';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!($to = egw_vfs::fopen($path, 'w')) ||
|
||||||
|
isset($options['stream']) && ($copied=stream_copy_to_stream($options['stream'], $to)) === false ||
|
||||||
|
isset($options['content']) && ($copied=fwrite($to, $options['content'])) === false)
|
||||||
|
{
|
||||||
|
return '403 Forbidden';
|
||||||
|
}
|
||||||
|
fclose($to);
|
||||||
|
error_log(__METHOD__."() content-type=$options[content_type], filename=$filename: $path updated $copied bytes copied");
|
||||||
|
$ret = '200 Ok';
|
||||||
|
header(self::MANAGED_ID_HEADER.': '.self::path2managed_id($path));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return '501 Unknown action parameter '.$action;
|
||||||
|
}
|
||||||
|
// update etag/ctag/sync-token by updating modification time
|
||||||
|
$handler->update_tags($entry);
|
||||||
|
|
||||||
|
// check/handle Prefer: return-representation
|
||||||
|
$handler->check_return_representation($options, $id, $user);
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return managed-id of a vfs-path
|
||||||
|
*
|
||||||
|
* @param string $path "/apps/$app/$id/something"
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function path2managed_id($path)
|
||||||
|
{
|
||||||
|
return base64_encode($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return vfs-path of a managed-id
|
||||||
|
*
|
||||||
|
* @param string $managed_id
|
||||||
|
* @param string $app=null app-name to check against path
|
||||||
|
* @param string|int $id=null id to check agains path
|
||||||
|
* @return string|boolean "/apps/$app/$id/something" or false if not found or not belonging to given $app/$id
|
||||||
|
*/
|
||||||
|
static public function managed_id2path($managed_id, $app=null, $id=null)
|
||||||
|
{
|
||||||
|
$path = base64_decode($managed_id);
|
||||||
|
|
||||||
|
if (!$path || substr($path, 0, 6) != '/apps/' || !egw_vfs::stat($path))
|
||||||
|
{
|
||||||
|
$path = false;
|
||||||
|
}
|
||||||
|
elseif (!empty($app) && !empty($id))
|
||||||
|
{
|
||||||
|
list(,,$a,$i) = explode('/', $path);
|
||||||
|
if ($a !== $app || $i !== (string)$id)
|
||||||
|
{
|
||||||
|
$path = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error_log(__METHOD__."('$managed_id', $app, $id) base64_decode('$managed_id')=".array2string(base64_decode($managed_id)).' returning '.array2string($path));
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Namespaces which need to be eplicitly named in self::$proppatch_props,
|
* Namespaces which need to be eplicitly named in self::$proppatch_props,
|
||||||
* because we consider them protected, if not explicitly named
|
* because we consider them protected, if not explicitly named
|
||||||
@ -1313,8 +1480,15 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
if (($handler = self::app_handler($app)))
|
if (($handler = self::app_handler($app)))
|
||||||
{
|
{
|
||||||
$status = $handler->put($options,$id,$user,$prefix);
|
$status = $handler->put($options,$id,$user,$prefix);
|
||||||
|
|
||||||
// set default stati: true --> 204 No Content, false --> should be already handled
|
// set default stati: true --> 204 No Content, false --> should be already handled
|
||||||
if (is_bool($status)) $status = $status ? '204 No Content' : '400 Something went wrong';
|
if (is_bool($status)) $status = $status ? '204 No Content' : '400 Something went wrong';
|
||||||
|
|
||||||
|
// check/handle Prefer: return-representation
|
||||||
|
if ($status[0] === '2')
|
||||||
|
{
|
||||||
|
$handler->check_return_representation($options, $id, $user);
|
||||||
|
}
|
||||||
return $status;
|
return $status;
|
||||||
}
|
}
|
||||||
return '501 Not Implemented';
|
return '501 Not Implemented';
|
||||||
@ -1596,7 +1770,10 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
self::$log_level === 'f' || $this->debug)
|
self::$log_level === 'f' || $this->debug)
|
||||||
{
|
{
|
||||||
self::$request_starttime = microtime(true);
|
self::$request_starttime = microtime(true);
|
||||||
$this->store_request = true;
|
// do NOT log non-text attachments
|
||||||
|
$this->store_request = $_SERVER['REQUEST_METHOD'] != 'POST' || !isset($_GET['action']) ||
|
||||||
|
!in_array($_GET['action'], array('attachment-add', 'attachment-update')) ||
|
||||||
|
substr($_SERVER['CONTENT_TYPE'], 0, 5) == 'text/';
|
||||||
ob_start();
|
ob_start();
|
||||||
}
|
}
|
||||||
parent::ServeRequest();
|
parent::ServeRequest();
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* @package api
|
* @package api
|
||||||
* @subpackage groupdav
|
* @subpackage groupdav
|
||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @copyright (c) 2007-12 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @copyright (c) 2007-13 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -103,6 +103,13 @@ abstract class groupdav_handler
|
|||||||
*/
|
*/
|
||||||
static $path_attr = 'id';
|
static $path_attr = 'id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New id of put/post stored here by put_response_headers for check_return_representation
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
var $new_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -184,6 +191,17 @@ abstract class groupdav_handler
|
|||||||
*/
|
*/
|
||||||
abstract function read($id /*,$path=null*/);
|
abstract function read($id /*,$path=null*/);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get id from entry-array returned by read()
|
||||||
|
*
|
||||||
|
* @param int|string|array $entry
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
function get_id($entry)
|
||||||
|
{
|
||||||
|
return is_array($entry) ? $entry['id'] : $entry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if user has the neccessary rights on an entry
|
* Check if user has the neccessary rights on an entry
|
||||||
*
|
*
|
||||||
@ -316,6 +334,49 @@ abstract class groupdav_handler
|
|||||||
return $entry;
|
return $entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return representation, if requested by HTTP Prefer header
|
||||||
|
*
|
||||||
|
* @param array $options
|
||||||
|
* @param int $id
|
||||||
|
* @param int $user=null account_id
|
||||||
|
* @return string|boolean http status of get or null if no representation was requested
|
||||||
|
*/
|
||||||
|
public function check_return_representation($options, $id, $user=null)
|
||||||
|
{
|
||||||
|
if (isset($_SERVER['HTTP_PREFER']) && in_array('return-representation', explode(',', $_SERVER['HTTP_PREFER'])))
|
||||||
|
{
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST')
|
||||||
|
{
|
||||||
|
$location = $this->groupdav->base_uri.$options['path'];
|
||||||
|
if ($location[0] == '/')
|
||||||
|
{
|
||||||
|
$location = (@$_SERVER['HTTPS'] === 'on' ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].$location;
|
||||||
|
}
|
||||||
|
header('Content-Location: '.$location);
|
||||||
|
}
|
||||||
|
if (($ret = $this->get($options, $id ? $id : $this->new_id, $user)) && !empty($options['data']))
|
||||||
|
{
|
||||||
|
header('Content-Length: '.$this->groupdav->bytes($options['data']));
|
||||||
|
header('Content-Type: '.$options['mimetype']);
|
||||||
|
echo $options['data'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update etag, ctag and sync-token to reflect changed attachments
|
||||||
|
*
|
||||||
|
* Not abstract, as not need to implement for apps not supporting managed attachments
|
||||||
|
*
|
||||||
|
* @param array|string|int $entry array with entry data from read, or id
|
||||||
|
*/
|
||||||
|
public function update_tags($entry)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the handler for the given app
|
* Get the handler for the given app
|
||||||
*
|
*
|
||||||
@ -498,6 +559,10 @@ abstract class groupdav_handler
|
|||||||
if (is_null($etag)) $etag = $this->get_etag($entry);
|
if (is_null($etag)) $etag = $this->get_etag($entry);
|
||||||
header('ETag: "'.$etag.'"');
|
header('ETag: "'.$etag.'"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store (new) id for check_return_representation
|
||||||
|
$this->new_id = $this->get_path($entry);
|
||||||
|
|
||||||
// send Location header only on success AND if we dont use caldav_name as path-attribute or
|
// send Location header only on success AND if we dont use caldav_name as path-attribute or
|
||||||
if ((is_bool($retval) ? $retval : $retval[0] === '2') && (!$path_attr_is_name ||
|
if ((is_bool($retval) ? $retval : $retval[0] === '2') && (!$path_attr_is_name ||
|
||||||
// POST with add-member query parameter
|
// POST with add-member query parameter
|
||||||
|
Loading…
Reference in New Issue
Block a user