summaryrefslogtreecommitdiffstats
path: root/apps/contacts
diff options
context:
space:
mode:
authorMichael Gapczynski <mtgap@owncloud.com>2012-07-11 20:25:59 -0400
committerMichael Gapczynski <mtgap@owncloud.com>2012-07-11 20:25:59 -0400
commit4bf13adff25f012c735931c0578b1f5d0790bdbe (patch)
treea7c5451ff25e2f39936ae984ceb5b3b9eb519088 /apps/contacts
parent88f4845ca33fd6f2988f230116e2190d15ab1866 (diff)
parent8890a4128015df0ad57101703d6c164ea54fe4ee (diff)
downloadnextcloud-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')
-rw-r--r--apps/contacts/ajax/addbook.php1
-rw-r--r--apps/contacts/ajax/categories/categoriesfor.php1
-rw-r--r--apps/contacts/ajax/categories/delete.php2
-rw-r--r--apps/contacts/ajax/categories/list.php2
-rw-r--r--apps/contacts/ajax/categories/rescan.php19
-rw-r--r--apps/contacts/ajax/contacts.php56
-rw-r--r--apps/contacts/ajax/currentphoto.php2
-rw-r--r--apps/contacts/ajax/editaddress.php2
-rw-r--r--apps/contacts/ajax/editaddressbook.php1
-rw-r--r--apps/contacts/ajax/editname.php2
-rw-r--r--apps/contacts/ajax/importaddressbook.php2
-rw-r--r--apps/contacts/ajax/importdialog.php1
-rw-r--r--apps/contacts/ajax/loadphoto.php10
-rw-r--r--apps/contacts/ajax/oc_photo.php2
-rw-r--r--apps/contacts/ajax/uploadimport.php4
-rw-r--r--apps/contacts/ajax/uploadphoto.php1
-rw-r--r--apps/contacts/appinfo/app.php1
-rw-r--r--apps/contacts/appinfo/database.xml8
-rw-r--r--apps/contacts/appinfo/migrate.php19
-rw-r--r--apps/contacts/appinfo/remote.php1
-rw-r--r--apps/contacts/appinfo/update.php25
-rw-r--r--apps/contacts/appinfo/version2
-rw-r--r--apps/contacts/css/contacts.css11
-rw-r--r--apps/contacts/export.php12
-rw-r--r--apps/contacts/import.php13
-rw-r--r--apps/contacts/index.php33
-rw-r--r--apps/contacts/js/contacts.js297
-rw-r--r--apps/contacts/lib/VCFExportPlugin.php100
-rw-r--r--apps/contacts/lib/addressbook.php181
-rw-r--r--apps/contacts/lib/app.php56
-rw-r--r--apps/contacts/lib/connector_sabre.php4
-rw-r--r--apps/contacts/lib/hooks.php4
-rw-r--r--apps/contacts/lib/vcard.php14
-rw-r--r--apps/contacts/settings.php2
-rw-r--r--apps/contacts/templates/index.php4
-rw-r--r--apps/contacts/templates/part.contact.php42
-rw-r--r--apps/contacts/templates/part.contactphoto.php16
-rw-r--r--apps/contacts/templates/part.contacts.php10
-rw-r--r--apps/contacts/templates/part.importaddressbook.php1
-rw-r--r--apps/contacts/templates/settings.php6
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>