123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- <?php
- /**
- * ownCloud - Addressbook
- *
- * @author Jakob Sack
- * @copyright 2011 Jakob Sack mail@jakobsack.de
- *
- * 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/>.
- *
- */
- /*
- *
- * The following SQL statement is just a help for developers and will not be
- * executed!
- *
- * CREATE TABLE contacts_cards (
- * id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- * addressbookid INT(11) UNSIGNED NOT NULL,
- * fullname VARCHAR(255),
- * carddata TEXT,
- * uri VARCHAR(100),
- * lastmodified INT(11) UNSIGNED
- * );
- */
- /**
- * This class manages our vCards
- */
- class OC_Contacts_VCard{
- /**
- * @brief Returns all cards of an address book
- * @param integer $id
- * @return array
- *
- * The cards are associative arrays. You'll find the original vCard in
- * ['carddata']
- */
- public static function all($id){
- if(is_array($id)) {
- $id_sql = join(',', array_fill(0, count($id), '?'));
- $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname';
- try {
- $stmt = OC_DB::prepare( $prep );
- $result = $stmt->execute($id);
- } catch(Exception $e) {
- OC_Log::write('contacts','OC_Contacts_VCard:all:, exception: '.$e->getMessage(),OC_Log::DEBUG);
- OC_Log::write('contacts','OC_Contacts_VCard:all, ids: '.join(',', $id),OC_Log::DEBUG);
- OC_Log::write('contacts','SQL:'.$prep,OC_Log::DEBUG);
- }
- } else {
- $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' );
- $result = $stmt->execute(array($id));
- }
- $cards = array();
- while( $row = $result->fetchRow()){
- $cards[] = $row;
- }
- return $cards;
- }
- /**
- * @brief Returns a card
- * @param integer $id
- * @return associative array
- */
- public static function find($id){
- $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE id = ?' );
- $result = $stmt->execute(array($id));
- return $result->fetchRow();
- }
- /**
- * @brief finds a card by its DAV Data
- * @param integer $aid Addressbook id
- * @param string $uri the uri ('filename')
- * @return associative array
- */
- public static function findWhereDAVDataIs($aid,$uri){
- $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri = ?' );
- $result = $stmt->execute(array($aid,$uri));
- return $result->fetchRow();
- }
- /**
- * @brief Adds a card
- * @param integer $id Addressbook id
- * @param string $data vCard file
- * @return insertid on success or null if card is not parseable.
- */
- public static function add($id,$data){
- $fn = null;
- $card = OC_VObject::parse($data);
- if(!is_null($card)){
- $fn = $card->getAsString('FN');
- if(!$fn){ // Fix missing 'FN' field.
- $n = $card->getAsString('N');
- if(!is_null($n)){
- $fn = join(' ', array_reverse(array_slice(explode(';', $n), 0, 2)));
- $card->setString('FN', $fn);
- OC_Log::write('contacts','OC_Contacts_VCard::add. Added missing \'FN\' field: '.$fn,OC_Log::DEBUG);
- } else {
- $fn = 'Unknown Name';
- }
- }
- $n = $card->getAsString('N');
- if(!$n){ // Fix missing 'N' field.
- $n = implode(';', array_reverse(array_slice(explode(' ', $fn), 0, 2))).';;;';
- $card->setString('N', $n);
- OC_Log::write('contacts','OC_Contacts_VCard::add. Added missing \'N\' field: '.$n,OC_Log::DEBUG);
- }
- $uid = $card->getAsString('UID');
- if(is_null($uid)){
- $card->setUID();
- $uid = $card->getAsString('UID');
- //$data = $card->serialize();
- };
- $uri = $uid.'.vcf';
- // Add product ID.
- $prodid = trim($card->getAsString('PRODID'));
- if(!$prodid) {
- $appinfo = OC_App::getAppInfo('contacts');
- $prodid = '//ownCloud//NONSGML '.$appinfo['name'].' '.$appinfo['version'].'//EN';
- $card->setString('PRODID', $prodid);
- }
- // VCARD must have a version
- $version = $card->getAsString('VERSION');
- // Add version if needed
- if(!$version){
- $card->add(new Sabre_VObject_Property('VERSION','3.0'));
- //$data = $card->serialize();
- }/* else {
- OC_Log::write('contacts','OC_Contacts_VCard::add. Version already set as: '.$version,OC_Log::DEBUG);
- }*/
- $now = new DateTime;
- $card->setString('REV', $now->format(DateTime::W3C));
- $data = $card->serialize();
- }
- else{
- // that's hard. Creating a UID and not saving it
- OC_Log::write('contacts','OC_Contacts_VCard::add. Error parsing VCard: '.$data,OC_Log::ERROR);
- return null; // Ditch cards that can't be parsed by Sabre.
- //$uid = self::createUID();
- //$uri = $uid.'.vcf';
- };
- $stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_cards (addressbookid,fullname,carddata,uri,lastmodified) VALUES(?,?,?,?,?)' );
- $result = $stmt->execute(array($id,$fn,$data,$uri,time()));
- $newid = OC_DB::insertid('*PREFIX*contacts_cards');
- OC_Contacts_Addressbook::touch($id);
- return $newid;
- }
- /**
- * @brief Adds a card with the data provided by sabredav
- * @param integer $id Addressbook id
- * @param string $uri the uri the card will have
- * @param string $data vCard file
- * @return insertid
- */
- public static function addFromDAVData($id,$uri,$data){
- $fn = $n = null;
- $email = null;
- $card = OC_VObject::parse($data);
- if(!is_null($card)){
- foreach($card->children as $property){
- if($property->name == 'FN'){
- $fn = $property->value;
- }
- if($property->name == 'N'){
- $n = $property->value;
- }
- if($property->name == 'EMAIL' && is_null($email)){
- $email = $property->value;
- }
- }
- }
- if(!$fn) {
- if($n){
- $fn = join(' ', array_reverse(array_slice(explode(';', $n), 0, 2)));
- } elseif($email) {
- $fn = $email;
- } else {
- $fn = 'Unknown Name';
- }
- $card->addProperty('FN', $fn);
- $data = $card->serialize();
- OC_Log::write('contacts','OC_Contacts_VCard::add. Added missing \'FN\' field: '.$n,OC_Log::DEBUG);
- }
- if(!$n){ // Fix missing 'N' field.
- $n = implode(';', array_reverse(array_slice(explode(' ', $fn), 0, 2))).';;;';
- $card->setString('N', $n);
- $data = $card->serialize();
- OC_Log::write('contacts','OC_Contacts_VCard::add. Added missing \'N\' field: '.$n,OC_Log::DEBUG);
- }
- $stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_cards (addressbookid,fullname,carddata,uri,lastmodified) VALUES(?,?,?,?,?)' );
- $result = $stmt->execute(array($id,$fn,$data,$uri,time()));
- OC_Contacts_Addressbook::touch($id);
- return OC_DB::insertid('*PREFIX*contacts_cards');
- }
- /**
- * @brief edits a card
- * @param integer $id id of card
- * @param string $data vCard file
- * @return boolean
- */
- public static function edit($id, $data){
- $oldcard = self::find($id);
- $fn = null;
- $card = OC_VObject::parse($data);
- if(!is_null($card)){
- foreach($card->children as $property){
- if($property->name == 'FN'){
- $fn = $property->value;
- break;
- }
- }
- } else {
- return false;
- }
- $now = new DateTime;
- $card->setString('REV', $now->format(DateTime::W3C));
- $data = $card->serialize();
- $stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_cards SET fullname = ?,carddata = ?, lastmodified = ? WHERE id = ?' );
- $result = $stmt->execute(array($fn,$data,time(),$id));
- OC_Contacts_Addressbook::touch($oldcard['addressbookid']);
- return true;
- }
- /**
- * @brief edits a card with the data provided by sabredav
- * @param integer $id Addressbook id
- * @param string $uri the uri of the card
- * @param string $data vCard file
- * @return boolean
- */
- public static function editFromDAVData($aid,$uri,$data){
- $oldcard = self::findWhereDAVDataIs($aid,$uri);
- $fn = null;
- $card = OC_VObject::parse($data);
- if(!is_null($card)){
- foreach($card->children as $property){
- if($property->name == 'FN'){
- $fn = $property->value;
- break;
- }
- }
- }
- $now = new DateTime;
- $card->setString('REV', $now->format(DateTime::W3C));
- $data = $card->serialize();
- $stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_cards SET fullname = ?,carddata = ?, lastmodified = ? WHERE id = ?' );
- $result = $stmt->execute(array($fn,$data,time(),$oldcard['id']));
- OC_Contacts_Addressbook::touch($oldcard['addressbookid']);
- return true;
- }
- /**
- * @brief deletes a card
- * @param integer $id id of card
- * @return boolean
- */
- public static function delete($id){
- // FIXME: Add error checking.
- $stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE id = ?' );
- $stmt->execute(array($id));
- return true;
- }
- /**
- * @brief Creates a UID
- * @return string
- */
- public static function createUID(){
- return substr(md5(rand().time()),0,10);
- }
- /**
- * @brief deletes a card with the data provided by sabredav
- * @param integer $aid Addressbook id
- * @param string $uri the uri of the card
- * @return boolean
- */
- public static function deleteFromDAVData($aid,$uri){
- // FIXME: Add error checking. Deleting a card gives an Kontact/Akonadi error.
- $stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri=?' );
- $stmt->execute(array($aid,$uri));
- return true;
- }
- /**
- * @brief Data structure of vCard
- * @param object $property
- * @return associative array
- *
- * look at code ...
- */
- public static function structureContact($object){
- $details = array();
- foreach($object->children as $property){
- $temp = self::structureProperty($property);
- if(array_key_exists($property->name,$details)){
- $details[$property->name][] = $temp;
- }
- else{
- $details[$property->name] = array($temp);
- }
- }
- return $details;
- }
- /**
- * @brief Data structure of properties
- * @param object $property
- * @return associative array
- *
- * returns an associative array with
- * ['name'] name of property
- * ['value'] htmlspecialchars escaped value of property
- * ['parameters'] associative array name=>value
- * ['checksum'] checksum of whole property
- * NOTE: $value is not escaped anymore. It shouldn't make any difference
- * but we should look out for any problems.
- */
- public static function structureProperty($property){
- $value = $property->value;
- //$value = htmlspecialchars($value);
- if($property->name == 'ADR' || $property->name == 'N'){
- $value = OC_VObject::unescapeSemicolons($value);
- }
- $temp = array(
- 'name' => $property->name,
- 'value' => $value,
- 'parameters' => array(),
- 'checksum' => md5($property->serialize()));
- foreach($property->parameters as $parameter){
- // Faulty entries by kaddressbook
- if($parameter->name == 'TYPE' && $parameter->value == 'PREF'){
- $parameter->name = 'PREF';
- $parameter->value = '1';
- }
- if ($property->name == 'TEL' && $parameter->name == 'TYPE'){
- if (isset($temp['parameters'][$parameter->name])){
- $temp['parameters'][$parameter->name][] = $parameter->value;
- }
- else{
- $temp['parameters'][$parameter->name] = array($parameter->value);
- }
- }
- else{
- $temp['parameters'][$parameter->name] = $parameter->value;
- }
- }
- return $temp;
- }
- }
|