From 2536d212fd986e433e495a752e4cfb2dfe9e399e Mon Sep 17 00:00:00 2001 From: Christian Putzke Date: Wed, 14 Mar 2012 22:15:04 +0100 Subject: [PATCH] - CardDAV backend class update to v0.5.1 - Minor comment, phpdoc and documentation changes --- CHANGELOG | 121 ++++++++------- README | 46 +++--- carddav.php | 149 +++++++++--------- carddav_addressbook.js | 13 ++ carddav_addressbook.php | 9 +- carddav_backend.php | 334 +++++++++++++++++++++++----------------- carddav_settings.js | 13 ++ config.inc.php.dist | 2 +- 8 files changed, 397 insertions(+), 290 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9b01f5f..f73d167 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,67 +1,76 @@ -v0.3.1 to v0.4 -- added add-functionality for CardDAV-Contacts -- added vCard import-functionality for CardDAV-Addressbooks -- license change from LGPLv2 to AGPLv3 -- CardDAV-Backend class update to v0.4.9 -- added logging -- each CardDAV-Server is now an own addressbook not a group of a global CardDAV-Addressbook like before -- minor bugfixes -- improved synchronization +Changes from v0.4 to v0.5 +- Added automaticly synchronized CardDAV contacts via cronjob +- Added larray skin support +- Added list of CardDAV servers +- Added read only option for CardDAV servers +- Added SOGo support +- CardDAV backend class update to v0.5.1 +- Minor comment, phpdoc and documentation changes -v0.3 to v0.3.1 -- bugfix: didn't merged vCards on edit correctly +Changes from v0.3.1 to v0.4 +- Added add functionality for CardDAV contacts +- Added vCard import functionality for CardDAV addressbooks +- License change from LGPLv2 to AGPLv3 +- CardDAV backend class update to v0.4.9 +- Added logging functionality +- Each CardDAV server is now an own addressbook not a group of a global CardDAV addressbook like before +- Minor bugfixes +- Improved synchronization -changes from v0.2.5 to v0.3 -- added edit and delete functionality for CardDAV-Contacts -- added sabreDAV support -- added ownCloud support -- CardDAV-Backend class update to v0.4.6 -- restructured and cleaned carddav_addressbook class (not completly done yet) -- minor improvements (CURL install check, usability improvements, sync don't add empty vcards now, ...) -- added IT and FR language files +Changes from v0.3 to v0.3.1 +- Bugfix: didn't merged vCards on edit correctly -changes from v0.2.4 to v0.2.5 -- bugfix: email and name can now be null -- ajax POST contents are now base64 encoded -- username and password can now be empty -- minor localization changes +Changes from v0.2.5 to v0.3 +- Added edit and delete functionality for CardDAV contacts +- Added sabreDAV support +- Added ownCloud support +- CardDAV backend class update to v0.4.6 +- Restructured and cleaned carddav_addressbook class (not completly done yet) +- Minor improvements (CURL install check, usability improvements, sync don't add empty vCards now, ...) +- Added IT and FR language files -changes from v0.2.3 to v0.2.4 -- bugfix: last_modified date is now STRING instead of INT -- CardDAV-Backend class update to v0.4.2 +Changes from v0.2.4 to v0.2.5 +- Bugfix: email and name can now be null +- Ajax POST contents are now base64 encoded +- Username and password can now be empty +- Minor localization changes -changes from v0.2.2 to v0.2.3 -- added memotoo support +Changes from v0.2.3 to v0.2.4 +- Bugfix: last_modified date is now STRING instead of INT +- CardDAV backend class update to v0.4.2 + +Changes from v0.2.2 to v0.2.3 +- Added memotoo support - CardDAV-Backend class update to v0.4.1 -- added addressbook search functionality -- changed version naming -- carddav_addressbook class restructured +- Added addressbook search functionality +- Changed version naming +- Restructured carddav_addressbook class -changes from 0.2.1 to 0.2.2 -- CardDAV-Backend class update to v0.4 -- added apple addressbook server support +Changes from 0.2.1 to 0.2.2 +- CardDAV backend class update to v0.4 +- Added apple addressbook server support -changes from 0.2 to 0.2.1 -- show CardDAV-Contacts list (addressbook pagination) bugfix -- autocomplete CardDAV-Contacts groups bugfix -- CardDAV-Groups will now be displayed correctly in the CardDAV-Contact detail view -- hide CardDAV-Contacts sync button if no CardDAV-Servers were added -- fallback skin path added "skins/default" -- minor localization changes +Changes from 0.2 to 0.2.1 +- Show CardDAV contacts list (addressbook pagination) bugfix +- Autocomplete CardDAV contacts groups bugfix +- CardDAV groups will now be displayed correctly in the CardDAV contact detail view +- Hide CardDAV contacts sync button if no CardDAV servers were added +- Fallback skin path added "skins/default" +- Minor localization changes -changes from 0.1 to 0.2 -- save / delete CardDAV-Server settings via ajax -- minor class structure changes -- minor localization changes -- minor database changes -- initial CardDAV-Contacts sync -- addressbook integration (read only) -- manuel CardDAV-Contacts sync (read only) -- CardDAV-Backend class update to v0.3.4 -- autocomplete CardDAV-Contacts +Changes from 0.1 to 0.2 +- Save / delete CardDAV server settings via ajax +- Minor class structure changes +- Minor localization changes +- Minor database changes +- Initial CardDAV contacts sync +- Addressbook integration (read only) +- Manuel CardDAV contacts sync (read only) +- CardDAV backend class update to v0.3.4 +- Autocomplete CardDAV contacts release 0.1 -- save / delete CardDAV-Server settings -- realtime CardDAV-Server check -- multiple CardDAV-Server for each user -- English and German localization +- Save / delete CardDAV server settings +- Realtime CardDAV server check +- Multiple CardDAV server for each user +- English and German localization \ No newline at end of file diff --git a/README b/README index 5c3c77f..21a27e3 100644 --- a/README +++ b/README @@ -1,46 +1,56 @@ Description ----------- -This is a CardDAV-Implementation for roundcube 0.6 or higher +This is a CardDAV-Implementation for roundcube 0.6 or higher. Features -------- -* add multiple CardDAV-Server for each user -* CardDAV-Contacts are stored in the local database which provides great performance -* tested CardDAV-Servers: davical, apple addressbook server, meetoo, sabreDAV, owncloud -* read / add / delete / edit CardDAV-Contacts -* autocomplete all CardDAV-Contacts within the compose email view -* search for all CardDAV-Contacts within the addressbook +* Add multiple CardDAV server for each user +* CardDAV contacts are stored in the local database which provides great performance +* Tested CardDAV servers: DAViCal, Apple Addressbook Server, meetoo, SabreDAV, ownCloud, SOGo +* You can read / add / delete / edit CardDAV contacts (vCards) +* Autocomplete all CardDAV contacts within the compose email view +* Search for all CardDAV contacts within the addressbook -Planned Features +Planned features ---------------- -* automaticly synchronized CardDAV-Contacts -* improved search for CardDAV-Contacts within the addressbook +* Automaticly synchronized CardDAV contacts +* Improved search for CardDAV contacts within the addressbook Requirements ------------ -* SQL-Database +* SQL database * CURL Installation ------------ -* execute SQL-Statements from /plugins/carddav/SQL/mysql.sql -* add 'carddav' to the plugins-array in /config/main.inc.php -* copy /plugins/carddav/config.inc.php.dist to /plugins/carddav/config.inc.php -* login into your roundcube webmail and add your CardDAV-Server in the settings +* Execute SQL statements from /plugins/carddav/SQL/mysql.sql +* Add 'carddav' to the plugins array in /config/main.inc.php +* Copy /plugins/carddav/config.inc.php.dist to /plugins/carddav/config.inc.php +* Login into your roundcube webmail and add your CardDAV server in the settings Update ------ -* execute new SQL-Statements from /plugins/carddav/SQL/mysql.update.sql +* Execute new SQL statements from /plugins/carddav/SQL/mysql.update.sql + + +CardDAV server list +------------------- +* DAViCal: https://example.com/{resource|principal|username}/{collection}/ +* Apple Addressbook Server: https://example.com/addressbooks/users/{resource|principal|username}/{collection}/ +* memotoo: https://sync.memotoo.com/cardDAV/ +* SabreDAV: https://example.com/addressbooks/{resource|principal|username}/{collection}/ +* ownCloud: https://example.com/apps/contacts/carddav.php/addressbooks/{resource|principal|username}/{collection}/ +* SOGo: https://example.com/SOGo/dav/{resource|principal|username}/Contacts/{collection}/ Contact ------- * Author: Christian Putzke -* Report feature requests and bugs here: https://github.com/graviox/CardDAV-PHP/issues +* Report feature requests and bugs here: https://github.com/graviox/Roundcube-CardDAV/issues * Visit Graviox Studios: http://www.graviox.de/ -* Follow me on Twitter: http://twitter.com/graviox +* Follow me on Twitter: https://twitter.com/graviox/ \ No newline at end of file diff --git a/carddav.php b/carddav.php index 04ed996..3e10999 100644 --- a/carddav.php +++ b/carddav.php @@ -1,7 +1,7 @@ - * @copyright Graviox Studios - * @link http://www.graviox.de + * @copyright Christian Putzke @ Graviox Studios * @since 06.09.2011 - * @version 0.4 + * @link http://www.graviox.de/ + * @link https://twitter.com/graviox/ + * @version 0.5 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * */ + class carddav extends rcube_plugin { /** - * Roundcube CardDAV Version + * Roundcube CardDAV version * - * @var constant + * @constant string */ - const VERSION = '0.4'; + const VERSION = '0.5'; /** - * tasks where CardDAV-Plugin is loaded + * Tasks where the CardDAV plugin is loaded * * @var string */ public $task = 'settings|addressbook|mail'; /** - * CardDAV-Addressbook + * CardDAV addressbook * * @var string */ protected $carddav_addressbook = 'carddav_addressbook'; /** - * init CardDAV-Plugins - register actions, include scripts, load texts, add hooks + * Init CardDAV plugin - register actions, include scripts, load texts, add hooks + * + * @return void */ public function init() { @@ -112,16 +115,16 @@ public function init() } /** - * get all CardDAV-Servers from the current user + * Get all CardDAV servers from the current user * - * @param boolean CardDAV-Server id to load a single CardDAV-Server - * @return array CardDAV-Server array with label, url, username, password (encrypted) + * @param boolean $carddav_server_id CardDAV server id to load a single CardDAV server + * @return array CardDAV server array with label, url, username, password (encrypted) */ public function get_carddav_server($carddav_server_id = false) { - $servers = array(); - $rcmail = rcmail::get_instance(); - $user_id = $rcmail->user->data['user_id']; + $servers = array(); + $rcmail = rcmail::get_instance(); + $user_id = $rcmail->user->data['user_id']; $query = " SELECT @@ -144,9 +147,9 @@ public function get_carddav_server($carddav_server_id = false) } /** - * render available CardDAV-Server list in HTML + * Render available CardDAV server list in HTML * - * @return string HTML rendered CardDAV-Server list + * @return string HTML rendered CardDAV server list */ protected function get_carddav_server_list() { @@ -154,8 +157,6 @@ protected function get_carddav_server_list() if (!empty($servers)) { - $rcmail = rcmail::get_instance(); - $table = new html_table(array( 'cols' => 5, 'width' => '950' @@ -169,15 +170,7 @@ protected function get_carddav_server_list() foreach ($servers as $server) { - /* $rcmail->output->button() seems not to work in ajax requests - $delete_submit = $rcmail->output->button(array( - 'command' => 'plugin.carddav-server-delete', - 'prop' => $server['carddav_server_id'], - 'type' => 'input', - 'class' => 'button mainaction', - 'label' => 'delete' - ));*/ - + // $rcmail->output->button() seems not to work within ajax requests so we build the button manually $delete_submit = ''; - $table->add(null, $server['label']); - $table->add(null, $server['url']); - $table->add(null, $server['username']); - $table->add(null, '**********'); - $table->add(null, $delete_submit); + $table->add(array(), $server['label']); + $table->add(array(), $server['url']); + $table->add(array(), $server['username']); + $table->add(array(), '**********'); + $table->add(array(), $delete_submit); } return $table->show(); } + else + { + return null; + } } /** - * get CardDAV-Addressbook instance + * Get CardDAV addressbook instance * - * @param array array with all available addressbooks - * @return array array with all available addressbooks + * @param array $addressbook Array with all available addressbooks + * @return array Array with all available addressbooks */ public function get_carddav_addressbook($addressbook) { @@ -218,10 +215,10 @@ public function get_carddav_addressbook($addressbook) } /** - * get CardDAV-Addressbook source + * Get CardDAV addressbook source * - * @param array array with all available addressbooks sources - * @return array array with all available addressbooks sources + * @param array $addressbook Array with all available addressbooks sources + * @return array Array with all available addressbooks sources */ public function get_carddav_addressbook_sources($addressbook) { @@ -243,9 +240,9 @@ public function get_carddav_addressbook_sources($addressbook) } /** - * check if curl is installed or not + * Check if CURL is installed or not * - * @return boolean + * @return boolean */ private function check_curl_installed() { @@ -260,14 +257,16 @@ private function check_curl_installed() } /** - * synchronize CardDAV addressbook + * Synchronize CardDAV addressbook * - * @param boolean CardDAV-Server id to synchronize a single CardDAV-Server - * @param boolean within a ajax request + * @param boolean $carddav_server_id CardDAV server id to synchronize a single CardDAV server + * @param boolean $ajax Within a ajax request or not + * @return void */ public function carddav_addressbook_sync($carddav_server_id = false, $ajax = true) { - $servers = $this->get_carddav_server(); + $servers = $this->get_carddav_server(); + $result = false; foreach ($servers as $server) { @@ -300,7 +299,9 @@ public function carddav_addressbook_sync($carddav_server_id = false, $ajax = tru } /** - * render CardDAV server settings + * Render CardDAV server settings + * + * @return void */ public function carddav_server() { @@ -311,14 +312,14 @@ public function carddav_server() } /** - * check if CardDAV-Server are available in the local database + * Check if CardDAV server are available in the local database * - * @return boolean if CardDAV-Server are available in the local database return true else false + * @return boolean If CardDAV-Server are available in the local database return true else false */ protected function carddav_server_available() { - $rcmail = rcmail::get_instance(); - $user_id = $rcmail->user->data['user_id']; + $rcmail = rcmail::get_instance(); + $user_id = $rcmail->user->data['user_id']; $query = " SELECT @@ -342,16 +343,15 @@ protected function carddav_server_available() } /** - * check if it's possible to connect to the CardDAV-Server + * Check if it's possible to connect to the CardDAV server * - * @return boolean + * @return boolean */ public function carddav_server_check_connection() { - $rcmail = rcmail::get_instance(); - $url = parse_input_value(base64_decode($_POST['_server_url'])); - $username = parse_input_value(base64_decode($_POST['_username'])); - $password = parse_input_value(base64_decode($_POST['_password'])); + $url = parse_input_value(base64_decode($_POST['_server_url'])); + $username = parse_input_value(base64_decode($_POST['_username'])); + $password = parse_input_value(base64_decode($_POST['_password'])); $carddav_backend = new carddav_backend($url); $carddav_backend->set_auth($username, $password); @@ -360,14 +360,14 @@ public function carddav_server_check_connection() } /** - * render CardDAV-Server settings formular and register javascript actions + * Render CardDAV server settings formular and register JavaScript actions * - * @return string HTML CardDAV-Server formular + * @return string HTML CardDAV server formular */ public function carddav_server_form() { - $rcmail = rcmail::get_instance(); - $boxcontent = null; + $rcmail = rcmail::get_instance(); + $boxcontent = null; if ($this->check_curl_installed()) { @@ -413,11 +413,11 @@ public function carddav_server_form() $table->add(array('class' => 'title', 'width' => '16%'), $this->gettext('password')); $table->add(array('width' => '16%'), null); - $table->add(null, $input_label->show()); - $table->add(null, $input_server_url->show()); - $table->add(null, $input_username->show()); - $table->add(null, $input_password->show()); - $table->add(null, $input_submit); + $table->add(array(), $input_label->show()); + $table->add(array(), $input_server_url->show()); + $table->add(array(), $input_username->show()); + $table->add(array(), $input_password->show()); + $table->add(array(), $input_submit); $boxcontent = $table->show(); } @@ -437,7 +437,9 @@ public function carddav_server_form() } /** - * save CardDAV-Server and execute first CardDAV-Contact sync + * Save CardDAV server and execute first CardDAV contact sync + * + * @return void */ public function carddav_server_save() { @@ -488,7 +490,9 @@ public function carddav_server_save() } /** - * delete CardDAV-Server and all related local contacts + * Delete CardDAV server and all related local contacts + * + * @return void */ public function carddav_server_delete() { @@ -525,7 +529,10 @@ public function carddav_server_delete() } /** - * extended write log with pre defined logfile name and add version before the message content + * Extended write log with pre defined logfile name and add version before the message content + * + * @param string $message Error log message + * @return void */ public function write_log($message) { diff --git a/carddav_addressbook.js b/carddav_addressbook.js index 64bc906..f6691aa 100644 --- a/carddav_addressbook.js +++ b/carddav_addressbook.js @@ -1,3 +1,16 @@ +/** + * Roundcube CardDAV addressbook extension + * + * @author Christian Putzke + * @copyright Christian Putzke @ Graviox Studios + * @since 22.09.2011 + * @link http://www.graviox.de/ + * @link https://twitter.com/graviox/ + * @version 0.5 + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later + * + */ + if (window.rcmail) { rcmail.addEventListener('init', function(evt) diff --git a/carddav_addressbook.php b/carddav_addressbook.php index b0111c2..575c1d4 100644 --- a/carddav_addressbook.php +++ b/carddav_addressbook.php @@ -1,13 +1,14 @@ - * @copyright Graviox Studios + * @copyright Christian Putzke @ Graviox Studios * @since 12.09.2011 - * @link http://www.graviox.de - * @version 0.4 + * @link http://www.graviox.de/ + * @link https://twitter.com/graviox/ + * @version 0.5 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * */ diff --git a/carddav_backend.php b/carddav_backend.php index a98d338..75e122d 100644 --- a/carddav_backend.php +++ b/carddav_backend.php @@ -1,7 +1,7 @@ get(); * * - * simple vCard query + * Simple vCard query * ------------------ * $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); * $carddav->set_auth('username', 'password'); * echo $carddav->get_vcard('0126FFB4-2EB74D0A-302EA17F'); * * - * xml vCard query + * XML vCard query * ------------------ * $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); * $carddav->set_auth('username', 'password'); * echo $carddav->get_xml_vcard('0126FFB4-2EB74D0A-302EA17F'); * * - * check CardDAV-Server connection + * Check CardDAV server connection * ------------------------------- * $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); * $carddav->set_auth('username', 'password'); @@ -50,7 +50,7 @@ * * $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); * $carddav->set_auth('username', 'password'); - * $carddav->add($vcard); + * $vcard_id = $carddav->add($vcard); * * * CardDAV update query @@ -68,20 +68,22 @@ * $carddav->update($vcard, '0126FFB4-2EB74D0A-302EA17F'); * * - * URL-Schema list - * --------------- - * DAViCal: https://example.com/{resource|principal}/{collection}/ - * Apple Addressbook Server: https://example.com/addressbooks/users/{resource|principal}/{collection}/ + * CardDAV server list + * ------------------- + * DAViCal: https://example.com/{resource|principal|username}/{collection}/ + * Apple Addressbook Server: https://example.com/addressbooks/users/{resource|principal|username}/{collection}/ * memotoo: https://sync.memotoo.com/cardDAV/ - * SabreDAV: https://example.com/addressbooks/{resource|principal}/{collection}/ - * ownCloud: https://example.com/apps/contacts/carddav.php/addressbooks/{username}/{resource|principal}/ + * SabreDAV: https://example.com/addressbooks/{resource|principal|username}/{collection}/ + * ownCloud: https://example.com/apps/contacts/carddav.php/addressbooks/{resource|principal|username}/{collection}/ + * SOGo: http://sogo-demo.inverse.ca/SOGo/dav/{resource|principal|username}/Contacts/{collection}/ * * * @author Christian Putzke - * @copyright Graviox Studios - * @link http://www.graviox.de + * @copyright Christian Putzke @ Graviox Studios + * @link http://www.graviox.de/ + * @link https://twitter.com/graviox/ * @since 20.07.2011 - * @version 0.4.9 + * @version 0.5.1 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * */ @@ -89,73 +91,74 @@ class carddav_backend { /** - * CardDAV-PHP Version + * CardDAV PHP Version * - * @var constant + * @constant string */ - const VERSION = '0.4.9'; + const VERSION = '0.5.1'; /** - * user agent displayed in http requests + * User agent displayed in http requests * - * @var constant + * @constant string */ - const USERAGENT = 'CardDAV-PHP/'; + const USERAGENT = 'CardDAV PHP/'; /** - * CardDAV-Server url + * CardDAV server url * * @var string */ private $url = null; /** - * CardDAV-Server url_parts + * CardDAV server url_parts * - * @var string + * @var array */ private $url_parts = null; /** - * authentication information + * Authentication string * * @var string */ private $auth = null; /** - * last used vCard id - * - * @var string - */ - private $vcard_id = null; - - /** - * authentication: username + * Authentication: username * * @var string */ private $username = null; /** - * authentication: password + * Authentication: password * * @var string */ private $password = null; /** - * characters used for vCard id generation + * Characters used for vCard id generation * * @var array */ private $vcard_id_chars = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F'); /** - * constructor - * set the CardDAV-Server url + * CardDAV server connection (curl handle) * - * @param string $url CardDAV-Server url + * @var resource + */ + private $curl; + + /** + * Constructor + * Sets the CardDAV server url + * + * @param string $url CardDAV server url + * @return void */ public function __construct($url = null) { @@ -166,9 +169,10 @@ public function __construct($url = null) } /** - * set the CardDAV-Server url + * Sets the CardDAV server url * - * @param string $url CardDAV-Server url + * @param string $url CardDAV server url + * @return void */ public function set_url($url) { @@ -183,10 +187,11 @@ public function set_url($url) } /** - * set authentication information + * Sets authentication string * - * @param string $username CardDAV-Server username - * @param string $password CardDAV-Server password + * @param string $username CardDAV server username + * @param string $password CardDAV server password + * @return void */ public function set_auth($username, $password) { @@ -196,11 +201,11 @@ public function set_auth($username, $password) } /** - * get propfind xml-response from the CardDAV-Server + * Gets propfind XML response from the CardDAV server * - * @param boolean $include_vcards include vCards in the response (simplified only) - * @param boolean $raw get response raw or simplified - * @return string raw or simplified xml response + * @param boolean $include_vcards vCards include vCards in the response (simplified only) + * @param boolean $raw Get response raw or simplified + * @return string Raw or simplified XML response */ public function get($include_vcards = true, $raw = false) { @@ -217,10 +222,10 @@ public function get($include_vcards = true, $raw = false) } /** - * get a clean vCard from the CardDAV-Server + * Gets a clean vCard from the CardDAV server * - * @param string $id vCard id on the CardDAV-Server - * @return string vCard (text/vcard) + * @param string $vcard_id vCard id on the CardDAV server + * @return string vCard (text/vcard) */ public function get_vcard($vcard_id) { @@ -229,12 +234,13 @@ public function get_vcard($vcard_id) } /** - * get a vCard + XML from the CardDAV-Server + * Gets a vCard + XML from the CardDAV Server * - * @param string $id vCard id on the CardDAV-Server - * @return string vCard (text/xml) + * @param string $vcard_id vCard id on the CardDAV Server + * @param boolean $raw Get response raw or simplified + * @return string Raw or simplified vCard (text/xml) */ - public function get_xml_vcard($vcard_id) + public function get_xml_vcard($vcard_id, $raw = false) { $vcard_id = str_replace('.vcf', null, $vcard_id); @@ -255,7 +261,7 @@ public function get_xml_vcard($vcard_id) $response = $this->query($this->url, 'REPORT', $xml->outputMemory(), 'text/xml'); - if ($response === false) + if ($raw === true || $response === false) { return $response; } @@ -266,39 +272,20 @@ public function get_xml_vcard($vcard_id) } /** - * get the last used vCard id - * - * @return string $vcard_id last vCard id - */ - public function get_last_vcard_id() - { - return $this->vcard_id; - } - - /** - * checks if the CardDAV-Server is reachable + * Checks if the CardDAV server is reachable * - * @return boolean + * @return boolean */ public function check_connection() { - $response = $this->query($this->url, 'OPTIONS'); - - if ($response === false) - { - return false; - } - else - { - return true; - } + return $this->query($this->url, 'OPTIONS', null, null, true); } /** - * cleans the vCard + * Cleans the vCard * - * @param string $vcard vCard - * @return string $vcard vCard + * @param string $vcard vCard + * @return string $vcard vCard */ private function clean_vcard($vcard) { @@ -308,53 +295,58 @@ private function clean_vcard($vcard) } /** - * deletes an entry from the CardDAV-Server + * Deletes an entry from the CardDAV server * - * @param string $id vCard id on the CardDAV-Server - * @return string CardDAV xml-response + * @param string $vcard_id vCard id on the CardDAV server + * @return boolean */ public function delete($vcard_id) { - $this->vcard_id = $vcard_id; - return $this->query($this->url . $vcard_id . '.vcf', 'DELETE'); + return $this->query($this->url . $vcard_id . '.vcf', 'DELETE', null, null, true); } /** - * adds an entry to the CardDAV-Server + * Adds an entry to the CardDAV server * - * @param string $vcard vCard - * @return string CardDAV xml-response + * @param string $vcard vCard + * @return string The new vCard id */ public function add($vcard) { $vcard_id = $this->generate_vcard_id(); - $this->vcard_id = $vcard_id; $vcard = $this->clean_vcard($vcard); - return $this->query($this->url . $vcard_id . '.vcf', 'PUT', $vcard, 'text/vcard'); + if ($this->query($this->url . $vcard_id . '.vcf', 'PUT', $vcard, 'text/vcard', true) === true) + { + return $vcard_id; + } + else + { + return false; + } } /** - * updates an entry to the CardDAV-Server + * Updates an entry to the CardDAV server * - * @param string $vcard vCard - * @param string $id vCard id on the CardDAV-Server - * @return string CardDAV xml-response + * @param string $vcard vCard + * @param string $vcard_id vCard id on the CardDAV server + * @return boolean */ public function update($vcard, $vcard_id) { $vcard_id = str_replace('.vcf', null, $vcard_id); - $this->vcard_id = $vcard_id; $vcard = $this->clean_vcard($vcard); - return $this->query($this->url . $vcard_id . '.vcf', 'PUT', $vcard, 'text/vcard'); + return $this->query($this->url . $vcard_id . '.vcf', 'PUT', $vcard, 'text/vcard', true); } /** - * simplify CardDAV xml-response + * Simplify CardDAV XML response * - * @param string $response CardDAV xml-response - * @return string simplified CardDAV xml-response + * @param string $response CardDAV XML response + * @param boolean $include_vcards Include vCards or not + * @return string Simplified CardDAV XML response */ private function simplify($response, $include_vcards = true) { @@ -378,18 +370,39 @@ private function simplify($response, $include_vcards = true) if (!empty($id)) { $simplified_xml->startElement('element'); - $simplified_xml->writeElement('id', $id); - $simplified_xml->writeElement('etag', str_replace('"', null, $response->propstat->prop->getetag)); - $simplified_xml->writeElement('last_modified', $response->propstat->prop->getlastmodified); - - if ($include_vcards === true) - { - $simplified_xml->writeElement('vcard', $this->get_vcard($id)); - } - + $simplified_xml->writeElement('id', $id); + $simplified_xml->writeElement('etag', str_replace('"', null, $response->propstat->prop->getetag)); + $simplified_xml->writeElement('last_modified', $response->propstat->prop->getlastmodified); + + if ($include_vcards === true) + { + $simplified_xml->writeElement('vcard', $this->get_vcard($id)); + } $simplified_xml->endElement(); } } + else if (preg_match('/unix-directory/', $response->propstat->prop->getcontenttype)) + { + if (isset($response->propstat->prop->href)) + { + $href = $response->propstat->prop->href; + } + else if (isset($response->href)) + { + $href = $response->href; + } + else + { + $href = null; + } + + $url = str_replace($this->url_parts['path'], null, $this->url) . $href; + $simplified_xml->startElement('addressbook_element'); + $simplified_xml->writeElement('display_name', $response->propstat->prop->displayname); + $simplified_xml->writeElement('url', $url); + $simplified_xml->writeElement('last_modified', $response->propstat->prop->getlastmodified); + $simplified_xml->endElement(); + } } $simplified_xml->endElement(); @@ -399,10 +412,10 @@ private function simplify($response, $include_vcards = true) } /** - * cleans CardDAV xml-response + * Cleans CardDAV XML response * - * @param string $response CardDAV xml-response - * @return string $response cleaned CardDAV xml-response + * @param string $response CardDAV XML response + * @return string $response Cleaned CardDAV XML response */ private function clean_response($response) { @@ -416,49 +429,76 @@ private function clean_response($response) } /** - * quries the CardDAV-Server via curl and returns the response + * Curl initialization * - * @param string $method HTTP-Method like (OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE) - * @param string $content content for CardDAV-Queries - * @param string $content_type set content-type - * @return string CardDAV xml-response + * @return void */ - private function query($url, $method, $content = null, $content_type = null) + public function curl_init() { - $ch = curl_init($url); + if (empty($this->curl)) + { + $this->curl = curl_init(); + curl_setopt($this->curl, CURLOPT_HEADER, false); + curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($this->curl, CURLOPT_USERAGENT, self::USERAGENT.self::VERSION); + + if ($this->auth !== null) + { + curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($this->curl, CURLOPT_USERPWD, $this->auth); + } + } + } - curl_setopt($ch, CURLOPT_HEADER, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - curl_setopt($ch, CURLOPT_USERAGENT, self::USERAGENT.self::VERSION); + /** + * Quries the CardDAV server via curl and returns the response + * + * @param string $url CardDAV server URL + * @param string $method HTTP-Method like (OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE) + * @param string $content Content for CardDAV queries + * @param string $content_type Set content type + * @param boolean $return_boolean Return just a boolean + * @return string CardDAV XML response + */ + private function query($url, $method, $content = null, $content_type = null, $return_boolean = false) + { + $this->curl_init(); + + curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method); if ($content !== null) { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $content); + curl_setopt($this->curl, CURLOPT_POST, true); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $content); + } + else + { + curl_setopt($this->curl, CURLOPT_POST, false); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, null); } if ($content_type !== null) { - curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: '.$content_type)); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-type: '.$content_type)); } - - if ($this->auth !== null) + else { - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_setopt($ch, CURLOPT_USERPWD, $this->auth); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, array()); } - $response = curl_exec($ch); - $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - curl_close($ch); + $response = curl_exec($this->curl); + $http_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); if (in_array($http_code, array(200, 207))) { - return $response; + return ($return_boolean === true ? true : $response); + } + else if ($return_boolean === true && in_array($http_code, array(201, 204))) + { + return true; } else { @@ -467,9 +507,9 @@ private function query($url, $method, $content = null, $content_type = null) } /** - * returns a valid and unused vCard id + * Returns a valid and unused vCard id * - * @return string valid vCard id + * @return string Valid vCard id */ private function generate_vcard_id() { @@ -490,13 +530,27 @@ private function generate_vcard_id() $carddav = new carddav_backend($this->url); $carddav->set_auth($this->username, $this->password); - if (!preg_match('/BEGIN:VCARD/', $carddav->query($this->url . $id . '.vcf', 'GET'))) + if ($carddav->query($this->url . $id . '.vcf', 'GET', null, null, true)) { - return $id; + return $this->generate_vcard_id(); } else { - return $this->generate_vcard_id(); + return $id; + } + } + + /** + * Destructor + * Close curl connection if it's open + * + * @return void + */ + public function __destruct() + { + if (!empty($this->curl)) + { + curl_close($this->curl); } } } diff --git a/carddav_settings.js b/carddav_settings.js index bfcb13f..84ff75e 100644 --- a/carddav_settings.js +++ b/carddav_settings.js @@ -1,3 +1,16 @@ +/** + * Roundcube CardDAV addressbook extension + * + * @author Christian Putzke + * @copyright Christian Putzke @ Graviox Studios + * @since 12.09.2011 + * @link http://www.graviox.de/ + * @link https://twitter.com/graviox/ + * @version 0.5 + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later + * + */ + if (window.rcmail) { rcmail.addEventListener('init', function(evt) diff --git a/config.inc.php.dist b/config.inc.php.dist index 563790b..310ff29 100644 --- a/config.inc.php.dist +++ b/config.inc.php.dist @@ -1,5 +1,5 @@