diff options
author | Michael Gapczynski <mtgap@owncloud.com> | 2012-07-11 20:25:59 -0400 |
---|---|---|
committer | Michael Gapczynski <mtgap@owncloud.com> | 2012-07-11 20:25:59 -0400 |
commit | 4bf13adff25f012c735931c0578b1f5d0790bdbe (patch) | |
tree | a7c5451ff25e2f39936ae984ceb5b3b9eb519088 /apps/contacts | |
parent | 88f4845ca33fd6f2988f230116e2190d15ab1866 (diff) | |
parent | 8890a4128015df0ad57101703d6c164ea54fe4ee (diff) | |
download | nextcloud-server-4bf13adff25f012c735931c0578b1f5d0790bdbe.tar.gz nextcloud-server-4bf13adff25f012c735931c0578b1f5d0790bdbe.zip |
Merge branch 'master' into share_api
Conflicts:
apps/contacts/lib/addressbook.php
apps/files_sharing/js/share.js
apps/files_sharing/sharedstorage.php
Diffstat (limited to 'apps/contacts')
40 files changed, 547 insertions, 423 deletions
diff --git a/apps/contacts/ajax/addbook.php b/apps/contacts/ajax/addbook.php index 70f47cc8123..751185b44fd 100644 --- a/apps/contacts/ajax/addbook.php +++ b/apps/contacts/ajax/addbook.php @@ -17,4 +17,3 @@ $tmpl = new OCP\Template('contacts', 'part.editaddressbook'); $tmpl->assign('new', true); $tmpl->assign('addressbook', $book); $tmpl->printPage(); -?> diff --git a/apps/contacts/ajax/categories/categoriesfor.php b/apps/contacts/ajax/categories/categoriesfor.php index 846af300de8..6b6fcad0ebb 100644 --- a/apps/contacts/ajax/categories/categoriesfor.php +++ b/apps/contacts/ajax/categories/categoriesfor.php @@ -25,4 +25,3 @@ foreach($vcard->children as $property){ } } OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error setting checksum.')))); -?> diff --git a/apps/contacts/ajax/categories/delete.php b/apps/contacts/ajax/categories/delete.php index 76c23d6487d..7c3261446bb 100644 --- a/apps/contacts/ajax/categories/delete.php +++ b/apps/contacts/ajax/categories/delete.php @@ -45,5 +45,3 @@ $catman->delete($categories, $cards); debug('After delete: '.print_r($catman->categories(), true)); OC_Contacts_VCard::updateDataByID($cards); OCP\JSON::success(array('data' => array('categories'=>$catman->categories()))); - -?> diff --git a/apps/contacts/ajax/categories/list.php b/apps/contacts/ajax/categories/list.php index 3ae7635390c..f234116ba8c 100644 --- a/apps/contacts/ajax/categories/list.php +++ b/apps/contacts/ajax/categories/list.php @@ -13,5 +13,3 @@ OCP\JSON::checkAppEnabled('contacts'); $categories = OC_Contacts_App::getCategories(); OCP\JSON::success(array('data' => array('categories'=>$categories))); - -?> diff --git a/apps/contacts/ajax/categories/rescan.php b/apps/contacts/ajax/categories/rescan.php index 48ec165381f..fd875a965dc 100644 --- a/apps/contacts/ajax/categories/rescan.php +++ b/apps/contacts/ajax/categories/rescan.php @@ -10,24 +10,7 @@ OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); -require_once('../loghandler.php'); - -$addressbooks = OC_Contacts_Addressbook::all(OCP\USER::getUser()); -if(count($addressbooks) == 0) { - bailOut(OC_Contacts_App::$l10n->t('No address books found.')); -} -$addressbookids = array(); -foreach($addressbooks as $addressbook) { - $addressbookids[] = $addressbook['id']; -} -$contacts = OC_Contacts_VCard::all($addressbookids); -if(count($contacts) == 0) { - bailOut(OC_Contacts_App::$l10n->t('No contacts found.')); -} - -OC_Contacts_App::scanCategories($contacts); +OC_Contacts_App::scanCategories(); $categories = OC_Contacts_App::getCategories(); OCP\JSON::success(array('data' => array('categories'=>$categories))); - -?> diff --git a/apps/contacts/ajax/contacts.php b/apps/contacts/ajax/contacts.php index 4bb7801cb2d..67ebcaf7362 100644 --- a/apps/contacts/ajax/contacts.php +++ b/apps/contacts/ajax/contacts.php @@ -17,40 +17,58 @@ function cmp($a, $b) OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); -$active_addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); +$start = isset($_GET['startat'])?$_GET['startat']:0; +$aid = isset($_GET['aid'])?$_GET['aid']:null; +if(is_null($aid)) { + // Called initially to get the active addressbooks. + $active_addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); +} else { + // called each time more contacts has to be shown. + $active_addressbooks = array(OC_Contacts_Addressbook::find($aid)); +} + + +session_write_close(); + +// create the addressbook associate array $contacts_addressbook = array(); $ids = array(); foreach($active_addressbooks as $addressbook) { $ids[] = $addressbook['id']; if(!isset($contacts_addressbook[$addressbook['id']])) { - $contacts_addressbook[$addressbook['id']] = array('contacts' => array()); + $contacts_addressbook[$addressbook['id']] = array('contacts' => array('type' => 'book',)); $contacts_addressbook[$addressbook['id']]['displayname'] = $addressbook['displayname']; } } -$contacts_alphabet = OC_Contacts_VCard::all($ids); -// Our new array for the contacts sorted by addressbook -foreach($contacts_alphabet as $contact) { - if(!isset($contacts_addressbook[$contact['addressbookid']])) { // It should never execute. - $contacts_addressbook[$contact['addressbookid']] = array('contacts' => array()); +$contacts_alphabet = array(); + +// get next 50 for each addressbook. +foreach($ids as $id) { + if($id) { + $contacts_alphabet = array_merge($contacts_alphabet, OC_Contacts_VCard::all($id, $start, 50)); } - $display = trim($contact['fullname']); - if(!$display) { - $vcard = OC_Contacts_App::getContactVCard($contact['id']); - if(!is_null($vcard)) { - $struct = OC_Contacts_VCard::structureContact($vcard); - $display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]'; +} +// Our new array for the contacts sorted by addressbook +if($contacts_alphabet) { + foreach($contacts_alphabet as $contact) { + if(!isset($contacts_addressbook[$contact['addressbookid']])) { // It should never execute. + $contacts_addressbook[$contact['addressbookid']] = array('contacts' => array('type' => 'book',)); } + $display = trim($contact['fullname']); + if(!$display) { + $vcard = OC_Contacts_App::getContactVCard($contact['id']); + if(!is_null($vcard)) { + $struct = OC_Contacts_VCard::structureContact($vcard); + $display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]'; + } + } + $contacts_addressbook[$contact['addressbookid']]['contacts'][] = array('type' => 'contact', 'id' => $contact['id'], 'addressbookid' => $contact['addressbookid'], 'displayname' => htmlspecialchars($display)); } - $contacts_addressbook[$contact['addressbookid']]['contacts'][] = array('id' => $contact['id'], 'addressbookid' => $contact['addressbookid'], 'displayname' => htmlspecialchars($display)); } unset($contacts_alphabet); uasort($contacts_addressbook, 'cmp'); -$tmpl = new OCP\Template("contacts", "part.contacts"); -$tmpl->assign('books', $contacts_addressbook, false); -$page = $tmpl->fetchPage(); - -OCP\JSON::success(array('data' => array( 'page' => $page ))); +OCP\JSON::success(array('data' => array('entries' => $contacts_addressbook))); diff --git a/apps/contacts/ajax/currentphoto.php b/apps/contacts/ajax/currentphoto.php index b10e752c453..8f60eca08ec 100644 --- a/apps/contacts/ajax/currentphoto.php +++ b/apps/contacts/ajax/currentphoto.php @@ -51,5 +51,3 @@ if( is_null($contact)) { bailOut(OC_Contacts_App::$l10n->t('The loading photo is not valid.')); } } - -?> diff --git a/apps/contacts/ajax/editaddress.php b/apps/contacts/ajax/editaddress.php index 2d7aba11b0e..1eb9429d79c 100644 --- a/apps/contacts/ajax/editaddress.php +++ b/apps/contacts/ajax/editaddress.php @@ -39,5 +39,3 @@ $tmpl->assign('adr_types',$adr_types); $page = $tmpl->fetchPage(); OCP\JSON::success(array('data' => array('page'=>$page, 'checksum'=>$checksum))); - -?> diff --git a/apps/contacts/ajax/editaddressbook.php b/apps/contacts/ajax/editaddressbook.php index 7a9b757ae0d..4bc77302e5b 100644 --- a/apps/contacts/ajax/editaddressbook.php +++ b/apps/contacts/ajax/editaddressbook.php @@ -14,4 +14,3 @@ $tmpl = new OCP\Template("contacts", "part.editaddressbook"); $tmpl->assign('new', false); $tmpl->assign('addressbook', $addressbook); $tmpl->printPage(); -?> diff --git a/apps/contacts/ajax/editname.php b/apps/contacts/ajax/editname.php index 868ca222e0a..9e7c090eeed 100644 --- a/apps/contacts/ajax/editname.php +++ b/apps/contacts/ajax/editname.php @@ -32,5 +32,3 @@ if($id) { } $page = $tmpl->fetchPage(); OCP\JSON::success(array('data' => array('page'=>$page))); - -?> diff --git a/apps/contacts/ajax/importaddressbook.php b/apps/contacts/ajax/importaddressbook.php index f93bbfa4d9d..6b5b06681ce 100644 --- a/apps/contacts/ajax/importaddressbook.php +++ b/apps/contacts/ajax/importaddressbook.php @@ -18,6 +18,6 @@ $maxUploadFilesize = min($maxUploadFilesize ,$freeSpace); $tmpl = new OCP\Template('contacts', 'part.importaddressbook'); $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); +$tmpl->assign('requesttoken', $_SERVER['HTTP_REQUESTTOKEN']); $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $tmpl->printpage(); -?> diff --git a/apps/contacts/ajax/importdialog.php b/apps/contacts/ajax/importdialog.php index 5f8805a6106..691522538fb 100644 --- a/apps/contacts/ajax/importdialog.php +++ b/apps/contacts/ajax/importdialog.php @@ -13,4 +13,3 @@ $tmpl = new OCP\Template('contacts', 'part.import'); $tmpl->assign('path', $_POST['path']); $tmpl->assign('filename', $_POST['filename']); $tmpl->printpage(); -?> diff --git a/apps/contacts/ajax/loadphoto.php b/apps/contacts/ajax/loadphoto.php index 61b5356edce..a35631055eb 100644 --- a/apps/contacts/ajax/loadphoto.php +++ b/apps/contacts/ajax/loadphoto.php @@ -42,11 +42,5 @@ foreach($vcard->children as $property){ } } -$tmpl = new OCP\Template("contacts", "part.contactphoto"); -$tmpl->assign('id', $id); -if($refresh) { - $tmpl->assign('refresh', 1); -} -$page = $tmpl->fetchPage(); -OCP\JSON::success(array('data' => array('page'=>$page, 'checksum'=>$checksum))); -?> +OCP\JSON::success(array('data' => array('checksum'=>$checksum))); + diff --git a/apps/contacts/ajax/oc_photo.php b/apps/contacts/ajax/oc_photo.php index 5c50ba92dbe..710179fffcc 100644 --- a/apps/contacts/ajax/oc_photo.php +++ b/apps/contacts/ajax/oc_photo.php @@ -58,5 +58,3 @@ if(OC_Cache::set($tmpkey, $image->data(), 600)) { } else { bailOut('Couldn\'t save temporary image: '.$tmpkey); } - -?> diff --git a/apps/contacts/ajax/uploadimport.php b/apps/contacts/ajax/uploadimport.php index c1e9c8b1ad1..80b282f38a3 100644 --- a/apps/contacts/ajax/uploadimport.php +++ b/apps/contacts/ajax/uploadimport.php @@ -23,6 +23,7 @@ // Check if we are a user OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); +OCP\JSON::callCheck(); require_once('loghandler.php'); $view = OCP\Files::getStorage('contacts'); @@ -69,6 +70,3 @@ if(file_exists($file['tmp_name'])) { } else { bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?'); } - - -?> diff --git a/apps/contacts/ajax/uploadphoto.php b/apps/contacts/ajax/uploadphoto.php index 8545ca84eee..6bb3fe8a5e0 100644 --- a/apps/contacts/ajax/uploadphoto.php +++ b/apps/contacts/ajax/uploadphoto.php @@ -102,4 +102,3 @@ if(file_exists($file['tmp_name'])) { } else { bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?'); } -?> diff --git a/apps/contacts/appinfo/app.php b/apps/contacts/appinfo/app.php index cec0f3e88cd..daf7bee1c97 100644 --- a/apps/contacts/appinfo/app.php +++ b/apps/contacts/appinfo/app.php @@ -5,6 +5,7 @@ OC::$CLASSPATH['OC_Contacts_VCard'] = 'apps/contacts/lib/vcard.php'; OC::$CLASSPATH['OC_Contacts_Hooks'] = 'apps/contacts/lib/hooks.php'; OC::$CLASSPATH['OC_Contacts_Share'] = 'apps/contacts/lib/share.php'; OC::$CLASSPATH['OC_Connector_Sabre_CardDAV'] = 'apps/contacts/lib/connector_sabre.php'; +OC::$CLASSPATH['Sabre_CardDAV_VCFExportPlugin'] = 'apps/contacts/lib/VCFExportPlugin.php'; OC::$CLASSPATH['OC_Search_Provider_Contacts'] = 'apps/contacts/lib/search.php'; OCP\Util::connectHook('OC_User', 'post_createUser', 'OC_Contacts_Hooks', 'createUser'); OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Contacts_Hooks', 'deleteUser'); diff --git a/apps/contacts/appinfo/database.xml b/apps/contacts/appinfo/database.xml index 7c8268d71f5..9b269d765dc 100644 --- a/apps/contacts/appinfo/database.xml +++ b/apps/contacts/appinfo/database.xml @@ -62,6 +62,14 @@ <length>4</length> </field> + <field> + <name>active</name> + <type>integer</type> + <default>1</default> + <notnull>true</notnull> + <length>4</length> + </field> + </declaration> </table> diff --git a/apps/contacts/appinfo/migrate.php b/apps/contacts/appinfo/migrate.php index 1400cdf79d4..02026c5979c 100644 --- a/apps/contacts/appinfo/migrate.php +++ b/apps/contacts/appinfo/migrate.php @@ -30,7 +30,7 @@ class OC_Migration_Provider_Contacts extends OC_Migration_Provider{ } - // Import function for bookmarks + // Import function for contacts function import( ){ switch( $this->appinfo->version ){ default: @@ -39,20 +39,23 @@ class OC_Migration_Provider_Contacts extends OC_Migration_Provider{ $results = $query->execute( array( $this->olduid ) ); $idmap = array(); while( $row = $results->fetchRow() ){ - // Import each bookmark, saving its id into the map - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_addressbooks (`userid`, `displayname`, `uri`, `description`, `ctag`) VALUES (?, ?, ?, ?, ?)" ); - $query->execute( array( $this->uid, $row['displayname'], $row['uri'], $row['description'], $row['ctag'] ) ); + // Import each addressbook + $addressbookquery = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_addressbooks (`userid`, `displayname`, `uri`, `description`, `ctag`) VALUES (?, ?, ?, ?, ?)" ); + $addressbookquery->execute( array( $this->uid, $row['displayname'], $row['uri'], $row['description'], $row['ctag'] ) ); // Map the id - $idmap[$row['id']] = OCP\DB::insertid(); + $idmap[$row['id']] = OCP\DB::insertid('*PREFIX*contacts_addressbooks'); + // Make the addressbook active + OC_Contacts_Addressbook::setActive($idmap[$row['id']], true); } // Now tags foreach($idmap as $oldid => $newid){ + $query = $this->content->prepare( "SELECT * FROM contacts_cards WHERE addressbookid LIKE ?" ); $results = $query->execute( array( $oldid ) ); while( $row = $results->fetchRow() ){ - // Import the tags for this bookmark, using the new bookmark id - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_cards (`addressbookid`, `fullname`, `carddata`, `uri`, `lastmodified`) VALUES (?, ?, ?, ?, ?)" ); - $query->execute( array( $newid, $row['fullname'], $row['carddata'], $row['uri'], $row['lastmodified'] ) ); + // Import the contacts + $contactquery = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_cards (`addressbookid`, `fullname`, `carddata`, `uri`, `lastmodified`) VALUES (?, ?, ?, ?, ?)" ); + $contactquery->execute( array( $newid, $row['fullname'], $row['carddata'], $row['uri'], $row['lastmodified'] ) ); } } // All done! diff --git a/apps/contacts/appinfo/remote.php b/apps/contacts/appinfo/remote.php index 5add3bc6889..09c2de17990 100644 --- a/apps/contacts/appinfo/remote.php +++ b/apps/contacts/appinfo/remote.php @@ -49,6 +49,7 @@ $server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud')); $server->addPlugin(new Sabre_CardDAV_Plugin()); $server->addPlugin(new Sabre_DAVACL_Plugin()); $server->addPlugin(new Sabre_DAV_Browser_Plugin(false)); // Show something in the Browser, but no upload +$server->addPlugin(new Sabre_CardDAV_VCFExportPlugin()); // And off we go! $server->exec(); diff --git a/apps/contacts/appinfo/update.php b/apps/contacts/appinfo/update.php new file mode 100644 index 00000000000..873899f578b --- /dev/null +++ b/apps/contacts/appinfo/update.php @@ -0,0 +1,25 @@ +<?php + +$installedVersion=OCP\Config::getAppValue('contacts', 'installed_version'); +if (version_compare($installedVersion, '0.2.90', '<')) { + // First set all address books in-active. + $stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET active=0' ); + $result = $stmt->execute(array()); + + // Then get all the active address books. + $stmt = OCP\DB::prepare( 'SELECT userid,configvalue FROM *PREFIX*preferences WHERE appid=\'contacts\' AND configkey=\'openaddressbooks\'' ); + $result = $stmt->execute(array()); + + // Prepare statement for updating the new 'active' field. + $stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET active=? WHERE id=? AND userid=?' ); + while( $row = $result->fetchRow()) { + $ids = explode(';', $row['configvalue']); + foreach($ids as $id) { + $r = $stmt->execute(array(1, $id, $row['userid'])); + } + } + + // Remove the old preferences. + $stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE appid=\'contacts\' AND configkey=\'openaddressbooks\'' ); + $result = $stmt->execute(array()); +} diff --git a/apps/contacts/appinfo/version b/apps/contacts/appinfo/version index 2f4536184bc..7dff5b89211 100644 --- a/apps/contacts/appinfo/version +++ b/apps/contacts/appinfo/version @@ -1 +1 @@ -0.2
\ No newline at end of file +0.2.1
\ No newline at end of file diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css index b3e5efb7859..439c611b1dc 100644 --- a/apps/contacts/css/contacts.css +++ b/apps/contacts/css/contacts.css @@ -12,12 +12,13 @@ .ui-draggable-dragging { width: 16em; } .ui-state-hover { border: 1px solid dashed; } #bottomcontrols { padding: 0; bottom:0px; height:2.8em; width: 20em; margin:0; background:#eee; border-top:1px solid #ccc; position:fixed; -moz-box-shadow: 0 -3px 3px -3px #000; -webkit-box-shadow: 0 -3px 3px -3px #000; box-shadow: 0 -3px 3px -3px #000;} +#bottomcontrols img { margin-top: 0.35em; } #contacts_newcontact { float: left; margin: 0.2em 0 0 1em; } #chooseaddressbook { float: right; margin: 0.2em 1em 0 0; } -#actionbar { height: 30px; width: 60px; position: fixed; right: 0px; top: 4em; margin: 0 0 0 0; padding: 0 0 0 0; z-index: 1000; } +#actionbar { position: relative; clear: both; height: 30px;} #contacts_deletecard {position:relative; float:left; background:url('%webroot%/core/img/actions/delete.svg') no-repeat center; } #contacts_downloadcard {position:relative; float:left; background:url('%webroot%/core/img/actions/download.svg') no-repeat center; } -#contacts_propertymenu { clear: both; max-width: 15em; margin: 2em; } +#contacts_propertymenu { clear: left; float:left; max-width: 15em; margin: 2em; } #contacts_propertymenu_button { position:relative;top:0;left:0; margin: 0; } #contacts_propertymenu_dropdown { background-color: #fff; position:relative; right:0; overflow:hidden; text-overflow:ellipsis; border: thin solid #1d2d44; box-shadow: 0 3px 5px #bbb; /* -moz-box-shadow:0 0 10px #000; -webkit-box-shadow:0 0 10px #000; box-shadow:0 0 10px #000; -moz-border-radius:0.5em; -webkit-border-radius:0.5em; border-radius:0.5em; -moz-border-radius:0.5em; -webkit-border-radius:0.5em;*/ border-radius: 3px; } #contacts_propertymenu li { display: block; font-weight: bold; height: 20px; } @@ -74,10 +75,10 @@ label:hover, dt:hover { color: #333; } .contactsection { position: relative; float: left; /*max-width: 40em;*/ padding: 0.5em; height: auto: border: thin solid lightgray;/* -webkit-border-radius: 0.5em; -moz-border-radius: 0.5em; border-radius: 0.5em; background-color: #f8f8f8;*/ } #cropbox { margin: auto; } -#contacts_details_photo_wrapper { min-width: 120px; } +#contacts_details_photo_wrapper { width: 200px; } #contacts_details_photo_wrapper.wait { opacity: 0.6; filter:alpha(opacity=0.6); z-index:1000; background: url('%webroot%/core/img/loading.gif') no-repeat center center; cursor: wait; } -#contacts_details_photo { border-radius: 0.5em; border: thin solid #bbb; margin: 0.3em; background: url('%webroot%/core/img/loading.gif') no-repeat center center; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; } -#contacts_details_photo:hover { background: #fff; cursor: default; } +.contacts_details_photo { border-radius: 0.5em; border: thin solid #bbb; margin: 0.3em; background: url('%webroot%/core/img/loading.gif') no-repeat center center; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; opacity: 1; } +.contacts_details_photo:hover { background: #fff; cursor: default; } #phototools { position:absolute; margin: 5px 0 0 10px; width:auto; height:22px; padding:0px; background-color:#fff; list-style-type:none; border-radius: 0.5em; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; } #phototools li { display: inline; } #phototools li a { float:left; cursor:pointer; width:22px; height:22px; opacity: 0.6; } diff --git a/apps/contacts/export.php b/apps/contacts/export.php index f84a10c1388..eb506506c42 100644 --- a/apps/contacts/export.php +++ b/apps/contacts/export.php @@ -14,12 +14,17 @@ $contactid = isset($_GET['contactid']) ? $_GET['contactid'] : NULL; $nl = "\n"; if(isset($bookid)){ $addressbook = OC_Contacts_App::getAddressbook($bookid); - $cardobjects = OC_Contacts_VCard::all($bookid); + //$cardobjects = OC_Contacts_VCard::all($bookid); header('Content-Type: text/directory'); header('Content-Disposition: inline; filename=' . str_replace(' ', '_', $addressbook['displayname']) . '.vcf'); - foreach($cardobjects as $card) { - echo $card['carddata'] . $nl; + $start = 0; + $batchsize = OCP\Config::getUserValue(OCP\User::getUser(), 'contacts', 'export_batch_size', 20); + while($cardobjects = OC_Contacts_VCard::all($bookid, $start, $batchsize)){ + foreach($cardobjects as $card) { + echo $card['carddata'] . $nl; + } + $start += $batchsize; } }elseif(isset($contactid)){ $data = OC_Contacts_App::getContactObject($contactid); @@ -27,4 +32,3 @@ if(isset($bookid)){ header('Content-Disposition: inline; filename=' . str_replace(' ', '_', $data['fullname']) . '.vcf'); echo $data['carddata']; } -?> diff --git a/apps/contacts/import.php b/apps/contacts/import.php index c95fd970fe1..93c47ef2667 100644 --- a/apps/contacts/import.php +++ b/apps/contacts/import.php @@ -12,6 +12,7 @@ OCP\JSON::checkLoggedIn(); OCP\App::checkAppEnabled('contacts'); session_write_close(); +$cr = "\r"; $nl = "\n"; global $progresskey; @@ -35,20 +36,20 @@ if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') { $file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']); } if(!$file) { - OCP\JSON::error(array('message' => 'Import file was empty.')); + OCP\JSON::error(array('data' => array('message' => 'Import file was empty.'))); exit(); } if(isset($_POST['method']) && $_POST['method'] == 'new'){ $id = OC_Contacts_Addressbook::add(OCP\USER::getUser(), $_POST['addressbookname']); if(!$id) { - OCP\JSON::error(array('message' => 'Error creating address book.')); + OCP\JSON::error(array('data' => array('message' => 'Error creating address book.'))); exit(); } OC_Contacts_Addressbook::setActive($id, 1); }else{ $id = $_POST['id']; if(!$id) { - OCP\JSON::error(array('message' => 'Error getting the ID of the address book.')); + OCP\JSON::error(array('data' => array('message' => 'Error getting the ID of the address book.'))); exit(); } OC_Contacts_App::getAddressbook($id); // is owner access check @@ -56,6 +57,10 @@ if(isset($_POST['method']) && $_POST['method'] == 'new'){ //analyse the contacts file writeProgress('40'); $lines = explode($nl, $file); +if(count($lines) == 1) { // Mac eol + $lines = explode($cr, $file); +} + $inelement = false; $parts = array(); $card = array(); @@ -77,7 +82,7 @@ writeProgress('70'); $imported = 0; $failed = 0; if(!count($parts) > 0) { - OCP\JSON::error(array('message' => 'No contacts to import in .'.$_POST['file'].' Please check if the file is corrupted.')); + OCP\JSON::error(array('data' => array('message' => 'No contacts to import in .'.$_POST['file'].' Please check if the file is corrupted.'))); exit(); } foreach($parts as $part){ diff --git a/apps/contacts/index.php b/apps/contacts/index.php index 0b4f89b30c0..c1e33252f56 100644 --- a/apps/contacts/index.php +++ b/apps/contacts/index.php @@ -14,28 +14,16 @@ OCP\App::checkAppEnabled('contacts'); // Get active address books. This creates a default one if none exists. $ids = OC_Contacts_Addressbook::activeIds(OCP\USER::getUser()); -$contacts = OC_Contacts_VCard::all($ids); +$has_contacts = (count(OC_Contacts_VCard::all($ids, 0, 1)) > 0 ? true : false); // just to check if there are any contacts. if($contacts === false) { OCP\Util::writeLog('contacts','index.html: No contacts found.',OCP\Util::DEBUG); } -$addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); - // Load the files we need OCP\App::setActiveNavigationEntry( 'contacts_index' ); // Load a specific user? $id = isset( $_GET['id'] ) ? $_GET['id'] : null; -$details = array(); - -if(is_null($id) && count($contacts) > 0) { - $id = $contacts[0]['id']; -} -unset($contacts); -if(!is_null($id)) { - $vcard = OC_Contacts_App::getContactVCard($id); - $details = OC_Contacts_VCard::structureContact($vcard); -} $property_types = OC_Contacts_App::getAddPropertyOptions(); $phone_types = OC_Contacts_App::getTypesOfProperty('TEL'); $email_types = OC_Contacts_App::getTypesOfProperty('EMAIL'); @@ -63,15 +51,12 @@ OCP\Util::addStyle('contacts','jquery.Jcrop'); OCP\Util::addStyle('contacts','contacts'); $tmpl = new OCP\Template( "contacts", "index", "user" ); -$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); -$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); -$tmpl->assign('property_types', $property_types); -$tmpl->assign('phone_types', $phone_types); -$tmpl->assign('email_types', $email_types); -$tmpl->assign('categories', $categories); -$tmpl->assign('addressbooks', $addressbooks); -$tmpl->assign('details', $details ); -$tmpl->assign('id',$id); +$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize, false); +$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize), false); +$tmpl->assign('property_types', $property_types, false); +$tmpl->assign('phone_types', $phone_types, false); +$tmpl->assign('email_types', $email_types, false); +$tmpl->assign('categories', $categories, false); +$tmpl->assign('has_contacts', $has_contacts, false); +$tmpl->assign('id',$id, false); $tmpl->printPage(); - -?> diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index 64b7af850ea..dd194db0161 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -48,7 +48,7 @@ Contacts={ adrstr = adrstr + adrarr[6].trim(); } adrstr = encodeURIComponent(adrstr); - var uri = 'http://open.mapquestapi.com/nominatim/v1/search.php?q=' + adrstr + '&limit=10&addressdetails=1&zoom='; + var uri = 'http://open.mapquestapi.com/nominatim/v1/search.php?q=' + adrstr + '&limit=10&addressdetails=1&polygon=1&zoom='; var newWindow = window.open(uri,'_blank'); newWindow.focus(); }, @@ -144,6 +144,31 @@ Contacts={ $('#edit_name').click(function(){Contacts.UI.Card.editName()}); $('#edit_name').keydown(function(){Contacts.UI.Card.editName()}); + $('#phototools li a').click(function() { + $(this).tipsy('hide'); + }); + $('#contacts_details_photo_wrapper').hover( + function () { + $('#phototools').slideDown(200); + }, + function () { + $('#phototools').slideUp(200); + } + ); + $('#phototools').hover( + function () { + $(this).removeClass('transparent'); + }, + function () { + $(this).addClass('transparent'); + } + ); + $('#phototools .upload').click(function() { + $('#file_upload_start').trigger('click'); + }); + $('#phototools .cloud').click(function() { + OC.dialogs.filepicker(t('contacts', 'Select photo'), Contacts.UI.Card.cloudPhotoSelected, false, 'image', true); + }); /* Initialize the photo edit dialog */ $('#edit_photo_dialog').dialog({ autoOpen: false, modal: true, height: 'auto', width: 'auto' @@ -234,6 +259,30 @@ Contacts={ $('#contacts_downloadcard').tipsy({gravity: 'ne'}); $('#contacts_propertymenu_button').tipsy(); $('#contacts_newcontact, #chooseaddressbook').tipsy({gravity: 'sw'}); + + $('body').click(function(e){ + if(!$(e.target).is('#contacts_propertymenu_button')) { + $('#contacts_propertymenu_dropdown').hide(); + } + }); + function propertyMenu(){ + var menu = $('#contacts_propertymenu_dropdown'); + if(menu.is(':hidden')) { + menu.show(); + menu.find('li').first().focus(); + } else { + menu.hide(); + } + } + $('#contacts_propertymenu_button').click(propertyMenu); + $('#contacts_propertymenu_button').keydown(propertyMenu); + function propertyMenuItem(){ + var type = $(this).data('type'); + Contacts.UI.Card.addProperty(type); + $('#contacts_propertymenu_dropdown').hide(); + } + $('#contacts_propertymenu_dropdown a').click(propertyMenuItem); + $('#contacts_propertymenu_dropdown a').keydown(propertyMenuItem); }, Card:{ id:'', @@ -249,7 +298,7 @@ Contacts={ update:function(id, bookid) { var newid, firstitem; if(!id) { - firstitem = $('#contacts:first-child li:first-child'); + firstitem = $('#contacts ul').first().find('li:first-child'); if(firstitem.length > 0) { newid = firstitem.data('id'); bookid = firstitem.data('bookid'); @@ -261,12 +310,13 @@ Contacts={ if(!bookid) { bookid = $('#contacts h3').first().data('id'); } + console.log('bookid: ' +bookid); var localLoadContact = function(newid, bookid) { if($('.contacts li').length > 0) { $('#contacts li[data-id="'+newid+'"]').addClass('active'); $.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':newid},function(jsondata){ if(jsondata.status == 'success'){ - $('#contacts h3[data-id="'+bookid+'"]').trigger('click'); + $('#contacts ul[data-id="'+bookid+'"]').slideDown(300); Contacts.UI.Card.loadContact(jsondata.data, bookid); } else { OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); @@ -276,8 +326,9 @@ Contacts={ } // Make sure proper DOM is loaded. - if(!$('#card')[0] && newid) { - $.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{},function(jsondata){ + if(!$('#card').length && newid) { + console.log('Loading card DOM'); + $.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{requesttoken:requesttoken},function(jsondata){ if(jsondata.status == 'success'){ $('#rightcontent').html(jsondata.data.page).ready(function() { Contacts.UI.loadHandlers(); @@ -289,6 +340,7 @@ Contacts={ }); } else if(!newid) { + console.log('Loading intro'); // load intro page $.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){ if(jsondata.status == 'success'){ @@ -316,7 +368,11 @@ Contacts={ Contacts.UI.Card.add(';;;;;', '', '', true); return false; }, + createEntry:function(data) { + return $('<li data-id="'+data.id+'" data-bookid="'+data.addressbookid+'" role="button"><a href="'+OC.linkTo('contacts', 'index.php')+'&id='+data.id+'" style="background: url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+data.id+') no-repeat scroll 0% 0% transparent;">'+data.displayname+'</a></li>'); + }, add:function(n, fn, aid, isnew){ // add a new contact + console.log('Adding ' + fn); aid = aid?aid:$('#contacts h3.active').first().data('id'); var localAddcontact = function(n, fn, aid, isnew) { $.post(OC.filePath('contacts', 'ajax', 'addcontact.php'), { n: n, fn: fn, aid: aid, isnew: isnew }, @@ -360,8 +416,8 @@ Contacts={ }); } - var card = $('#card')[0]; - if(!card) { + if(!$('#card').length) { + console.log('Loading card DOM'); $.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{'requesttoken': requesttoken},function(jsondata){ if(jsondata.status == 'success'){ $('#rightcontent').html(jsondata.data.page).ready(function() { @@ -607,7 +663,7 @@ Contacts={ return false; } container = $(obj).parents('.propertycontainer').first(); // get the parent holding the metadata. - Contacts.UI.loading(container, true); + Contacts.UI.loading(obj, true); var checksum = container.data('checksum'); var name = container.data('element'); var fields = container.find('input.contacts_property,select.contacts_property').serializeArray(); @@ -630,7 +686,7 @@ Contacts={ var q = container.find('input.contacts_property,select.contacts_property,textarea.contacts_property').serialize(); if(q == '' || q == undefined) { OC.dialogs.alert(t('contacts', 'Couldn\'t serialize elements.'), t('contacts', 'Error')); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); return false; } q = q + '&id=' + this.id + '&name=' + name; @@ -642,13 +698,13 @@ Contacts={ if(jsondata.status == 'success'){ container.data('checksum', jsondata.data.checksum); Contacts.UI.Card.savePropertyInternal(name, fields, checksum, jsondata.data.checksum); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); $(obj).removeAttr('disabled'); return true; } else{ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); $(obj).removeAttr('disabled'); return false; } @@ -661,13 +717,13 @@ Contacts={ container.data('checksum', jsondata.data.checksum); // TODO: savePropertyInternal doesn't know about new fields //Contacts.UI.Card.savePropertyInternal(name, fields, checksum, jsondata.data.checksum); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); $(obj).removeAttr('disabled'); return true; } else{ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); $(obj).removeAttr('disabled'); return false; } @@ -1081,25 +1137,6 @@ Contacts={ loadPhotoHandlers:function(){ $('#phototools li a').tipsy('hide'); $('#phototools li a').tipsy(); - $('#phototools li a').click(function() { - $(this).tipsy('hide'); - }); - $('#contacts_details_photo_wrapper').hover( - function () { - $('#phototools').slideDown(200); - }, - function () { - $('#phototools').slideUp(200); - } - ); - $('#phototools').hover( - function () { - $(this).removeClass('transparent'); - }, - function () { - $(this).addClass('transparent'); - } - ); if(this.data.PHOTO) { $('#phototools .delete').click(function() { $(this).tipsy('hide'); @@ -1110,16 +1147,12 @@ Contacts={ $(this).tipsy('hide'); Contacts.UI.Card.editCurrentPhoto(); }); + $('#phototools .delete').show(); + $('#phototools .edit').show(); } else { $('#phototools .delete').hide(); $('#phototools .edit').hide(); } - $('#phototools .upload').click(function() { - $('#file_upload_start').trigger('click'); - }); - $('#phototools .cloud').click(function() { - OC.dialogs.filepicker(t('contacts', 'Select photo'), Contacts.UI.Card.cloudPhotoSelected, false, 'image', true); - }); }, cloudPhotoSelected:function(path){ $.getJSON(OC.filePath('contacts', 'ajax', 'oc_photo.php'),{'path':path,'id':Contacts.UI.Card.id},function(jsondata){ @@ -1134,22 +1167,33 @@ Contacts={ }); }, loadPhoto:function(refresh){ + var self = this; + var refreshstr = (refresh?'&refresh=1'+Math.random():'') $('#phototools li a').tipsy('hide'); var wrapper = $('#contacts_details_photo_wrapper'); - wrapper.addClass('wait'); + wrapper.addClass('loading').addClass('wait'); + + var img = new Image(); + $(img).load(function () { + $('img.contacts_details_photo').remove() + $(this).addClass('contacts_details_photo').hide(); + wrapper.removeClass('loading').removeClass('wait'); + $(this).insertAfter($('#phototools')).fadeIn(); + }).error(function () { + // notify the user that the image could not be loaded + $(t('contacts','something went wrong.')).insertAfter($('#phototools')); + }).attr('src', OC.linkTo('contacts', 'photo.php')+'?id='+self.id+refreshstr); + $.getJSON(OC.filePath('contacts', 'ajax', 'loadphoto.php'),{'id':this.id, 'refresh': refresh},function(jsondata){ if(jsondata.status == 'success'){ $('#contacts_details_photo_wrapper').data('checksum', jsondata.data.checksum); - wrapper.html(jsondata.data.page).ready(function(){ wrapper.removeClass('wait').tipsy() }); Contacts.UI.Card.loadPhotoHandlers(); } else{ - wrapper.removeClass('wait'); OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); } }); $('#file_upload_form').show(); - $('#contacts_propertymenu_dropdown a[data-type="PHOTO"]').parent().hide(); }, editCurrentPhoto:function(){ $.getJSON(OC.filePath('contacts', 'ajax', 'currentphoto.php'),{'id':this.id},function(jsondata){ @@ -1185,15 +1229,15 @@ Contacts={ var target = $('#crop_target'); var form = $('#cropform'); var wrapper = $('#contacts_details_photo_wrapper'); + var self = this; wrapper.addClass('wait'); form.submit(); target.load(function(){ var response=jQuery.parseJSON(target.contents().text()); if(response != undefined && response.status == 'success'){ // load cropped photo. - wrapper.html(response.data.page).ready(function(){ wrapper.removeClass('wait') }); + self.loadPhoto(true); Contacts.UI.Card.data.PHOTO = true; - Contacts.UI.Card.loadPhotoHandlers(); }else{ OC.dialogs.alert(response.data.message, t('contacts', 'Error')); wrapper.removeClass('wait'); @@ -1318,13 +1362,18 @@ Contacts={ } return false; }, - activation:function(checkbox, bookid) - { - $.post(OC.filePath('contacts', 'ajax', 'activation.php'), { bookid: bookid, active: checkbox.checked?1:0 }, - function(data) { - if (data.status == 'success'){ - checkbox.checked = data.active == 1; - Contacts.UI.Contacts.update(); + activation:function(checkbox, bookid){ + var active = checkbox.checked; + $.post(OC.filePath('contacts', 'ajax', 'activation.php'), {bookid: bookid, active: (active?1:0)}, function(jsondata) { + if (jsondata.status == 'success'){ + if(!active) { + $('#contacts h3[data-id="'+bookid+'"],#contacts ul[data-id="'+bookid+'"]').remove(); + } else { + Contacts.UI.Contacts.update(); + } + } else { + OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); + checkbox.checked = !active; } }); }, @@ -1347,6 +1396,7 @@ Contacts={ function(jsondata) { if (jsondata.status == 'success'){ $(obj).closest('tr').remove(); + $('#contacts h3[data-id="'+bookid+'"],#contacts ul[data-id="'+bookid+'"]').remove(); Contacts.UI.Contacts.update(); } else { OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); @@ -1419,7 +1469,7 @@ Contacts={ } } }; - xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadimport.php') + '?file='+encodeURIComponent(file.name), true); + xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadimport.php') + '?file='+encodeURIComponent(file.name)+'&requesttoken='+requesttoken, true); xhr.setRequestHeader('Cache-Control', 'no-cache'); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name)); @@ -1508,6 +1558,7 @@ Contacts={ } }, Contacts:{ + batchnum:50, drop:function(event, ui) { var dragitem = ui.draggable, droptarget = $(this); //console.log('Drop ' + dragitem.data('id') +' on: ' + droptarget.data('id')); @@ -1539,64 +1590,81 @@ Contacts={ }); }, // Reload the contacts list. - update:function(id){ - $.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),{},function(jsondata){ + update:function(id, aid, start){ + self = this; + console.log('update: ' + aid + ' ' + start); + var firstrun = false; + var opts = {}; + opts['startat'] = (start?start:0); + if(aid) { + opts['aid'] = aid; + } + $.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),opts,function(jsondata){ if(jsondata.status == 'success'){ - $('#contacts').html(jsondata.data.page).ready(function() { - /*setTimeout(function() { - $('.contacts li').unbind('inview'); - $('.contacts li:visible').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { - if (isInView) { - if (!$(this).find('a').attr('style')) { - $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); - } + var books = jsondata.data.entries; + $.each(jsondata.data.entries, function(b, book) { + if($('#contacts h3[data-id="'+b+'"]').length == 0) { + firstrun = true; + + if($('#contacts h3').length == 0) { + $('#contacts').html('<h3 class="addressbook" data-id="'+b+'">'+book.displayname+'</h3><ul class="contacts hidden" data-id="'+b+'"></ul>'); + } else { + if(!$('#contacts h3[data-id="'+b+'"]').length) { + $('<h3 class="addressbook" data-id="'+b+'">'+book.displayname+'</h3><ul class="contacts hidden" data-id="'+b+'"></ul>') + .appendTo('#contacts'); } - })}, 100); - setTimeout(Contacts.UI.Contacts.lazyupdate, 500);*/ - if($('#contacts h3').length > 1) { - $('#contacts h3,#contacts ul').each(function(index) { - var id = $(this).data('id'); - var accept = 'li:not([data-bookid="'+id+'"])'; - $(this).droppable({ - drop: Contacts.UI.Contacts.drop, - activeClass: 'ui-state-hover', - accept: accept - }); + } + $('#contacts h3[data-id="'+b+'"]').on('click', function(event) { + $('#contacts h3').removeClass('active'); + $(this).addClass('active'); + $('#contacts ul[data-id="'+b+'"]').slideToggle(300); + return false; }); - $('#contacts li').draggable({ - revert: 'invalid', - axis: 'y', containment: '#contacts', - scroll: true, scrollSensitivity: 100, - opacity: 0.7, helper: 'clone' + var accept = 'li:not([data-bookid="'+b+'"])'; + $('#contacts h3[data-id="'+b+'"]').droppable({ + drop: Contacts.UI.Contacts.drop, + activeClass: 'ui-state-hover', + accept: accept }); - } else { - $('#contacts h3').first().addClass('active'); + } + var contactlist = $('#contacts ul[data-id="'+b+'"]'); + for(var c in book.contacts) { + if(book.contacts[c].id == undefined) { continue; } + if($('#contacts li[data-id="'+book.contacts[c]['id']+'"][data-id="'+book.contacts[c]['bookid']+'"]').length == 0) { + var contact = Contacts.UI.Card.createEntry(book.contacts[c]); + if(c == self.batchnum-5) { + contact.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { + $(this).unbind(event); + var bookid = $(this).data('bookid'); + var numsiblings = $('.contacts li[data-bookid="'+bookid+'"]').length; + if (isInView && numsiblings >= self.batchnum) { + console.log('This would be a good time to load more contacts.'); + Contacts.UI.Contacts.update(id, bookid, $('#contacts li[data-bookid="'+bookid+'"]').length); + } + }); + } + contactlist.append(contact); + } } }); - Contacts.UI.Card.update(id); + if($('#contacts h3').length > 1) { + $('#contacts li').draggable({ + revert: 'invalid', + axis: 'y', containment: '#contacts', + scroll: true, scrollSensitivity: 100, + opacity: 0.7, helper: 'clone' + }); + } else { + $('#contacts h3').first().addClass('active'); + } + if(opts['startat'] == 0) { // only update card on first load. + Contacts.UI.Card.update(); + } } else{ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); } }); - /*setTimeout(function() { - $('.contacts li').unbind('inview'); - $('.contacts li:visible').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { - if (isInView) { - if (!$(this).find('a').attr('style')) { - $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); - } - } - })}, 500); - setTimeout(Contacts.UI.Contacts.lazyupdate, 500);*/ - }, - // Add thumbnails to the contact list as they become visible in the viewport. - lazyupdate:function(){ - $('.contacts li').live('inview', function(){ - if (!$(this).find('a').attr('style')) { - $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); - } - }); }, refreshThumbnail:function(id){ var item = $('.contacts li[data-id="'+id+'"]').find('a'); @@ -1657,13 +1725,6 @@ $(document).ready(function(){ return false; }); - $(document).on('click', '.addressbook', function(event){ - $('#contacts h3').removeClass('active'); - $(this).addClass('active'); - $(this).next().slideToggle(300); - return false; - }); - /*$('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { if (isInView) { //NOTE: I've kept all conditions for future reference ;-) // element is now visible in the viewport @@ -1739,30 +1800,6 @@ $(document).ready(function(){ xhr.send(file); } - $('body').click(function(e){ - if(!$(e.target).is('#contacts_propertymenu_button')) { - $('#contacts_propertymenu_dropdown').hide(); - } - }); - function propertyMenu(){ - var menu = $('#contacts_propertymenu_dropdown'); - if(menu.is(':hidden')) { - menu.show(); - menu.find('li').first().focus(); - } else { - menu.hide(); - } - } - $('#contacts_propertymenu_button').click(propertyMenu); - $('#contacts_propertymenu_button').keydown(propertyMenu); - function propertyMenuItem(){ - var type = $(this).data('type'); - Contacts.UI.Card.addProperty(type); - $('#contacts_propertymenu_dropdown').hide(); - } - $('#contacts_propertymenu_dropdown a').click(propertyMenuItem); - $('#contacts_propertymenu_dropdown a').keydown(propertyMenuItem); - Contacts.UI.loadHandlers(); Contacts.UI.Contacts.update(id); }); diff --git a/apps/contacts/lib/VCFExportPlugin.php b/apps/contacts/lib/VCFExportPlugin.php new file mode 100644 index 00000000000..6554cb258e8 --- /dev/null +++ b/apps/contacts/lib/VCFExportPlugin.php @@ -0,0 +1,100 @@ +<?php + +/** + * VCF Exporter + * + * This plugin adds the ability to export entire address books as .vcf files. + * This is useful for clients that don't support CardDAV yet. They often do + * support vcf files. + * + * @package Sabre + * @subpackage CardDAV + * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License + */ +class Sabre_CardDAV_VCFExportPlugin extends Sabre_DAV_ServerPlugin { + + /** + * Reference to Server class + * + * @var Sabre_DAV_Server + */ + private $server; + + /** + * Initializes the plugin and registers event handlers + * + * @param Sabre_DAV_Server $server + * @return void + */ + public function initialize(Sabre_DAV_Server $server) { + + $this->server = $server; + $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90); + + } + + /** + * 'beforeMethod' event handles. This event handles intercepts GET requests ending + * with ?export + * + * @param string $method + * @param string $uri + * @return bool + */ + public function beforeMethod($method, $uri) { + + if ($method!='GET') return; + if ($this->server->httpRequest->getQueryString()!='export') return; + + // splitting uri + list($uri) = explode('?',$uri,2); + + $node = $this->server->tree->getNodeForPath($uri); + + if (!($node instanceof Sabre_CardDAV_IAddressBook)) return; + + // Checking ACL, if available. + if ($aclPlugin = $this->server->getPlugin('acl')) { + $aclPlugin->checkPrivileges($uri, '{DAV:}read'); + } + + $this->server->httpResponse->setHeader('Content-Type','text/directory'); + $this->server->httpResponse->sendStatus(200); + + $nodes = $this->server->getPropertiesForPath($uri, array( + '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data', + ),1); + + $this->server->httpResponse->sendBody($this->generateVCF($nodes)); + + // Returning false to break the event chain + return false; + + } + + /** + * Merges all vcard objects, and builds one big vcf export + * + * @param array $nodes + * @return string + */ + public function generateVCF(array $nodes) { + $objects = array(); + + foreach($nodes as $node) { + + if (!isset($node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'])) { + continue; + } + $nodeData = $node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data']; + $objects[] = $nodeData; + + } + + return implode("\r\n", $objects); + + } + +} diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php index 4f00ce1f9e3..4077d26e58a 100644 --- a/apps/contacts/lib/addressbook.php +++ b/apps/contacts/lib/addressbook.php @@ -41,28 +41,63 @@ class OC_Contacts_Addressbook{ /** * @brief Returns the list of addressbooks for a specific user. * @param string $uid + * @param boolean $active Only return addressbooks with this $active state, default(=false) is don't care * @return array or false. */ - public static function all($uid){ + public static function all($uid, $active=false){ + $values = array($uid); + $active_where = ''; + if ($active){ + $active_where = ' AND active = ?'; + $values[] = 1; + } try { - $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ? ORDER BY displayname' ); - $result = $stmt->execute(array($uid)); + $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ? ' . $active_where . ' ORDER BY displayname' ); + $result = $stmt->execute($values); } catch(Exception $e) { OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(),OCP\Util::ERROR); OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' uid: '.$uid,OCP\Util::DEBUG); return false; } - $addressbooks = array(); while( $row = $result->fetchRow()){ $addressbooks[] = $row; } $addressbooks = array_merge($addressbooks, OCP\Share::getItemsSharedWith('addressbook', OC_Contacts_Share::FORMAT_ADDRESSBOOKS)); + if(!$active && !count($addressbooks)) { + self::addDefault($uid); + } return $addressbooks; } /** + * @brief Get active addressbook IDs for a user. + * @param integer $uid User id. If null current user will be used. + * @return array + */ + public static function activeIds($uid = null){ + if(is_null($uid)){ + $uid = OCP\USER::getUser(); + } + $activeaddressbooks = self::all($uid, true); + $ids = array(); + foreach($activeaddressbooks as $addressbook) { + $ids[] = $addressbook['id']; + } + return $ids; + } + + /** + * @brief Returns the list of active addressbooks for a specific user. + * @param string $uid + * @return array + */ + public static function active($uid){ + return self::all($uid, true); + } + + /** * @brief Returns the list of addressbooks for a principal (DAV term of user) * @param string $principaluri * @return array @@ -113,10 +148,17 @@ class OC_Contacts_Addressbook{ * @return insertid */ public static function add($uid,$name,$description=''){ - $all = self::all($uid); + try { + $stmt = OCP\DB::prepare( 'SELECT uri FROM *PREFIX*contacts_addressbooks WHERE userid = ? ' ); + $result = $stmt->execute(array($uid)); + } catch(Exception $e) { + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(),OCP\Util::ERROR); + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' uid: '.$uid,OCP\Util::DEBUG); + return false; + } $uris = array(); - foreach($all as $i){ - $uris[] = $i['uri']; + while($row = $result->fetchRow()){ + $uris[] = $row['uri']; } $uri = self::createURI($name, $uris ); @@ -186,88 +228,6 @@ class OC_Contacts_Addressbook{ return true; } - public static function cleanArray($array, $remove_null_number = true){ - $new_array = array(); - - $null_exceptions = array(); - - foreach ($array as $key => $value){ - $value = trim($value); - - if($remove_null_number){ - $null_exceptions[] = '0'; - } - - if(!in_array($value, $null_exceptions) && $value != "") { - $new_array[] = $value; - } - } - return $new_array; - } - - /** - * @brief Get active addressbooks for a user. - * @param integer $uid User id. If null current user will be used. - * @return array - */ - public static function activeIds($uid = null){ - if(is_null($uid)){ - $uid = OCP\USER::getUser(); - } - $prefbooks = OCP\Config::getUserValue($uid,'contacts','openaddressbooks',null); - if(!$prefbooks){ - $addressbooks = OC_Contacts_Addressbook::all($uid); - if(count($addressbooks) == 0){ - self::addDefault($uid); - } - } - $prefbooks = OCP\Config::getUserValue($uid,'contacts','openaddressbooks',null); - return explode(';',$prefbooks); - } - - /** - * @brief Returns the list of active addressbooks for a specific user. - * @param string $uid - * @return array - */ - public static function active($uid){ - if(is_null($uid)){ - $uid = OCP\USER::getUser(); - } - $active = self::activeIds($uid); - $shared = OCP\Share::getItemsSharedWith('addressbook', OC_Contacts_Share::FORMAT_ADDRESSBOOKS); - $addressbooks = array(); - $ids_sql = join(',', array_fill(0, count($active), '?')); - $prep = 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id IN ('.$ids_sql.') ORDER BY displayname'; - try { - $stmt = OCP\DB::prepare( $prep ); - $result = $stmt->execute($active); - } catch(Exception $e) { - OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR); - OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', uid: '.$uid,OCP\Util::DEBUG); - OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', ids: '.join(',', $active),OCP\Util::DEBUG); - OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', SQL:'.$prep,OCP\Util::DEBUG); - } - - while( $row = $result->fetchRow()){ - // Insert formatted shared addressbook instead - if ($row['userid'] != $uid) { - foreach ($shared as $addressbook) { - if ($addressbook['id'] == $row['id']) { - $addressbooks[] = $addressbook; - break; - } - } - } else { - $addressbooks[] = $row; - } - } - if(!count($addressbooks)) { - self::addDefault($uid); - } - return $addressbooks; - } - /** * @brief Activates an addressbook * @param integer $id @@ -275,30 +235,16 @@ class OC_Contacts_Addressbook{ * @return boolean */ public static function setActive($id,$active){ - // Need these ones for checking uri - //$addressbook = self::find($id); - - if(is_null($id)){ - $id = 0; - } - - $openaddressbooks = self::activeIds(); - if($active) { - if(!in_array($id, $openaddressbooks)) { - $openaddressbooks[] = $id; - } - } else { - if(in_array($id, $openaddressbooks)) { - unset($openaddressbooks[array_search($id, $openaddressbooks)]); - } + $sql = 'UPDATE *PREFIX*contacts_addressbooks SET active = ? WHERE id = ?'; + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '.$id.', active: '.intval($active),OCP\Util::ERROR); + try { + $stmt = OCP\DB::prepare($sql); + $stmt->execute(array(intval($active), $id)); + return true; + } catch(Exception $e) { + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception for '.$id.': '.$e->getMessage(),OCP\Util::ERROR); + return false; } - // NOTE: Ugly hack... - $openaddressbooks = self::cleanArray($openaddressbooks, false); - sort($openaddressbooks, SORT_NUMERIC); - // FIXME: I alway end up with a ';' prepending when imploding the array..? - OCP\Config::setUserValue(OCP\USER::getUser(),'contacts','openaddressbooks',implode(';', $openaddressbooks)); - - return true; } /** @@ -307,8 +253,15 @@ class OC_Contacts_Addressbook{ * @return boolean */ public static function isActive($id){ - //OCP\Util::writeLog('contacts','OC_Contacts_Addressbook::isActive('.$id.'):'.in_array($id, self::activeIds()), OCP\Util::DEBUG); - return in_array($id, self::activeIds()); + $sql = 'SELECT active FROM *PREFIX*contacts_addressbooks WHERE id = ?'; + try { + $stmt = OCP\DB::prepare( $sql ); + $result = $stmt->execute(array($id)); + $row = $result->fetchRow(); + return (bool)$row['active']; + } catch(Exception $e) { + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR); + } } /** diff --git a/apps/contacts/lib/app.php b/apps/contacts/lib/app.php index 3b16ffd5c16..ed2300adae0 100644 --- a/apps/contacts/lib/app.php +++ b/apps/contacts/lib/app.php @@ -10,7 +10,6 @@ * This class manages our app actions */ OC_Contacts_App::$l10n = OC_L10N::get('contacts'); -OC_Contacts_App::$categories = new OC_VCategories('contacts'); class OC_Contacts_App { /* * @brief language object for calendar app @@ -139,31 +138,55 @@ class OC_Contacts_App { } } - /* + /** * @brief returns the vcategories object of the user * @return (object) $vcategories */ protected static function getVCategories() { if (is_null(self::$categories)) { - self::$categories = new OC_VCategories('contacts'); + self::$categories = new OC_VCategories('contacts', null, self::getDefaultCategories()); } return self::$categories; } - /* + /** * @brief returns the categories for the user * @return (Array) $categories */ public static function getCategories() { - $categories = self::$categories->categories(); + $categories = self::getVCategories()->categories(); if(count($categories) == 0) { self::scanCategories(); $categories = self::$categories->categories(); } - return $categories; + return ($categories ? $categories : self::getDefaultCategories()); } /** + * @brief returns the default categories of ownCloud + * @return (array) $categories + */ + public static function getDefaultCategories(){ + return array( + (string)self::$l10n->t('Birthday'), + (string)self::$l10n->t('Business'), + (string)self::$l10n->t('Call'), + (string)self::$l10n->t('Clients'), + (string)self::$l10n->t('Deliverer'), + (string)self::$l10n->t('Holidays'), + (string)self::$l10n->t('Ideas'), + (string)self::$l10n->t('Journey'), + (string)self::$l10n->t('Jubilee'), + (string)self::$l10n->t('Meeting'), + (string)self::$l10n->t('Other'), + (string)self::$l10n->t('Personal'), + (string)self::$l10n->t('Projects'), + (string)self::$l10n->t('Questions'), + (string)self::$l10n->t('Work'), + ); + } + + /** * scan vcards for categories. * @param $vccontacts VCards to scan. null to check all vcards for the current user. */ @@ -175,16 +198,19 @@ class OC_Contacts_App { foreach($vcaddressbooks as $vcaddressbook) { $vcaddressbookids[] = $vcaddressbook['id']; } - $vccontacts = OC_Contacts_VCard::all($vcaddressbookids); - } - } - if(is_array($vccontacts) && count($vccontacts) > 0) { - $cards = array(); - foreach($vccontacts as $vccontact) { - $cards[] = $vccontact['carddata']; + $start = 0; + $batchsize = 10; + while($vccontacts = OC_Contacts_VCard::all($vcaddressbookids, $start, $batchsize)){ + $cards = array(); + foreach($vccontacts as $vccontact) { + $cards[] = $vccontact['carddata']; + } + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', scanning: '.$batchsize.' starting from '.$start,OCP\Util::DEBUG); + // only reset on first batch. + self::getVCategories()->rescan($cards, true, ($start==0?true:false)); + $start += $batchsize; + } } - - self::$categories->rescan($cards); } } diff --git a/apps/contacts/lib/connector_sabre.php b/apps/contacts/lib/connector_sabre.php index c967e906601..99b94fc767e 100644 --- a/apps/contacts/lib/connector_sabre.php +++ b/apps/contacts/lib/connector_sabre.php @@ -138,7 +138,9 @@ class OC_Connector_Sabre_CardDAV extends Sabre_CardDAV_Backend_Abstract { foreach($data as $i){ $cards[] = array( 'id' => $i['id'], - 'carddata' => $i['carddata'], + //'carddata' => $i['carddata'], + 'size' => strlen($i['carddata']), + 'etag' => md5($i['carddata']), 'uri' => $i['uri'], 'lastmodified' => $i['lastmodified'] ); } diff --git a/apps/contacts/lib/hooks.php b/apps/contacts/lib/hooks.php index 9794a9c9b94..d91d3c565b5 100644 --- a/apps/contacts/lib/hooks.php +++ b/apps/contacts/lib/hooks.php @@ -90,9 +90,10 @@ class OC_Contacts_Hooks{ if ($birthday) { $date = new DateTime($birthday); $vevent = new OC_VObject('VEVENT'); - $vevent->setDateTime('LAST-MODIFIED', new DateTime($vcard->REV)); + //$vevent->setDateTime('LAST-MODIFIED', new DateTime($vcard->REV)); $vevent->setDateTime('DTSTART', $date, Sabre_VObject_Element_DateTime::DATE); $vevent->setString('DURATION', 'P1D'); + $vevent->setString('UID', substr(md5(rand().time()),0,10)); // DESCRIPTION? $vevent->setString('RRULE', 'FREQ=YEARLY'); $title = str_replace('{name}', $vcard->getAsString('FN'), OC_Contacts_App::$l10n->t('{name}\'s Birthday')); @@ -101,6 +102,7 @@ class OC_Contacts_Hooks{ 'vevent' => $vevent, 'repeating' => true, 'summary' => $title, + 'calendardata' => "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Contacts " . OCP\App::getAppVersion('contacts') . "\n" . $vevent->serialize() . "END:VCALENDAR" ); } } diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php index bf22be0de74..e3b65605624 100644 --- a/apps/contacts/lib/vcard.php +++ b/apps/contacts/lib/vcard.php @@ -47,11 +47,18 @@ class OC_Contacts_VCard{ * The cards are associative arrays. You'll find the original vCard in * ['carddata'] */ - public static function all($id){ + public static function all($id, $start=null, $num=null){ + $limitsql = ''; + if(!is_null($num)) { + $limitsql = ' LIMIT '.$num; + } + if(!is_null($start) && !is_null($num)) { + $limitsql .= ' OFFSET '.$start.' '; + } $result = null; if(is_array($id) && count($id)) { $id_sql = join(',', array_fill(0, count($id), '?')); - $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname'; + $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname '.$limitsql; try { $stmt = OCP\DB::prepare( $prep ); $result = $stmt->execute($id); @@ -63,7 +70,8 @@ class OC_Contacts_VCard{ } } elseif(is_int($id) || is_string($id)) { try { - $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' ); + $sql = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname'.$limitsql; + $stmt = OCP\DB::prepare( $sql ); $result = $stmt->execute(array($id)); } catch(Exception $e) { OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR); diff --git a/apps/contacts/settings.php b/apps/contacts/settings.php index c88fed0b4d6..a079499381b 100644 --- a/apps/contacts/settings.php +++ b/apps/contacts/settings.php @@ -1,6 +1,6 @@ <?php $tmpl = new OCP\Template( 'contacts', 'settings'); +$tmpl->assign('addressbooks', OC_Contacts_Addressbook::all(OCP\USER::getUser()), false); return $tmpl->fetchPage(); -?> diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php index 0d4219c9f2d..5b49b68e954 100644 --- a/apps/contacts/templates/index.php +++ b/apps/contacts/templates/index.php @@ -9,14 +9,14 @@ </div> <div id="bottomcontrols"> <form> - <button class="svg" id="contacts_newcontact" title="<?php echo $l->t('Add Contact'); ?>"><img class="svg" src="<?php echo OCP\Util::linkTo('contacts', 'img/contact-new.svg'); ?>" alt="<?php echo $l->t('Add Contact'); ?>" /></button> + <button class="svg" id="contacts_newcontact" title="<?php echo $l->t('Add Contact'); ?>"><img class="svg" src="<?php echo OCP\Util::imagePath('contacts', 'contact-new.svg'); ?>" alt="<?php echo $l->t('Add Contact'); ?>" /></button> <button class="svg" id="chooseaddressbook" title="<?php echo $l->t('Addressbooks'); ?>"><img class="svg" src="core/img/actions/settings.svg" alt="<?php echo $l->t('Addressbooks'); ?>" /></button> </form> </div> </div> <div id="rightcontent" class="rightcontent" data-id="<?php echo $_['id']; ?>"> <?php - if ($_['id']){ + if($_['has_contacts']){ echo $this->inc('part.contact'); } else{ diff --git a/apps/contacts/templates/part.contact.php b/apps/contacts/templates/part.contact.php index 5757563fe5b..4233bffede3 100644 --- a/apps/contacts/templates/part.contact.php +++ b/apps/contacts/templates/part.contact.php @@ -9,16 +9,19 @@ $id = isset($_['id']) ? $_['id'] : ''; <input type="hidden" class="max_human_file_size" value="(max <?php echo $_['uploadMaxHumanFilesize']; ?>)"> <input id="file_upload_start" type="file" accept="image/*" name="imagefile" /> </form> - <div id="actionbar"> - <button class="svg action" id="contacts_downloadcard" title="<?php echo $l->t('Download contact');?>"></button> - <button class="svg action" id="contacts_deletecard" title="<?php echo $l->t('Delete contact');?>"></button> - </div> <div id="contact_photo" class="contactsection"> <iframe name="file_upload_target" id='file_upload_target' src=""></iframe> <div class="tip propertycontainer" id="contacts_details_photo_wrapper" title="<?php echo $l->t('Drop photo to upload'); ?> (max <?php echo $_['uploadMaxHumanFilesize']; ?>)" data-element="PHOTO"> + <ul id="phototools" class="transparent hidden"> + <li><a class="svg delete" title="<?php echo $l->t('Delete current photo'); ?>"></a></li> + <li><a class="svg edit" title="<?php echo $l->t('Edit current photo'); ?>"></a></li> + <li><a class="svg upload" title="<?php echo $l->t('Upload new photo'); ?>"></a></li> + <li><a class="svg cloud" title="<?php echo $l->t('Select photo from ownCloud'); ?>"></a></li> + </ul> </div> + <img /> </div> <!-- contact_photo --> <div id="contact_identity" class="contactsection"> @@ -101,20 +104,23 @@ $id = isset($_['id']) ? $_['id'] : ''; </form> </div> <!-- contact_note --> - <div id="contacts_propertymenu"> - <button class="button" id="contacts_propertymenu_button"><?php echo $l->t('Add field'); ?></button> - <ul id="contacts_propertymenu_dropdown" role="menu" class="hidden"> - <li><a role="menuitem" data-type="PHOTO"><?php echo $l->t('Profile picture'); ?></a></li> - <li><a role="menuitem" data-type="ORG"><?php echo $l->t('Organization'); ?></a></li> - <li><a role="menuitem" data-type="NICKNAME"><?php echo $l->t('Nickname'); ?></a></li> - <li><a role="menuitem" data-type="BDAY"><?php echo $l->t('Birthday'); ?></a></li> - <li><a role="menuitem" data-type="TEL"><?php echo $l->t('Phone'); ?></a></li> - <li><a role="menuitem" data-type="EMAIL"><?php echo $l->t('Email'); ?></a></li> - <li><a role="menuitem" data-type="ADR"><?php echo $l->t('Address'); ?></a></li> - <li><a role="menuitem" data-type="NOTE"><?php echo $l->t('Note'); ?></a></li> - <li><a role="menuitem" data-type="URL"><?php echo $l->t('Web site'); ?></a></li> - <li><a role="menuitem" data-type="CATEGORIES"><?php echo $l->t('Groups'); ?></a></li> - </ul> + <div id="actionbar"> + <div id="contacts_propertymenu"> + <button class="button" id="contacts_propertymenu_button"><?php echo $l->t('Add field'); ?></button> + <ul id="contacts_propertymenu_dropdown" role="menu" class="hidden"> + <li><a role="menuitem" data-type="ORG"><?php echo $l->t('Organization'); ?></a></li> + <li><a role="menuitem" data-type="NICKNAME"><?php echo $l->t('Nickname'); ?></a></li> + <li><a role="menuitem" data-type="BDAY"><?php echo $l->t('Birthday'); ?></a></li> + <li><a role="menuitem" data-type="TEL"><?php echo $l->t('Phone'); ?></a></li> + <li><a role="menuitem" data-type="EMAIL"><?php echo $l->t('Email'); ?></a></li> + <li><a role="menuitem" data-type="ADR"><?php echo $l->t('Address'); ?></a></li> + <li><a role="menuitem" data-type="NOTE"><?php echo $l->t('Note'); ?></a></li> + <li><a role="menuitem" data-type="URL"><?php echo $l->t('Web site'); ?></a></li> + <li><a role="menuitem" data-type="CATEGORIES"><?php echo $l->t('Groups'); ?></a></li> + </ul> + </div> + <button class="svg action" id="contacts_downloadcard" title="<?php echo $l->t('Download contact');?>"></button> + <button class="svg action" id="contacts_deletecard" title="<?php echo $l->t('Delete contact');?>"></button> </div> </div> <!-- card --> diff --git a/apps/contacts/templates/part.contactphoto.php b/apps/contacts/templates/part.contactphoto.php deleted file mode 100644 index bddf4cc8a81..00000000000 --- a/apps/contacts/templates/part.contactphoto.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -$id = $_['id']; -$wattr = isset($_['width'])?'width="'.$_['width'].'"':''; -$hattr = isset($_['height'])?'height="'.$_['height'].'"':''; -$rand = isset($_['refresh'])?'&refresh='.rand():''; -?> -<ul id="phototools" class="transparent hidden"> - <li><a class="svg delete" title="<?php echo $l->t('Delete current photo'); ?>"></a></li> - <li><a class="svg edit" title="<?php echo $l->t('Edit current photo'); ?>"></a></li> - <li><a class="svg upload" title="<?php echo $l->t('Upload new photo'); ?>"></a></li> - <li><a class="svg cloud" title="<?php echo $l->t('Select photo from ownCloud'); ?>"></a></li> -</ul> -<img class="loading" id="contacts_details_photo" <?php echo $wattr; ?> <?php echo $hattr; ?> src="<?php echo OCP\Util::linkToAbsolute('contacts', 'photo.php'); ?>?id=<?php echo $id.$rand; ?>" /> -<progress id="contacts_details_photo_progress" style="display:none;" value="0" max="100">0 %</progress> - - diff --git a/apps/contacts/templates/part.contacts.php b/apps/contacts/templates/part.contacts.php deleted file mode 100644 index c33c5832e82..00000000000 --- a/apps/contacts/templates/part.contacts.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php -foreach($_['books'] as $id => $addressbook) { - echo '<h3 class="addressbook" data-id="'.$id.'">'.$addressbook['displayname'].'</h3>'; - echo '<ul class="contacts hidden" data-id="'.$id.'">'; - foreach($addressbook['contacts'] as $contact) { - echo '<li role="button" data-bookid="'.$contact['addressbookid'].'" data-id="'.$contact['id'].'"><a href="'.link_to('contacts','index.php').'&id='.$contact['id'].'" style="background: url('.link_to('contacts','thumbnail.php').'?id='.$contact['id'].') no-repeat scroll 0 0 transparent;">'.$contact['displayname'].'</a></li>'; - } - echo '</ul>'; -} -?> diff --git a/apps/contacts/templates/part.importaddressbook.php b/apps/contacts/templates/part.importaddressbook.php index 01f8dd77d0a..8ceb5f3538b 100644 --- a/apps/contacts/templates/part.importaddressbook.php +++ b/apps/contacts/templates/part.importaddressbook.php @@ -12,6 +12,7 @@ <th><?php echo $l->t('Select address book to import to:') ?></th> <td> <form id="import_upload_form" action="<?php echo OCP\Util::linkTo('contacts', 'ajax/uploadimport.php'); ?>" method="post" enctype="multipart/form-data" target="import_upload_target"> + <input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>"> <select id="book" name="book" class="float"> <?php $contacts_options = OC_Contacts_Addressbook::all(OCP\USER::getUser()); diff --git a/apps/contacts/templates/settings.php b/apps/contacts/templates/settings.php index 216003b6c69..f520559d143 100644 --- a/apps/contacts/templates/settings.php +++ b/apps/contacts/templates/settings.php @@ -7,6 +7,12 @@ <dd><code><?php echo OCP\Util::linkToRemote('carddav'); ?></code></dd> <dt><?php echo $l->t('iOS/OS X'); ?></dt> <dd><code><?php echo OCP\Util::linkToRemote('carddav'); ?>principals/<?php echo OCP\USER::getUser(); ?></code>/</dd> + <dt><?php echo $l->t('Read only vCard directory link(s)'); ?></dt> + <dd> + <?php foreach($_['addressbooks'] as $addressbook) { ?> + <a href="<?php echo OCP\Util::linkToRemote('carddav').'addressbooks/'.OCP\USER::getUser().'/'.rawurlencode($addressbook['uri']) ?>?export"><?php echo $addressbook['displayname'] ?></a><br /> + <?php } ?> + </dd> </dl> Powered by <a href="http://geonames.org/" target="_blank">geonames.org webservice</a> </fieldset> |