Blame view

sources/apps/contacts/lib/controller/addressbookcontroller.php 9.4 KB
d1bafeea1   Kload   [fix] Upgrade to ...
1
2
3
  <?php
  /**
   * @author Thomas Tanghus
6d9380f96   Cédric Dupont   Update sources OC...
4
   * @copyright 2013-2014 Thomas Tanghus (thomas@tanghus.net)
d1bafeea1   Kload   [fix] Upgrade to ...
5
6
7
8
9
10
11
12
13
14
15
   * This file is licensed under the Affero General Public License version 3 or
   * later.
   * See the COPYING-README file.
   */
  
  namespace OCA\Contacts\Controller;
  
  use OCA\Contacts\App,
  	OCA\Contacts\JSONResponse,
  	OCA\Contacts\Utils\JSONSerializer,
  	OCA\Contacts\Controller,
6d9380f96   Cédric Dupont   Update sources OC...
16
17
18
  	OCP\AppFramework\Http,
  	OCP\AppFramework\IApi,
  	OCP\IRequest;
d1bafeea1   Kload   [fix] Upgrade to ...
19
20
21
22
23
24
25
  
  /**
   * Controller class For Address Books
   */
  class AddressBookController extends Controller {
  
  	/**
6d9380f96   Cédric Dupont   Update sources OC...
26
27
28
29
30
31
32
33
34
35
  	 * @var \OCP\AppFramework\IApi
  	 */
  	protected $api;
  
  	public function __construct($appName, IRequest $request, App $app, IApi $api) {
  		parent::__construct($appName, $request, $app);
  		$this->api = $api;
  	}
  
  	/**
d1bafeea1   Kload   [fix] Upgrade to ...
36
37
38
39
40
41
42
  	 * @NoAdminRequired
  	 * @NoCSRFRequired
  	 */
  	public function userAddressBooks() {
  		$addressBooks = $this->app->getAddressBooksForUser();
  		$result = array();
  		$lastModified = 0;
6d9380f96   Cédric Dupont   Update sources OC...
43

d1bafeea1   Kload   [fix] Upgrade to ...
44
  		foreach($addressBooks as $addressBook) {
6d9380f96   Cédric Dupont   Update sources OC...
45

d1bafeea1   Kload   [fix] Upgrade to ...
46
47
  			$data = $addressBook->getMetaData();
  			$result[] = $data;
6d9380f96   Cédric Dupont   Update sources OC...
48
49
  
  			if (!is_null($data['lastmodified'])) {
d1bafeea1   Kload   [fix] Upgrade to ...
50
51
  				$lastModified = max($lastModified, $data['lastmodified']);
  			}
6d9380f96   Cédric Dupont   Update sources OC...
52

d1bafeea1   Kload   [fix] Upgrade to ...
53
54
55
  		}
  
  		// To avoid invalid cache deletion time is saved
6d9380f96   Cédric Dupont   Update sources OC...
56
  		/*$lastModified = max(
d1bafeea1   Kload   [fix] Upgrade to ...
57
58
  			$lastModified,
  			\OCP\Config::getUserValue($this->api->getUserId(), 'contacts', 'last_address_book_deleted', 0)
6d9380f96   Cédric Dupont   Update sources OC...
59
  		);*/
d1bafeea1   Kload   [fix] Upgrade to ...
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  
  		$response = new JSONResponse(array(
  			'addressbooks' => $result,
  		));
  
  		/** FIXME: Caching is currently disabled
  		if($lastModified > 0) {
  			$response->setLastModified(\DateTime::createFromFormat('U', $lastModified) ?: null);
  			$response->setETag(md5($lastModified));
  		}
  		*/
  
  		return $response;
  	}
  
  	/**
  	 * @NoAdminRequired
  	 * @NoCSRFRequired
  	 */
  	public function getAddressBook() {
  		$params = $this->request->urlParams;
  
  		$addressBook = $this->app->getAddressBook($params['backend'], $params['addressBookId']);
  		$lastModified = $addressBook->lastModified();
6d9380f96   Cédric Dupont   Update sources OC...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
  		$response = new JSONResponse();
  		$response->setData(array('data' => $addressBook->getMetaData()));
  
  		if (!is_null($lastModified)) {
  			$response->addHeader('Cache-Control', 'private, must-revalidate');
  			$response->setLastModified(\DateTime::createFromFormat('U', $lastModified) ?: null);
  			$etag = md5($lastModified);
  			$response->setETag($etag);
  		}
  
  		return $response;
  	}
  
  	/**
  	 * @NoAdminRequired
  	 * @NoCSRFRequired
  	 */
  	public function getContacts() {
  		$params = $this->request->urlParams;
  
  		$addressBook = $this->app->getAddressBook($params['backend'], $params['addressBookId']);
  		$lastModified = $addressBook->lastModified();
d1bafeea1   Kload   [fix] Upgrade to ...
106
107
  		$etag = null;
  		$response = new JSONResponse();
6d9380f96   Cédric Dupont   Update sources OC...
108
  		if (!is_null($lastModified)) {
d1bafeea1   Kload   [fix] Upgrade to ...
109
110
111
112
113
  			//$response->addHeader('Cache-Control', 'private, must-revalidate');
  			$response->setLastModified(\DateTime::createFromFormat('U', $lastModified) ?: null);
  			$etag = md5($lastModified);
  			$response->setETag($etag);
  		}
6d9380f96   Cédric Dupont   Update sources OC...
114
  		if (!is_null($etag)
d1bafeea1   Kload   [fix] Upgrade to ...
115
116
117
118
  			&& $this->request->getHeader('If-None-Match') === '"'.$etag.'"')
  		{
  			return $response->setStatus(Http::STATUS_NOT_MODIFIED);
  		} else {
6d9380f96   Cédric Dupont   Update sources OC...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  			switch ($this->request->method) {
  				case 'OPTIONS':
  					$options = array('GET', 'HEAD', 'OPTIONS');
  					if ($addressBook->hasPermission(\OCP\PERMISSION_DELETE)
  						&& $addressBook->getBackend()->hasAddressBookMethodFor(\OCP\PERMISSION_DELETE))
  					{
  						$options[] = 'DELETE';
  					}
  					if ($addressBook->hasPermission(\OCP\PERMISSION_UPDATE)
  						&& $addressBook->getBackend()->hasAddressBookMethodFor(\OCP\PERMISSION_UPDATE))
  					{
  						$options[] = 'POST';
  					}
  					$response->addHeader('Allow' , implode(',', $options));
  					return $response;
  				case 'HEAD':
  					return $response;
  				case 'GET':
  					$contacts = array();
  
  					foreach ($addressBook->getChildren() as $i => $contact) {
  						$result = JSONSerializer::serializeContact($contact);
  						if ($result !== null) {
  							$contacts[] = $result;
  						}
  					}
  
  					return $response->setData(array('contacts' => $contacts));
d1bafeea1   Kload   [fix] Upgrade to ...
147
  			}
d1bafeea1   Kload   [fix] Upgrade to ...
148
149
150
151
152
153
154
155
156
157
158
159
  		}
  	}
  
  	/**
  	 * @NoAdminRequired
  	 */
  	public function addAddressBook() {
  		$params = $this->request->urlParams;
  
  		$response = new JSONResponse();
  
  		$backend = $this->app->getBackend($params['backend']);
6d9380f96   Cédric Dupont   Update sources OC...
160
161
  
  		if (!$backend->hasAddressBookMethodFor(\OCP\PERMISSION_CREATE)) {
d1bafeea1   Kload   [fix] Upgrade to ...
162
163
  			throw new \Exception('This backend does not support adding address books', 501);
  		}
6d9380f96   Cédric Dupont   Update sources OC...
164

d1bafeea1   Kload   [fix] Upgrade to ...
165
166
  		try {
  			$id = $backend->createAddressBook($this->request->post);
6d9380f96   Cédric Dupont   Update sources OC...
167
  		} catch(\Exception $e) {
d1bafeea1   Kload   [fix] Upgrade to ...
168
169
  			return $response->bailOut($e->getMessage());
  		}
6d9380f96   Cédric Dupont   Update sources OC...
170
171
  
  		if ($id === false) {
d1bafeea1   Kload   [fix] Upgrade to ...
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  			return $response->bailOut(App::$l10n->t('Error creating address book'));
  		}
  
  		return $response->setStatus('201')->setParams($backend->getAddressBook($id));
  	}
  
  	/**
  	 * @NoAdminRequired
  	 */
  	public function updateAddressBook() {
  		$params = $this->request->urlParams;
  
  		$response = new JSONResponse();
  
  		$addressBook = $this->app->getAddressBook($params['backend'], $params['addressBookId']);
6d9380f96   Cédric Dupont   Update sources OC...
187
  		$addressBook->update($this->request['properties']);
d1bafeea1   Kload   [fix] Upgrade to ...
188
189
190
191
192
193
194
195
196
197
198
199
  		return $response->setParams($addressBook->getMetaData());
  	}
  
  	/**
  	 * @NoAdminRequired
  	 */
  	public function deleteAddressBook() {
  		$params = $this->request->urlParams;
  
  		$response = new JSONResponse();
  
  		$backend = $this->app->getBackend($params['backend']);
6d9380f96   Cédric Dupont   Update sources OC...
200
201
  		if (!$backend->hasAddressBookMethodFor(\OCP\PERMISSION_DELETE)) {
  			throw new \Exception(App::$l10n->t(
d1bafeea1   Kload   [fix] Upgrade to ...
202
  				'The "%s" backend does not support deleting address books', array($backend->name)
6d9380f96   Cédric Dupont   Update sources OC...
203
  			), 501);
d1bafeea1   Kload   [fix] Upgrade to ...
204
205
206
  		}
  
  		$addressBookInfo = $backend->getAddressBook($params['addressBookId']);
6d9380f96   Cédric Dupont   Update sources OC...
207
208
209
210
211
  		if (!$addressBookInfo['permissions'] & \OCP\PERMISSION_DELETE) {
  			throw new \Exception(App::$l10n->t(
  				'You do not have permissions to delete the "%s" address book',
  				array($addressBookInfo['displayname'])
  			), 403);
d1bafeea1   Kload   [fix] Upgrade to ...
212
  		}
6d9380f96   Cédric Dupont   Update sources OC...
213
214
215
216
  		if (!$backend->deleteAddressBook($params['addressBookId'])) {
  			throw new \Exception(App::$l10n->t(
  				'Error deleting address book'
  			), 500);
d1bafeea1   Kload   [fix] Upgrade to ...
217
  		}
6d9380f96   Cédric Dupont   Update sources OC...
218

d1bafeea1   Kload   [fix] Upgrade to ...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
  		\OCP\Config::setUserValue($this->api->getUserId(), 'contacts', 'last_address_book_deleted', time());
  		return $response;
  	}
  
  	/**
  	 * @NoAdminRequired
  	 */
  	public function activateAddressBook() {
  		$params = $this->request->urlParams;
  
  		$response = new JSONResponse();
  
  		$addressBook = $this->app->getAddressBook($params['backend'], $params['addressBookId']);
  
  		$addressBook->setActive($this->request->post['state']);
  
  		return $response;
  	}
  
  	/**
  	 * @NoAdminRequired
  	 */
  	public function addChild() {
  		$params = $this->request->urlParams;
  
  		$response = new JSONResponse();
  
  		$addressBook = $this->app->getAddressBook($params['backend'], $params['addressBookId']);
  
  		try {
  			$id = $addressBook->addChild();
6d9380f96   Cédric Dupont   Update sources OC...
250
  		} catch(\Exception $e) {
d1bafeea1   Kload   [fix] Upgrade to ...
251
252
  			return $response->bailOut($e->getMessage());
  		}
6d9380f96   Cédric Dupont   Update sources OC...
253
  		if ($id === false) {
d1bafeea1   Kload   [fix] Upgrade to ...
254
255
256
257
  			return $response->bailOut(App::$l10n->t('Error creating contact.'));
  		}
  
  		$contact = $addressBook->getChild($id);
6d9380f96   Cédric Dupont   Update sources OC...
258
259
260
261
262
263
264
265
266
267
  
  		$serialized = JSONSerializer::serializeContact($contact);
  
  		if (is_null($serialized)) {
  			throw new \Exception(App::$l10n->t(
  				'Error creating contact'
  			));
  		}
  
  		$response->setStatus('201')->setETag($contact->getETag());
d1bafeea1   Kload   [fix] Upgrade to ...
268
269
270
271
272
273
274
275
276
277
  		$response->addHeader('Location',
  			\OCP\Util::linkToRoute(
  				'contacts_contact_get',
  				array(
  					'backend' => $params['backend'],
  					'addressBookId' => $params['addressBookId'],
  					'contactId' => $id
  				)
  			)
  		);
6d9380f96   Cédric Dupont   Update sources OC...
278
  		return $response->setParams($serialized);
d1bafeea1   Kload   [fix] Upgrade to ...
279
280
281
282
283
284
285
286
287
288
289
  	}
  
  	/**
  	 * @NoAdminRequired
  	 */
  	public function deleteChild() {
  		$params = $this->request->urlParams;
  
  		$response = new JSONResponse();
  
  		$addressBook = $this->app->getAddressBook($params['backend'], $params['addressBookId']);
6d9380f96   Cédric Dupont   Update sources OC...
290
  		$result = $addressBook->deleteChild($params['contactId']);
d1bafeea1   Kload   [fix] Upgrade to ...
291

6d9380f96   Cédric Dupont   Update sources OC...
292
293
294
295
  		if ($result === false) {
  			throw new \Exception(App::$l10n->t(
  				'Error deleting contact'
  			), 500);
d1bafeea1   Kload   [fix] Upgrade to ...
296
  		}
6d9380f96   Cédric Dupont   Update sources OC...
297

d1bafeea1   Kload   [fix] Upgrade to ...
298
299
300
301
302
303
304
305
306
307
308
309
310
  		return $response->setStatus('204');
  	}
  
  	/**
  	 * @NoAdminRequired
  	 */
  	public function deleteChildren() {
  		$params = $this->request->urlParams;
  
  		$response = new JSONResponse();
  
  		$addressBook = $this->app->getAddressBook($params['backend'], $params['addressBookId']);
  		$contacts = $this->request->post['contacts'];
6d9380f96   Cédric Dupont   Update sources OC...
311
  		$result = $addressBook->deleteChildren($contacts);
d1bafeea1   Kload   [fix] Upgrade to ...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
  
  		return $response->setParams(array('result' => $result));
  	}
  
  	/**
  	 * @NoAdminRequired
  	 */
  	public function moveChild() {
  		$params = $this->request->urlParams;
  		$targetInfo = $this->request->post['target'];
  
  		$response = new JSONResponse();
  
  		// TODO: Check if the backend supports move (is 'local' or 'shared') and use that operation instead.
  		// If so, set status 204 and don't return the serialized contact.
  		$fromAddressBook = $this->app->getAddressBook($params['backend'], $params['addressBookId']);
  		$targetAddressBook = $this->app->getAddressBook($targetInfo['backend'], $targetInfo['id']);
  		$contact = $fromAddressBook->getChild($params['contactId']);
6d9380f96   Cédric Dupont   Update sources OC...
330
331
332
333
334
  
  		if (!$contact) {
  			throw new \Exception(App::$l10n->t(
  				'Error retrieving contact'
  			), 500);
d1bafeea1   Kload   [fix] Upgrade to ...
335
  		}
6d9380f96   Cédric Dupont   Update sources OC...
336
337
338
339
  
  		$contactId = $targetAddressBook->addChild($contact);
  
  		// Retrieve the contact again to be sure it's in sync
d1bafeea1   Kload   [fix] Upgrade to ...
340
  		$contact = $targetAddressBook->getChild($contactId);
6d9380f96   Cédric Dupont   Update sources OC...
341
342
343
344
345
  
  		if (!$contact) {
  			throw new \Exception(App::$l10n->t(
  				'Error saving contact'
  			), 500);
d1bafeea1   Kload   [fix] Upgrade to ...
346
  		}
6d9380f96   Cédric Dupont   Update sources OC...
347
348
  
  		if (!$fromAddressBook->deleteChild($params['contactId'])) {
d1bafeea1   Kload   [fix] Upgrade to ...
349
350
351
  			// Don't bail out because we have to return the contact
  			return $response->debug(App::$l10n->t('Error removing contact from other address book.'));
  		}
6d9380f96   Cédric Dupont   Update sources OC...
352
353
354
355
356
357
358
359
360
361
  
  		$serialized = JSONSerializer::serializeContact($contact);
  
  		if (is_null($serialized)) {
  			throw new \Exception(App::$l10n->t(
  				'Error getting moved contact'
  			));
  		}
  
  		return $response->setParams($serialized);
d1bafeea1   Kload   [fix] Upgrade to ...
362
363
364
  	}
  
  }