summaryrefslogtreecommitdiffstats
path: root/apps/contacts/lib
diff options
context:
space:
mode:
authorMichael Gapczynski <mtgap@owncloud.com>2012-07-11 20:25:59 -0400
committerMichael Gapczynski <mtgap@owncloud.com>2012-07-11 20:25:59 -0400
commit4bf13adff25f012c735931c0578b1f5d0790bdbe (patch)
treea7c5451ff25e2f39936ae984ceb5b3b9eb519088 /apps/contacts/lib
parent88f4845ca33fd6f2988f230116e2190d15ab1866 (diff)
parent8890a4128015df0ad57101703d6c164ea54fe4ee (diff)
downloadnextcloud-server-4bf13adff25f012c735931c0578b1f5d0790bdbe.tar.gz
nextcloud-server-4bf13adff25f012c735931c0578b1f5d0790bdbe.zip
Merge branch 'master' into share_api
Conflicts: apps/contacts/lib/addressbook.php apps/files_sharing/js/share.js apps/files_sharing/sharedstorage.php
Diffstat (limited to 'apps/contacts/lib')
-rw-r--r--apps/contacts/lib/VCFExportPlugin.php100
-rw-r--r--apps/contacts/lib/addressbook.php181
-rw-r--r--apps/contacts/lib/app.php56
-rw-r--r--apps/contacts/lib/connector_sabre.php4
-rw-r--r--apps/contacts/lib/hooks.php4
-rw-r--r--apps/contacts/lib/vcard.php14
6 files changed, 225 insertions, 134 deletions
diff --git a/apps/contacts/lib/VCFExportPlugin.php b/apps/contacts/lib/VCFExportPlugin.php
new file mode 100644
index 00000000000..6554cb258e8
--- /dev/null
+++ b/apps/contacts/lib/VCFExportPlugin.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * VCF Exporter
+ *
+ * This plugin adds the ability to export entire address books as .vcf files.
+ * This is useful for clients that don't support CardDAV yet. They often do
+ * support vcf files.
+ *
+ * @package Sabre
+ * @subpackage CardDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CardDAV_VCFExportPlugin extends Sabre_DAV_ServerPlugin {
+
+ /**
+ * Reference to Server class
+ *
+ * @var Sabre_DAV_Server
+ */
+ private $server;
+
+ /**
+ * Initializes the plugin and registers event handlers
+ *
+ * @param Sabre_DAV_Server $server
+ * @return void
+ */
+ public function initialize(Sabre_DAV_Server $server) {
+
+ $this->server = $server;
+ $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90);
+
+ }
+
+ /**
+ * 'beforeMethod' event handles. This event handles intercepts GET requests ending
+ * with ?export
+ *
+ * @param string $method
+ * @param string $uri
+ * @return bool
+ */
+ public function beforeMethod($method, $uri) {
+
+ if ($method!='GET') return;
+ if ($this->server->httpRequest->getQueryString()!='export') return;
+
+ // splitting uri
+ list($uri) = explode('?',$uri,2);
+
+ $node = $this->server->tree->getNodeForPath($uri);
+
+ if (!($node instanceof Sabre_CardDAV_IAddressBook)) return;
+
+ // Checking ACL, if available.
+ if ($aclPlugin = $this->server->getPlugin('acl')) {
+ $aclPlugin->checkPrivileges($uri, '{DAV:}read');
+ }
+
+ $this->server->httpResponse->setHeader('Content-Type','text/directory');
+ $this->server->httpResponse->sendStatus(200);
+
+ $nodes = $this->server->getPropertiesForPath($uri, array(
+ '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data',
+ ),1);
+
+ $this->server->httpResponse->sendBody($this->generateVCF($nodes));
+
+ // Returning false to break the event chain
+ return false;
+
+ }
+
+ /**
+ * Merges all vcard objects, and builds one big vcf export
+ *
+ * @param array $nodes
+ * @return string
+ */
+ public function generateVCF(array $nodes) {
+ $objects = array();
+
+ foreach($nodes as $node) {
+
+ if (!isset($node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'])) {
+ continue;
+ }
+ $nodeData = $node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'];
+ $objects[] = $nodeData;
+
+ }
+
+ return implode("\r\n", $objects);
+
+ }
+
+}
diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php
index 4f00ce1f9e3..4077d26e58a 100644
--- a/apps/contacts/lib/addressbook.php
+++ b/apps/contacts/lib/addressbook.php
@@ -41,28 +41,63 @@ class OC_Contacts_Addressbook{
/**
* @brief Returns the list of addressbooks for a specific user.
* @param string $uid
+ * @param boolean $active Only return addressbooks with this $active state, default(=false) is don't care
* @return array or false.
*/
- public static function all($uid){
+ public static function all($uid, $active=false){
+ $values = array($uid);
+ $active_where = '';
+ if ($active){
+ $active_where = ' AND active = ?';
+ $values[] = 1;
+ }
try {
- $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ? ORDER BY displayname' );
- $result = $stmt->execute(array($uid));
+ $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ? ' . $active_where . ' ORDER BY displayname' );
+ $result = $stmt->execute($values);
} catch(Exception $e) {
OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(),OCP\Util::ERROR);
OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' uid: '.$uid,OCP\Util::DEBUG);
return false;
}
-
$addressbooks = array();
while( $row = $result->fetchRow()){
$addressbooks[] = $row;
}
$addressbooks = array_merge($addressbooks, OCP\Share::getItemsSharedWith('addressbook', OC_Contacts_Share::FORMAT_ADDRESSBOOKS));
+ if(!$active && !count($addressbooks)) {
+ self::addDefault($uid);
+ }
return $addressbooks;
}
/**
+ * @brief Get active addressbook IDs for a user.
+ * @param integer $uid User id. If null current user will be used.
+ * @return array
+ */
+ public static function activeIds($uid = null){
+ if(is_null($uid)){
+ $uid = OCP\USER::getUser();
+ }
+ $activeaddressbooks = self::all($uid, true);
+ $ids = array();
+ foreach($activeaddressbooks as $addressbook) {
+ $ids[] = $addressbook['id'];
+ }
+ return $ids;
+ }
+
+ /**
+ * @brief Returns the list of active addressbooks for a specific user.
+ * @param string $uid
+ * @return array
+ */
+ public static function active($uid){
+ return self::all($uid, true);
+ }
+
+ /**
* @brief Returns the list of addressbooks for a principal (DAV term of user)
* @param string $principaluri
* @return array
@@ -113,10 +148,17 @@ class OC_Contacts_Addressbook{
* @return insertid
*/
public static function add($uid,$name,$description=''){
- $all = self::all($uid);
+ try {
+ $stmt = OCP\DB::prepare( 'SELECT uri FROM *PREFIX*contacts_addressbooks WHERE userid = ? ' );
+ $result = $stmt->execute(array($uid));
+ } catch(Exception $e) {
+ OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(),OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' uid: '.$uid,OCP\Util::DEBUG);
+ return false;
+ }
$uris = array();
- foreach($all as $i){
- $uris[] = $i['uri'];
+ while($row = $result->fetchRow()){
+ $uris[] = $row['uri'];
}
$uri = self::createURI($name, $uris );
@@ -186,88 +228,6 @@ class OC_Contacts_Addressbook{
return true;
}
- public static function cleanArray($array, $remove_null_number = true){
- $new_array = array();
-
- $null_exceptions = array();
-
- foreach ($array as $key => $value){
- $value = trim($value);
-
- if($remove_null_number){
- $null_exceptions[] = '0';
- }
-
- if(!in_array($value, $null_exceptions) && $value != "") {
- $new_array[] = $value;
- }
- }
- return $new_array;
- }
-
- /**
- * @brief Get active addressbooks for a user.
- * @param integer $uid User id. If null current user will be used.
- * @return array
- */
- public static function activeIds($uid = null){
- if(is_null($uid)){
- $uid = OCP\USER::getUser();
- }
- $prefbooks = OCP\Config::getUserValue($uid,'contacts','openaddressbooks',null);
- if(!$prefbooks){
- $addressbooks = OC_Contacts_Addressbook::all($uid);
- if(count($addressbooks) == 0){
- self::addDefault($uid);
- }
- }
- $prefbooks = OCP\Config::getUserValue($uid,'contacts','openaddressbooks',null);
- return explode(';',$prefbooks);
- }
-
- /**
- * @brief Returns the list of active addressbooks for a specific user.
- * @param string $uid
- * @return array
- */
- public static function active($uid){
- if(is_null($uid)){
- $uid = OCP\USER::getUser();
- }
- $active = self::activeIds($uid);
- $shared = OCP\Share::getItemsSharedWith('addressbook', OC_Contacts_Share::FORMAT_ADDRESSBOOKS);
- $addressbooks = array();
- $ids_sql = join(',', array_fill(0, count($active), '?'));
- $prep = 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id IN ('.$ids_sql.') ORDER BY displayname';
- try {
- $stmt = OCP\DB::prepare( $prep );
- $result = $stmt->execute($active);
- } catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', uid: '.$uid,OCP\Util::DEBUG);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', ids: '.join(',', $active),OCP\Util::DEBUG);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', SQL:'.$prep,OCP\Util::DEBUG);
- }
-
- while( $row = $result->fetchRow()){
- // Insert formatted shared addressbook instead
- if ($row['userid'] != $uid) {
- foreach ($shared as $addressbook) {
- if ($addressbook['id'] == $row['id']) {
- $addressbooks[] = $addressbook;
- break;
- }
- }
- } else {
- $addressbooks[] = $row;
- }
- }
- if(!count($addressbooks)) {
- self::addDefault($uid);
- }
- return $addressbooks;
- }
-
/**
* @brief Activates an addressbook
* @param integer $id
@@ -275,30 +235,16 @@ class OC_Contacts_Addressbook{
* @return boolean
*/
public static function setActive($id,$active){
- // Need these ones for checking uri
- //$addressbook = self::find($id);
-
- if(is_null($id)){
- $id = 0;
- }
-
- $openaddressbooks = self::activeIds();
- if($active) {
- if(!in_array($id, $openaddressbooks)) {
- $openaddressbooks[] = $id;
- }
- } else {
- if(in_array($id, $openaddressbooks)) {
- unset($openaddressbooks[array_search($id, $openaddressbooks)]);
- }
+ $sql = 'UPDATE *PREFIX*contacts_addressbooks SET active = ? WHERE id = ?';
+ OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '.$id.', active: '.intval($active),OCP\Util::ERROR);
+ try {
+ $stmt = OCP\DB::prepare($sql);
+ $stmt->execute(array(intval($active), $id));
+ return true;
+ } catch(Exception $e) {
+ OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception for '.$id.': '.$e->getMessage(),OCP\Util::ERROR);
+ return false;
}
- // NOTE: Ugly hack...
- $openaddressbooks = self::cleanArray($openaddressbooks, false);
- sort($openaddressbooks, SORT_NUMERIC);
- // FIXME: I alway end up with a ';' prepending when imploding the array..?
- OCP\Config::setUserValue(OCP\USER::getUser(),'contacts','openaddressbooks',implode(';', $openaddressbooks));
-
- return true;
}
/**
@@ -307,8 +253,15 @@ class OC_Contacts_Addressbook{
* @return boolean
*/
public static function isActive($id){
- //OCP\Util::writeLog('contacts','OC_Contacts_Addressbook::isActive('.$id.'):'.in_array($id, self::activeIds()), OCP\Util::DEBUG);
- return in_array($id, self::activeIds());
+ $sql = 'SELECT active FROM *PREFIX*contacts_addressbooks WHERE id = ?';
+ try {
+ $stmt = OCP\DB::prepare( $sql );
+ $result = $stmt->execute(array($id));
+ $row = $result->fetchRow();
+ return (bool)$row['active'];
+ } catch(Exception $e) {
+ OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
+ }
}
/**
diff --git a/apps/contacts/lib/app.php b/apps/contacts/lib/app.php
index 3b16ffd5c16..ed2300adae0 100644
--- a/apps/contacts/lib/app.php
+++ b/apps/contacts/lib/app.php
@@ -10,7 +10,6 @@
* This class manages our app actions
*/
OC_Contacts_App::$l10n = OC_L10N::get('contacts');
-OC_Contacts_App::$categories = new OC_VCategories('contacts');
class OC_Contacts_App {
/*
* @brief language object for calendar app
@@ -139,31 +138,55 @@ class OC_Contacts_App {
}
}
- /*
+ /**
* @brief returns the vcategories object of the user
* @return (object) $vcategories
*/
protected static function getVCategories() {
if (is_null(self::$categories)) {
- self::$categories = new OC_VCategories('contacts');
+ self::$categories = new OC_VCategories('contacts', null, self::getDefaultCategories());
}
return self::$categories;
}
- /*
+ /**
* @brief returns the categories for the user
* @return (Array) $categories
*/
public static function getCategories() {
- $categories = self::$categories->categories();
+ $categories = self::getVCategories()->categories();
if(count($categories) == 0) {
self::scanCategories();
$categories = self::$categories->categories();
}
- return $categories;
+ return ($categories ? $categories : self::getDefaultCategories());
}
/**
+ * @brief returns the default categories of ownCloud
+ * @return (array) $categories
+ */
+ public static function getDefaultCategories(){
+ return array(
+ (string)self::$l10n->t('Birthday'),
+ (string)self::$l10n->t('Business'),
+ (string)self::$l10n->t('Call'),
+ (string)self::$l10n->t('Clients'),
+ (string)self::$l10n->t('Deliverer'),
+ (string)self::$l10n->t('Holidays'),
+ (string)self::$l10n->t('Ideas'),
+ (string)self::$l10n->t('Journey'),
+ (string)self::$l10n->t('Jubilee'),
+ (string)self::$l10n->t('Meeting'),
+ (string)self::$l10n->t('Other'),
+ (string)self::$l10n->t('Personal'),
+ (string)self::$l10n->t('Projects'),
+ (string)self::$l10n->t('Questions'),
+ (string)self::$l10n->t('Work'),
+ );
+ }
+
+ /**
* scan vcards for categories.
* @param $vccontacts VCards to scan. null to check all vcards for the current user.
*/
@@ -175,16 +198,19 @@ class OC_Contacts_App {
foreach($vcaddressbooks as $vcaddressbook) {
$vcaddressbookids[] = $vcaddressbook['id'];
}
- $vccontacts = OC_Contacts_VCard::all($vcaddressbookids);
- }
- }
- if(is_array($vccontacts) && count($vccontacts) > 0) {
- $cards = array();
- foreach($vccontacts as $vccontact) {
- $cards[] = $vccontact['carddata'];
+ $start = 0;
+ $batchsize = 10;
+ while($vccontacts = OC_Contacts_VCard::all($vcaddressbookids, $start, $batchsize)){
+ $cards = array();
+ foreach($vccontacts as $vccontact) {
+ $cards[] = $vccontact['carddata'];
+ }
+ OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', scanning: '.$batchsize.' starting from '.$start,OCP\Util::DEBUG);
+ // only reset on first batch.
+ self::getVCategories()->rescan($cards, true, ($start==0?true:false));
+ $start += $batchsize;
+ }
}
-
- self::$categories->rescan($cards);
}
}
diff --git a/apps/contacts/lib/connector_sabre.php b/apps/contacts/lib/connector_sabre.php
index c967e906601..99b94fc767e 100644
--- a/apps/contacts/lib/connector_sabre.php
+++ b/apps/contacts/lib/connector_sabre.php
@@ -138,7 +138,9 @@ class OC_Connector_Sabre_CardDAV extends Sabre_CardDAV_Backend_Abstract {
foreach($data as $i){
$cards[] = array(
'id' => $i['id'],
- 'carddata' => $i['carddata'],
+ //'carddata' => $i['carddata'],
+ 'size' => strlen($i['carddata']),
+ 'etag' => md5($i['carddata']),
'uri' => $i['uri'],
'lastmodified' => $i['lastmodified'] );
}
diff --git a/apps/contacts/lib/hooks.php b/apps/contacts/lib/hooks.php
index 9794a9c9b94..d91d3c565b5 100644
--- a/apps/contacts/lib/hooks.php
+++ b/apps/contacts/lib/hooks.php
@@ -90,9 +90,10 @@ class OC_Contacts_Hooks{
if ($birthday) {
$date = new DateTime($birthday);
$vevent = new OC_VObject('VEVENT');
- $vevent->setDateTime('LAST-MODIFIED', new DateTime($vcard->REV));
+ //$vevent->setDateTime('LAST-MODIFIED', new DateTime($vcard->REV));
$vevent->setDateTime('DTSTART', $date, Sabre_VObject_Element_DateTime::DATE);
$vevent->setString('DURATION', 'P1D');
+ $vevent->setString('UID', substr(md5(rand().time()),0,10));
// DESCRIPTION?
$vevent->setString('RRULE', 'FREQ=YEARLY');
$title = str_replace('{name}', $vcard->getAsString('FN'), OC_Contacts_App::$l10n->t('{name}\'s Birthday'));
@@ -101,6 +102,7 @@ class OC_Contacts_Hooks{
'vevent' => $vevent,
'repeating' => true,
'summary' => $title,
+ 'calendardata' => "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Contacts " . OCP\App::getAppVersion('contacts') . "\n" . $vevent->serialize() . "END:VCALENDAR"
);
}
}
diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php
index bf22be0de74..e3b65605624 100644
--- a/apps/contacts/lib/vcard.php
+++ b/apps/contacts/lib/vcard.php
@@ -47,11 +47,18 @@ class OC_Contacts_VCard{
* The cards are associative arrays. You'll find the original vCard in
* ['carddata']
*/
- public static function all($id){
+ public static function all($id, $start=null, $num=null){
+ $limitsql = '';
+ if(!is_null($num)) {
+ $limitsql = ' LIMIT '.$num;
+ }
+ if(!is_null($start) && !is_null($num)) {
+ $limitsql .= ' OFFSET '.$start.' ';
+ }
$result = null;
if(is_array($id) && count($id)) {
$id_sql = join(',', array_fill(0, count($id), '?'));
- $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname';
+ $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname '.$limitsql;
try {
$stmt = OCP\DB::prepare( $prep );
$result = $stmt->execute($id);
@@ -63,7 +70,8 @@ class OC_Contacts_VCard{
}
} elseif(is_int($id) || is_string($id)) {
try {
- $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' );
+ $sql = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname'.$limitsql;
+ $stmt = OCP\DB::prepare( $sql );
$result = $stmt->execute(array($id));
} catch(Exception $e) {
OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);