diff --git a/.gitignore b/.gitignore index 33f8e0c524b..ea8e5bd42fa 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,8 @@ RCS/* # eclipse .project .settings + +# netbeans +nbproject + +.DS_Store \ No newline at end of file diff --git a/3rdparty/Sabre/CalDAV/Backend/Abstract.php b/3rdparty/Sabre/CalDAV/Backend/Abstract.php index 7ac282f44a0..b694eef49e4 100644 --- a/3rdparty/Sabre/CalDAV/Backend/Abstract.php +++ b/3rdparty/Sabre/CalDAV/Backend/Abstract.php @@ -36,20 +36,17 @@ abstract class Sabre_CalDAV_Backend_Abstract { * If the creation was a success, an id must be returned that can be used to reference * this calendar in other methods, such as updateCalendar. * - * This function must return a server-wide unique id that can be used - * later to reference the calendar. - * * @param string $principalUri * @param string $calendarUri * @param array $properties - * @return string|int + * @return void */ abstract function createCalendar($principalUri,$calendarUri,array $properties); /** - * Updates properties on this node, + * Updates properties for a calendar. * - * The properties array uses the propertyName in clark-notation as key, + * The mutations array uses the propertyName in clark-notation as key, * and the array value for the property value. In the case a property * should be deleted, the property value will be null. * @@ -79,10 +76,10 @@ abstract class Sabre_CalDAV_Backend_Abstract { * (424 Failed Dependency) because the request needs to be atomic. * * @param string $calendarId - * @param array $properties + * @param array $mutations * @return bool|array */ - public function updateCalendar($calendarId, array $properties) { + public function updateCalendar($calendarId, array $mutations) { return false; @@ -97,7 +94,7 @@ abstract class Sabre_CalDAV_Backend_Abstract { abstract function deleteCalendar($calendarId); /** - * Returns all calendar objects within a calendar object. + * Returns all calendar objects within a calendar. * * Every item contains an array with the following keys: * * id - unique identifier which will be used for subsequent updates diff --git a/3rdparty/Sabre/CalDAV/Backend/PDO.php b/3rdparty/Sabre/CalDAV/Backend/PDO.php index d1785bb8f8f..7b1b33b912e 100644 --- a/3rdparty/Sabre/CalDAV/Backend/PDO.php +++ b/3rdparty/Sabre/CalDAV/Backend/PDO.php @@ -129,7 +129,6 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract { * @param string $principalUri * @param string $calendarUri * @param array $properties - * @return mixed */ public function createCalendar($principalUri,$calendarUri, array $properties) { @@ -173,9 +172,9 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract { } /** - * Updates a calendars properties + * Updates properties for a calendar. * - * The properties array uses the propertyName in clark-notation as key, + * The mutations array uses the propertyName in clark-notation as key, * and the array value for the property value. In the case a property * should be deleted, the property value will be null. * @@ -205,10 +204,10 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract { * (424 Failed Dependency) because the request needs to be atomic. * * @param string $calendarId - * @param array $properties + * @param array $mutations * @return bool|array */ - public function updateCalendar($calendarId, array $properties) { + public function updateCalendar($calendarId, array $mutations) { $newValues = array(); $result = array( @@ -219,13 +218,13 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract { $hasError = false; - foreach($properties as $propertyName=>$propertyValue) { + foreach($mutations as $propertyName=>$propertyValue) { // We don't know about this property. if (!isset($this->propertyMap[$propertyName])) { $hasError = true; $result[403][$propertyName] = null; - unset($properties[$propertyName]); + unset($mutations[$propertyName]); continue; } @@ -237,7 +236,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract { // If there were any errors we need to fail the request if ($hasError) { // Properties has the remaining properties - foreach($properties as $propertyName=>$propertyValue) { + foreach($mutations as $propertyName=>$propertyValue) { $result[424][$propertyName] = null; } @@ -284,7 +283,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract { } /** - * Returns all calendar objects within a calendar object. + * Returns all calendar objects within a calendar. * * Every item contains an array with the following keys: * * id - unique identifier which will be used for subsequent updates diff --git a/3rdparty/Sabre/CalDAV/Calendar.php b/3rdparty/Sabre/CalDAV/Calendar.php index a50aef12b4f..0d2b3875771 100644 --- a/3rdparty/Sabre/CalDAV/Calendar.php +++ b/3rdparty/Sabre/CalDAV/Calendar.php @@ -12,7 +12,7 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Sabre_CalDAV_Calendar implements Sabre_DAV_ICollection, Sabre_DAV_IProperties, Sabre_DAVACL_IACL { +class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProperties, Sabre_DAVACL_IACL { /** * This is an array with calendar information @@ -178,6 +178,8 @@ class Sabre_CalDAV_Calendar implements Sabre_DAV_ICollection, Sabre_DAV_IPropert public function createFile($name,$calendarData = null) { $calendarData = stream_get_contents($calendarData); + // Converting to UTF-8, if needed + $calendarData = Sabre_DAV_StringUtil::ensureUTF8($calendarData); $supportedComponents = $this->calendarInfo['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set']; if ($supportedComponents) { diff --git a/3rdparty/Sabre/CalDAV/CalendarObject.php b/3rdparty/Sabre/CalDAV/CalendarObject.php index b5c4e49b838..0c99f18deb7 100644 --- a/3rdparty/Sabre/CalDAV/CalendarObject.php +++ b/3rdparty/Sabre/CalDAV/CalendarObject.php @@ -9,7 +9,7 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_DAVACL_IACL { +class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV_ICalendarObject, Sabre_DAVACL_IACL { /** * Sabre_CalDAV_Backend_Abstract @@ -93,6 +93,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_DAVACL if (is_resource($calendarData)) $calendarData = stream_get_contents($calendarData); + // Converting to UTF-8, if needed + $calendarData = Sabre_DAV_StringUtil::ensureUTF8($calendarData); + $supportedComponents = $this->calendarInfo['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set']; if ($supportedComponents) { $supportedComponents = $supportedComponents->getValue(); diff --git a/3rdparty/Sabre/CalDAV/ICalendar.php b/3rdparty/Sabre/CalDAV/ICalendar.php new file mode 100644 index 00000000000..8193dff3a83 --- /dev/null +++ b/3rdparty/Sabre/CalDAV/ICalendar.php @@ -0,0 +1,18 @@ +server->tree->getNodeForPath($uri); - if ($node instanceof Sabre_CalDAV_Calendar || $node instanceof Sabre_CalDAV_CalendarObject) { + if ($node instanceof Sabre_CalDAV_ICalendar || $node instanceof Sabre_CalDAV_ICalendarObject) { return array( '{' . self::NS_CALDAV . '}calendar-multiget', '{' . self::NS_CALDAV . '}calendar-query', @@ -143,7 +143,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { $server->propertyMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre_CalDAV_Property_SupportedCalendarComponentSet'; - $server->resourceTypeMapping['Sabre_CalDAV_Calendar'] = '{urn:ietf:params:xml:ns:caldav}calendar'; + $server->resourceTypeMapping['Sabre_CalDAV_ICalendar'] = '{urn:ietf:params:xml:ns:caldav}calendar'; $server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyRead'] = '{http://calendarserver.org/ns/}calendar-proxy-read'; $server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyWrite'] = '{http://calendarserver.org/ns/}calendar-proxy-write'; @@ -326,7 +326,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin { } // instanceof IPrincipal - if ($node instanceof Sabre_CalDAV_CalendarObject) { + if ($node instanceof Sabre_CalDAV_ICalendarObject) { // The calendar-data property is not supposed to be a 'real' // property, but in large chunks of the spec it does act as such. // Therefore we simply expose it as a property. diff --git a/3rdparty/Sabre/CalDAV/Version.php b/3rdparty/Sabre/CalDAV/Version.php index 5ecc0cebb37..df8fe1f6bd6 100644 --- a/3rdparty/Sabre/CalDAV/Version.php +++ b/3rdparty/Sabre/CalDAV/Version.php @@ -14,7 +14,7 @@ class Sabre_CalDAV_Version { /** * Full version number */ - const VERSION = '1.5.0'; + const VERSION = '1.5.3'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/CardDAV/AddressBook.php b/3rdparty/Sabre/CardDAV/AddressBook.php index 04e4c227b86..3333480ea85 100644 --- a/3rdparty/Sabre/CardDAV/AddressBook.php +++ b/3rdparty/Sabre/CardDAV/AddressBook.php @@ -112,6 +112,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca public function createFile($name,$vcardData = null) { $vcardData = stream_get_contents($vcardData); + // Converting to UTF-8, if needed + $vcardData = Sabre_DAV_StringUtil::ensureUTF8($vcardData); $this->carddavBackend->createCard($this->addressBookInfo['id'],$name,$vcardData); diff --git a/3rdparty/Sabre/CardDAV/Backend/PDO.php b/3rdparty/Sabre/CardDAV/Backend/PDO.php index 63a74745aac..5556d0a7648 100644 --- a/3rdparty/Sabre/CardDAV/Backend/PDO.php +++ b/3rdparty/Sabre/CardDAV/Backend/PDO.php @@ -66,7 +66,9 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract { 'principaluri' => $row['principaluri'], '{DAV:}displayname' => $row['displayname'], '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'], - '{http://calendarserver.org/ns/}getctag' => $row['ctag'], + '{http://calendarserver.org/ns/}getctag' => $row['ctag'], + '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' => + new Sabre_CardDAV_Property_SupportedAddressData(), ); } diff --git a/3rdparty/Sabre/CardDAV/Card.php b/3rdparty/Sabre/CardDAV/Card.php index 52d8b79d7dd..5298d31e245 100644 --- a/3rdparty/Sabre/CardDAV/Card.php +++ b/3rdparty/Sabre/CardDAV/Card.php @@ -88,6 +88,9 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard, if (is_resource($cardData)) $cardData = stream_get_contents($cardData); + // Converting to UTF-8, if needed + $cardData = Sabre_DAV_StringUtil::ensureUTF8($cardData); + $this->carddavBackend->updateCard($this->addressBookInfo['id'],$this->cardData['uri'],$cardData); $this->cardData['carddata'] = $cardData; diff --git a/3rdparty/Sabre/CardDAV/Plugin.php b/3rdparty/Sabre/CardDAV/Plugin.php index a96f9aaebb6..17766b78278 100644 --- a/3rdparty/Sabre/CardDAV/Plugin.php +++ b/3rdparty/Sabre/CardDAV/Plugin.php @@ -95,9 +95,10 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin { public function getSupportedReportSet($uri) { $node = $this->server->tree->getNodeForPath($uri); - if ($node instanceof Sabre_CardDAV_AddressBook || $node instanceof Sabre_CardDAV_ICard) { + if ($node instanceof Sabre_CardDAV_IAddressBook || $node instanceof Sabre_CardDAV_ICard) { return array( '{' . self::NS_CARDDAV . '}addressbook-multiget', + '{' . self::NS_CARDDAV . '}addressbook-query', ); } return array(); diff --git a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php new file mode 100644 index 00000000000..d57d3a6e7bd --- /dev/null +++ b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php @@ -0,0 +1,69 @@ + 'text/vcard', 'version' => '3.0'), + array('contentType' => 'text/vcard', 'version' => '4.0'), + ); + } + + $this->supportedData = $supportedData; + + } + + /** + * Serializes the property in a DOMDocument + * + * @param Sabre_DAV_Server $server + * @param DOMElement $node + * @return void + */ + public function serialize(Sabre_DAV_Server $server,DOMElement $node) { + + $doc = $node->ownerDocument; + + $prefix = + isset($server->xmlNamespaces[Sabre_CardDAV_Plugin::NS_CARDDAV]) ? + $server->xmlNamespaces[Sabre_CardDAV_Plugin::NS_CARDDAV] : + 'card'; + + foreach($this->supportedData as $supported) { + + $caldata = $doc->createElementNS(Sabre_CardDAV_Plugin::NS_CARDDAV, $prefix . ':address-data-type'); + $caldata->setAttribute('content-type',$supported['contentType']); + $caldata->setAttribute('version',$supported['version']); + $node->appendChild($caldata); + + } + + } + +} diff --git a/3rdparty/Sabre/CardDAV/Version.php b/3rdparty/Sabre/CardDAV/Version.php index 8961027fc89..c76ee360354 100644 --- a/3rdparty/Sabre/CardDAV/Version.php +++ b/3rdparty/Sabre/CardDAV/Version.php @@ -18,11 +18,11 @@ class Sabre_CardDAV_Version { /** * Full version number */ - const VERSION = '0.2'; + const VERSION = '1.5.3'; /** * Stability : alpha, beta, stable */ - const STABILITY = 'alpha'; + const STABILITY = 'stable'; } diff --git a/3rdparty/Sabre/DAV/Browser/Plugin.php b/3rdparty/Sabre/DAV/Browser/Plugin.php index 8e0ca24cff2..cd5617babb1 100644 --- a/3rdparty/Sabre/DAV/Browser/Plugin.php +++ b/3rdparty/Sabre/DAV/Browser/Plugin.php @@ -68,9 +68,16 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin { public function httpGetInterceptor($method, $uri) { if ($method!='GET') return true; - - $node = $this->server->tree->getNodeForPath($uri); - if ($node instanceof Sabre_DAV_IFile) return true; + + try { + $node = $this->server->tree->getNodeForPath($uri); + } catch (Sabre_DAV_Exception_FileNotFound $e) { + // We're simply stopping when the file isn't found to not interfere + // with other plugins. + return; + } + if ($node instanceof Sabre_DAV_IFile) + return; $this->server->httpResponse->sendStatus(200); $this->server->httpResponse->setHeader('Content-Type','text/html; charset=utf-8'); @@ -165,6 +172,8 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin { '{DAV:}getlastmodified', ),1); + $parent = $this->server->tree->getNodeForPath($path); + if ($path) { @@ -189,6 +198,7 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin { $type = null; + if (isset($file[200]['{DAV:}resourcetype'])) { $type = $file[200]['{DAV:}resourcetype']->getValue(); @@ -246,7 +256,7 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin { $html.= "
"; - if ($this->enablePost) { + if ($this->enablePost && $parent instanceof Sabre_DAV_ICollection) { $html.= '

Create new folder

diff --git a/3rdparty/Sabre/DAV/Server.php b/3rdparty/Sabre/DAV/Server.php index c6c63143d13..b99866dad5e 100644 --- a/3rdparty/Sabre/DAV/Server.php +++ b/3rdparty/Sabre/DAV/Server.php @@ -738,6 +738,34 @@ class Sabre_DAV_Server { $body = $this->httpRequest->getBody(); + // Intercepting Content-Range + if ($this->httpRequest->getHeader('Content-Range')) { + /** + Content-Range is dangerous for PUT requests: PUT per definition + stores a full resource. draft-ietf-httpbis-p2-semantics-15 says + in section 7.6: + An origin server SHOULD reject any PUT request that contains a + Content-Range header field, since it might be misinterpreted as + partial content (or might be partial content that is being mistakenly + PUT as a full representation). Partial content updates are possible + by targeting a separately identified resource with state that + overlaps a portion of the larger resource, or by using a different + method that has been specifically defined for partial updates (for + example, the PATCH method defined in [RFC5789]). + This clarifies RFC2616 section 9.6: + The recipient of the entity MUST NOT ignore any Content-* + (e.g. Content-Range) headers that it does not understand or implement + and MUST return a 501 (Not Implemented) response in such cases. + OTOH is a PUT request with a Content-Range currently the only way to + continue an aborted upload request and is supported by curl, mod_dav, + Tomcat and others. Since some clients do use this feature which results + in unexpected behaviour (cf PEAR::HTTP_WebDAV_Client 1.0.1), we reject + all PUT requests with a Content-Range for now. + */ + + throw new Sabre_DAV_Exception_NotImplemented('PUT with Content-Range is not allowed.'); + } + // Intercepting the Finder problem if (($expected = $this->httpRequest->getHeader('X-Expected-Entity-Length')) && $expected > 0) { @@ -798,7 +826,10 @@ class Sabre_DAV_Server { } else { // If we got here, the resource didn't exist yet. - $this->createFile($this->getRequestUri(),$body); + if (!$this->createFile($this->getRequestUri(),$body)) { + // For one reason or another the file was not created. + return; + } $this->httpResponse->setHeader('Content-Length','0'); $this->httpResponse->sendStatus(201); @@ -1377,23 +1408,27 @@ class Sabre_DAV_Server { * Currently this is done by HTTP PUT and HTTP LOCK (in the Locks_Plugin). * It was important to get this done through a centralized function, * allowing plugins to intercept this using the beforeCreateFile event. + * + * This method will return true if the file was actually created * * @param string $uri * @param resource $data - * @return void + * @return bool */ public function createFile($uri,$data) { list($dir,$name) = Sabre_DAV_URLUtil::splitPath($uri); - if (!$this->broadcastEvent('beforeBind',array($uri))) return; - if (!$this->broadcastEvent('beforeCreateFile',array($uri,$data))) return; + if (!$this->broadcastEvent('beforeBind',array($uri))) return false; + if (!$this->broadcastEvent('beforeCreateFile',array($uri,$data))) return false; $parent = $this->tree->getNodeForPath($dir); $parent->createFile($name,$data); $this->tree->markDirty($dir); $this->broadcastEvent('afterBind',array($uri)); + + return true; } /** diff --git a/3rdparty/Sabre/DAV/SimpleFile.php b/3rdparty/Sabre/DAV/SimpleFile.php new file mode 100644 index 00000000000..304dff1c5ec --- /dev/null +++ b/3rdparty/Sabre/DAV/SimpleFile.php @@ -0,0 +1,120 @@ +name = $name; + $this->contents = $contents; + $this->mimeType = $mimeType; + + } + + /** + * Returns the node name for this file. + * + * This name is used to construct the url. + * + * @return string + */ + public function getName() { + + return $this->name; + + } + + /** + * Returns the data + * + * This method may either return a string or a readable stream resource + * + * @return mixed + */ + public function get() { + + return $this->contents; + + } + + /** + * Returns the size of the file, in bytes. + * + * @return int + */ + public function getSize() { + + return strlen($this->contents); + + } + + /** + * Returns the ETag for a file + * + * An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change. + * The ETag is an arbritrary string, but MUST be surrounded by double-quotes. + * + * Return null if the ETag can not effectively be determined + */ + public function getETag() { + + return '"' . md5($this->contents) . '"'; + + } + + /** + * Returns the mime-type for a file + * + * If null is returned, we'll assume application/octet-stream + */ + public function getContentType() { + + return $this->mimeType; + + } + +} + +?> diff --git a/3rdparty/Sabre/DAV/StringUtil.php b/3rdparty/Sabre/DAV/StringUtil.php index b0b708f8e0f..440cf6866ca 100644 --- a/3rdparty/Sabre/DAV/StringUtil.php +++ b/3rdparty/Sabre/DAV/StringUtil.php @@ -64,6 +64,27 @@ class Sabre_DAV_StringUtil { } + } + + /** + * This method takes an input string, checks if it's not valid UTF-8 and + * attempts to convert it to UTF-8 if it's not. + * + * Note that currently this can only convert ISO-8559-1 to UTF-8 (latin-1), + * anything else will likely fail. + * + * @param string $input + * @return string + */ + static public function ensureUTF8($input) { + + $encoding = mb_detect_encoding($input , array('UTF-8','ISO-8859-1'), true); + + if ($encoding === 'ISO-8859-1') { + return utf8_encode($input); + } else { + return $input; + } } diff --git a/3rdparty/Sabre/DAV/URLUtil.php b/3rdparty/Sabre/DAV/URLUtil.php index 1502e4dd2ce..8f38749264b 100644 --- a/3rdparty/Sabre/DAV/URLUtil.php +++ b/3rdparty/Sabre/DAV/URLUtil.php @@ -30,9 +30,14 @@ class Sabre_DAV_URLUtil { */ static function encodePath($path) { - $path = explode('/',$path); - return implode('/',array_map(array('Sabre_DAV_URLUtil','encodePathSegment'), $path)); - + $valid_chars = '/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.~()'; + $newStr = ''; + for( $i=0; isset($path[$i]); ++$i ) { + if( strpos($valid_chars,($c=$path[$i]))===false ) $newStr .= '%'.sprintf('%02x',ord($c)); + else $newStr .= $c; + } + return $newStr; + } /** @@ -45,35 +50,13 @@ class Sabre_DAV_URLUtil { */ static function encodePathSegment($pathSegment) { + $valid_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.~()'; $newStr = ''; - for($i=0;$i=0x41 /* A */ && $c<=0x5a /* Z */) || - ($c>=0x61 /* a */ && $c<=0x7a /* z */) || - ($c>=0x30 /* 0 */ && $c<=0x39 /* 9 */) || - $c===0x5f /* _ */ || - $c===0x2d /* - */ || - $c===0x2e /* . */ || - $c===0x7E /* ~ */ || - - /* Reserved, but no reserved purpose */ - $c===0x28 /* ( */ || - $c===0x29 /* ) */ - - ) { - $newStr.=$pathSegment[$i]; - } else { - $newStr.='%' . str_pad(dechex($c), 2, '0', STR_PAD_LEFT); - } - + for( $i=0; isset($pathSegment[$i]); ++$i ) { + if( strpos($valid_chars,($c=$pathSegment[$i]))===false ) $newStr .= '%'.sprintf('%02x',ord($c)); + else $newStr .= $c; } return $newStr; - } /** @@ -103,6 +86,7 @@ class Sabre_DAV_URLUtil { case 'ISO-8859-1' : $path = utf8_encode($path); + } return $path; diff --git a/3rdparty/Sabre/DAV/Version.php b/3rdparty/Sabre/DAV/Version.php index c93d793ab67..e7f7f83e6ff 100644 --- a/3rdparty/Sabre/DAV/Version.php +++ b/3rdparty/Sabre/DAV/Version.php @@ -14,11 +14,11 @@ class Sabre_DAV_Version { /** * Full version number */ - const VERSION = '1.5.0'; + const VERSION = '1.5.3'; /** * Stability : alpha, beta, stable */ - const STABILITY = 'alpha'; + const STABILITY = 'stable'; } diff --git a/3rdparty/Sabre/DAVACL/Principal.php b/3rdparty/Sabre/DAVACL/Principal.php index 158b271058c..790603c900f 100644 --- a/3rdparty/Sabre/DAVACL/Principal.php +++ b/3rdparty/Sabre/DAVACL/Principal.php @@ -68,12 +68,19 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri */ public function getAlternateUriSet() { - if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) { - return array('mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address']); - } else { - return array(); + $uris = array(); + if (isset($this->principalProperties['{DAV:}alternate-URI-set'])) { + + $uris = $this->principalProperties['{DAV:}alternate-URI-set']; + } + if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) { + $uris[] = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address']; + } + + return array_unique($uris); + } /** diff --git a/3rdparty/Sabre/DAVACL/Version.php b/3rdparty/Sabre/DAVACL/Version.php index a705507486c..124463e311e 100644 --- a/3rdparty/Sabre/DAVACL/Version.php +++ b/3rdparty/Sabre/DAVACL/Version.php @@ -14,7 +14,7 @@ class Sabre_DAVACL_Version { /** * Full version number */ - const VERSION = '1.4.4'; + const VERSION = '1.5.2'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/HTTP/Response.php b/3rdparty/Sabre/HTTP/Response.php index c8c77251a17..dce6feac553 100644 --- a/3rdparty/Sabre/HTTP/Response.php +++ b/3rdparty/Sabre/HTTP/Response.php @@ -23,7 +23,7 @@ class Sabre_HTTP_Response { 100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', - 200 => 'Ok', + 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authorative Information', diff --git a/3rdparty/Sabre/HTTP/Version.php b/3rdparty/Sabre/HTTP/Version.php index f8d1bb75429..67be232fc26 100644 --- a/3rdparty/Sabre/HTTP/Version.php +++ b/3rdparty/Sabre/HTTP/Version.php @@ -14,7 +14,7 @@ class Sabre_HTTP_Version { /** * Full version number */ - const VERSION = '1.4.1'; + const VERSION = '1.5.3'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/Sabre/VObject/Property.php b/3rdparty/Sabre/VObject/Property.php index 201e6356ad6..624dd4b8a58 100644 --- a/3rdparty/Sabre/VObject/Property.php +++ b/3rdparty/Sabre/VObject/Property.php @@ -128,6 +128,44 @@ class Sabre_VObject_Property extends Sabre_VObject_Element { } + /** + * Adds a new componenten or element + * + * You can call this method with the following syntaxes: + * + * add(Sabre_VObject_Parameter $element) + * add(string $name, $value) + * + * The first version adds an Parameter + * The second adds a property as a string. + * + * @param mixed $item + * @param mixed $itemValue + * @return void + */ + public function add($item, $itemValue = null) { + + if ($item instanceof Sabre_VObject_Parameter) { + if (!is_null($itemValue)) { + throw new InvalidArgumentException('The second argument must not be specified, when passing a VObject'); + } + $this->parameters[] = $item; + } elseif(is_string($item)) { + + if (!is_scalar($itemValue)) { + throw new InvalidArgumentException('The second argument must be scalar'); + } + $this->parameters[] = new Sabre_VObject_Parameter($item,$itemValue); + + } else { + + throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string'); + + } + + } + + /* ArrayAccess interface {{{ */ /** diff --git a/3rdparty/Sabre/VObject/Reader.php b/3rdparty/Sabre/VObject/Reader.php index 9c20e33cea0..c38afbfb632 100644 --- a/3rdparty/Sabre/VObject/Reader.php +++ b/3rdparty/Sabre/VObject/Reader.php @@ -42,16 +42,10 @@ class Sabre_VObject_Reader { */ static function read($data) { - // Detecting line endings - if (strpos($data,"\r\n")!==false) { - $newLine = "\r\n"; - } elseif (strpos($data,"\r")) { - $newLine = "\r"; - } else { - $newLine = "\n"; - } + // Normalizing newlines + $data = str_replace(array("\r","\n\n"), array("\n","\n"), $data); - $lines = explode($newLine, $data); + $lines = explode("\n", $data); // Unfolding lines $lines2 = array(); diff --git a/3rdparty/Sabre/VObject/Version.php b/3rdparty/Sabre/VObject/Version.php index 8c3fe67b1f4..950c1c51104 100644 --- a/3rdparty/Sabre/VObject/Version.php +++ b/3rdparty/Sabre/VObject/Version.php @@ -14,7 +14,7 @@ class Sabre_VObject_Version { /** * Full version number */ - const VERSION = '1.2.0'; + const VERSION = '1.2.2'; /** * Stability : alpha, beta, stable diff --git a/3rdparty/css/chosen.css b/3rdparty/css/chosen.css index 247d07bf021..96bae0fe95a 100644 --- a/3rdparty/css/chosen.css +++ b/3rdparty/css/chosen.css @@ -10,6 +10,7 @@ select.chzn-select { display: inline-block; zoom: 1; *display: inline; + vertical-align: bottom; } .chzn-container .chzn-drop { background: #fff; diff --git a/README b/README index 4ad4f82f304..60b18defd59 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ It is alpha software in development and should be treated accordingly. http://ownCloud.org -Installation instructions: http://owncloud.org/index.php/Installation +Installation instructions: http://owncloud.org/install Source code: http://gitorious.org/owncloud Mailing list: http://mail.kde.org/mailman/listinfo/owncloud diff --git a/apps/admin_export/appinfo/app.php b/apps/admin_export/appinfo/app.php new file mode 100644 index 00000000000..beebb4864e9 --- /dev/null +++ b/apps/admin_export/appinfo/app.php @@ -0,0 +1,33 @@ +. +* +*/ + + +OC_APP::registerAdmin('admin_export','settings'); + +// add settings page to navigation +$entry = array( + 'id' => "admin_export_settings", + 'order'=>1, + 'href' => OC_Helper::linkTo( "admin_export", "settings.php" ), + 'name' => 'Export' +); diff --git a/apps/admin_export/appinfo/info.xml b/apps/admin_export/appinfo/info.xml new file mode 100644 index 00000000000..c4a2a9b398c --- /dev/null +++ b/apps/admin_export/appinfo/info.xml @@ -0,0 +1,10 @@ + + + admin_export + Import/Export + Import/Export your owncloud data + 0.1 + AGPL + Thomas Schmidt + 2 + diff --git a/apps/admin_export/settings.php b/apps/admin_export/settings.php new file mode 100644 index 00000000000..8308a2b89b5 --- /dev/null +++ b/apps/admin_export/settings.php @@ -0,0 +1,96 @@ +. + * + */ +OC_Util::checkAdminUser(); +OC_Util::checkAppEnabled('admin_export'); +if (isset($_POST['admin_export'])) { + $root = OC::$SERVERROOT . "/"; + $zip = new ZipArchive(); + $filename = sys_get_temp_dir() . "/owncloud_export_" . date("y-m-d_H-i-s") . ".zip"; + error_log("Creating export file at: " . $filename); + if ($zip->open($filename, ZIPARCHIVE::CREATE) !== TRUE) { + exit("Cannot open <$filename>\n"); + } + + if (isset($_POST['owncloud_system'])) { + // adding owncloud system files + error_log("Adding owncloud system files to export"); + zipAddDir($root, $zip, false); + foreach (array(".git", "3rdparty", "apps", "core", "files", "l10n", "lib", "ocs", "search", "settings", "tests") as $dirname) { + zipAddDir($root . $dirname, $zip, true, basename($root) . "/"); + } + } + + if (isset($_POST['owncloud_config'])) { + // adding owncloud config + // todo: add database export + error_log("Adding owncloud config to export"); + zipAddDir($root . "config/", $zip, true, basename($root) . "/"); + $zip->addFile($root . '/data/.htaccess', basename($root) . "/data/owncloud.db"); + } + + if (isset($_POST['user_files'])) { + // adding user files + $zip->addFile($root . '/data/.htaccess', basename($root) . "/data/.htaccess"); + $zip->addFile($root . '/data/index.html', basename($root) . "/data/index.html"); + foreach (OC_User::getUsers() as $i) { + error_log("Adding owncloud user files of $i to export"); + zipAddDir($root . "data/" . $i, $zip, true, basename($root) . "/data/"); + } + } + + $zip->close(); + + header("Content-Type: application/zip"); + header("Content-Disposition: attachment; filename=" . basename($filename)); + header("Content-Length: " . filesize($filename)); + ob_end_clean(); + readfile($filename); + unlink($filename); +} else { +// fill template + $tmpl = new OC_Template('admin_export', 'settings'); + return $tmpl->fetchPage(); +} + +function zipAddDir($dir, $zip, $recursive=true, $internalDir='') { + $dirname = basename($dir); + $zip->addEmptyDir($internalDir . $dirname); + $internalDir.=$dirname.='/'; + + if ($dirhandle = opendir($dir)) { + while (false !== ( $file = readdir($dirhandle))) { + + if (( $file != '.' ) && ( $file != '..' )) { + + if (is_dir($dir . '/' . $file) && $recursive) { + zipAddDir($dir . '/' . $file, $zip, $recursive, $internalDir); + } elseif (is_file($dir . '/' . $file)) { + $zip->addFile($dir . '/' . $file, $internalDir . $file); + } + } + } + closedir($dirhandle); + } else { + error_log("Was not able to open directory: " . $dir); + } +} diff --git a/apps/admin_export/templates/settings.php b/apps/admin_export/templates/settings.php new file mode 100644 index 00000000000..47689facbbc --- /dev/null +++ b/apps/admin_export/templates/settings.php @@ -0,0 +1,13 @@ + +
+ t('Export this ownCloud instance');?> +

t('This will create a compressed file that contains the data of this owncloud instance. + Please choose which components should be included:');?> +

+


+
+ +

+ +
+ diff --git a/apps/bookmarks/addBm.php b/apps/bookmarks/addBm.php index b62fcdfbeb0..a2a39134eab 100644 --- a/apps/bookmarks/addBm.php +++ b/apps/bookmarks/addBm.php @@ -25,6 +25,7 @@ require_once('../../lib/base.php'); // Check if we are a user OC_Util::checkLoggedIn(); +OC_Util::checkAppEnabled('bookmarks'); require_once('bookmarksHelper.php'); diff --git a/apps/bookmarks/ajax/addBookmark.php b/apps/bookmarks/ajax/addBookmark.php index 9b0beb388a0..0dc83d9014d 100644 --- a/apps/bookmarks/ajax/addBookmark.php +++ b/apps/bookmarks/ajax/addBookmark.php @@ -28,6 +28,7 @@ require_once('../../../lib/base.php'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('bookmarks'); $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){ diff --git a/apps/bookmarks/ajax/delBookmark.php b/apps/bookmarks/ajax/delBookmark.php index afe60f7d1bf..4aef86e771b 100644 --- a/apps/bookmarks/ajax/delBookmark.php +++ b/apps/bookmarks/ajax/delBookmark.php @@ -28,6 +28,7 @@ require_once('../../../lib/base.php'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('bookmarks'); $params=array( htmlspecialchars_decode($_GET["url"]), diff --git a/apps/bookmarks/ajax/editBookmark.php b/apps/bookmarks/ajax/editBookmark.php index 5125f9ce898..b427a175e5f 100644 --- a/apps/bookmarks/ajax/editBookmark.php +++ b/apps/bookmarks/ajax/editBookmark.php @@ -28,6 +28,7 @@ require_once('../../../lib/base.php'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('bookmarks'); $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){ diff --git a/apps/bookmarks/ajax/getMeta.php b/apps/bookmarks/ajax/getMeta.php index 4583ef204b4..ca797315ef4 100644 --- a/apps/bookmarks/ajax/getMeta.php +++ b/apps/bookmarks/ajax/getMeta.php @@ -28,6 +28,7 @@ require_once('../../../lib/base.php'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('bookmarks'); // $metadata = array(); diff --git a/apps/bookmarks/ajax/recordClick.php b/apps/bookmarks/ajax/recordClick.php index f5f7c20c6a0..e6fdfe043e1 100644 --- a/apps/bookmarks/ajax/recordClick.php +++ b/apps/bookmarks/ajax/recordClick.php @@ -28,6 +28,7 @@ require_once('../../../lib/base.php'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('bookmarks'); $query = OC_DB::prepare(" UPDATE *PREFIX*bookmarks diff --git a/apps/bookmarks/ajax/updateList.php b/apps/bookmarks/ajax/updateList.php index de3480d6c3a..8e9bda0bc20 100644 --- a/apps/bookmarks/ajax/updateList.php +++ b/apps/bookmarks/ajax/updateList.php @@ -28,6 +28,7 @@ require_once('../../../lib/base.php'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('bookmarks'); $params=array(OC_User::getUser()); $CONFIG_DBTYPE = OC_Config::getValue( 'dbtype', 'sqlite' ); diff --git a/apps/bookmarks/index.php b/apps/bookmarks/index.php index 45c9a52f557..50fea3fddbd 100644 --- a/apps/bookmarks/index.php +++ b/apps/bookmarks/index.php @@ -25,6 +25,7 @@ require_once('../../lib/base.php'); // Check if we are a user OC_Util::checkLoggedIn(); +OC_Util::checkAppEnabled('bookmarks'); OC_App::setActiveNavigationEntry( 'bookmarks_index' ); diff --git a/apps/bookmarks/templates/addBm.php b/apps/bookmarks/templates/addBm.php index cbc4910e1ae..36f04e135b6 100644 --- a/apps/bookmarks/templates/addBm.php +++ b/apps/bookmarks/templates/addBm.php @@ -1,8 +1,8 @@
-

-

-

-

-

-

-
\ No newline at end of file +

+

+

+

+

+

+ diff --git a/apps/bookmarks/templates/list.php b/apps/bookmarks/templates/list.php index 2aa5093c82b..d73657b36ac 100644 --- a/apps/bookmarks/templates/list.php +++ b/apps/bookmarks/templates/list.php @@ -1,30 +1,27 @@ -

+

t('Bookmarks with tag: ') . urldecode($_GET["tag"]) : $l->t('All bookmarks'); ?>

-

-

+

+

-

+

-

-

-

+

+

+

    -
  • Recent Bookmarks
  • -
  • Most clicks
  • +
  • t('Recent Bookmarks'); ?>
  • +
  • t('Most clicks'); ?>
- - You have no bookmarks + t('You have no bookmarks'); ?>
diff --git a/apps/calendar/ajax/activation.php b/apps/calendar/ajax/activation.php index 38f727e9488..89239f21759 100644 --- a/apps/calendar/ajax/activation.php +++ b/apps/calendar/ajax/activation.php @@ -10,6 +10,7 @@ require_once ("../../../lib/base.php"); if(!OC_USER::isLoggedIn()) { die(""); } +OC_JSON::checkAppEnabled('calendar'); $calendarid = $_POST['calendarid']; OC_Calendar_Calendar::setCalendarActive($calendarid, $_POST['active']); $cal = OC_Calendar_Calendar::findCalendar($calendarid); diff --git a/apps/calendar/ajax/changeview.php b/apps/calendar/ajax/changeview.php index d19a11585a0..b396ff4945b 100644 --- a/apps/calendar/ajax/changeview.php +++ b/apps/calendar/ajax/changeview.php @@ -10,6 +10,7 @@ require_once ("../../../lib/base.php"); if(!OC_USER::isLoggedIn()) { die(""); } +OC_JSON::checkAppEnabled('calendar'); $currentview = $_GET["v"]; OC_Preferences::setValue(OC_USER::getUser(), "calendar", "currentview", $currentview); ?> diff --git a/apps/calendar/ajax/choosecalendar.php b/apps/calendar/ajax/choosecalendar.php index 44ff22906f1..0935a4c42ad 100644 --- a/apps/calendar/ajax/choosecalendar.php +++ b/apps/calendar/ajax/choosecalendar.php @@ -11,6 +11,7 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(""); } +OC_JSON::checkAppEnabled('calendar'); $output = new OC_TEMPLATE("calendar", "part.choosecalendar"); $output -> printpage(); ?> diff --git a/apps/calendar/ajax/createcalendar.php b/apps/calendar/ajax/createcalendar.php index 7d80333b258..82176d4368a 100644 --- a/apps/calendar/ajax/createcalendar.php +++ b/apps/calendar/ajax/createcalendar.php @@ -12,6 +12,7 @@ $l10n = new OC_L10N('calendar'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('calendar'); $userid = OC_User::getUser(); $calendarid = OC_Calendar_Calendar::addCalendar($userid, $_POST['name'], $_POST['description'], 'VEVENT,VTODO,VJOURNAL', null, 0, $_POST['color']); diff --git a/apps/calendar/ajax/daysofweekend.php b/apps/calendar/ajax/daysofweekend.php new file mode 100755 index 00000000000..606d13b1e1c --- /dev/null +++ b/apps/calendar/ajax/daysofweekend.php @@ -0,0 +1,11 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +echo OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'weekend', '{"Monday":"false","Tuesday":"false","Wednesday":"false","Thursday":"false","Friday":"false","Saturday":"true","Sunday":"true"}'); +?> diff --git a/apps/calendar/ajax/deletecalendar.php b/apps/calendar/ajax/deletecalendar.php index 30607b92e6f..e8ffe0d0598 100644 --- a/apps/calendar/ajax/deletecalendar.php +++ b/apps/calendar/ajax/deletecalendar.php @@ -12,6 +12,7 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(''); } +OC_JSON::checkAppEnabled('calendar'); $cal = $_POST["calendarid"]; $calendar = OC_Calendar_Calendar::findCalendar($cal); diff --git a/apps/calendar/ajax/deleteevent.php b/apps/calendar/ajax/deleteevent.php index a6750267bd2..9e3c7dd87dd 100644 --- a/apps/calendar/ajax/deleteevent.php +++ b/apps/calendar/ajax/deleteevent.php @@ -12,6 +12,7 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(''); } +OC_JSON::checkAppEnabled('calendar'); $id = $_POST['id']; $data = OC_Calendar_Object::find($id); diff --git a/apps/calendar/ajax/duration.php b/apps/calendar/ajax/duration.php new file mode 100644 index 00000000000..cdc41388abd --- /dev/null +++ b/apps/calendar/ajax/duration.php @@ -0,0 +1,12 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +$duration = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'duration', "60"); +OC_JSON::encodedPrint(array("duration" => $duration)); +?> diff --git a/apps/calendar/ajax/editcalendar.php b/apps/calendar/ajax/editcalendar.php index 8f798d1bbf2..5f61cf50135 100644 --- a/apps/calendar/ajax/editcalendar.php +++ b/apps/calendar/ajax/editcalendar.php @@ -11,9 +11,21 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(""); } +$calendarcolor_options = array( + 'ff0000', // "Red" + '00ff00', // "Green" + 'ffff00', // "Yellow" + '808000', // "Olive" + 'ffa500', // "Orange" + 'ff7f50', // "Coral" + 'ee82ee', // "Violet" + 'ecc255', // dark yellow +); +OC_JSON::checkAppEnabled('calendar'); $calendar = OC_Calendar_Calendar::findCalendar($_GET['calendarid']); $tmpl = new OC_Template("calendar", "part.editcalendar"); $tmpl->assign('new', false); +$tmpl->assign('calendarcolor_options', $calendarcolor_options); $tmpl->assign('calendar', $calendar); $tmpl->printPage(); ?> diff --git a/apps/calendar/ajax/editevent.php b/apps/calendar/ajax/editevent.php index 7187e05d56f..3abf4de98b3 100644 --- a/apps/calendar/ajax/editevent.php +++ b/apps/calendar/ajax/editevent.php @@ -13,6 +13,7 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(''); } +OC_JSON::checkAppEnabled('calendar'); $errarr = OC_Calendar_Object::validateRequest($_POST); if($errarr){ diff --git a/apps/calendar/ajax/editeventform.php b/apps/calendar/ajax/editeventform.php index 47008e02e90..34d6c657cec 100644 --- a/apps/calendar/ajax/editeventform.php +++ b/apps/calendar/ajax/editeventform.php @@ -13,6 +13,7 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(''); } +OC_JSON::checkAppEnabled('calendar'); $calendar_options = OC_Calendar_Calendar::allCalendars(OC_User::getUser()); $category_options = OC_Calendar_Object::getCategoryOptions($l10n); @@ -28,9 +29,10 @@ if($calendar['userid'] != OC_User::getUser()){ $object = Sabre_VObject_Reader::read($data['calendardata']); $vevent = $object->VEVENT; $dtstart = $vevent->DTSTART; -$dtend = $vevent->DTEND; +$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); switch($dtstart->getDateType()) { case Sabre_VObject_Element_DateTime::LOCALTZ: + case Sabre_VObject_Element_DateTime::LOCAL: $startdate = $dtstart->getDateTime()->format('d-m-Y'); $starttime = $dtstart->getDateTime()->format('H:i'); $enddate = $dtend->getDateTime()->format('d-m-Y'); @@ -54,6 +56,11 @@ if (isset($vevent->CATEGORIES)){ $categories = explode(',', $vevent->CATEGORIES->value); $categories = array_map('trim', $categories); } +foreach($categories as $category){ + if (!in_array($category, $category_options)){ + array_unshift($category_options, $category); + } +} $repeat = isset($vevent->CATEGORY) ? $vevent->CATEGORY->value : ''; $description = isset($vevent->DESCRIPTION) ? $vevent->DESCRIPTION->value : ''; diff --git a/apps/calendar/ajax/firstdayofweek.php b/apps/calendar/ajax/firstdayofweek.php new file mode 100755 index 00000000000..eff82cece1d --- /dev/null +++ b/apps/calendar/ajax/firstdayofweek.php @@ -0,0 +1,12 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +$firstdayofweek = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'firstdayofweek', "1"); +OC_JSON::encodedPrint(array("firstdayofweek" => $firstdayofweek)); +?> \ No newline at end of file diff --git a/apps/calendar/ajax/getcal.php b/apps/calendar/ajax/getcal.php index 9794a83ce49..a65c6cf2602 100644 --- a/apps/calendar/ajax/getcal.php +++ b/apps/calendar/ajax/getcal.php @@ -10,6 +10,61 @@ require_once ("../../../lib/base.php"); if(!OC_USER::isLoggedIn()) { die(""); } -$output = new OC_TEMPLATE("calendar", "part.getcal"); -$output -> printpage(); -?> +OC_JSON::checkAppEnabled('calendar'); + +$calendars = OC_Calendar_Calendar::allCalendars(OC_User::getUser(), 1); +$events = array(); +$return = array('calendars'=>array()); +foreach($calendars as $calendar) { + $tmp = OC_Calendar_Object::all($calendar['id']); + $events = array_merge($events, $tmp); + $return['calendars'][$calendar['id']] = array( + 'displayname' => $calendar['displayname'], + 'color' => '#'.$calendar['calendarcolor'] + ); +} + +$select_year = $_GET["year"]; +$user_timezone = OC_Preferences::getValue(OC_USER::getUser(), "calendar", "timezone", "Europe/London"); +foreach($events as $event) +{ + if ($select_year != substr($event['startdate'], 0, 4)) + continue; + $object = Sabre_VObject_Reader::read($event['calendardata']); + $vevent = $object->VEVENT; + $dtstart = $vevent->DTSTART; + $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); + $start_dt = $dtstart->getDateTime(); + $start_dt->setTimezone(new DateTimeZone($user_timezone)); + $end_dt = $dtend->getDateTime(); + $end_dt->setTimezone(new DateTimeZone($user_timezone)); + $year = $start_dt->format('Y'); + $month = $start_dt->format('n') - 1; // return is 0 based + $day = $start_dt->format('j'); + $hour = $start_dt->format('G'); + if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE) { + $hour = 'allday'; + } + + $return_event = array(); + foreach(array('id', 'calendarid', 'objecttype', 'repeating') as $prop) + { + $return_event[$prop] = $event[$prop]; + } + $return_event['startdate'] = explode('|', $start_dt->format('Y|m|d|H|i')); + $return_event['enddate'] = explode('|', $end_dt->format('Y|m|d|H|i')); + $return_event['description'] = $event['summary']; + if ($hour == 'allday') + { + $return_event['allday'] = true; + } + if (isset($return[$year][$month][$day][$hour])) + { + $return[$year][$month][$day][$hour][] = $return_event; + } + else + { + $return[$year][$month][$day][$hour] = array(1 => $return_event); + } +} +OC_JSON::encodedPrint($return); diff --git a/apps/calendar/ajax/geteventinfo.php b/apps/calendar/ajax/geteventinfo.php deleted file mode 100644 index 2e5e713c197..00000000000 --- a/apps/calendar/ajax/geteventinfo.php +++ /dev/null @@ -1,9 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -?> diff --git a/apps/calendar/ajax/moveevent.php b/apps/calendar/ajax/moveevent.php new file mode 100644 index 00000000000..e2b777969da --- /dev/null +++ b/apps/calendar/ajax/moveevent.php @@ -0,0 +1,103 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +error_reporting(E_ALL); +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +$data = OC_Calendar_Object::find($_POST["id"]); +$calendarid = $data["calendarid"]; +$cal = $calendarid; +$id = $_POST["id"]; +$calendar = OC_Calendar_Calendar::findCalendar($calendarid); +if(OC_User::getUser() != $calendar["userid"]){ + OC_JSON::error(); + exit; +} +$newdate = $_POST["newdate"]; +$caldata = array(); +//modified part of editeventform.php +$object = Sabre_VObject_Reader::read($data['calendardata']); +$vevent = $object->VEVENT; +$dtstart = $vevent->DTSTART; +$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); +switch($dtstart->getDateType()) { + case Sabre_VObject_Element_DateTime::LOCALTZ: + case Sabre_VObject_Element_DateTime::LOCAL: + $startdate = $dtstart->getDateTime()->format('d-m-Y'); + $starttime = $dtstart->getDateTime()->format('H:i'); + $enddate = $dtend->getDateTime()->format('d-m-Y'); + $endtime = $dtend->getDateTime()->format('H:i'); + $allday = false; + break; + case Sabre_VObject_Element_DateTime::DATE: + $startdate = $dtstart->getDateTime()->format('d-m-Y'); + $starttime = '00:00'; + $dtend->getDateTime()->modify('-1 day'); + $enddate = $dtend->getDateTime()->format('d-m-Y'); + $endtime = '23:59'; + $allday = true; + break; +} +$caldata["title"] = isset($vevent->SUMMARY) ? $vevent->SUMMARY->value : ''; +$caldata["location"] = isset($vevent->LOCATION) ? $vevent->LOCATION->value : ''; +$caldata["categories"] = array(); +if (isset($vevent->CATEGORIES)){ + $caldata["categories"] = explode(',', $vevent->CATEGORIES->value); + $caldata["categories"] = array_map('trim', $categories); +} +foreach($caldata["categories"] as $category){ + if (!in_array($category, $category_options)){ + array_unshift($category_options, $category); + } +} +$caldata["repeat"] = isset($vevent->CATEGORY) ? $vevent->CATEGORY->value : ''; +$caldata["description"] = isset($vevent->DESCRIPTION) ? $vevent->DESCRIPTION->value : ''; +//end part of editeventform.php +$startdatearray = explode("-", $startdate); +$starttimearray = explode(":", $starttime); +$startunix = mktime($starttimearray[0], $starttimearray[1], 0, $startdatearray[1], $startdatearray[0], $startdatearray[2]); +$enddatearray = explode("-", $enddate); +$endtimearray = explode(":", $endtime); +$endunix = mktime($endtimearray[0], $endtimearray[1], 0, $enddatearray[1], $enddatearray[0], $enddatearray[2]); +$difference = $endunix - $startunix; +if(strlen($newdate) > 10){ + $newdatestringarray = explode("-", $newdate); + if($newdatestringarray[1] == "allday"){ + $allday = true; + $newdatestringarray[1] = "00:00"; + }else{ + if($allday == true){ + $difference = 3600; + } + $allday = false; + } +}else{ + $newdatestringarray = array(); + $newdatestringarray[0] = $newdate; + $newdatestringarray[1] = $starttime; +} +$newdatearray = explode(".", $newdatestringarray[0]); +$newtimearray = explode(":", $newdatestringarray[1]); +$newstartunix = mktime($newtimearray[0], $newtimearray[1], 0, $newdatearray[1], $newdatearray[0], $newdatearray[2]); +$newendunix = $newstartunix + $difference; +if($allday == true){ + $caldata["allday"] = true; +}else{ + unset($caldata["allday"]); +} +$caldata["from"] = date("d-m-Y", $newstartunix); +$caldata["fromtime"] = date("H:i", $newstartunix); +$caldata["to"] = date("d-m-Y", $newendunix); +$caldata["totime"] = date("H:i", $newendunix); +//modified part of editevent.php +$vcalendar = Sabre_VObject_Reader::read($data["calendardata"]); +OC_Calendar_Object::updateVCalendarFromRequest($caldata, $vcalendar); + +$result = OC_Calendar_Object::edit($id, $vcalendar->serialize()); +OC_JSON::success(); +//end part of editevent.php +?> \ No newline at end of file diff --git a/apps/calendar/ajax/newcalendar.php b/apps/calendar/ajax/newcalendar.php index ffcffb8afd7..e01ae01ee8a 100644 --- a/apps/calendar/ajax/newcalendar.php +++ b/apps/calendar/ajax/newcalendar.php @@ -11,11 +11,12 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(""); } +OC_JSON::checkAppEnabled('calendar'); $calendar = array( 'id' => 'new', - 'displayname' => 'Test', - 'description' => 'Test calendar', - 'calendarcolor' => 'black', + 'displayname' => '', + 'description' => '', + 'calendarcolor' => '', ); $tmpl = new OC_Template('calendar', 'part.editcalendar'); $tmpl->assign('new', true); diff --git a/apps/calendar/ajax/newevent.php b/apps/calendar/ajax/newevent.php index 9ac3b0aaff6..1a696cf7780 100644 --- a/apps/calendar/ajax/newevent.php +++ b/apps/calendar/ajax/newevent.php @@ -13,6 +13,7 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(""); } +OC_JSON::checkAppEnabled('calendar'); $errarr = OC_Calendar_Object::validateRequest($_POST); if($errarr){ diff --git a/apps/calendar/ajax/neweventform.php b/apps/calendar/ajax/neweventform.php index 7a4c6f469e5..9d4dcfa2e13 100644 --- a/apps/calendar/ajax/neweventform.php +++ b/apps/calendar/ajax/neweventform.php @@ -13,6 +13,7 @@ $l10n = new OC_L10N('calendar'); if(!OC_USER::isLoggedIn()) { die(''); } +OC_JSON::checkAppEnabled('calendar'); $calendar_options = OC_Calendar_Calendar::allCalendars(OC_User::getUser()); $category_options = OC_Calendar_Object::getCategoryOptions($l10n); @@ -28,21 +29,21 @@ if($starttime != 'undefined' && !is_nan($starttime) && !$allday){ $starttime = '0'; $startminutes = '00'; }else{ - $starttime = date('H'); + $starttime = date('G'); + $startminutes = date('i'); } -$endday = $startday; -$endmonth = $startmonth; -$endyear = $startyear; -$endtime = $starttime; -$endminutes = $startminutes; -if($endtime == 23) { - $endday++; - $endtime = 0; -} else { - $endtime++; -} +$datetimestamp = mktime($starttime, $startminutes, 0, $startmonth, $startday, $startyear); +$duration = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'duration', "60"); +$datetimestamp = $datetimestamp + ($duration * 60); +$endmonth = date("m", $datetimestamp); +$endday = date("d", $datetimestamp); +$endyear = date("Y", $datetimestamp); +$endtime = date("G", $datetimestamp); +$endminutes = date("i", $datetimestamp); + + $tmpl = new OC_Template('calendar', 'part.newevent'); $tmpl->assign('calendar_options', $calendar_options); diff --git a/apps/calendar/ajax/setdaysofweekend.php b/apps/calendar/ajax/setdaysofweekend.php new file mode 100755 index 00000000000..b5ef5f8573f --- /dev/null +++ b/apps/calendar/ajax/setdaysofweekend.php @@ -0,0 +1,30 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +$weekenddays = array("Monday"=>"false", "Tuesday"=>"false", "Wednesday"=>"false", "Thursday"=>"false", "Friday"=>"false", "Saturday"=>"false", "Sunday"=>"false"); +for($i = 0;$i < count($_POST["weekend"]); $i++){ + switch ($_POST["weekend"][$i]){ + case "Monday": + case "Tuesday": + case "Wednesday": + case "Thursday": + case "Friday": + case "Saturday": + case "Sunday": + break; + default: + OC_JSON::error(); + exit; + } + $weekenddays[$_POST["weekend"][$i]] = "true"; +} +$setValue = json_encode($weekenddays); +OC_Preferences::setValue(OC_User::getUser(), 'calendar', 'weekend', $setValue); +OC_JSON::success(); +?> diff --git a/apps/calendar/ajax/setduration.php b/apps/calendar/ajax/setduration.php new file mode 100644 index 00000000000..a75c8faea42 --- /dev/null +++ b/apps/calendar/ajax/setduration.php @@ -0,0 +1,17 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +if(isset($_POST["duration"])){ + OC_Preferences::setValue(OC_User::getUser(), 'calendar', 'duration', $_POST["duration"]); + OC_JSON::success(); +}else{ + OC_JSON::error(); +} +?> + diff --git a/apps/calendar/ajax/setfirstdayofweek.php b/apps/calendar/ajax/setfirstdayofweek.php new file mode 100755 index 00000000000..571b95af0e3 --- /dev/null +++ b/apps/calendar/ajax/setfirstdayofweek.php @@ -0,0 +1,16 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +if(isset($_POST["firstdayofweek"])){ + OC_Preferences::setValue(OC_User::getUser(), 'calendar', 'firstdayofweek', $_POST["firstdayofweek"]); + OC_JSON::success(); +}else{ + OC_JSON::error(); +} +?> diff --git a/apps/calendar/ajax/settimeformat.php b/apps/calendar/ajax/settimeformat.php new file mode 100644 index 00000000000..7805120ba5e --- /dev/null +++ b/apps/calendar/ajax/settimeformat.php @@ -0,0 +1,17 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +if(isset($_POST["timeformat"])){ + OC_Preferences::setValue(OC_User::getUser(), 'calendar', 'timeformat', $_POST["timeformat"]); + OC_JSON::success(); +}else{ + OC_JSON::error(); +} +?> + diff --git a/apps/calendar/ajax/settimezone.php b/apps/calendar/ajax/settimezone.php index 2b82bc8e4bc..c726a11471d 100644 --- a/apps/calendar/ajax/settimezone.php +++ b/apps/calendar/ajax/settimezone.php @@ -13,6 +13,7 @@ $l=new OC_L10N('calendar'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('calendar'); // Get data if( isset( $_POST['timezone'] ) ){ diff --git a/apps/calendar/ajax/timeformat.php b/apps/calendar/ajax/timeformat.php new file mode 100644 index 00000000000..3533adcf8e0 --- /dev/null +++ b/apps/calendar/ajax/timeformat.php @@ -0,0 +1,12 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +$timeformat = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'timeformat', "24"); +OC_JSON::encodedPrint(array("timeformat" => $timeformat)); +?> diff --git a/apps/calendar/ajax/updatecalendar.php b/apps/calendar/ajax/updatecalendar.php index d53515d0deb..5cf48d50ea1 100644 --- a/apps/calendar/ajax/updatecalendar.php +++ b/apps/calendar/ajax/updatecalendar.php @@ -12,6 +12,7 @@ $l10n = new OC_L10N('calendar'); // Check if we are a user OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('calendar'); $calendarid = $_POST['id']; OC_Calendar_Calendar::editCalendar($calendarid, $_POST['name'], $_POST['description'], null, null, null, $_POST['color']); diff --git a/apps/calendar/caldav.php b/apps/calendar/caldav.php index 83f6a5ab51d..b581274398d 100644 --- a/apps/calendar/caldav.php +++ b/apps/calendar/caldav.php @@ -10,6 +10,7 @@ $RUNTIME_NOSETUPFS = true; require_once('../../lib/base.php'); +OC_Util::checkAppEnabled('calendar'); // Backends $authBackend = new OC_Connector_Sabre_Auth(); diff --git a/apps/calendar/css/style.css b/apps/calendar/css/style.css index f1bd0f9a9c4..5e19b88f55a 100644 --- a/apps/calendar/css/style.css +++ b/apps/calendar/css/style.css @@ -45,6 +45,7 @@ .weekend_thead, .weekend_row{height: 20px;text-align: center;text-align: center;background: #F3F3F3;} .thisday{background: #FFFABC;} .event {position:relative;} +.event.colored {border-bottom: 1px solid white;} .popup {display: none; position: absolute; z-index: 1000; background: #eeeeee; color: #000000; border: 1px solid #1a1a1a; font-size: 90%;} .event_popup {width: 280px; height: 40px; padding: 10px;} @@ -57,3 +58,6 @@ color:#A9A9A9; } select#category{width:140px;} button.category{margin:0 3px;} + +.calendar-colorpicker-color{display:inline-block;width:20px;height:20px;margin-right:2px;cursor:pointer;} +.calendar-colorpicker-color.active{background-image:url("../../../core/img/jquery-ui/ui-icons_222222_256x240.png");background-position:-62px -143px;} diff --git a/apps/calendar/export.php b/apps/calendar/export.php index a6fdaba1d2f..b3e5ecd6834 100644 --- a/apps/calendar/export.php +++ b/apps/calendar/export.php @@ -8,16 +8,31 @@ require_once ("../../lib/base.php"); OC_Util::checkLoggedIn(); +OC_Util::checkAppEnabled('calendar'); $cal = $_GET["calid"]; -$calendar = OC_Calendar_Calendar::findCalendar($cal); -if($calendar["userid"] != OC_User::getUser()){ - header( 'Location: '.OC_Helper::linkTo('', 'index.php')); - exit; -} -$calobjects = OC_Calendar_Object::all($cal); -header("Content-Type: text/Calendar"); -header("Content-Disposition: inline; filename=calendar.ics"); -for($i = 0;$i <= count($calobjects); $i++){ - echo $calobjects[$i]["calendardata"] . "\n"; +$event = $_GET["eventid"]; +if(isset($cal)){ + $calendar = OC_Calendar_Calendar::findCalendar($cal); + if($calendar["userid"] != OC_User::getUser()){ + OC_JSON::error(); + exit; + } + $calobjects = OC_Calendar_Object::all($cal); + header("Content-Type: text/Calendar"); + header("Content-Disposition: inline; filename=calendar.ics"); + for($i = 0;$i <= count($calobjects); $i++){ + echo $calobjects[$i]["calendardata"] . "\n"; + } +}elseif(isset($event)){ + $data = OC_Calendar_Object::find($_GET["eventid"]); + $calendarid = $data["calendarid"]; + $calendar = OC_Calendar_Calendar::findCalendar($calendarid); + if($calendar["userid"] != OC_User::getUser()){ + OC_JSON::error(); + exit; + } + header("Content-Type: text/Calendar"); + header("Content-Disposition: inline; filename=" . $data["summary"] . ".ics"); + echo $data["calendardata"]; } ?> diff --git a/apps/calendar/index.php b/apps/calendar/index.php index 39f961d1bb9..1e4d724b307 100644 --- a/apps/calendar/index.php +++ b/apps/calendar/index.php @@ -8,6 +8,7 @@ require_once ('../../lib/base.php'); OC_Util::checkLoggedIn(); +OC_Util::checkAppEnabled('calendar'); // Create default calendar ... $calendars = OC_Calendar_Calendar::allCalendars(OC_User::getUser()); if( count($calendars) == 0){ diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index 1b345452912..131325007a0 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -8,6 +8,8 @@ Calendar={ space:' ', + firstdayofweek: '', + weekend: '', Date:{ normal_year_cal: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], leap_year_cal: [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], @@ -79,7 +81,7 @@ Calendar={ }, UI:{ - weekdays: ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"], + weekdays: '', formatDayShort:function(day){ if (typeof(day) == 'undefined'){ day = Calendar.Date.current.getDay(); @@ -124,7 +126,7 @@ Calendar={ $('#'+this.currentview + "_radio").removeClass('active'); this.currentview = view; //sending ajax request on every change view - $("#sysbox").load(oc_webroot + "/apps/calendar/ajax/changeview.php?v="+view); + $("#sysbox").load(OC.filePath('calendar', 'ajax', 'changeview.php') + "?v="+view); //not necessary to check whether the response is true or not switch(view) { case "onedayview": @@ -153,6 +155,7 @@ Calendar={ Calendar.UI.updateView() }); }, + drageventid: '', updateDate:function(direction){ if(direction == 'forward' && this.current.forward) { this.current.forward(); @@ -178,18 +181,19 @@ Calendar={ if( typeof (this.events[year]) == "undefined") { this.events[year] = [] } - $.getJSON(oc_webroot + "/apps/calendar/ajax/getcal.php?year=" + year, function(newevents, status) { + $.getJSON(OC.filePath('calendar', 'ajax', 'getcal.php') + "?year=" + year, function(jsondata, status) { if(status == "nosession") { alert("You are not logged in. That can happen if you don't use owncloud for a long time."); document.location(oc_webroot); } - if(status == "parsingfail" || typeof (newevents) == "undefined") { + if(status == "parsingfail" || typeof (jsondata) == "undefined") { $.ready(function() { $( "#parsingfail_dialog" ).dialog(); }); } else { - if (typeof(newevents[year]) != 'undefined'){ - Calendar.UI.events[year] = newevents[year]; + if (typeof(jsondata[year]) != 'undefined'){ + Calendar.UI.calendars = jsondata['calendars']; + Calendar.UI.events[year] = jsondata[year]; } $(document).ready(function() { Calendar.UI.updateView(); @@ -218,7 +222,7 @@ Calendar={ if (!events) { return; } - var weekday = (date.getDay()+6)%7; + var weekday = (date.getDay()+7-Calendar.firstdayofweek)%7; if( typeof (events["allday"]) != "undefined") { var eventnumber = 1; var eventcontainer = this.current.getEventContainer(week, weekday, "allday"); @@ -244,7 +248,17 @@ Calendar={ .data('event_info', event) .hover(this.createEventPopup, this.hideEventPopup) + .draggable({ + drag: function() { + Calendar.UI.drageventid = event.id; + } + }) .click(this.editEvent); + var color = this.calendars[event['calendarid']]['color']; + if (color){ + event_holder.css('background-color', color) + .addClass('colored'); + } eventcontainer.append(event_holder); }, startEventDialog:function(){ @@ -286,7 +300,7 @@ Calendar={ // TODO: save event $('#event').dialog('destroy').remove(); }else{ - $('#dialog_holder').load(oc_webroot + '/apps/calendar/ajax/neweventform.php?d=' + date + '&t=' + time, Calendar.UI.startEventDialog); + $('#dialog_holder').load(OC.filePath('calendar', 'ajax', 'neweventform.php') + '?d=' + date + '&t=' + time, Calendar.UI.startEventDialog); } }, editEvent:function(event){ @@ -297,12 +311,12 @@ Calendar={ // TODO: save event $('#event').dialog('destroy').remove(); }else{ - $('#dialog_holder').load(oc_webroot + '/apps/calendar/ajax/editeventform.php?id=' + id, Calendar.UI.startEventDialog); + $('#dialog_holder').load(OC.filePath('calendar', 'ajax', 'editeventform.php') + '?id=' + id, Calendar.UI.startEventDialog); } }, submitDeleteEventForm:function(url){ var post = $( "#event_form" ).serialize(); - $("#errorbox").html(""); + $("#errorbox").empty(); $.post(url, post, function(data){ if(data.status == 'success'){ $('#event').dialog('destroy').remove(); @@ -315,7 +329,7 @@ Calendar={ }, validateEventForm:function(url){ var post = $( "#event_form" ).serialize(); - $("#errorbox").html(""); + $("#errorbox").empty(); $.post(url, post, function(data){ if(data.status == "error"){ @@ -352,6 +366,12 @@ Calendar={ } },"json"); }, + moveevent:function(eventid, newstartdate){ + $.post(OC.filePath('calendar', 'ajax', 'moveevent.php'), { id: eventid, newdate: newstartdate}, + function(data) { + console.log("Event moved successfully"); + }); + }, showadvancedoptions:function(){ $("#advanced_options").css("display", "block"); $("#advanced_options_button").css("display", "none"); @@ -425,7 +445,7 @@ Calendar={ if(check == false){ return false; }else{ - $.post(oc_webroot + "/apps/calendar/ajax/deletecalendar.php", { calendarid: calid}, + $.post(OC.filePath('calendar', 'ajax', 'deletecalendar.php'), { calendarid: calid}, function(data) { Calendar.UI.loadEvents(); $('#choosecalendar_dialog').dialog('destroy').remove(); @@ -438,7 +458,7 @@ Calendar={ if($('#choosecalendar_dialog').dialog('isOpen') == true){ $('#choosecalendar_dialog').dialog('moveToTop'); }else{ - $('#dialog_holder').load(oc_webroot + '/apps/calendar/ajax/choosecalendar.php', function(){ + $('#dialog_holder').load(OC.filePath('calendar', 'ajax', 'choosecalendar.php'), function(){ $('#choosecalendar_dialog').dialog({ width : 600, close : function(event, ui) { @@ -450,7 +470,7 @@ Calendar={ }, activation:function(checkbox, calendarid) { - $.post(oc_webroot + "/apps/calendar/ajax/activation.php", { calendarid: calendarid, active: checkbox.checked?1:0 }, + $.post(OC.filePath('calendar', 'ajax', 'activation.php'), { calendarid: calendarid, active: checkbox.checked?1:0 }, function(data) { checkbox.checked = data == 1; Calendar.UI.loadEvents(); @@ -458,14 +478,43 @@ Calendar={ }, newCalendar:function(object){ var tr = $(document.createElement('tr')) - .load(oc_webroot + "/apps/calendar/ajax/newcalendar.php"); + .load(OC.filePath('calendar', 'ajax', 'newcalendar.php')); $(object).closest('tr').after(tr).hide(); }, edit:function(object, calendarid){ var tr = $(document.createElement('tr')) - .load(oc_webroot + "/apps/calendar/ajax/editcalendar.php?calendarid="+calendarid); + .load(OC.filePath('calendar', 'ajax', 'editcalendar.php') + "?calendarid="+calendarid, + function(){Calendar.UI.Calendar.colorPicker(this)}); $(object).closest('tr').after(tr).hide(); }, + colorPicker:function(container){ + // based on jquery-colorpicker at jquery.webspirited.com + var obj = $('.colorpicker', container); + var picker = $('
'); + var size = 20; + + //build an array of colors + var colors = {}; + $(obj).children('option').each(function(i, elm) { + colors[i] = {}; + colors[i].color = $(elm).val(); + colors[i].label = $(elm).text(); + }); + for (var i in colors) { + picker.append(''); + } + picker.delegate(".calendar-colorpicker-color", "click", function() { + $(obj).val($(this).attr('rel')); + $(obj).change(); + picker.children('.calendar-colorpicker-color.active').removeClass('active'); + $(this).addClass('active'); + }); + $(obj).after(picker); + $(obj).css({ + position: 'absolute', + left: -10000 + }); + }, submit:function(button, calendarid){ var displayname = $("#displayname_"+calendarid).val(); var active = $("#edit_active_"+calendarid+":checked").length; @@ -490,7 +539,7 @@ Calendar={ cancel:function(button, calendarid){ $(button).closest('tr').prev().show().next().remove(); }, - }, + },/* OneDay:{ forward:function(){ Calendar.Date.forward_day(); @@ -499,7 +548,7 @@ Calendar={ Calendar.Date.backward_day(); }, removeEvents:function(){ - $("#onedayview .calendar_row").html(""); + $("#onedayview .calendar_row").empty(); }, renderCal:function(){ $("#datecontrol_date").val(Calendar.UI.formatDayShort() + Calendar.space + Calendar.Date.current.getDate() + Calendar.space + Calendar.UI.formatMonthShort() + Calendar.space + Calendar.Date.current.getFullYear()); @@ -520,7 +569,7 @@ Calendar={ return $(document.createElement('p')) .html(time + event['description']) }, - }, + },*/ OneWeek:{ forward:function(){ Calendar.Date.forward_week(); @@ -530,7 +579,7 @@ Calendar={ }, removeEvents:function(){ for( i = 0; i <= 6; i++) { - $("#oneweekview ." + Calendar.UI.weekdays[i]).html(""); + $("#oneweekview ." + Calendar.UI.weekdays[i]).empty(); } $("#oneweekview .thisday").removeClass("thisday"); }, @@ -539,7 +588,23 @@ Calendar={ var dates = this.generateDates(); var today = new Date(); for(var i = 0; i <= 6; i++){ - $("#oneweekview th." + Calendar.UI.weekdays[i]).html(Calendar.UI.formatDayShort((i+1)%7) + Calendar.space + dates[i].getDate() + Calendar.space + Calendar.UI.formatMonthShort(dates[i].getMonth())); + $("#oneweekview th." + Calendar.UI.weekdays[i]).html(Calendar.UI.formatDayShort((i+Calendar.firstdayofweek)%7) + Calendar.space + dates[i].getDate() + Calendar.space + Calendar.UI.formatMonthShort(dates[i].getMonth())); + $("#oneweekview td." + Calendar.UI.weekdays[i] + ".allday").attr('title', dates[i].getDate() + "." + String(parseInt(dates[i].getMonth()) + 1) + "." + dates[i].getFullYear() + "-" + "allday"); + $("#oneweekview td." + Calendar.UI.weekdays[i] + ".allday").droppable({ + drop: function() { + Calendar.UI.moveevent(Calendar.UI.drageventid, this.title); + Calendar.UI.loadEvents(); + } + }); + for(var ii = 0;ii <= 23; ii++){ + $("#oneweekview td." + Calendar.UI.weekdays[i] + "." + String(ii)).attr('title', dates[i].getDate() + "." + String(parseInt(dates[i].getMonth()) + 1) + "." + dates[i].getFullYear() + "-" + String(ii) + ":00"); + $("#oneweekview td." + Calendar.UI.weekdays[i] + "." + String(ii)).droppable({ + drop: function() { + Calendar.UI.moveevent(Calendar.UI.drageventid, this.title); + Calendar.UI.loadEvents(); + } + }); + } if(dates[i].getDate() == today.getDate() && dates[i].getMonth() == today.getMonth() && dates[i].getFullYear() == today.getFullYear()){ $("#oneweekview ." + Calendar.UI.weekdays[i]).addClass("thisday"); } @@ -570,14 +635,18 @@ Calendar={ if(dayofweek == 0) { dayofweek = 7; } - date.setDate(date.getDate() - dayofweek + 1); + if(Calendar.firstdayofweek > dayofweek){ + date.setDate(date.getDate() - dayofweek + Calendar.firstdayofweek - 7); + }else{ + date.setDate(date.getDate() - dayofweek + Calendar.firstdayofweek); + } for(var i = 0; i <= 6; i++) { dates[i] = new Date(date) date.setDate(date.getDate() + 1); } return dates; }, - }, + },/* FourWeeks:{ forward:function(){ Calendar.Date.forward_week(); @@ -587,7 +656,7 @@ Calendar={ }, removeEvents:function(){ $('#fourweeksview .day.thisday').removeClass('thisday'); - $('#fourweeksview .day .events').html(''); + $('#fourweeksview .day .events').empty(); }, renderCal:function(){ var calw1 = Calendar.Date.calw(); @@ -674,7 +743,7 @@ Calendar={ } return dates; }, - }, + },*/ OneMonth:{ forward:function(){ Calendar.Date.forward_month(); @@ -684,7 +753,7 @@ Calendar={ }, removeEvents:function(){ $('#onemonthview .day.thisday').removeClass('thisday'); - $('#onemonthview .day .events').html(''); + $('#onemonthview .day .events').empty(); }, renderCal:function(){ $("#datecontrol_date").val(Calendar.UI.formatMonthLong() + Calendar.space + Calendar.Date.current.getFullYear()); @@ -712,6 +781,13 @@ Calendar={ var month = dates[i].getMonth(); var year = dates[i].getFullYear(); $("#onemonthview .week_" + week + " ." + Calendar.UI.weekdays[weekday] + " .dateinfo").html(dayofmonth + Calendar.space + Calendar.UI.formatMonthShort(month)); + $("#onemonthview .week_" + week + " ." + Calendar.UI.weekdays[weekday]).attr('title', dayofmonth + "." + String(parseInt(month) + 1) + "." + year); + $("#onemonthview .week_" + week + " ." + Calendar.UI.weekdays[weekday]).droppable({ + drop: function() { + Calendar.UI.moveevent(Calendar.UI.drageventid, this.title); + Calendar.UI.loadEvents(); + } + }); if(dayofmonth == today.getDate() && month == today.getMonth() && year == today.getFullYear()){ $("#onemonthview .week_" + week + " ." + Calendar.UI.weekdays[weekday]).addClass('thisday'); } @@ -776,7 +852,11 @@ Calendar={ dayofweek = 7; this.rows++; } - date.setDate(date.getDate() - dayofweek + 1); + if(Calendar.firstdayofweek > dayofweek){ + date.setDate(date.getDate() - dayofweek + Calendar.firstdayofweek - 7); + }else{ + date.setDate(date.getDate() - dayofweek + Calendar.firstdayofweek); + } for(var i = 0; i <= 41; i++) { dates[i] = new Date(date) date.setDate(date.getDate() + 1); @@ -786,7 +866,7 @@ Calendar={ }, List:{ removeEvents:function(){ - this.eventContainer = $('#listview #events').html(''); + this.eventContainer = $('#listview #events').empty(); this.startdate = new Date(); this.enddate = new Date(); this.enddate.setDate(this.enddate.getDate()); diff --git a/apps/calendar/js/settings.js b/apps/calendar/js/settings.js index 90876389858..6c00be06b39 100644 --- a/apps/calendar/js/settings.js +++ b/apps/calendar/js/settings.js @@ -3,9 +3,61 @@ $(document).ready(function(){ OC.msg.startSaving('#calendar .msg') // Serialize the data var post = $( "#timezone" ).serialize(); - $.post( oc_webroot + '/apps/calendar/ajax/settimezone.php', post, function(data){ - OC.msg.finishedSaving('#calendar .msg', data); + $.post( OC.filePath('calendar', 'ajax', 'settimezone.php'), post, function(data){ + //OC.msg.finishedSaving('#calendar .msg', data); }); return false; }); + $("#timezone").chosen(); + $("#firstdayofweek").change( function(){ + var data = $("#firstdayofweek").serialize(); + $.post( OC.filePath('calendar', 'ajax', 'setfirstdayofweek.php'), data, function(data){ + if(data == "error"){ + console.log("saving first day of week failed"); + } + }); + }); + $.getJSON(OC.filePath('calendar', 'ajax', 'firstdayofweek.php'), function(jsondata, status) { + $("#select_" + jsondata.firstdayofweek).attr('selected',true); + $("#firstdayofweek").chosen(); + }); + $.getJSON(OC.filePath('calendar', 'ajax', 'daysofweekend.php'), function(jsondata, status) { + for(day in jsondata){ + if(jsondata[day] == "true"){ + $("#selectweekend_" + day).attr('selected',true); + } + } + $("#weekend").chosen(); + }); + $("#timeformat").change( function(){ + var data = $("#timeformat").serialize(); + $.post( OC.filePath('calendar', 'ajax', 'settimeformat.php'), data, function(data){ + if(data == "error"){ + console.log("saving timeformat failed"); + } + }); + }); + $.getJSON(OC.filePath('calendar', 'ajax', 'timeformat.php'), function(jsondata, status) { + $("#" + jsondata.timeformat).attr('selected',true); + $("#timeformat").chosen(); + }); + $("#duration").blur( function(){ + var data = $("#duration").val(); + $.post( OC.filePath('calendar', 'ajax', 'setduration.php'), {duration: data}, function(data){ + if(data == "error"){ + console.log("saving duration failed"); + } + }); + }); + $.getJSON(OC.filePath('calendar', 'ajax', 'duration.php'), function(jsondata, status) { + $("#duration").val(jsondata.duration); + }); + $("#weekend").change( function(){ + var data = $("#weekend").serialize(); + $.post( OC.filePath('calendar', 'ajax', 'setdaysofweekend.php'), data, function(data){ + if(data == "error"){ + console.log("saving days of weekend failed"); + } + }); + }); }); diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php index 0c7649776d5..0c3e497d4f2 100644 --- a/apps/calendar/lib/object.php +++ b/apps/calendar/lib/object.php @@ -286,6 +286,30 @@ class OC_Calendar_Object{ } } + public static function getDTEndFromVEvent($vevent) + { + if ($vevent->DTEND) { + $dtend = $vevent->DTEND; + }else{ + $dtend = clone $vevent->DTSTART; + if ($vevent->DURATION){ + $duration = strval($vevent->DURATION); + $invert = 0; + if ($duration[0] == '-'){ + $duration = substr($duration, 1); + $invert = 1; + } + if ($duration[0] == '+'){ + $duration = substr($duration, 1); + } + $interval = new DateInterval($duration); + $interval->invert = $invert; + $dtend->getDateTime()->add($interval); + } + } + return $dtend; + } + public static function getCategoryOptions($l10n) { return array( @@ -482,6 +506,7 @@ class OC_Calendar_Object{ } $vevent->DTSTART = $dtstart; $vevent->DTEND = $dtend; + unset($vevent->DURATION); if($location != ""){ $vevent->LOCATION = $location; diff --git a/apps/calendar/templates/calendar.php b/apps/calendar/templates/calendar.php index a185d3e7087..317bb17ddbc 100644 --- a/apps/calendar/templates/calendar.php +++ b/apps/calendar/templates/calendar.php @@ -1,5 +1,5 @@ $l->t('All day'), 0 => '0', 1 => '1', @@ -26,9 +26,58 @@ $hours = array( 22 => '22', 23 => '23', ); -$weekdays = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'); +$hoursampm = array( + 'allday' => $l->t('All day'), + 0 => '12 a.m.', + 1 => '1 a.m.', + 2 => '2 a.m.', + 3 => '3 a.m.', + 4 => '4 a.m.', + 5 => '5 a.m.', + 6 => '6 a.m.', + 7 => '7 a.m.', + 8 => '8 a.m.', + 9 => '9 a.m.', + 10 => '10 a.m.', + 11 => '11 a.m.', + 12 => '12 p.m.', + 13 => '1 p.m.', + 14 => '2 p.m.', + 15 => '3 p.m.', + 16 => '4 p.m.', + 17 => '5 p.m.', + 18 => '6 p.m.', + 19 => '7 p.m.', + 20 => '8 p.m.', + 21 => '9 p.m.', + 22 => '10 p.m.', + 23 => '11 p.m.', +); +if(OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'timeformat', "24") == "24"){ + $hours = $hours24; +}else{ + $hours = $hoursampm; +} +$weekdaynames = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); +$dayforgenerator = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'firstdayofweek', "1"); +$weekdays = array(); +for($i = 0;$i <= 6; $i++){ + $weekdays[$i] = $weekdaynames[$dayforgenerator]; + if($dayforgenerator == 6){ + $dayforgenerator = 0; + }else{ + $dayforgenerator++; + } +} +$weekendjson = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'weekend', '{"Monday":"false","Tuesday":"false","Wednesday":"false","Thursday":"false","Friday":"false","Saturday":"true","Sunday":"true"}'); +$weekend = json_decode($weekendjson, true); +$weekenddays = array("sunday"=>$weekend["Sunday"], "monday"=>$weekend["Monday"], "tuesday"=>$weekend["Tuesday"], "wednesday"=>$weekend["Wednesday"], "thursday"=>$weekend["Thursday"], "friday"=>$weekend["Friday"], "saturday"=>$weekend["Saturday"]); ?>