2013-03-13 04:11:37 +01:00
|
|
|
<?php
|
|
|
|
/**
|
2014-01-26 00:40:22 +01:00
|
|
|
* ownCloud - Utility class for VObject properties
|
2013-03-13 04:11:37 +01:00
|
|
|
*
|
|
|
|
* @author Thomas Tanghus
|
2014-01-26 00:40:22 +01:00
|
|
|
* @copyright 2013-2014 Thomas Tanghus (thomas@tanghus.net)
|
2013-03-13 04:11:37 +01:00
|
|
|
*
|
|
|
|
* 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\Utils;
|
|
|
|
|
2013-11-07 14:06:12 +01:00
|
|
|
use OCA\Contacts\App;
|
|
|
|
|
2013-09-16 02:24:08 +02:00
|
|
|
Properties::$l10n = \OCP\Util::getL10N('contacts');
|
2013-03-13 04:11:37 +01:00
|
|
|
|
|
|
|
Class Properties {
|
2013-03-13 08:52:00 +01:00
|
|
|
|
2013-11-07 14:06:12 +01:00
|
|
|
const THUMBNAIL_PREFIX = 'contact-thumbnail-';
|
2013-12-14 15:22:42 +01:00
|
|
|
const THUMBNAIL_SIZE = 32;
|
2013-11-07 14:06:12 +01:00
|
|
|
|
2013-03-13 08:52:00 +01:00
|
|
|
private static $deleteindexstmt;
|
|
|
|
private static $updateindexstmt;
|
2013-03-29 05:00:03 +01:00
|
|
|
protected static $cardsTableName = '*PREFIX*contacts_cards';
|
|
|
|
protected static $indexTableName = '*PREFIX*contacts_cards_properties';
|
2013-03-13 08:52:00 +01:00
|
|
|
|
2013-03-13 04:11:37 +01:00
|
|
|
/**
|
|
|
|
* @brief language object for calendar app
|
|
|
|
*
|
|
|
|
* @var OC_L10N
|
|
|
|
*/
|
|
|
|
public static $l10n;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Properties there can be more than one of.
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2015-06-17 10:41:36 +02:00
|
|
|
public static $multiProperties = array('EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'CLOUD');
|
2013-03-13 04:11:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Properties to index.
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2014-03-18 00:58:01 +01:00
|
|
|
public static $indexProperties = array(
|
2013-03-13 04:11:37 +01:00
|
|
|
'BDAY', 'UID', 'N', 'FN', 'TITLE', 'ROLE', 'NOTE', 'NICKNAME',
|
2015-06-17 10:41:36 +02:00
|
|
|
'ORG', 'CATEGORIES', 'EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'GEO', 'CLOUD');
|
2013-03-13 04:11:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get options for IMPP properties
|
|
|
|
* @param string $im
|
|
|
|
* @return array of vcard prop => label
|
|
|
|
*/
|
|
|
|
public static function getIMOptions($im = null) {
|
|
|
|
$l10n = self::$l10n;
|
|
|
|
$ims = array(
|
|
|
|
'jabber' => array(
|
|
|
|
'displayname' => (string)$l10n->t('Jabber'),
|
|
|
|
'xname' => 'X-JABBER',
|
|
|
|
'protocol' => 'xmpp',
|
|
|
|
),
|
2013-04-27 04:36:45 +02:00
|
|
|
'sip' => array(
|
|
|
|
'displayname' => (string)$l10n->t('Internet call'),
|
|
|
|
'xname' => 'X-SIP',
|
|
|
|
'protocol' => 'sip',
|
|
|
|
),
|
2013-03-13 04:11:37 +01:00
|
|
|
'aim' => array(
|
|
|
|
'displayname' => (string)$l10n->t('AIM'),
|
|
|
|
'xname' => 'X-AIM',
|
|
|
|
'protocol' => 'aim',
|
|
|
|
),
|
|
|
|
'msn' => array(
|
|
|
|
'displayname' => (string)$l10n->t('MSN'),
|
|
|
|
'xname' => 'X-MSN',
|
|
|
|
'protocol' => 'msn',
|
|
|
|
),
|
|
|
|
'twitter' => array(
|
|
|
|
'displayname' => (string)$l10n->t('Twitter'),
|
|
|
|
'xname' => 'X-TWITTER',
|
|
|
|
'protocol' => 'twitter',
|
|
|
|
),
|
|
|
|
'googletalk' => array(
|
|
|
|
'displayname' => (string)$l10n->t('GoogleTalk'),
|
|
|
|
'xname' => null,
|
|
|
|
'protocol' => 'xmpp',
|
|
|
|
),
|
|
|
|
'facebook' => array(
|
|
|
|
'displayname' => (string)$l10n->t('Facebook'),
|
|
|
|
'xname' => null,
|
|
|
|
'protocol' => 'xmpp',
|
|
|
|
),
|
|
|
|
'xmpp' => array(
|
|
|
|
'displayname' => (string)$l10n->t('XMPP'),
|
|
|
|
'xname' => null,
|
|
|
|
'protocol' => 'xmpp',
|
|
|
|
),
|
|
|
|
'icq' => array(
|
|
|
|
'displayname' => (string)$l10n->t('ICQ'),
|
|
|
|
'xname' => 'X-ICQ',
|
|
|
|
'protocol' => 'icq',
|
|
|
|
),
|
|
|
|
'yahoo' => array(
|
|
|
|
'displayname' => (string)$l10n->t('Yahoo'),
|
|
|
|
'xname' => 'X-YAHOO',
|
|
|
|
'protocol' => 'ymsgr',
|
|
|
|
),
|
|
|
|
'skype' => array(
|
|
|
|
'displayname' => (string)$l10n->t('Skype'),
|
|
|
|
'xname' => 'X-SKYPE',
|
|
|
|
'protocol' => 'skype',
|
|
|
|
),
|
|
|
|
'qq' => array(
|
|
|
|
'displayname' => (string)$l10n->t('QQ'),
|
|
|
|
'xname' => 'X-SKYPE',
|
|
|
|
'protocol' => 'x-apple',
|
|
|
|
),
|
|
|
|
'gadugadu' => array(
|
|
|
|
'displayname' => (string)$l10n->t('GaduGadu'),
|
|
|
|
'xname' => 'X-SKYPE',
|
|
|
|
'protocol' => 'x-apple',
|
|
|
|
),
|
2014-02-04 08:03:32 +01:00
|
|
|
'owncloud-handle' => array(
|
2014-05-09 09:50:50 +02:00
|
|
|
'displayname' => (string)$l10n->t('ownCloud'),
|
2014-02-03 18:37:55 +01:00
|
|
|
'xname' => null,
|
2014-02-08 12:28:21 +01:00
|
|
|
'protocol' => 'x-owncloud-handle'
|
2014-02-03 18:37:55 +01:00
|
|
|
),
|
2013-03-13 04:11:37 +01:00
|
|
|
);
|
|
|
|
if(is_null($im)) {
|
|
|
|
return $ims;
|
|
|
|
} else {
|
|
|
|
$ims['ymsgr'] = $ims['yahoo'];
|
|
|
|
$ims['gtalk'] = $ims['googletalk'];
|
|
|
|
return isset($ims[$im]) ? $ims[$im] : null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get standard set of TYPE values for different properties.
|
|
|
|
*
|
|
|
|
* @param string $prop
|
|
|
|
* @return array Type values for property $prop
|
|
|
|
*/
|
|
|
|
public static function getTypesForProperty($prop) {
|
|
|
|
$l = self::$l10n;
|
|
|
|
switch($prop) {
|
|
|
|
case 'LABEL':
|
|
|
|
case 'ADR':
|
|
|
|
case 'IMPP':
|
|
|
|
return array(
|
|
|
|
'HOME' => (string)$l->t('Home'),
|
2015-06-25 16:53:33 +02:00
|
|
|
'WORK' => (string)$l->t('Work'),
|
2013-03-13 04:11:37 +01:00
|
|
|
'OTHER' => (string)$l->t('Other'),
|
|
|
|
);
|
|
|
|
case 'TEL':
|
|
|
|
return array(
|
|
|
|
'HOME' => (string)$l->t('Home'),
|
|
|
|
'CELL' => (string)$l->t('Mobile'),
|
|
|
|
'WORK' => (string)$l->t('Work'),
|
|
|
|
'TEXT' => (string)$l->t('Text'),
|
|
|
|
'VOICE' => (string)$l->t('Voice'),
|
|
|
|
'MSG' => (string)$l->t('Message'),
|
|
|
|
'FAX' => (string)$l->t('Fax'),
|
|
|
|
'VIDEO' => (string)$l->t('Video'),
|
|
|
|
'PAGER' => (string)$l->t('Pager'),
|
|
|
|
'OTHER' => (string)$l->t('Other'),
|
|
|
|
);
|
|
|
|
case 'EMAIL':
|
|
|
|
return array(
|
|
|
|
'HOME' => (string)$l->t('Home'),
|
2015-06-25 16:53:33 +02:00
|
|
|
'WORK' => (string)$l->t('Work'),
|
2013-03-13 04:11:37 +01:00
|
|
|
'INTERNET' => (string)$l->t('Internet'),
|
|
|
|
'OTHER' => (string)$l->t('Other'),
|
|
|
|
);
|
2015-06-17 10:41:36 +02:00
|
|
|
case 'CLOUD':
|
|
|
|
return array(
|
|
|
|
'HOME' => (string)$l->t('Home'),
|
|
|
|
'WORK' => (string)$l->t('Work'),
|
|
|
|
'OTHER' => (string)$l->t('Other'),
|
|
|
|
);
|
2013-03-13 04:11:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief returns the default categories of ownCloud
|
2015-05-08 00:57:33 +02:00
|
|
|
* @return string[] $categories
|
2013-03-13 04:11:37 +01:00
|
|
|
*/
|
|
|
|
public static function getDefaultCategories() {
|
|
|
|
$l10n = self::$l10n;
|
|
|
|
return array(
|
|
|
|
(string)$l10n->t('Friends'),
|
|
|
|
(string)$l10n->t('Family'),
|
|
|
|
(string)$l10n->t('Work'),
|
|
|
|
(string)$l10n->t('Other'),
|
|
|
|
);
|
|
|
|
}
|
2013-03-13 08:52:00 +01:00
|
|
|
|
2013-04-09 17:20:30 +02:00
|
|
|
public static function generateUID($app = 'contacts') {
|
2014-03-17 23:19:58 +01:00
|
|
|
$uuid = new UUID();
|
|
|
|
return $uuid->get() . '@' . \OCP\Util::getServerHostName();
|
2013-04-09 17:20:30 +02:00
|
|
|
}
|
|
|
|
|
2013-03-20 11:25:04 +01:00
|
|
|
/**
|
2013-05-27 01:44:14 +02:00
|
|
|
* Purge indexed properties.
|
2013-03-20 11:25:04 +01:00
|
|
|
*
|
2013-05-27 01:44:14 +02:00
|
|
|
* @param string[] $ids
|
2013-03-20 11:25:04 +01:00
|
|
|
*/
|
2013-05-27 01:44:14 +02:00
|
|
|
public static function purgeIndexes($ids) {
|
|
|
|
\OCP\Util::writeLog('contacts', __METHOD__.', ids: ' . print_r($ids, true), \OCP\Util::DEBUG);
|
|
|
|
if(!is_array($ids) || count($ids) === 0) {
|
|
|
|
throw new \Exception(__METHOD__ . ' takes only arrays with at least one value.');
|
|
|
|
}
|
|
|
|
\OCP\Util::writeLog('contacts', __METHOD__.', ids: ' . print_r($ids, true), \OCP\Util::DEBUG);
|
2013-03-13 08:52:00 +01:00
|
|
|
if(!isset(self::$deleteindexstmt)) {
|
|
|
|
self::$deleteindexstmt
|
2013-03-29 05:00:03 +01:00
|
|
|
= \OCP\DB::prepare('DELETE FROM `' . self::$indexTableName . '`'
|
2013-05-27 01:44:14 +02:00
|
|
|
. ' WHERE `contactid` IN (' . str_repeat('?,', count($ids)-1) . '?) ');
|
2013-03-13 08:52:00 +01:00
|
|
|
}
|
|
|
|
try {
|
2013-05-27 01:44:14 +02:00
|
|
|
self::$deleteindexstmt->execute($ids);
|
2013-03-13 08:52:00 +01:00
|
|
|
} catch(\Exception $e) {
|
|
|
|
\OCP\Util::writeLog('contacts', __METHOD__.
|
|
|
|
', exception: ' . $e->getMessage(), \OCP\Util::ERROR);
|
2013-05-27 01:44:14 +02:00
|
|
|
\OCP\Util::writeLog('contacts', __METHOD__.', ids: '
|
2014-09-29 10:48:51 +02:00
|
|
|
. print_r($ids, true), \OCP\Util::DEBUG);
|
2013-05-27 01:44:14 +02:00
|
|
|
return false;
|
2013-03-13 08:52:00 +01:00
|
|
|
}
|
2013-05-27 01:44:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the contact property index.
|
|
|
|
*
|
|
|
|
* If vcard is null the properties for that contact will be purged.
|
|
|
|
* If it is a valid object the old properties will first be purged
|
|
|
|
* and the current properties indexed.
|
|
|
|
*
|
|
|
|
* @param string $contactid
|
|
|
|
* @param \OCA\VObject\VCard|null $vcard
|
|
|
|
*/
|
|
|
|
public static function updateIndex($contactid, $vcard = null) {
|
|
|
|
self::purgeIndexes(array($contactid));
|
2013-03-13 08:52:00 +01:00
|
|
|
|
|
|
|
if(is_null($vcard)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!isset(self::$updateindexstmt)) {
|
2013-03-29 05:00:03 +01:00
|
|
|
self::$updateindexstmt = \OCP\DB::prepare( 'INSERT INTO `' . self::$indexTableName . '` '
|
2013-03-13 08:52:00 +01:00
|
|
|
. '(`userid`, `contactid`,`name`,`value`,`preferred`) VALUES(?,?,?,?,?)' );
|
|
|
|
}
|
|
|
|
foreach($vcard->children as $property) {
|
2014-03-18 00:58:01 +01:00
|
|
|
if(!in_array($property->name, self::$indexProperties)) {
|
2013-03-13 08:52:00 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$preferred = 0;
|
|
|
|
foreach($property->parameters as $parameter) {
|
2015-02-16 18:42:41 +01:00
|
|
|
if($parameter->name == 'TYPE' && strtoupper($parameter->getValue()) == 'PREF') {
|
2013-03-13 08:52:00 +01:00
|
|
|
$preferred = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
$result = self::$updateindexstmt->execute(
|
|
|
|
array(
|
2015-02-16 18:42:41 +01:00
|
|
|
\OC::$server->getUserSession()->getUser()->getUId(),
|
2013-03-13 08:52:00 +01:00
|
|
|
$contactid,
|
|
|
|
$property->name,
|
2015-02-16 18:42:41 +01:00
|
|
|
substr($property->getValue(), 0, 254),
|
2013-03-13 08:52:00 +01:00
|
|
|
$preferred,
|
|
|
|
)
|
|
|
|
);
|
2013-09-16 02:24:08 +02:00
|
|
|
if (\OCP\DB::isError($result)) {
|
2013-03-13 08:52:00 +01:00
|
|
|
\OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
|
2013-09-16 02:24:08 +02:00
|
|
|
. \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
|
2013-03-13 08:52:00 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} catch(\Exception $e) {
|
|
|
|
\OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-11-07 14:06:12 +01:00
|
|
|
|
|
|
|
public static function cacheThumbnail($backendName, $addressBookId, $contactId,
|
2014-03-22 21:19:59 +01:00
|
|
|
\OCP\Image $image = null, $vcard = null, $options = array()
|
|
|
|
) {
|
2013-11-07 14:06:12 +01:00
|
|
|
$cache = \OC::$server->getCache();
|
|
|
|
$key = self::THUMBNAIL_PREFIX . $backendName . '::' . $addressBookId . '::' . $contactId;
|
|
|
|
//$cache->remove($key);
|
2014-12-20 11:16:40 +01:00
|
|
|
$haskey = $cache->hasKey($key);
|
|
|
|
|
2014-12-20 13:48:22 +01:00
|
|
|
if (!array_key_exists('remove', $options) && !array_key_exists('update', $options)){
|
2014-12-20 11:16:40 +01:00
|
|
|
if ($cache->hasKey($key) && $image === null){
|
|
|
|
return $cache->get($key);
|
|
|
|
}
|
|
|
|
} else {
|
2015-04-12 11:30:54 +02:00
|
|
|
if ( (isset($options['remove']) && $options['remove'] === false)
|
|
|
|
&& (isset($options['update']) && $options['update'] === false) ){
|
2014-12-20 11:16:40 +01:00
|
|
|
return $cache->get($key);
|
|
|
|
}
|
2013-11-07 14:06:12 +01:00
|
|
|
}
|
2014-03-21 15:19:26 +01:00
|
|
|
|
|
|
|
if (isset($options['remove']) && $options['remove']) {
|
2013-11-07 14:06:12 +01:00
|
|
|
$cache->remove($key);
|
|
|
|
if(!isset($options['update']) || !$options['update']) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2014-03-21 15:19:26 +01:00
|
|
|
|
|
|
|
if (is_null($image)) {
|
|
|
|
if (is_null($vcard)) {
|
2013-11-07 14:06:12 +01:00
|
|
|
$app = new App();
|
|
|
|
$vcard = $app->getContact($backendName, $addressBookId, $contactId);
|
2014-03-22 21:19:59 +01:00
|
|
|
}
|
2014-08-10 20:16:52 +02:00
|
|
|
$image = new \OCP\Image();
|
|
|
|
if (!isset($vcard->PHOTO) || !$image->loadFromBase64((string)$vcard->PHOTO)) {
|
2014-03-22 21:19:59 +01:00
|
|
|
return false;
|
2013-11-07 14:06:12 +01:00
|
|
|
}
|
|
|
|
}
|
2014-03-21 15:19:26 +01:00
|
|
|
|
|
|
|
if (!$image->centerCrop()) {
|
2013-11-07 14:06:12 +01:00
|
|
|
\OCP\Util::writeLog('contacts',
|
|
|
|
__METHOD__ .'. Couldn\'t crop thumbnail for ID ' . $key,
|
|
|
|
\OCP\Util::ERROR);
|
|
|
|
return false;
|
|
|
|
}
|
2014-03-21 15:19:26 +01:00
|
|
|
|
|
|
|
if (!$image->resize(self::THUMBNAIL_SIZE)) {
|
2013-11-07 14:06:12 +01:00
|
|
|
\OCP\Util::writeLog('contacts',
|
|
|
|
__METHOD__ . '. Couldn\'t resize thumbnail for ID ' . $key,
|
|
|
|
\OCP\Util::ERROR);
|
|
|
|
return false;
|
|
|
|
}
|
2014-03-21 15:19:26 +01:00
|
|
|
|
2013-11-07 14:06:12 +01:00
|
|
|
// Cache as base64 for around a month
|
|
|
|
$cache->set($key, strval($image), 3000000);
|
|
|
|
return $cache->get($key);
|
|
|
|
}
|
|
|
|
|
2013-03-13 04:11:37 +01:00
|
|
|
}
|