diff --git a/appinfo/routes.php b/appinfo/routes.php index 82346416..48edba89 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -36,7 +36,17 @@ $this->create('contacts_address_books_for_user', 'addressbooks/') } ); -$this->create('contacts_address_book_collection', 'addressbook/{backend}/{addressbookid}/contacts') +$this->create('contacts_address_book_add', 'addressbook/{backend}/add') + ->post() + ->action( + function($params) { + session_write_close(); + Main::main('AddressBookController', 'addAddressBook', $params, new DIContainer()); + } + ) + ->requirements(array('backend', 'addressbookid')); + +$this->create('contacts_address_book', 'addressbook/{backend}/{addressbookid}') ->get() ->action( function($params) { @@ -46,12 +56,12 @@ $this->create('contacts_address_book_collection', 'addressbook/{backend}/{addres ) ->requirements(array('backend', 'addressbookid')); -$this->create('contacts_address_book_add', 'addressbook/{backend}/add') - ->post() +$this->create('contacts_address_book_export', 'addressbook/{backend}/{addressbookid}/export') + ->get() ->action( function($params) { session_write_close(); - Main::main('AddressBookController', 'addAddressBook', $params, new DIContainer()); + Main::main('AddressBookController', 'exportAddressBook', $params, new DIContainer()); } ) ->requirements(array('backend', 'addressbookid')); @@ -146,6 +156,16 @@ $this->create('contacts_contact_photo', 'addressbook/{backend}/{addressbookid}/c ) ->requirements(array('backend', 'addressbook', 'contactid')); +$this->create('contacts_contact_export', 'addressbook/{backend}/{addressbookid}/contact/{contactid}/export') + ->get() + ->action( + function($params) { + session_write_close(); + Main::main('ContactController', 'exportContact', $params, new DIContainer()); + } + ) + ->requirements(array('backend', 'addressbook', 'contactid')); + $this->create('contacts_contact_delete_property', 'addressbook/{backend}/{addressbookid}/contact/{contactid}/property/delete') ->post() ->action( diff --git a/js/addressbooks.js b/js/addressbooks.js index e33d837b..ccd83639 100644 --- a/js/addressbooks.js +++ b/js/addressbooks.js @@ -25,6 +25,14 @@ OC.Contacts = OC.Contacts || {}; if(!this.hasPermission(OC.PERMISSION_UPDATE)) { this.$li.find('a.action.edit').hide(); } + this.$li.find('a.action.download') + .attr('href', OC.Router.generate( + 'contacts_address_book_export', + { + backend: this.getBackend(), + addressbookid: this.getId() + } + )); this.$li.find('a.action.delete').on('click keypress', function() { $('.tipsy').remove(); console.log('delete', self.getId()); diff --git a/js/app.js b/js/app.js index f7cd32d5..288dfbb6 100644 --- a/js/app.js +++ b/js/app.js @@ -518,9 +518,8 @@ OC.Contacts = OC.Contacts || { }); $(document).bind('request.contact.export', function(e, data) { - var id = String(data.id); - console.log('contact', data.id, 'request.contact.export'); - document.location.href = OC.linkTo('contacts', 'export.php') + '?' + $.param(data); + console.log('request.contact.export', data); + document.location.href = OC.Router.generate('contacts_contact_export', data); }); $(document).bind('request.contact.close', function(e, data) { diff --git a/js/contacts.js b/js/contacts.js index ef5cd325..5ec4100a 100644 --- a/js/contacts.js +++ b/js/contacts.js @@ -2278,7 +2278,7 @@ OC.Contacts = OC.Contacts || {}; */ ContactList.prototype.loadContacts = function(backend, addressBookId) { var self = this; - return $.when(this.storage.getContacts(backend, addressBookId)).then(function(response) { + return $.when(this.storage.getAddressBook(backend, addressBookId)).then(function(response) { var defer = this; //console.log('ContactList.loadContacts', response); if(!response.error) { diff --git a/js/storage.js b/js/storage.js index b3ff2f05..4010786d 100644 --- a/js/storage.js +++ b/js/storage.js @@ -138,7 +138,9 @@ OC.Contacts = OC.Contacts || {}; * * @param string backend * @param string addressbookid Address book ID - * @return An array containing contact data e.g.: + * @return Depending of the value of the 'request' property in params: + * 'collection' + * An array containing contact data e.g.: * { * metadata: * { @@ -150,12 +152,15 @@ OC.Contacts = OC.Contacts || {}; * parent: (id of the parent address book) * data: //array of VCard data * } + * 'export' + * A stream of vCards separated by "\r\n\r\n" */ - Storage.prototype.getContacts = function(backend, addressbookid) { + Storage.prototype.getAddressBook = function(backend, addressbookid, params) { return this.requestRoute( - 'contacts_address_book_collection', + 'contacts_address_book', 'GET', - {backend: backend, addressbookid: addressbookid} + {backend: backend, addressbookid: addressbookid}, + params ); } diff --git a/lib/controller/addressbookcontroller.php b/lib/controller/addressbookcontroller.php index d1d0eff0..603d7465 100644 --- a/lib/controller/addressbookcontroller.php +++ b/lib/controller/addressbookcontroller.php @@ -9,12 +9,11 @@ namespace OCA\Contacts\Controller; -use OCA\Contacts\App; -use OCA\Contacts\JSONResponse; -use OCA\Contacts\Utils\JSONSerializer; -//use OCA\Contacts\Request; -use OCA\AppFramework\Controller\Controller as BaseController; -use OCA\AppFramework\Core\API; +use OCA\Contacts\App, + OCA\Contacts\JSONResponse, + OCA\Contacts\Utils\JSONSerializer, + OCA\AppFramework\Controller\Controller as BaseController, + OCA\AppFramework\Http\TextDownloadResponse; /** @@ -47,6 +46,7 @@ class AddressBookController extends BaseController { * @Ajax */ public function getAddressBook() { + \OCP\Util::writeLog('contacts', __METHOD__, \OCP\Util::DEBUG); $params = $this->request->urlParams; $app = new App($this->api->getUserId()); @@ -72,6 +72,34 @@ class AddressBookController extends BaseController { return $response; } + /** + * @IsAdminExemption + * @IsSubAdminExemption + * @CSRFExemption + */ + public function exportAddressBook() { + \OCP\Util::writeLog('contacts', __METHOD__, \OCP\Util::DEBUG); + $params = $this->request->urlParams; + $app = new App($this->api->getUserId()); + + $addressBook = $app->getAddressBook($params['backend'], $params['addressbookid']); + $lastModified = $addressBook->lastModified(); + $response = new JSONResponse(); + + if(!is_null($lastModified)) { + $response->addHeader('Cache-Control', 'private, must-revalidate'); + $response->setLastModified(\DateTime::createFromFormat('U', $lastModified) ?: null); + $response->setETag(md5($lastModified)); + } + + $contacts = ''; + foreach($addressBook->getChildren() as $i => $contact) { + $contacts .= $contact->serialize() . "\r\n"; + } + $name = str_replace(' ', '_', $addressBook->getDisplayName()) . '.vcf'; + return new TextDownloadResponse($contacts, $name, 'text/directory'); + } + /** * @IsAdminExemption * @IsSubAdminExemption diff --git a/lib/controller/contactcontroller.php b/lib/controller/contactcontroller.php index 09831f6d..9fa2151c 100644 --- a/lib/controller/contactcontroller.php +++ b/lib/controller/contactcontroller.php @@ -9,14 +9,14 @@ namespace OCA\Contacts\Controller; -use OCA\Contacts\App; -use OCA\Contacts\JSONResponse; -use OCA\Contacts\ImageResponse; -use OCA\Contacts\Utils\JSONSerializer; -use OCA\Contacts\Utils\Properties; -//use OCA\Contacts\Request; -use OCA\AppFramework\Controller\Controller as BaseController; -use OCA\AppFramework\Core\API; +use OCA\Contacts\App, + OCA\Contacts\JSONResponse, + OCA\Contacts\ImageResponse, + OCA\Contacts\Utils\JSONSerializer, + OCA\Contacts\Utils\Properties, + OCA\AppFramework\Controller\Controller as BaseController, + OCA\AppFramework\Core\API, + OCA\AppFramework\Http\TextDownloadResponse; /** @@ -50,6 +50,29 @@ class ContactController extends BaseController { return $response; } + /** + * @IsAdminExemption + * @IsSubAdminExemption + * @CSRFExemption + */ + public function exportContact() { + $app = new App($this->api->getUserId()); + + $params = $this->request->urlParams; + + $addressBook = $app->getAddressBook($params['backend'], $params['addressbookid']); + $contact = $addressBook->getChild($params['contactid']); + + if(!$contact) { + $response = new JSONResponse(); + $response->bailOut(App::$l10n->t('Couldn\'t find contact.')); + return $response; + } + + $name = str_replace(' ', '_', $contact->getDisplayName()) . '.vcf'; + return new TextDownloadResponse($contact->serialize(), $name, 'text/vcard'); + } + /** * @IsAdminExemption * @IsSubAdminExemption