diff --git a/apps/contacts/ajax/addproperty.php b/apps/contacts/ajax/addproperty.php index d92566d6a1..68075efc6a 100644 --- a/apps/contacts/ajax/addproperty.php +++ b/apps/contacts/ajax/addproperty.php @@ -44,6 +44,12 @@ if( $addressbook === false || $addressbook['userid'] != OC_USER::getUser()){ exit(); } +// Check if the card is valid +if( !OC_Contacts_Addressbook::isValidVObject($card['carddata'])){ + echo json_encode( array( 'status' => 'error', 'data' => array( 'message' => $l10n->t('Unable to parse vCard!')))); + exit(); +} + $vcard = Sabre_VObject_Reader::read($card['carddata']); $name = $_POST['name']; diff --git a/apps/contacts/ajax/deleteproperty.php b/apps/contacts/ajax/deleteproperty.php index d141cc00b8..f73758a367 100644 --- a/apps/contacts/ajax/deleteproperty.php +++ b/apps/contacts/ajax/deleteproperty.php @@ -48,6 +48,12 @@ if( $addressbook === false || $addressbook['userid'] != OC_USER::getUser()){ exit(); } +// Check if the card is valid +if( !OC_Contacts_Addressbook::isValidVObject($card['carddata'])){ + echo json_encode( array( 'status' => 'error', 'data' => array( 'message' => $l10n->t('Unable to parse vCard!')))); + exit(); +} + $vcard = Sabre_VObject_Reader::read($card['carddata']); $line = null; for($i=0;$ichildren);$i++){ diff --git a/apps/contacts/ajax/getdetails.php b/apps/contacts/ajax/getdetails.php index 4ee3625afc..ddd29be95c 100644 --- a/apps/contacts/ajax/getdetails.php +++ b/apps/contacts/ajax/getdetails.php @@ -46,6 +46,12 @@ if( $addressbook === false || $addressbook['userid'] != OC_USER::getUser()){ exit(); } +// Check if the card is valid +if( !OC_Contacts_Addressbook::isValidVObject($card['carddata'])){ + echo json_encode( array( 'status' => 'error', 'data' => array( 'message' => $l10n->t('Unable to parse vCard!')))); + exit(); +} + $vcard = Sabre_VObject_Reader::read($card['carddata']); $details = OC_Contacts_Addressbook::structureContact($vcard); $tmpl = new OC_Template('contacts','part.details'); diff --git a/apps/contacts/ajax/setproperty.php b/apps/contacts/ajax/setproperty.php index 08d8892254..f3b8e0c56b 100644 --- a/apps/contacts/ajax/setproperty.php +++ b/apps/contacts/ajax/setproperty.php @@ -45,6 +45,12 @@ if( $addressbook === false || $addressbook['userid'] != OC_USER::getUser()){ exit(); } +// Check if the card is valid +if( !OC_Contacts_Addressbook::isValidVObject($card['carddata'])){ + echo json_encode( array( 'status' => 'error', 'data' => array( 'message' => $l10n->t('Unable to parse vCard!')))); + exit(); +} + $vcard = Sabre_VObject_Reader::read($card['carddata']); $line = null; for($i=0;$ichildren);$i++){ diff --git a/apps/contacts/ajax/showsetproperty.php b/apps/contacts/ajax/showsetproperty.php index a00043384f..adae17553c 100644 --- a/apps/contacts/ajax/showsetproperty.php +++ b/apps/contacts/ajax/showsetproperty.php @@ -45,6 +45,12 @@ if( $addressbook === false || $addressbook['userid'] != OC_USER::getUser()){ exit(); } +// Check if the card is valid +if( !OC_Contacts_Addressbook::isValidVObject($card['carddata'])){ + echo json_encode( array( 'status' => 'error', 'data' => array( 'message' => $l10n->t('Unable to parse vCard!')))); + exit(); +} + $vcard = Sabre_VObject_Reader::read($card['carddata']); $line = null; for($i=0;$ichildren);$i++){ diff --git a/apps/contacts/index.php b/apps/contacts/index.php index 0d4ff83ef8..a8926cd96f 100644 --- a/apps/contacts/index.php +++ b/apps/contacts/index.php @@ -60,6 +60,9 @@ $contacts = array(); foreach( $openaddressbooks as $addressbook ){ $addressbookcontacts = OC_Contacts_Addressbook::allCards($addressbook); foreach( $addressbookcontacts as $contact ){ + if(is_null($contact['fullname'])){ + continue; + } $contacts[] = array( 'name' => $contact['fullname'], 'id' => $contact['id'] ); } } diff --git a/apps/contacts/js/interface.js b/apps/contacts/js/interface.js index b8a66d51aa..66ee677219 100644 --- a/apps/contacts/js/interface.js +++ b/apps/contacts/js/interface.js @@ -1,15 +1,25 @@ $(document).ready(function(){ - /* $('.contacts_addressbooksexpander').click(function(){ - $('.contacts_addressbooksdetails').toggle(); - return false; - });*/ + /*------------------------------------------------------------------------- + * Actions for startup + *-----------------------------------------------------------------------*/ + if( $('#leftcontent li').length > 0 ){ + $('#leftcontent li').first().addClass('active'); + } + /*------------------------------------------------------------------------- + * Event handlers + *-----------------------------------------------------------------------*/ $('#leftcontent li').live('click',function(){ var id = $(this).data('id'); + var oldid = $('#rightcontent').data('id'); + if(oldid != 0){ + $('#leftcontent li[data-id="'+oldid+'"]').removeClass('active'); + } $.getJSON('ajax/getdetails.php',{'id':id},function(jsondata){ if(jsondata.status == 'success'){ $('#rightcontent').data('id',jsondata.data.id); $('#rightcontent').html(jsondata.data.page); + $('#leftcontent li[data-id="'+jsondata.data.id+'"]').addClass('active'); } else{ alert(jsondata.data.message); diff --git a/apps/contacts/l10n/.gitkeep b/apps/contacts/l10n/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php index 9a5dea6f45..89894d33b5 100644 --- a/apps/contacts/lib/addressbook.php +++ b/apps/contacts/lib/addressbook.php @@ -47,6 +47,11 @@ * This class manages our addressbooks. */ class OC_Contacts_Addressbook{ + /** + * @brief Returns the list of addressbooks for a specific user. + * @param string $uid + * @return array + */ public static function allAddressbooks($uid){ $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ?' ); $result = $stmt->execute(array($uid)); @@ -59,11 +64,21 @@ class OC_Contacts_Addressbook{ return $addressbooks; } + /** + * @brief Returns the list of addressbooks for a principal (DAV term of user) + * @param string $principaluri + * @return array + */ public static function allAddressbooksWherePrincipalURIIs($principaluri){ $uid = self::extractUserID($principaluri); return self::allAddressbooks($uid); } + /** + * @brief Gets the data of one address book + * @param integer $id + * @return associative array + */ public static function findAddressbook($id){ $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id = ?' ); $result = $stmt->execute(array($id)); @@ -71,6 +86,13 @@ class OC_Contacts_Addressbook{ return $result->fetchRow(); } + /** + * @brief Creates a new address book + * @param string $userid + * @param string $name + * @param string $description + * @return insertid + */ public static function addAddressbook($userid,$name,$description){ $all = self::allAddressbooks($userid); $uris = array(); @@ -86,6 +108,14 @@ class OC_Contacts_Addressbook{ return OC_DB::insertid(); } + /** + * @brief Creates a new address book from the data sabredav provides + * @param string $principaluri + * @param string $uri + * @param string $name + * @param string $description + * @return insertid + */ public static function addAddressbookFromDAVData($principaluri,$uri,$name,$description){ $userid = self::extractUserID($principaluri); @@ -95,6 +125,13 @@ class OC_Contacts_Addressbook{ return OC_DB::insertid(); } + /** + * @brief Edits an addressbook + * @param integer $id + * @param string $name + * @param string $description + * @return boolean + */ public static function editAddressbook($id,$name,$description){ // Need these ones for checking uri $addressbook = self::find($id); @@ -112,6 +149,11 @@ class OC_Contacts_Addressbook{ return true; } + /** + * @brief Updates ctag for addressbook + * @param integer $id + * @return boolean + */ public static function touchAddressbook($id){ $stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET ctag = ctag + 1 WHERE id = ?' ); $stmt->execute(array($id)); @@ -119,6 +161,11 @@ class OC_Contacts_Addressbook{ return true; } + /** + * @brief removes an address book + * @param integer $id + * @return boolean + */ public static function deleteAddressbook($id){ $stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_addressbooks WHERE id = ?' ); $stmt->execute(array($id)); @@ -129,6 +176,14 @@ class OC_Contacts_Addressbook{ return true; } + /** + * @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 allCards($id){ $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ?' ); $result = $stmt->execute(array($id)); @@ -141,6 +196,11 @@ class OC_Contacts_Addressbook{ return $addressbooks; } + /** + * @brief Returns a card + * @param integer $id + * @return associative array + */ public static function findCard($id){ $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE id = ?' ); $result = $stmt->execute(array($id)); @@ -148,6 +208,12 @@ class OC_Contacts_Addressbook{ 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 findCardWhereDAVDataIs($aid,$uri){ $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri = ?' ); $result = $stmt->execute(array($aid,$uri)); @@ -155,23 +221,36 @@ class OC_Contacts_Addressbook{ return $result->fetchRow(); } + /** + * @brief Adds a card + * @param integer $id Addressbook id + * @param string $data vCard file + * @return insertid + */ public static function addCard($id,$data){ $fn = null; $uri = null; - $card = Sabre_VObject_Reader::read($data); - foreach($card->children as $property){ - if($property->name == 'FN'){ - $fn = $property->value; - } - elseif(is_null($uri) && $property->name == 'UID' ){ - $uri = $property->value.'.vcf'; + if(self::isValidVObject($data)){ + $card = Sabre_VObject_Reader::read($data); + foreach($card->children as $property){ + if($property->name == 'FN'){ + $fn = $property->value; + } + elseif(is_null($uri) && $property->name == 'UID' ){ + $uri = $property->value.'.vcf'; + } } + if(is_null($uri)){ + $uid = self::createUID(); + $uri = $uid.'.vcf'; + $card->add(new Sabre_VObject_Property('UID',$uid)); + $data = $card->serialize(); + }; } - if(is_null($uri)){ + else{ + // that's hard. Creating a UID and not saving it $uid = self::createUID(); $uri = $uid.'.vcf'; - $card->add(new Sabre_VObject_Property('UID',$uid)); - $data = $card->serialize(); }; $stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_cards (addressbookid,fullname,carddata,uri,lastmodified) VALUES(?,?,?,?,?)' ); @@ -182,12 +261,21 @@ class OC_Contacts_Addressbook{ return OC_DB::insertid(); } + /** + * @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 addCardFromDAVData($id,$uri,$data){ $fn = null; - $card = Sabre_VObject_Reader::read($data); - foreach($card->children as $property){ - if($property->name == 'FN'){ - $fn = $property->value; + if(self::isValidVObject($data)){ + $card = Sabre_VObject_Reader::read($data); + foreach($card->children as $property){ + if($property->name == 'FN'){ + $fn = $property->value; + } } } @@ -199,13 +287,21 @@ class OC_Contacts_Addressbook{ return OC_DB::insertid(); } + /** + * @brief edits a card + * @param integer $id id of card + * @param string $data vCard file + * @return boolean + */ public static function editCard($id, $data){ $oldcard = self::findCard($id); $fn = null; - $card = Sabre_VObject_Reader::read($data); - foreach($card->children as $property){ - if($property->name == 'FN'){ - $fn = $property->value; + if(self::isValidVObject($data)){ + $card = Sabre_VObject_Reader::read($data); + foreach($card->children as $property){ + if($property->name == 'FN'){ + $fn = $property->value; + } } } @@ -217,14 +313,23 @@ class OC_Contacts_Addressbook{ 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 editCardFromDAVData($aid,$uri,$data){ $oldcard = self::findCardWhereDAVDataIs($aid,$uri); $fn = null; - $card = Sabre_VObject_Reader::read($data); - foreach($card->children as $property){ - if($property->name == 'FN'){ - $fn = $property->value; + if(self::isValidVObject($data)){ + $card = Sabre_VObject_Reader::read($data); + foreach($card->children as $property){ + if($property->name == 'FN'){ + $fn = $property->value; + } } } @@ -236,6 +341,11 @@ class OC_Contacts_Addressbook{ return true; } + /** + * @brief deletes a card + * @param integer $id id of card + * @return boolean + */ public static function deleteCard($id){ $stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE id = ?' ); $stmt->execute(array($id)); @@ -243,6 +353,12 @@ class OC_Contacts_Addressbook{ return true; } + /** + * @brief deletes a card with the data provided by sabredav + * @param integer $id Addressbook id + * @param string $uri the uri of the card + * @return boolean + */ public static function deleteCardFromDAVData($aid,$uri){ $stmt = OC_DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri=?' ); $stmt->execute(array($aid,$uri)); @@ -250,6 +366,12 @@ class OC_Contacts_Addressbook{ return true; } + /** + * @brief Creates a URI for Addressbook + * @param string $name name of the addressbook + * @param array $existing the uri of the card + * @return boolean + */ public static function createURI($name,$existing){ $name = strtolower($name); $newname = $name; @@ -261,15 +383,28 @@ class OC_Contacts_Addressbook{ return $newname; } + /** + * @brief Creates a UID + * @return string + */ public static function createUID(){ return substr(md5(rand().time()),0,10); } + /** + * @brief gets the userid from a principal path + * @return string + */ public static function extractUserID($principaluri){ list($prefix,$userid) = Sabre_DAV_URLUtil::splitPath($principaluri); return $userid; } + /** + * @brief Escapes semicolons + * @param string $value + * @return string + */ public static function escapeSemicolons($value){ foreach($value as &$i ){ $i = implode("\\\\;", explode(';', $i)); @@ -277,6 +412,11 @@ class OC_Contacts_Addressbook{ return implode(';',$value); } + /** + * @brief Creates an array out of a multivalue property + * @param string $value + * @return array + */ public static function unescapeSemicolons($value){ $array = explode(';',$value); for($i=0;$ichildren as $property){ @@ -308,6 +455,17 @@ class OC_Contacts_Addressbook{ 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 + */ public static function structureProperty($property){ $value = $property->value; $value = htmlspecialchars($value); @@ -329,4 +487,20 @@ class OC_Contacts_Addressbook{ } return $temp; } + + /** + * @brief Checks if SabreDAV can parse the file + * @param string vCard + * @return boolean + * + * The code is largely copypasted from Sabre_VObject_Reader + */ + public static function isValidVObject($data){ + try { + Sabre_VObject_Reader::read($data); + return true; + } catch (Exception $e) { + return false; + } + } } diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php index 46e85a09d1..6d67584b29 100644 --- a/apps/contacts/templates/index.php +++ b/apps/contacts/templates/index.php @@ -3,15 +3,16 @@ OC_Util::addScript('contacts','interface'); OC_Util::addStyle('contacts','styles'); ?> +
+
+ +
+
    inc("part.contacts"); ?>
- t('Add Contact'); ?>
inc("part.details"); ?>
- - t('The path to this addressbook is %s', array(((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].OC::$WEBROOT.'/apps/contacts/carddav.php/addressbooks/'.OC_User::getUser().'/'.$_['addressbooks'][0]['uri'])); ?> - diff --git a/apps/contacts/templates/part.addcardform.php b/apps/contacts/templates/part.addcardform.php index 94a59fe097..e87c64507d 100644 --- a/apps/contacts/templates/part.addcardform.php +++ b/apps/contacts/templates/part.addcardform.php @@ -2,12 +2,14 @@ + +
- + diff --git a/apps/contacts/templates/part.details.php b/apps/contacts/templates/part.details.php index 81b32f2ff5..c6bedcdd91 100644 --- a/apps/contacts/templates/part.details.php +++ b/apps/contacts/templates/part.details.php @@ -29,7 +29,7 @@ -
- <?php echo $l->t('Delete');?> - <?php echo $l->t('Download');?> -
+
+ + +
diff --git a/apps/contacts/templates/part.setpropertyform.php b/apps/contacts/templates/part.setpropertyform.php index d8127bb08b..52483ebf4b 100644 --- a/apps/contacts/templates/part.setpropertyform.php +++ b/apps/contacts/templates/part.setpropertyform.php @@ -2,17 +2,17 @@ - t('PO Box'); ?> - t('Extended Address'); ?> - t('Street Name'); ?> - t('City'); ?> - t('Region'); ?> - t('Postal Code'); ?> - t('Country'); ?> +
+
+
+
+
+
+
- +