2011-12-05 21:51:25 +01:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Copyright (c) 2011 Bart Visscher bartv@thisnet.nl
|
|
|
|
* This file is licensed under the Affero General Public License version 3 or
|
|
|
|
* later.
|
|
|
|
* See the COPYING-README file.
|
|
|
|
*/
|
|
|
|
|
2012-10-25 03:34:12 +02:00
|
|
|
namespace OCA\Contacts;
|
|
|
|
|
2011-12-05 21:51:25 +01:00
|
|
|
/**
|
|
|
|
* This class manages our app actions
|
|
|
|
*/
|
2012-10-25 03:34:12 +02:00
|
|
|
App::$l10n = \OC_L10N::get('contacts');
|
|
|
|
|
|
|
|
class App {
|
2012-05-13 23:25:51 +02:00
|
|
|
/*
|
|
|
|
* @brief language object for calendar app
|
|
|
|
*/
|
|
|
|
|
2011-12-05 21:51:25 +01:00
|
|
|
public static $l10n;
|
2012-05-13 23:25:51 +02:00
|
|
|
/*
|
|
|
|
* @brief categories of the user
|
|
|
|
*/
|
|
|
|
public static $categories = null;
|
2011-12-05 21:51:25 +01:00
|
|
|
|
2012-10-25 23:12:21 +02:00
|
|
|
/**
|
|
|
|
* Properties there can be more than one of.
|
|
|
|
*/
|
|
|
|
public static $multi_properties = array('EMAIL', 'TEL', 'IMPP', 'ADR', 'URL');
|
|
|
|
|
2012-10-24 21:35:51 +02:00
|
|
|
const THUMBNAIL_PREFIX = 'contact-thumbnail-';
|
|
|
|
const THUMBNAIL_SIZE = 28;
|
|
|
|
|
2012-01-12 18:04:23 +01:00
|
|
|
/**
|
2012-02-09 19:04:07 +01:00
|
|
|
* @brief Gets the VCard as an OC_VObject
|
2012-01-12 18:04:23 +01:00
|
|
|
* @returns The card or null if the card could not be parsed.
|
|
|
|
*/
|
2012-02-11 21:57:38 +01:00
|
|
|
public static function getContactVCard($id) {
|
2012-10-05 05:05:49 +02:00
|
|
|
$card = null;
|
|
|
|
try {
|
2012-10-25 03:34:12 +02:00
|
|
|
$card = VCard::find($id);
|
2012-10-05 05:05:49 +02:00
|
|
|
} catch(Exception $e) {
|
|
|
|
return null;
|
|
|
|
}
|
2011-12-06 22:31:04 +01:00
|
|
|
|
2012-10-25 03:34:12 +02:00
|
|
|
$vcard = \OC_VObject::parse($card['carddata']);
|
2012-02-12 15:13:30 +01:00
|
|
|
if (!is_null($vcard) && !isset($vcard->REV)) {
|
2012-10-25 03:34:12 +02:00
|
|
|
$rev = new \DateTime('@'.$card['lastmodified']);
|
2012-02-12 15:13:30 +01:00
|
|
|
$vcard->setString('REV', $rev->format(DateTime::W3C));
|
|
|
|
}
|
2011-12-06 22:31:04 +01:00
|
|
|
return $vcard;
|
|
|
|
}
|
|
|
|
|
2012-02-11 21:57:38 +01:00
|
|
|
public static function getPropertyLineByChecksum($vcard, $checksum) {
|
2011-12-06 22:31:04 +01:00
|
|
|
$line = null;
|
2012-02-11 21:57:38 +01:00
|
|
|
for($i=0;$i<count($vcard->children);$i++) {
|
2012-10-26 00:02:44 +02:00
|
|
|
if(substr(md5($vcard->children[$i]->serialize()), 0, 8) == $checksum ) {
|
2011-12-06 22:31:04 +01:00
|
|
|
$line = $i;
|
2012-01-11 03:56:53 +01:00
|
|
|
break;
|
2011-12-06 22:31:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $line;
|
|
|
|
}
|
|
|
|
|
2011-12-05 21:51:25 +01:00
|
|
|
/**
|
|
|
|
* @return array of vcard prop => label
|
|
|
|
*/
|
2012-08-22 18:50:50 +02:00
|
|
|
public static function getIMOptions($im = null) {
|
2011-12-06 22:31:04 +01:00
|
|
|
$l10n = self::$l10n;
|
2012-08-22 18:50:50 +02:00
|
|
|
$ims = array(
|
|
|
|
'jabber' => array(
|
|
|
|
'displayname' => (string)$l10n->t('Jabber'),
|
|
|
|
'xname' => 'X-JABBER',
|
|
|
|
'protocol' => 'xmpp',
|
|
|
|
),
|
|
|
|
'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' => null,
|
|
|
|
),
|
|
|
|
'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',
|
|
|
|
),
|
|
|
|
);
|
|
|
|
if(is_null($im)) {
|
|
|
|
return $ims;
|
|
|
|
} else {
|
|
|
|
$ims['ymsgr'] = $ims['yahoo'];
|
|
|
|
$ims['gtalk'] = $ims['googletalk'];
|
|
|
|
return isset($ims[$im]) ? $ims[$im] : null;
|
|
|
|
}
|
2011-12-05 21:51:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return types for property $prop
|
|
|
|
*/
|
2012-02-11 21:57:38 +01:00
|
|
|
public static function getTypesOfProperty($prop) {
|
2011-12-06 22:31:04 +01:00
|
|
|
$l = self::$l10n;
|
2012-02-11 21:57:38 +01:00
|
|
|
switch($prop) {
|
2012-07-30 05:31:06 +02:00
|
|
|
case 'ADR':
|
2012-08-22 18:50:50 +02:00
|
|
|
case 'IMPP':
|
2012-07-30 05:31:06 +02:00
|
|
|
return array(
|
|
|
|
'WORK' => $l->t('Work'),
|
|
|
|
'HOME' => $l->t('Home'),
|
2012-08-21 03:56:12 +02:00
|
|
|
'OTHER' => $l->t('Other'),
|
2012-07-30 05:31:06 +02:00
|
|
|
);
|
|
|
|
case 'TEL':
|
|
|
|
return array(
|
|
|
|
'HOME' => $l->t('Home'),
|
|
|
|
'CELL' => $l->t('Mobile'),
|
|
|
|
'WORK' => $l->t('Work'),
|
|
|
|
'TEXT' => $l->t('Text'),
|
|
|
|
'VOICE' => $l->t('Voice'),
|
|
|
|
'MSG' => $l->t('Message'),
|
|
|
|
'FAX' => $l->t('Fax'),
|
|
|
|
'VIDEO' => $l->t('Video'),
|
|
|
|
'PAGER' => $l->t('Pager'),
|
2012-08-21 03:56:12 +02:00
|
|
|
'OTHER' => $l->t('Other'),
|
2012-07-30 05:31:06 +02:00
|
|
|
);
|
|
|
|
case 'EMAIL':
|
|
|
|
return array(
|
|
|
|
'WORK' => $l->t('Work'),
|
|
|
|
'HOME' => $l->t('Home'),
|
|
|
|
'INTERNET' => $l->t('Internet'),
|
2012-09-30 06:40:04 +02:00
|
|
|
'OTHER' => $l->t('Other'),
|
2012-07-30 05:31:06 +02:00
|
|
|
);
|
2011-12-05 21:51:25 +01:00
|
|
|
}
|
|
|
|
}
|
2012-02-12 17:20:30 +01:00
|
|
|
|
2012-06-27 02:12:14 +02:00
|
|
|
/**
|
2012-05-13 23:25:51 +02:00
|
|
|
* @brief returns the vcategories object of the user
|
|
|
|
* @return (object) $vcategories
|
|
|
|
*/
|
2012-09-11 14:19:28 +02:00
|
|
|
public static function getVCategories() {
|
2012-05-13 23:25:51 +02:00
|
|
|
if (is_null(self::$categories)) {
|
2012-10-25 03:34:12 +02:00
|
|
|
if(\OC_VCategories::isEmpty('contact')) {
|
2012-09-11 14:19:28 +02:00
|
|
|
self::scanCategories();
|
|
|
|
}
|
2012-10-25 03:34:12 +02:00
|
|
|
self::$categories = new \OC_VCategories('contact',
|
2012-07-30 05:31:06 +02:00
|
|
|
null,
|
|
|
|
self::getDefaultCategories());
|
2012-05-13 23:25:51 +02:00
|
|
|
}
|
|
|
|
return self::$categories;
|
|
|
|
}
|
2012-07-30 05:31:06 +02:00
|
|
|
|
2012-06-27 02:12:14 +02:00
|
|
|
/**
|
2012-05-13 23:25:51 +02:00
|
|
|
* @brief returns the categories for the user
|
|
|
|
* @return (Array) $categories
|
|
|
|
*/
|
2012-09-17 16:15:31 +02:00
|
|
|
public static function getCategories($format = null) {
|
|
|
|
$categories = self::getVCategories()->categories($format);
|
2012-06-27 02:12:14 +02:00
|
|
|
return ($categories ? $categories : self::getDefaultCategories());
|
2012-04-12 22:31:28 +02:00
|
|
|
}
|
|
|
|
|
2012-06-27 02:12:14 +02:00
|
|
|
/**
|
|
|
|
* @brief returns the default categories of ownCloud
|
|
|
|
* @return (array) $categories
|
|
|
|
*/
|
2012-09-07 15:21:03 +02:00
|
|
|
public static function getDefaultCategories() {
|
2012-06-27 02:12:14 +02:00
|
|
|
return array(
|
2012-10-03 22:10:48 +02:00
|
|
|
(string)self::$l10n->t('Friends'),
|
|
|
|
(string)self::$l10n->t('Family'),
|
2012-06-27 02:12:14 +02:00
|
|
|
(string)self::$l10n->t('Work'),
|
2012-10-03 22:10:48 +02:00
|
|
|
(string)self::$l10n->t('Other'),
|
2012-06-27 02:12:14 +02:00
|
|
|
);
|
|
|
|
}
|
2012-07-30 05:31:06 +02:00
|
|
|
|
2012-04-12 22:31:28 +02:00
|
|
|
/**
|
|
|
|
* scan vcards for categories.
|
|
|
|
* @param $vccontacts VCards to scan. null to check all vcards for the current user.
|
|
|
|
*/
|
|
|
|
public static function scanCategories($vccontacts = null) {
|
|
|
|
if (is_null($vccontacts)) {
|
2012-11-01 15:31:36 +01:00
|
|
|
$vcaddressbooks = Addressbook::all(\OCP\USER::getUser());
|
2012-04-12 22:31:28 +02:00
|
|
|
if(count($vcaddressbooks) > 0) {
|
|
|
|
$vcaddressbookids = array();
|
|
|
|
foreach($vcaddressbooks as $vcaddressbook) {
|
2012-11-01 15:31:36 +01:00
|
|
|
if($vcaddressbook['userid'] === \OCP\User::getUser()) {
|
2012-10-03 22:03:29 +02:00
|
|
|
$vcaddressbookids[] = $vcaddressbook['id'];
|
|
|
|
}
|
2012-04-12 22:31:28 +02:00
|
|
|
}
|
2012-07-09 00:16:14 +02:00
|
|
|
$start = 0;
|
|
|
|
$batchsize = 10;
|
2012-10-25 03:34:12 +02:00
|
|
|
$categories = new \OC_VCategories('contact');
|
2012-07-30 05:31:06 +02:00
|
|
|
while($vccontacts =
|
2012-10-30 07:08:41 +01:00
|
|
|
VCard::all($vcaddressbookids, $start, $batchsize)) {
|
2012-07-09 00:16:14 +02:00
|
|
|
$cards = array();
|
|
|
|
foreach($vccontacts as $vccontact) {
|
2012-09-11 14:19:28 +02:00
|
|
|
$cards[] = array($vccontact['id'], $vccontact['carddata']);
|
2012-07-09 00:16:14 +02:00
|
|
|
}
|
2012-10-25 03:34:12 +02:00
|
|
|
\OCP\Util::writeLog('contacts',
|
2012-07-30 05:31:06 +02:00
|
|
|
__CLASS__.'::'.__METHOD__
|
|
|
|
.', scanning: '.$batchsize.' starting from '.$start,
|
2012-10-25 03:34:12 +02:00
|
|
|
\OCP\Util::DEBUG);
|
2012-07-09 00:16:14 +02:00
|
|
|
// only reset on first batch.
|
2012-09-11 14:19:28 +02:00
|
|
|
$categories->rescan($cards,
|
2012-07-30 05:31:06 +02:00
|
|
|
true,
|
|
|
|
($start == 0 ? true : false));
|
2012-07-09 00:16:14 +02:00
|
|
|
$start += $batchsize;
|
|
|
|
}
|
2012-04-12 22:31:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* check VCard for new categories.
|
|
|
|
* @see OC_VCategories::loadFromVObject
|
|
|
|
*/
|
2012-10-25 03:34:12 +02:00
|
|
|
public static function loadCategoriesFromVCard($id, \OC_VObject $contact) {
|
2012-09-11 14:19:28 +02:00
|
|
|
self::getVCategories()->loadFromVObject($id, $contact, true);
|
2012-03-07 21:50:55 +01:00
|
|
|
}
|
|
|
|
|
2012-08-09 16:31:04 +02:00
|
|
|
/**
|
|
|
|
* @brief Get the last modification time.
|
2012-10-24 21:35:51 +02:00
|
|
|
* @param $contact OC_VObject|integer
|
2012-08-09 16:31:04 +02:00
|
|
|
* $return DateTime | null
|
|
|
|
*/
|
2012-10-24 21:35:51 +02:00
|
|
|
public static function lastModified($contact) {
|
|
|
|
if(is_numeric($contact)) {
|
2012-10-25 03:34:12 +02:00
|
|
|
$card = VCard::find($contact);
|
|
|
|
return ($card ? new \DateTime('@' . $card['lastmodified']) : null);
|
|
|
|
} elseif($contact instanceof \OC_VObject) {
|
2012-10-24 21:35:51 +02:00
|
|
|
$rev = $contact->getAsString('REV');
|
|
|
|
if ($rev) {
|
2012-10-25 23:13:59 +02:00
|
|
|
return \DateTime::createFromFormat(\DateTime::W3C, $rev);
|
2012-10-24 21:35:51 +02:00
|
|
|
}
|
2012-08-09 16:31:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-24 21:35:51 +02:00
|
|
|
public static function cacheThumbnail($id, OC_Image $image = null) {
|
2012-10-25 03:34:12 +02:00
|
|
|
if(\OC_Cache::hasKey(self::THUMBNAIL_PREFIX . $id)) {
|
|
|
|
return \OC_Cache::get(self::THUMBNAIL_PREFIX . $id);
|
2012-10-24 21:35:51 +02:00
|
|
|
}
|
|
|
|
if(is_null($image)) {
|
|
|
|
$vcard = self::getContactVCard($id);
|
|
|
|
|
|
|
|
// invalid vcard
|
|
|
|
if(is_null($vcard)) {
|
2012-10-25 03:34:12 +02:00
|
|
|
\OCP\Util::writeLog('contacts',
|
2012-10-24 21:35:51 +02:00
|
|
|
__METHOD__.' The VCard for ID ' . $id . ' is not RFC compatible',
|
2012-10-25 03:34:12 +02:00
|
|
|
\OCP\Util::ERROR);
|
2012-10-24 21:35:51 +02:00
|
|
|
return false;
|
|
|
|
}
|
2012-10-25 03:34:12 +02:00
|
|
|
$image = new \OC_Image();
|
2012-10-24 21:35:51 +02:00
|
|
|
$photo = $vcard->getAsString('PHOTO');
|
|
|
|
if(!$photo) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(!$image->loadFromBase64($photo)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!$image->centerCrop()) {
|
2012-10-25 03:34:12 +02:00
|
|
|
\OCP\Util::writeLog('contacts',
|
2012-10-24 21:35:51 +02:00
|
|
|
'thumbnail.php. Couldn\'t crop thumbnail for ID ' . $id,
|
2012-10-25 03:34:12 +02:00
|
|
|
\OCP\Util::ERROR);
|
2012-10-24 21:35:51 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(!$image->resize(self::THUMBNAIL_SIZE)) {
|
2012-10-25 03:34:12 +02:00
|
|
|
\OCP\Util::writeLog('contacts',
|
2012-10-24 21:35:51 +02:00
|
|
|
'thumbnail.php. Couldn\'t resize thumbnail for ID ' . $id,
|
2012-10-25 03:34:12 +02:00
|
|
|
\OCP\Util::ERROR);
|
2012-10-24 21:35:51 +02:00
|
|
|
return false;
|
2012-02-12 17:20:30 +01:00
|
|
|
}
|
2012-10-24 21:35:51 +02:00
|
|
|
// Cache for around a month
|
2012-10-25 03:34:12 +02:00
|
|
|
\OC_Cache::set(self::THUMBNAIL_PREFIX . $id, $image->data(), 3000000);
|
2012-11-01 02:00:29 +01:00
|
|
|
\OCP\Util::writeLog('contacts', 'Caching ' . $id, \OCP\Util::DEBUG);
|
2012-10-25 03:34:12 +02:00
|
|
|
return \OC_Cache::get(self::THUMBNAIL_PREFIX . $id);
|
2012-02-12 17:20:30 +01:00
|
|
|
}
|
2011-12-05 21:51:25 +01:00
|
|
|
}
|