diff --git a/appinfo/app.php b/appinfo/app.php
index 60112aea..c36e43df 100644
--- a/appinfo/app.php
+++ b/appinfo/app.php
@@ -68,3 +68,4 @@ if (\OCP\User::isLoggedIn()) {
}
}
}
+
diff --git a/appinfo/database.xml b/appinfo/database.xml
index 5033108a..703e4edf 100644
--- a/appinfo/database.xml
+++ b/appinfo/database.xml
@@ -345,4 +345,130 @@
+
+
+
+ *dbprefix*contacts_ocu_cards
+
+
+
+
+ id
+ text
+
+ true
+ 255
+
+
+
+ owner
+ text
+
+ true
+ 255
+
+
+
+ addressbookid
+ integer
+
+ true
+ true
+ 4
+
+
+
+ fullname
+ text
+
+ false
+ 255
+
+
+
+ carddata
+ clob
+ false
+
+
+
+ uri
+ text
+
+ false
+ 200
+
+
+
+ lastmodified
+ integer
+
+ false
+ true
+ 4
+
+
+
+
+
+
+
+
+ *dbprefix*contacts_ocu_cards_properties
+
+
+
+
+ id
+ integer
+ 0
+ true
+ 1
+ true
+ 4
+
+
+
+ addressbookid
+ text
+
+ true
+ 255
+
+
+
+ contactid
+ text
+
+ true
+ 255
+
+
+
+ name
+ text
+
+ false
+ 64
+
+
+
+ value
+ text
+
+ false
+ 255
+
+
+
+ preferred
+ integer
+ 1
+ true
+ 4
+
+
+
+
+
diff --git a/appinfo/version b/appinfo/version
index b8b1645c..7af4042f 100644
--- a/appinfo/version
+++ b/appinfo/version
@@ -1 +1 @@
-0.3.0.1
+0.3.0.14
\ No newline at end of file
diff --git a/js/addressbooks.js b/js/addressbooks.js
index 7adb92de..10cf8e0e 100644
--- a/js/addressbooks.js
+++ b/js/addressbooks.js
@@ -31,6 +31,12 @@ OC.Contacts = OC.Contacts || {};
if(!this.hasPermission(OC.PERMISSION_UPDATE)) {
this.$li.find('a.action.edit').hide();
}
+ if(!this.hasPermission(OC.PERMISSION_SHARE)) {
+ this.$li.find('a.action.share').hide();
+ }
+ if(['local', 'ldap'].indexOf(this.getBackend() === -1)) {
+ this.$li.find('a.action.carddav').hide();
+ }
this.$li.find('input:checkbox').prop('checked', this.book.active).on('change', function() {
console.log('activate', self.getId());
var checkbox = $(this).get(0);
@@ -55,7 +61,7 @@ OC.Contacts = OC.Contacts || {};
console.log('delete', self.getId());
self.destroy();
});
- this.$li.find('a.action.globe').on('click keypress', function() {
+ this.$li.find('a.action.carddav').on('click keypress', function() {
var uri = (self.book.owner === oc_current_user ) ? self.book.uri : self.book.uri + '_shared_by_' + self.book.owner;
var link = OC.linkToRemote('carddav')+'/addressbooks/'+encodeURIComponent(oc_current_user)+'/'+encodeURIComponent(uri);
var $dropdown = $('')
diff --git a/js/contacts.js b/js/contacts.js
index 8306745b..044c9e7d 100644
--- a/js/contacts.js
+++ b/js/contacts.js
@@ -1488,15 +1488,18 @@ OC.Contacts = OC.Contacts || {};
}
}
});
- if(this.metadata.owner !== OC.currentUser
- && !(this.hasPermission(OC.PERMISSION_UPDATE)
- || this.hasPermission(OC.PERMISSION_DELETE))) {
- this.setEnabled(false);
- this.showActions(['close', 'export']);
- } else {
- this.setEnabled(true);
- this.showActions(['close', 'add', 'export', 'delete']);
+ var actions = ['close', 'export'];
+ if(this.hasPermission(OC.PERMISSION_DELETE)) {
+ actions.push('delete');
}
+ if(this.hasPermission(OC.PERMISSION_UPDATE)) {
+ actions.push('add');
+ this.setEnabled(true);
+ } else {
+ this.setEnabled(false);
+ }
+ this.showActions(actions);
+
return this.$fullelem;
};
diff --git a/l10n/cs_CZ.php b/l10n/cs_CZ.php
index f86cdee4..d83c24e7 100644
--- a/l10n/cs_CZ.php
+++ b/l10n/cs_CZ.php
@@ -174,7 +174,7 @@
"Address books" => "Adresáře kontaktů",
"Display name" => "Zobrazované jméno",
"Add Address Book" => "Přidat adresář kontaktů",
-"Automatic format" => "Automatícký formát",
+"Automatic format" => "Automatický formát",
"Select file..." => "Vybrat soubor...",
"(De-)select all" => "Vybrat (odznačit) vše",
"Sort order" => "Řazení",
diff --git a/l10n/cs_CZ/contacts.po b/l10n/cs_CZ/contacts.po
index e7c369d2..67de9689 100644
--- a/l10n/cs_CZ/contacts.po
+++ b/l10n/cs_CZ/contacts.po
@@ -18,9 +18,9 @@ msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-04-08 00:50-0400\n"
-"PO-Revision-Date: 2014-04-08 04:50+0000\n"
-"Last-Translator: I Robot\n"
+"POT-Creation-Date: 2014-04-15 00:48-0400\n"
+"PO-Revision-Date: 2014-04-14 05:00+0000\n"
+"Last-Translator: pstast \n"
"Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/owncloud/language/cs_CZ/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -116,7 +116,7 @@ msgstr "Sloučení selhalo. Chyba při ukládání kontaktu."
msgid "Select photo"
msgstr "Vybrat fotku"
-#: js/app.js:705 js/app.js:1675
+#: js/app.js:705 js/app.js:1679
msgid "Network or server error. Please inform administrator."
msgstr "Chyba sítě či serveru. Kontaktujte prosím správce."
@@ -167,11 +167,11 @@ msgstr "OK"
msgid "Could not find contact: {id}"
msgstr "Nelze nalézt kontakt: {id}"
-#: js/app.js:1630
+#: js/app.js:1634
msgid "Edit profile picture"
msgstr "Upravit obrázek profilu"
-#: js/app.js:1634
+#: js/app.js:1638
msgid "Crop photo"
msgstr "Oříznout fotku"
@@ -191,17 +191,17 @@ msgstr "Chyba parsování narozenin {bday}"
msgid "The backend does not support multi-byte characters."
msgstr "Úložiště nepodporuje více-bajtové znaky."
-#: js/contacts.js:2222
+#: js/contacts.js:2224
msgid ""
"Some contacts are marked for deletion, but not deleted yet. Please wait for "
"them to be deleted."
msgstr "Některé kontakty jsou označeny ke smazání, ale ještě smazány nejsou. Počkejte, prosím, na dokončení operace."
-#: js/contacts.js:2233
+#: js/contacts.js:2235
msgid "Click to undo deletion of {num} contacts"
msgstr "Klikněte pro navrácení smazání {num} kontaktů"
-#: js/contacts.js:2242
+#: js/contacts.js:2244
msgid "Cancelled deletion of {num} contacts"
msgstr "Smazání {num} kontaktů zrušeno"
@@ -388,49 +388,49 @@ msgstr "Neznámý komunikátor: "
msgid "{name}'s Birthday"
msgstr "Narozeniny {name}"
-#: lib/controller/addressbookcontroller.php:163
+#: lib/controller/addressbookcontroller.php:175
msgid "Error creating address book"
msgstr "Chyba při vytváření adresáře kontaktů"
-#: lib/controller/addressbookcontroller.php:195
+#: lib/controller/addressbookcontroller.php:207
#, php-format
msgid "The \"%s\" backend does not support deleting address books"
msgstr "Toto uložiště \"%s\" nepodporuje mazání adresářů kontaktů"
-#: lib/controller/addressbookcontroller.php:203
+#: lib/controller/addressbookcontroller.php:215
#, php-format
msgid "You do not have permissions to delete the \"%s\" address book"
msgstr "Nemáte oprávnění pro smazání adresáře kontaktů \"%s\""
-#: lib/controller/addressbookcontroller.php:210
+#: lib/controller/addressbookcontroller.php:222
msgid "Error deleting address book"
msgstr "Chyba při mazání adresáře kontaktů"
-#: lib/controller/addressbookcontroller.php:250
+#: lib/controller/addressbookcontroller.php:262
msgid "Error creating contact."
msgstr "Chyba při vytváření kontaktu"
-#: lib/controller/addressbookcontroller.php:259
+#: lib/controller/addressbookcontroller.php:271
msgid "Error creating contact"
msgstr "Chyba při vytváření kontaktu"
-#: lib/controller/addressbookcontroller.php:291
+#: lib/controller/addressbookcontroller.php:303
msgid "Error deleting contact"
msgstr "Chyba při odstraňování kontaktu"
-#: lib/controller/addressbookcontroller.php:331
+#: lib/controller/addressbookcontroller.php:343
msgid "Error retrieving contact"
msgstr "Chyba při otevírání kontaktu"
-#: lib/controller/addressbookcontroller.php:342
+#: lib/controller/addressbookcontroller.php:354
msgid "Error saving contact"
msgstr "Chyba při ukládání kontaktu"
-#: lib/controller/addressbookcontroller.php:348
+#: lib/controller/addressbookcontroller.php:360
msgid "Error removing contact from other address book."
msgstr "Chyba při odebírání kontaktu z jiného adresáře kontaktů."
-#: lib/controller/addressbookcontroller.php:355
+#: lib/controller/addressbookcontroller.php:367
msgid "Error getting moved contact"
msgstr "Chyba při získávání přesunutého kontaktu"
@@ -753,7 +753,7 @@ msgstr "Přidat adresář kontaktů"
#: templates/contacts.php:35
msgid "Automatic format"
-msgstr "Automatícký formát"
+msgstr "Automatický formát"
#: templates/contacts.php:44 templates/contacts.php:45
msgid "Select file..."
diff --git a/l10n/templates/contacts.pot b/l10n/templates/contacts.pot
index 0b355782..ea0bc165 100644
--- a/l10n/templates/contacts.pot
+++ b/l10n/templates/contacts.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ownCloud contacts 5.0.0\n"
"Report-Msgid-Bugs-To: translations@owncloud.org\n"
-"POT-Creation-Date: 2014-04-14 00:48-0400\n"
+"POT-Creation-Date: 2014-04-15 00:48-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
diff --git a/lib/app.php b/lib/app.php
index 97024464..2c82187c 100644
--- a/lib/app.php
+++ b/lib/app.php
@@ -57,6 +57,7 @@ class App {
'ldap' => 'OCA\Contacts\Backend\Ldap',
'local' => 'OCA\Contacts\Backend\Database',
'shared' => 'OCA\Contacts\Backend\Shared',
+ 'localusers' => 'OCA\Contacts\Backend\LocalUsers',
);
public function __construct(
diff --git a/lib/backend/database.php b/lib/backend/database.php
index b6734f31..2a0e9a04 100644
--- a/lib/backend/database.php
+++ b/lib/backend/database.php
@@ -439,7 +439,7 @@ class Database extends AbstractBackend {
}
}
-
+
return $cards;
}
@@ -1018,4 +1018,9 @@ class Database extends AbstractBackend {
return self::$preparedQueries[$identifier];
}
+
+ public function getSearchProvider($addressbook){
+ return new \OCA\Contacts\AddressbookProvider($addressbook);
+ }
+
}
diff --git a/lib/backend/localusers.php b/lib/backend/localusers.php
new file mode 100644
index 00000000..5e20b158
--- /dev/null
+++ b/lib/backend/localusers.php
@@ -0,0 +1,411 @@
+.
+ *
+ */
+
+namespace OCA\Contacts\Backend;
+
+use OCA\Contacts\Contact,
+ OCA\Contacts\VObject\VCard,
+ OCA\Contacts\Utils\Properties,
+ Sabre\VObject\Reader,
+ OCA\Contacts\Addressbook,
+ OCA\Contacts\LocalUsersAddressbookProvider;
+
+/**
+ * Contact backend for storing all the ownCloud users in this installation.
+ * Every user has *1* personal addressbook. The id of this addresbook is the
+ * userid of the owner.
+ */
+class LocalUsers extends AbstractBackend {
+
+ public $name = 'localusers';
+
+ /**
+ * The table that holds the address books.
+ * For every user there is *1* addressbook.
+ * @var string
+ */
+ private $addressBooksTableName = '*PREFIX*contacts_ocu_addressbooks';
+
+ /**
+ * The table that holds the contacts.
+ * @var string
+ */
+ private $cardsTableName = '*PREFIX*contacts_ocu_cards';
+
+ /**
+ * The table that holds the properties of the contacts.
+ * This is used to provice a search function.
+ * @var string
+ */
+ private $indexTableName = '*PREFIX*contacts_ocu_cards_properties';
+
+ /**
+ * All possible properties which can be stored in the $indexTableName.
+ * @var string
+ */
+ private $indexProperties = array(
+ 'BDAY', 'UID', 'N', 'FN', 'TITLE', 'ROLE', 'NOTE', 'NICKNAME',
+ 'ORG', 'CATEGORIES', 'EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'GEO');
+
+ /**
+ * language object
+ * @var OC_L10N
+ */
+ public static $l10n;
+
+ /**
+ * Defaults object
+ * @var OC_Defaults
+ */
+ public static $defaults;
+
+ public function __construct($userid){
+ self::$l10n = \OCP\Util::getL10N('contacts');
+ self::$defaults = new \OCP\Defaults();
+ $this->userid = $userid ? $userid : \OCP\User::getUser();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAddressBooksForUser(array $options = array()) {
+ return array($this->getAddressBook($this->userid));
+ }
+
+ /**
+ * {@inheritdoc}
+ * Only 1 addressbook for every user
+ */
+ public function getAddressBook($addressBookId, array $options = array()) {
+ $addressbook = array(
+ "id" => $addressBookId,
+ "displayname" => self::$l10n->t('On this') . self::$defaults->getName(),
+ "description" => self::$l10n->t('On this') . self::$defaults->getName(),
+ "ctag" => time(),
+ "permissions" => \OCP\PERMISSION_READ,
+ "backend" => $this->name,
+ "active" => 1
+ );
+ return $addressbook;
+ }
+
+ /**
+ * {@inheritdoc}
+ * There are as many contacts in this addressbook as in this ownCloud installation
+ */
+ public function getContacts($addressbookid, array $options = array()){
+ $this->updateDatabase();
+ $contacts = array();
+ try{
+ $sql = 'SELECT * FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?';
+ $query = \OCP\DB::prepare($sql);
+ $result = $query->execute(array($this->userid));
+
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
+ . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return true;
+ } else {
+ while($row = $result->fetchRow()){
+ $row['permissions'] = \OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE;
+ $contacts[] = $row;
+ }
+ }
+ return $contacts;
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('contacts', __METHOD__.' exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ return array();
+ }
+
+ }
+
+ /**
+ * {@inheritdoc}
+ * If your username is "admin" and you want to retrieve your own contact
+ * the params would be: $addressbookid = 'admin'; $id = 'admin';
+ * If your username is 'foo' and you want to retrieve the contact with
+ * ownCloud username 'bar' the params would be: $addressbookid = 'foo'; $id = 'bar';
+ */
+ public function getContact($addressbookid, $id, array $options = array()){
+ try{
+ $sql = 'SELECT * FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND id = ?';
+ $query = \OCP\DB::prepare($sql);
+ $result = $query->execute(array($this->userid, $id));
+
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
+ . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return array();
+ } else {
+ $row = $result->fetchRow();
+ $row['permissions'] = \OCP\PERMISSION_READ | \OCP\PERMISSION_UPDATE;
+ return $row;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('contacts', __METHOD__.' exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ return array();
+ }
+ }
+
+ /**
+ * Help function to add contacts to an addressbook.
+ * This only happens when an admin creates new users
+ * @param array $contacts array with userid of ownCloud users
+ * @param string $addressBookId
+ * @return bool
+ */
+ private function addContacts($contacts, $addressbookid){
+ foreach($contacts as $user){
+ try{
+ $sql = 'INSERT INTO ' . $this->cardsTableName . ' ('
+ . 'id, '
+ . 'addressbookid, '
+ . 'fullname, '
+ . 'carddata, '
+ . 'lastmodified'
+ . ') VALUES ('
+ . '?,'
+ . '?,'
+ . '?,'
+ . '?,'
+ . '?'
+ . ')';
+
+ $query = \OCP\DB::prepare($sql);
+
+ $vcard = \Sabre\VObject\Component::create('VCARD');
+ $vcard->FN = \OCP\User::getDisplayName($user);
+ $now = new \DateTime('now');
+ $vcard->REV = $now->format(\DateTime::W3C);
+
+ $appinfo = \OCP\App::getAppInfo('contacts');
+ $appversion = \OCP\App::getAppVersion('contacts');
+ $prodid = '-//ownCloud//NONSGML ' . $appinfo['name'] . ' ' . $appversion.'//EN';
+ $vcard->PRODID = $prodid;
+ $vcard->add('IMPP', 'x-owncloud-handle:' . $user, array("X-SERVICE-TYPE" => array("owncloud-handle")));
+
+ $result = $query->execute(array($user, $this->userid, \OCP\User::getDisplayName($user), $vcard->serialize(), time()));
+
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
+ . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ } else {
+ // All done
+ // now update the index table with all the properties
+ $this->updateIndex($user, $vcard);
+ return true;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('contacts', __METHOD__.' exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Help function to remove contacts from an addressbook.
+ * This only happens when an admin remove an ownCloud user
+ * @param array $contacts array with userid of ownCloud users
+ * @param string $addressBookId
+ * @return bool
+ */
+ private function removeContacts($contacts, $addressbookid){
+ foreach($contacts as $user){
+ try{
+ $sql = 'DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND id = ?';
+ $query = \OCP\DB::prepare($sql);
+ $result = $query->execute(array($this->userid, $user));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
+ . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ } else {
+ return true;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('contacts', __METHOD__.' exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ return false;
+ }
+ }
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function updateContact($addressBookId, $id, $contact, array $options = array()) {
+
+ $updateRevision = true;
+ $isCardDAV = false;
+
+ if (!$contact instanceof VCard) {
+ try {
+ $contact = Reader::read($contact);
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR);
+ return false;
+ }
+ }
+
+ if ($updateRevision || !isset($contact->REV)) {
+ $now = new \DateTime;
+ $contact->REV = $now->format(\DateTime::W3C);
+ }
+
+ try{
+ $sql = 'UPDATE ' . $this->cardsTableName
+ . ' SET '
+ . '`fullname` = ?, '
+ . '`carddata` = ?, '
+ . '`lastmodified` = ? '
+ . ' WHERE '
+ . '`id` = ? '
+ . 'AND `addressbookid` = ? ';
+ $query = \OCP\DB::prepare($sql);
+ $result = $query->execute(array($contact->FN, $contact->serialize(), time(), $id, $this->userid));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
+ . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ } else {
+ // All done
+ // now update the indexes in the DB
+ $this->updateIndex($id, $contact);
+ return true;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('contacts', __METHOD__.' exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ return false;
+ }
+ }
+
+ /**
+ * This is a hack so backends can have different search functions.
+ * @return \OCA\Contacts\LocalUsersAddressbookProvider
+ */
+ public function getSearchProvider(){
+ return new LocalUsersAddressbookProvider($this);
+ }
+
+ /**
+ * Updates the index table. All properties of a contact are stored in it.
+ * Needed for the search function.
+ * @param type $contactId
+ * @param type $vcard
+ * @return boolean
+ */
+ private function updateIndex($contactId, $vcard){
+ // Utils\Properties::updateIndex($parameters['id'], $contact);
+ $this->purgeIndex($contactId);
+ $updatestmt = \OCP\DB::prepare('INSERT INTO `' . $this->indexTableName . '` '
+ . '(`addressbookid`, `contactid`,`name`,`value`,`preferred`) VALUES(?,?,?,?,?)');
+ // Insert all properties in the table
+ foreach($vcard->children as $property) {
+ if(!in_array($property->name, $this->indexProperties)) {
+ continue;
+ }
+ $preferred = 0;
+ foreach($property->parameters as $parameter) {
+ if($parameter->name == 'TYPE' && strtoupper($parameter->value) == 'PREF') {
+ $preferred = 1;
+ break;
+ }
+ }
+ try {
+ $result = $updatestmt->execute(
+ array(
+ \OCP\User::getUser(),
+ $contactId,
+ $property->name,
+ substr($property->value, 0, 254),
+ $preferred,
+ )
+ );
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
+ . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR);
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Remove all indexes from the table.
+ * This is always called before adding new properties.
+ * @param type $contactId
+ * @param type $vcard
+ * @return boolean
+ */
+ private function purgeIndex($id){
+ // Remove all indexes from the table
+ try {
+ $query = \OCP\DB::prepare('DELETE FROM `' . $this->indexTableName . '`'
+ . ' WHERE `contactid` = ?');
+ $query->execute(array($id));
+
+ } catch(\Exception $e) {
+ return false;
+ }
+ }
+
+ public function updateDatabase(){
+ $sql = 'SELECT * FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?';
+ $query = \OCP\DB::prepare($sql);
+ $result = $query->execute(array($this->userid));
+
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
+ . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return true;
+ } else {
+ $contactsId = array();
+ while($row = $result->fetchRow()){
+ $contactsId[] = $row['id'];
+ }
+
+ $users = \OCP\User::getUsers();
+
+ $add = array_diff($users, $contactsId);
+ $remove = array_diff($contactsId, $users);
+ if(count($add) > 0){
+ $this->addContacts($add, $addressbookid);
+ $recall = true;
+ }
+
+ if(count($remove) > 0){
+ $this->removeContacts($remove, $addressbookid);
+ $recall = true;
+ }
+ return true;
+ }
+ }
+
+}
diff --git a/lib/localusersaddressbookprovider.php b/lib/localusersaddressbookprovider.php
new file mode 100644
index 00000000..8176ce57
--- /dev/null
+++ b/lib/localusersaddressbookprovider.php
@@ -0,0 +1,163 @@
+backend = $backend;
+ }
+
+ /**
+ * @param $pattern
+ * @param $searchProperties
+ * @param $options
+ * @return array|false
+ */
+ public function search($pattern, $searchProperties, $options) {
+ // First make sure the database is updated
+ $this->backend->updateDatabase();
+
+ $ids = array();
+ $results = array();
+ $query = 'SELECT DISTINCT `contactid` FROM `' . $this->indexTableName . '` WHERE (';
+ $params = array();
+ foreach($searchProperties as $property) {
+ $params[] = $property;
+ $params[] = '%' . $pattern . '%';
+ $query .= '(`name` = ? AND `value` LIKE ?) OR ';
+ }
+ $query = substr($query, 0, strlen($query) - 4);
+ $query .= ')';
+
+ $stmt = \OCP\DB::prepare($query);
+ $result = $stmt->execute($params);
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ while( $row = $result->fetchRow()) {
+ $ids[] = $row['contactid'];
+ }
+
+ if(count($ids) > 0) {
+ $query = 'SELECT `' . $this->cardsTableName . '`.`addressbookid`, `' . $this->indexTableName . '`.`contactid`, `'
+ . $this->indexTableName . '`.`name`, `' . $this->indexTableName . '`.`value` FROM `'
+ . $this->indexTableName . '`,`' . $this->cardsTableName . '` WHERE `'
+ . $this->cardsTableName . '`.`addressbookid` = \'' . \OCP\User::getUser() . '\' AND `'
+ . $this->indexTableName . '`.`contactid` = `' . $this->cardsTableName . '`.`id` AND `'
+ . $this->indexTableName . '`.`contactid` IN (' . join(',', array_fill(0, count($ids), '?')) . ')';
+
+ $stmt = \OCP\DB::prepare($query);
+ $result = $stmt->execute($ids);
+ }
+
+ while( $row = $result->fetchRow()) {
+ $this->getProperty($results, $row);
+ }
+ return $results;
+ }
+
+ public function getKey(){
+
+ }
+
+ /**
+ * In comparison to getKey() this function returns a human readable (maybe translated) name
+ * @return mixed
+ */
+ public function getDisplayName(){
+
+}
+
+ public function createOrUpdate($properties){
+
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getPermissions(){
+
+ }
+
+ /**
+ * @param object $id the unique identifier to a contact
+ * @return bool successful or not
+ */
+ public function delete($id){
+
+ }
+
+ private function getProperty(&$results, $row) {
+ if(!$row['name'] || !$row['value']) {
+ return false;
+ }
+
+ $value = null;
+
+ switch($row['name']) {
+ case 'PHOTO':
+ $value = 'VALUE=uri:' . \OCP\Util::linkToAbsolute('contacts', 'photo.php') . '?id=' . $row['contactid'];
+ break;
+ case 'N':
+ case 'ORG':
+ case 'ADR':
+ case 'GEO':
+ case 'CATEGORIES':
+ $property = \Sabre\VObject\Property::create($row['name'], $row['value']);
+ $value = $property->getParts();
+ break;
+ default:
+ $value = $value = strtr($row['value'], array('\,' => ',', '\;' => ';'));
+ break;
+ }
+
+ if(in_array($row['name'], Properties::$multiProperties)) {
+ if(!isset($results[$row['contactid']])) {
+ $results[$row['contactid']] = array('id' => $row['contactid'], $row['name'] => array($value));
+ } elseif(!isset($results[$row['contactid']][$row['name']])) {
+ $results[$row['contactid']][$row['name']] = array($value);
+ } else {
+ $results[$row['contactid']][$row['name']][] = $value;
+ }
+ } else {
+ if(!isset($results[$row['contactid']])) {
+ $results[$row['contactid']] = array('id' => $row['contactid'], $row['name'] => $value);
+ } elseif(!isset($results[$row['contactid']][$row['name']])) {
+ $results[$row['contactid']][$row['name']] = $value;
+ }
+ }
+ }
+
+}
diff --git a/templates/contacts.php b/templates/contacts.php
index 9401d83e..736af6e8 100644
--- a/templates/contacts.php
+++ b/templates/contacts.php
@@ -504,7 +504,7 @@ use OCA\Contacts\ImportManager;
-
+