1
0
mirror of https://github.com/owncloudarchive/contacts.git synced 2024-12-10 21:24:33 +01:00
OwncloudContactsOfficial/lib/app.php

406 lines
11 KiB
PHP
Raw Normal View History

<?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;
2012-11-22 00:14:03 +01:00
use Sabre\VObject;
/**
* This class manages our app actions
*/
2012-10-25 03:34:12 +02:00
App::$l10n = \OC_L10N::get('contacts');
class App {
/*
* @brief language object for calendar app
*/
public static $l10n;
/*
* @brief categories of the user
*/
public static $categories = null;
/**
* Properties there can be more than one of.
*/
public static $multi_properties = array('EMAIL', 'TEL', 'IMPP', 'ADR', 'URL');
2012-11-15 06:07:44 +01:00
/**
* Properties to index.
*/
2013-02-18 03:08:01 +01:00
public static $index_properties = array('BDAY', 'UID', 'N', 'FN', 'NOTE', 'NICKNAME', 'ORG', 'CATEGORIES', 'EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'GEO', 'PHOTO');
2012-11-15 06:07:44 +01:00
const THUMBNAIL_PREFIX = 'contact-thumbnail-';
const THUMBNAIL_SIZE = 28;
/**
2013-01-08 05:50:41 +01:00
* @brief Gets the VCard as a \Sabre\VObject\Component
* @param integer $id
* @returns \Sabre\VObject\Component|null The card or null if the card could not be parsed.
*/
public static function getContactVCard($id) {
2012-10-05 05:05:49 +02:00
$card = null;
2012-11-22 00:14:03 +01:00
$vcard = null;
2012-10-05 05:05:49 +02:00
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;
}
2012-11-22 00:14:03 +01:00
try {
$vcard = \Sabre\VObject\Reader::read($card['carddata']);
} catch(Exception $e) {
\OCP\Util::writeLog('contacts', __METHOD__.', exception: ' . $e->getMessage(), \OCP\Util::ERROR);
\OCP\Util::writeLog('contacts', __METHOD__.', id: ' . $id, \OCP\Util::DEBUG);
return null;
}
if (!is_null($vcard) && !isset($vcard->REV)) {
2012-10-25 03:34:12 +02:00
$rev = new \DateTime('@'.$card['lastmodified']);
2012-11-22 00:14:03 +01:00
$vcard->REV = $rev->format(\DateTime::W3C);
}
return $vcard;
}
public static function getPropertyLineByChecksum($vcard, $checksum) {
$line = null;
2012-11-22 00:14:03 +01:00
foreach($vcard->children as $i => $property) {
if(substr(md5($property->serialize()), 0, 8) == $checksum ) {
$line = $i;
break;
}
}
return $line;
}
/**
* @return array of vcard prop => label
*/
2012-08-22 18:50:50 +02:00
public static function getIMOptions($im = null) {
$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;
}
}
/**
* @return types for property $prop
*/
public static function getTypesOfProperty($prop) {
$l = self::$l10n;
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'),
'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'),
'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
);
}
}
/**
* @brief returns the vcategories object of the user
* @return (object) $vcategories
*/
public static function getVCategories() {
if (is_null(self::$categories)) {
2012-10-25 03:34:12 +02:00
if(\OC_VCategories::isEmpty('contact')) {
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());
}
return self::$categories;
}
2012-07-30 05:31:06 +02:00
/**
* @brief returns the categories for the user
* @return (Array) $categories
*/
public static function getCategories($format = null) {
$categories = self::getVCategories()->categories($format);
return ($categories ? $categories : self::getDefaultCategories());
}
/**
* @brief returns the default categories of ownCloud
* @return (array) $categories
*/
2012-09-07 15:21:03 +02:00
public static function getDefaultCategories() {
return array(
(string)self::$l10n->t('Friends'),
(string)self::$l10n->t('Family'),
(string)self::$l10n->t('Work'),
(string)self::$l10n->t('Other'),
);
}
2012-07-30 05:31:06 +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());
if(count($vcaddressbooks) > 0) {
$vcaddressbookids = array();
foreach($vcaddressbooks as $vcaddressbook) {
2012-11-01 15:31:36 +01:00
if($vcaddressbook['userid'] === \OCP\User::getUser()) {
$vcaddressbookids[] = $vcaddressbook['id'];
}
}
$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)) {
$cards = array();
foreach($vccontacts as $vccontact) {
$cards[] = array($vccontact['id'], $vccontact['carddata']);
}
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);
// only reset on first batch.
$categories->rescan($cards,
2012-07-30 05:31:06 +02:00
true,
($start == 0 ? true : false));
$start += $batchsize;
}
}
}
}
/**
* check VCard for new categories.
* @see OC_VCategories::loadFromVObject
*/
2012-11-22 00:14:03 +01:00
public static function loadCategoriesFromVCard($id, $contact) {
if(!$contact instanceof \OC_VObject) {
$contact = new \OC_VObject($contact);
}
self::getVCategories()->loadFromVObject($id, $contact, true);
2012-03-07 21:50:55 +01:00
}
/**
* @brief Get the last modification time.
* @param OC_VObject|Sabre\VObject\Component|integer|null $contact
2012-11-12 01:24:20 +01:00
* @returns DateTime | null
*/
2012-12-09 19:44:27 +01:00
public static function lastModified($contact = null) {
if(is_null($contact)) {
// FIXME: This doesn't take shared address books into account.
$sql = 'SELECT MAX(`lastmodified`) FROM `*PREFIX*contacts_cards`, `*PREFIX*contacts_addressbooks` ' .
'WHERE `*PREFIX*contacts_cards`.`addressbookid` = `*PREFIX*contacts_addressbooks`.`id` AND ' .
'`*PREFIX*contacts_addressbooks`.`userid` = ?';
$stmt = \OCP\DB::prepare($sql);
$result = $stmt->execute(array(\OCP\USER::getUser()));
if (\OC_DB::isError($result)) {
\OC_Log::write('contacts', __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
return null;
}
$lastModified = $result->fetchOne();
if(!is_null($lastModified)) {
return new \DateTime('@' . $lastModified);
}
2012-12-09 19:44:27 +01:00
} else if(is_numeric($contact)) {
$card = VCard::find($contact, array('lastmodified'));
2012-12-09 19:44:27 +01:00
return ($card ? new \DateTime('@' . $card['lastmodified']) : null);
} elseif($contact instanceof \OC_VObject || $contact instanceof VObject\Component) {
return isset($contact->REV)
? \DateTime::createFromFormat(\DateTime::W3C, $contact->REV)
: null;
}
}
2012-11-22 00:14:03 +01:00
public static function cacheThumbnail($id, \OC_Image $image = null) {
if(\OC_Cache::hasKey(self::THUMBNAIL_PREFIX . $id) && $image === null) {
2012-10-25 03:34:12 +02:00
return \OC_Cache::get(self::THUMBNAIL_PREFIX . $id);
}
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',
__METHOD__.' The VCard for ID ' . $id . ' is not RFC compatible',
2012-10-25 03:34:12 +02:00
\OCP\Util::ERROR);
return false;
}
2012-10-25 03:34:12 +02:00
$image = new \OC_Image();
2012-11-22 00:14:03 +01:00
if(!isset($vcard->PHOTO)) {
return false;
}
2012-11-22 00:31:08 +01:00
if(!$image->loadFromBase64((string)$vcard->PHOTO)) {
return false;
}
}
if(!$image->centerCrop()) {
2012-10-25 03:34:12 +02:00
\OCP\Util::writeLog('contacts',
'thumbnail.php. Couldn\'t crop thumbnail for ID ' . $id,
2012-10-25 03:34:12 +02:00
\OCP\Util::ERROR);
return false;
}
if(!$image->resize(self::THUMBNAIL_SIZE)) {
2012-10-25 03:34:12 +02:00
\OCP\Util::writeLog('contacts',
'thumbnail.php. Couldn\'t resize thumbnail for ID ' . $id,
2012-10-25 03:34:12 +02:00
\OCP\Util::ERROR);
return false;
}
// 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-11-22 00:14:03 +01:00
public static function updateDBProperties($contactid, $vcard = null) {
2012-11-13 22:42:55 +01:00
$stmt = \OCP\DB::prepare('DELETE FROM `*PREFIX*contacts_cards_properties` WHERE `contactid` = ?');
try {
$stmt->execute(array($contactid));
} catch(\Exception $e) {
\OCP\Util::writeLog('contacts', __METHOD__.
', exception: ' . $e->getMessage(), \OCP\Util::ERROR);
\OCP\Util::writeLog('contacts', __METHOD__.', id: '
. $id, \OCP\Util::DEBUG);
throw new \Exception(
App::$l10n->t(
'There was an error deleting properties for this contact.'
)
);
}
if(is_null($vcard)) {
return;
}
2012-11-15 06:07:44 +01:00
$stmt = \OCP\DB::prepare( 'INSERT INTO `*PREFIX*contacts_cards_properties` '
. '(`userid`, `contactid`,`name`,`value`,`preferred`) VALUES(?,?,?,?,?)' );
2012-11-13 22:42:55 +01:00
foreach($vcard->children as $property) {
2012-11-15 06:07:44 +01:00
if(!in_array($property->name, self::$index_properties)) {
continue;
}
$preferred = 0;
foreach($property->parameters as $parameter) {
if($parameter->name == 'TYPE' && strtoupper($parameter->value) == 'PREF') {
$preferred = 1;
break;
}
}
try {
2012-11-15 06:07:44 +01:00
$result = $stmt->execute(
array(
\OCP\User::getUser(),
$contactid,
$property->name,
$property->value,
$preferred,
)
);
if (\OC_DB::isError($result)) {
2012-11-15 06:07:44 +01:00
\OCP\Util::writeLog('contacts', __METHOD__. 'DB error: '
. \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
return false;
}
} catch(\Exception $e) {
\OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR);
return false;
}
}
}
}