mirror of
https://github.com/owncloudarchive/contacts.git
synced 2025-01-18 07:52:21 +01:00
Merge branch 'master' of https://github.com/owncloud/contacts into ldap
This commit is contained in:
commit
b8c3c4e1ea
@ -68,3 +68,4 @@ if (\OCP\User::isLoggedIn()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,4 +345,130 @@
|
||||
|
||||
</declaration>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
|
||||
<name>*dbprefix*contacts_ocu_cards</name>
|
||||
|
||||
<declaration>
|
||||
|
||||
<field>
|
||||
<name>id</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>owner</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>addressbookid</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<unsigned>true</unsigned>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>fullname</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>false</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>carddata</name>
|
||||
<type>clob</type>
|
||||
<notnull>false</notnull>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>uri</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>false</notnull>
|
||||
<length>200</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>lastmodified</name>
|
||||
<type>integer</type>
|
||||
<default></default>
|
||||
<notnull>false</notnull>
|
||||
<unsigned>true</unsigned>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
</declaration>
|
||||
|
||||
</table>
|
||||
|
||||
<table>
|
||||
|
||||
<name>*dbprefix*contacts_ocu_cards_properties</name>
|
||||
|
||||
<declaration>
|
||||
|
||||
<field>
|
||||
<name>id</name>
|
||||
<type>integer</type>
|
||||
<default>0</default>
|
||||
<notnull>true</notnull>
|
||||
<autoincrement>1</autoincrement>
|
||||
<unsigned>true</unsigned>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>addressbookid</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>contactid</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>true</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>name</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>false</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>value</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>false</notnull>
|
||||
<length>255</length>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>preferred</name>
|
||||
<type>integer</type>
|
||||
<default>1</default>
|
||||
<notnull>true</notnull>
|
||||
<length>4</length>
|
||||
</field>
|
||||
|
||||
</declaration>
|
||||
</table>
|
||||
|
||||
</database>
|
||||
|
@ -1 +1 @@
|
||||
0.3.0.1
|
||||
0.3.0.14
|
@ -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 = $('<li><div id="dropdown" class="drop"><input type="text" value="{link}" readonly /></div></li>')
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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í",
|
||||
|
@ -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 <petr@stastny.eu>\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..."
|
||||
|
@ -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 <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -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(
|
||||
|
@ -1018,4 +1018,9 @@ class Database extends AbstractBackend {
|
||||
|
||||
return self::$preparedQueries[$identifier];
|
||||
}
|
||||
|
||||
public function getSearchProvider($addressbook){
|
||||
return new \OCA\Contacts\AddressbookProvider($addressbook);
|
||||
}
|
||||
|
||||
}
|
||||
|
411
lib/backend/localusers.php
Normal file
411
lib/backend/localusers.php
Normal file
@ -0,0 +1,411 @@
|
||||
<?php
|
||||
/**
|
||||
* ownCloud - ownCloud users backend for Contacts
|
||||
*
|
||||
* @author Tobia De Koninck
|
||||
* @copyright 2014 Tobia De Koninck (tobia@ledfan.be)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
163
lib/localusersaddressbookprovider.php
Normal file
163
lib/localusersaddressbookprovider.php
Normal file
@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace OCA\Contacts;
|
||||
|
||||
use OCA\Contacts\Utils\Properties;
|
||||
use OCA\Contacts\Backend\LocalUsers;
|
||||
|
||||
|
||||
class LocalUsersAddressbookProvider implements \OCP\IAddressBook {
|
||||
|
||||
/**
|
||||
* 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';
|
||||
|
||||
/**
|
||||
* @var LocalUsers
|
||||
*/
|
||||
private $backend;
|
||||
|
||||
public function __construct(LocalUsers $backend){
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -504,7 +504,7 @@ use OCA\Contacts\ImportManager;
|
||||
<span class="actions">
|
||||
<a title="<?php p($l->t('Share')); ?>" class="icon-share share action" data-possible-permissions="{permissions}" data-item="{id}" data-item-type="addressbook"></a>
|
||||
<a title="<?php p($l->t('Export')); ?>" class="icon-download download action"></a>
|
||||
<a title="<?php p($l->t('CardDAV link')); ?>" class="icon-public globe action"></a>
|
||||
<a title="<?php p($l->t('CardDAV link')); ?>" class="icon-public carddav action"></a>
|
||||
<a title="<?php p($l->t('Edit')); ?>" class="icon-rename edit action"></a>
|
||||
<a title="<?php p($l->t('Delete')); ?>" class="icon-delete delete action"></a>
|
||||
</span>
|
||||
|
Loading…
x
Reference in New Issue
Block a user