This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * ownCloud - Database backend for Contacts |
||
4 | * |
||
5 | * @author Thomas Tanghus |
||
6 | * @copyright 2013-2014 Thomas Tanghus ([email protected]) |
||
7 | * |
||
8 | * This library is free software; you can redistribute it and/or |
||
9 | * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
||
10 | * License as published by the Free Software Foundation; either |
||
11 | * version 3 of the License, or any later version. |
||
12 | * |
||
13 | * This library is distributed in the hope that it will be useful, |
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | * GNU AFFERO GENERAL PUBLIC LICENSE for more details. |
||
17 | * |
||
18 | * You should have received a copy of the GNU Affero General Public |
||
19 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
||
20 | * |
||
21 | */ |
||
22 | |||
23 | namespace OCA\Contacts\Backend; |
||
24 | |||
25 | use OCA\Contacts\Contact; |
||
26 | use OCA\Contacts\VObject\VCard; |
||
27 | use OCA\Contacts\Utils\Properties; |
||
28 | use Sabre\VObject\Reader; |
||
29 | |||
30 | /** |
||
31 | * Backend class for a users own contacts. |
||
32 | */ |
||
33 | |||
34 | class Database extends AbstractBackend { |
||
35 | |||
36 | static private $preparedQueries = array(); |
||
37 | |||
38 | /** |
||
39 | * The name of the backend. |
||
40 | * |
||
41 | * @var string |
||
42 | */ |
||
43 | public $name = 'local'; |
||
44 | |||
45 | /** |
||
46 | * The cached address books. |
||
47 | * |
||
48 | * @var array[] |
||
49 | */ |
||
50 | public $addressBooks; |
||
51 | |||
52 | /** |
||
53 | * The table that holds the address books. |
||
54 | * |
||
55 | * @var string |
||
56 | */ |
||
57 | public $addressBooksTableName; |
||
58 | |||
59 | /** |
||
60 | * The table that holds the contact vCards. |
||
61 | * |
||
62 | * @var string |
||
63 | */ |
||
64 | public $cardsTableName; |
||
65 | |||
66 | /** |
||
67 | * The table that holds the indexed vCard properties. |
||
68 | * |
||
69 | * @var string |
||
70 | */ |
||
71 | public $indexTableName; |
||
72 | |||
73 | /** |
||
74 | * Sets up the backend |
||
75 | * |
||
76 | */ |
||
77 | 2 | public function __construct( |
|
78 | $userid = null, |
||
79 | $options = array( |
||
80 | 'addressBooksTableName' => '*PREFIX*contacts_addressbooks', |
||
81 | 'cardsTableName' => '*PREFIX*contacts_cards', |
||
82 | 'indexTableName' => '*PREFIX*contacts_cards_properties' |
||
83 | ) |
||
84 | ) { |
||
85 | 2 | $this->userid = $userid ? $userid : \OCP\User::getUser(); |
|
86 | 2 | $this->addressBooksTableName = $options['addressBooksTableName']; |
|
87 | 2 | $this->cardsTableName = $options['cardsTableName']; |
|
88 | 2 | $this->indexTableName = $options['indexTableName']; |
|
89 | 2 | $this->addressBooks = array(); |
|
90 | 2 | } |
|
91 | |||
92 | /** |
||
93 | * {@inheritdoc} |
||
94 | */ |
||
95 | public function getAddressBooksForUser(array $options = array()) { |
||
96 | |||
97 | try { |
||
98 | $result = $this->getPreparedQuery('getaddressbooksforuser') |
||
99 | ->execute(array($this->userid)); |
||
100 | |||
101 | View Code Duplication | if (\OCP\DB::isError($result)) { |
|
0 ignored issues
–
show
|
|||
102 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' |
||
103 | . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
104 | return $this->addressBooks; |
||
105 | } |
||
106 | |||
107 | } catch(\Exception $e) { |
||
108 | \OCP\Util::writeLog('contacts', __METHOD__.' exception: ' |
||
109 | . $e->getMessage(), \OCP\Util::ERROR); |
||
110 | return $this->addressBooks; |
||
111 | } |
||
112 | |||
113 | while ($row = $result->fetchRow()) { |
||
114 | $row['permissions'] = \OCP\PERMISSION_ALL; |
||
115 | $this->addressBooks[$row['id']] = $row; |
||
116 | } |
||
117 | |||
118 | // Create default address book if the list is empty |
||
119 | if (count($this->addressBooks) === 0) { |
||
120 | $l10n = \OCP\Util::getL10N('contacts'); |
||
121 | $id = $this->createAddressBook(array('displayname' => $l10n->t('Contacts'))); |
||
122 | if ($id !== false) { |
||
123 | $addressBook = $this->getAddressBook($id); |
||
124 | $this->addressBooks[$id] = $addressBook; |
||
125 | } else { |
||
126 | \OCP\Util::writeLog( |
||
127 | 'contacts', |
||
128 | __METHOD__ . ', Error creating default address book', |
||
129 | \OCP\Util::ERROR |
||
130 | ); |
||
131 | } |
||
132 | } |
||
133 | |||
134 | return $this->addressBooks; |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * {@inheritdoc} |
||
139 | */ |
||
140 | 2 | public function getAddressBook($addressBookId, array $options = array()) { |
|
141 | 2 | $owner = isset($options['shared_by']) ? $options['shared_by'] : $this->userid; |
|
142 | //\OCP\Util::writeLog('contacts', __METHOD__.' id: ' |
||
143 | // . $addressBookId, \OCP\Util::DEBUG); |
||
144 | 2 | if ($this->addressBooks && isset($this->addressBooks[$addressBookId])) { |
|
0 ignored issues
–
show
The expression
$this->addressBooks of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
145 | //print(__METHOD__ . ' ' . __LINE__ .' addressBookInfo: ' . print_r($this->addressBooks[$addressBookId], true)); |
||
146 | return $this->addressBooks[$addressBookId]; |
||
147 | } |
||
148 | |||
149 | // Hmm, not found. Lets query the db. |
||
150 | try { |
||
151 | 2 | $result = $this->getPreparedQuery('getaddressbook')->execute(array($addressBookId, $owner)); |
|
152 | |||
153 | 2 | View Code Duplication | if (\OCP\DB::isError($result)) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
154 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' |
||
155 | . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
156 | return null; |
||
157 | } |
||
158 | |||
159 | 2 | $row = $result->fetchRow(); |
|
160 | |||
161 | 2 | if (!$row) { |
|
162 | return null; |
||
163 | } |
||
164 | |||
165 | 2 | $row['permissions'] = \OCP\PERMISSION_ALL; |
|
166 | 2 | $row['backend'] = $this->name; |
|
167 | 2 | $this->addressBooks[$addressBookId] = $row; |
|
168 | 2 | return $row; |
|
169 | |||
170 | } catch(\Exception $e) { |
||
171 | \OCP\Util::writeLog('contacts', __METHOD__.' exception: ' |
||
172 | . $e->getMessage(), \OCP\Util::ERROR); |
||
173 | return null; |
||
174 | } |
||
175 | |||
176 | } |
||
177 | |||
178 | /** |
||
179 | * {@inheritdoc} |
||
180 | * @param string|false $addressBookId |
||
181 | */ |
||
182 | public function hasAddressBook($addressBookId) { |
||
183 | |||
184 | // First check if it's already cached |
||
185 | if ($this->addressBooks && isset($this->addressBooks[$addressBookId])) { |
||
0 ignored issues
–
show
The expression
$this->addressBooks of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
186 | return true; |
||
187 | } |
||
188 | |||
189 | return count($this->getAddressBook($addressBookId)) > 0; |
||
0 ignored issues
–
show
It seems like
$addressBookId defined by parameter $addressBookId on line 182 can also be of type false ; however, OCA\Contacts\Backend\Database::getAddressBook() does only seem to accept string , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Updates an addressbook's properties |
||
194 | * |
||
195 | * @param string $addressBookId |
||
196 | * @param array $changes |
||
197 | * @return bool |
||
198 | */ |
||
199 | 2 | public function updateAddressBook($addressBookId, array $changes) { |
|
200 | |||
201 | if (count($changes) === 0) { |
||
202 | return false; |
||
203 | } |
||
204 | |||
205 | $query = 'UPDATE `' . $this->addressBooksTableName . '` SET '; |
||
206 | |||
207 | $updates = array(); |
||
208 | |||
209 | View Code Duplication | if (isset($changes['displayname'])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
210 | $query .= '`displayname` = ?, '; |
||
211 | $updates[] = $changes['displayname']; |
||
212 | |||
213 | if ($this->addressBooks && isset($this->addressBooks[$addressBookId])) { |
||
0 ignored issues
–
show
The expression
$this->addressBooks of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
214 | $this->addressBooks[$addressBookId]['displayname'] = $changes['displayname']; |
||
215 | } |
||
216 | |||
217 | } |
||
218 | |||
219 | View Code Duplication | if (isset($changes['description'])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
220 | |||
221 | $query .= '`description` = ?, '; |
||
222 | $updates[] = $changes['description']; |
||
223 | |||
224 | if ($this->addressBooks && isset($this->addressBooks[$addressBookId])) { |
||
0 ignored issues
–
show
The expression
$this->addressBooks of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
225 | $this->addressBooks[$addressBookId]['description'] = $changes['description']; |
||
226 | } |
||
227 | |||
228 | } |
||
229 | |||
230 | $query .= '`ctag` = ? + 1 WHERE `id` = ?'; |
||
231 | $now = time(); |
||
232 | $updates[] = $now; |
||
233 | $updates[] = $addressBookId; |
||
234 | |||
235 | View Code Duplication | if ($this->addressBooks && isset($this->addressBooks[$addressBookId])) { |
|
0 ignored issues
–
show
The expression
$this->addressBooks of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
236 | $this->addressBooks[$addressBookId]['lastmodified'] = $now; |
||
237 | } |
||
238 | |||
239 | try { |
||
240 | |||
241 | $stmt = \OCP\DB::prepare($query); |
||
242 | $result = $stmt->execute($updates); |
||
243 | |||
244 | View Code Duplication | if (\OCP\DB::isError($result)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
245 | \OCP\Util::writeLog('contacts', |
||
246 | 2 | __METHOD__. 'DB error: ' |
|
247 | . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
248 | return false; |
||
249 | } |
||
250 | |||
251 | } catch(\Exception $e) { |
||
252 | \OCP\Util::writeLog('contacts', |
||
253 | __METHOD__ . ', exception: ' |
||
254 | . $e->getMessage(), \OCP\Util::ERROR); |
||
255 | return false; |
||
256 | } |
||
257 | |||
258 | return true; |
||
259 | } |
||
260 | |||
261 | /** |
||
262 | * Creates a new address book |
||
263 | * |
||
264 | * Supported properties are 'displayname', 'description' and 'uri'. |
||
265 | * 'uri' is supported to allow to add from CardDAV requests, and MUST |
||
266 | * be used for the 'uri' database field if present. |
||
267 | * 'displayname' MUST be present. |
||
268 | * |
||
269 | * @param array $properties |
||
270 | * @return string|false The ID if the newly created AddressBook or false on error. |
||
271 | */ |
||
272 | 2 | public function createAddressBook(array $properties) { |
|
273 | |||
274 | 2 | if (count($properties) === 0 || !isset($properties['displayname'])) { |
|
275 | return false; |
||
276 | 2 | } |
|
277 | |||
278 | 2 | $updates = array($this->userid, $properties['displayname']); |
|
279 | 2 | $updates[] = isset($properties['uri']) |
|
280 | 2 | ? $properties['uri'] |
|
281 | 2 | : $this->createAddressBookURI($properties['displayname']); |
|
282 | 2 | $updates[] = isset($properties['description']) ? $properties['description'] : ''; |
|
283 | 2 | $ctag = time(); |
|
284 | 2 | $updates[] = $ctag; |
|
285 | |||
286 | try { |
||
287 | 2 | $result = $this->getPreparedQuery('createaddressbook')->execute($updates); |
|
288 | |||
289 | 2 | View Code Duplication | if (\OCP\DB::isError($result)) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
290 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
291 | return false; |
||
292 | } |
||
293 | |||
294 | 2 | } catch(\Exception $e) { |
|
295 | \OCP\Util::writeLog('contacts', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); |
||
296 | return false; |
||
297 | } |
||
298 | |||
299 | 2 | $newid = \OCP\DB::insertid($this->addressBooksTableName); |
|
300 | |||
301 | 2 | if ($this->addressBooks) { |
|
0 ignored issues
–
show
The expression
$this->addressBooks of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
302 | $updates['id'] = $newid; |
||
303 | $updates['ctag'] = $ctag; |
||
304 | $updates['lastmodified'] = $ctag; |
||
305 | $updates['permissions'] = \OCP\PERMISSION_ALL; |
||
306 | $this->addressBooks[$newid] = $updates; |
||
307 | } |
||
308 | |||
309 | 2 | return $newid; |
|
310 | } |
||
311 | |||
312 | /** |
||
313 | * Get all contact ids from the address book to run pre_deleteAddressBook hook |
||
314 | * |
||
315 | * @param string $addressBookId |
||
316 | */ |
||
317 | 2 | protected function preDeleteAddressBook($addressBookId) { |
|
318 | // Get all contact ids for this address book |
||
319 | $ids = array(); |
||
320 | $result = null; |
||
321 | |||
322 | try { |
||
323 | |||
324 | $result = $this->getPreparedQuery('getcontactids') |
||
325 | ->execute(array($addressBookId)); |
||
326 | |||
327 | View Code Duplication | if (\OCP\DB::isError($result)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
328 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' |
||
329 | . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
330 | return false; |
||
331 | } |
||
332 | |||
333 | } catch(\Exception $e) { |
||
334 | \OCP\Util::writeLog('contacts', __METHOD__. |
||
335 | 2 | ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); |
|
336 | return false; |
||
337 | } |
||
338 | |||
339 | if (!is_null($result)) { |
||
340 | while ($id = $result->fetchOne()) { |
||
341 | $ids[] = $id; |
||
342 | 2 | } |
|
343 | |||
344 | \OCP\Util::emitHook('OCA\Contacts', 'pre_deleteAddressBook', |
||
345 | array('addressbookid' => $addressBookId, 'contactids' => $ids) |
||
346 | ); |
||
347 | } |
||
348 | } |
||
349 | |||
350 | /** |
||
351 | * Deletes an entire addressbook and all its contents |
||
352 | * |
||
353 | * NOTE: For efficience this method bypasses the cleanup hooks and deletes |
||
354 | * property indexes and category/group relations by itself. |
||
355 | * |
||
356 | * @param string $addressBookId |
||
357 | * @return bool |
||
358 | */ |
||
359 | public function deleteAddressBook($addressBookId) { |
||
360 | |||
361 | $this->preDeleteAddressBook($addressBookId); |
||
362 | |||
363 | try { |
||
364 | $this->getPreparedQuery('deleteaddressbookcontacts') |
||
365 | ->execute(array($addressBookId)); |
||
366 | } catch(\Exception $e) { |
||
367 | \OCP\Util::writeLog('contacts', __METHOD__. |
||
368 | ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); |
||
369 | return false; |
||
370 | } |
||
371 | |||
372 | try { |
||
373 | $this->getPreparedQuery('deleteaddressbook') |
||
374 | ->execute(array($addressBookId)); |
||
375 | } catch(\Exception $e) { |
||
376 | \OCP\Util::writeLog('contacts', __METHOD__. |
||
377 | ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); |
||
378 | return false; |
||
379 | } |
||
380 | |||
381 | if ($this->addressBooks && isset($this->addressBooks[$addressBookId])) { |
||
0 ignored issues
–
show
The expression
$this->addressBooks of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
382 | unset($this->addressBooks[$addressBookId]); |
||
383 | } |
||
384 | |||
385 | return true; |
||
386 | } |
||
387 | |||
388 | /** |
||
389 | * @brief Updates ctag for addressbook |
||
390 | * @param integer $id |
||
391 | * @return boolean |
||
392 | */ |
||
393 | 2 | public function setModifiedAddressBook($id) { |
|
394 | 2 | $ctag = time(); |
|
395 | 2 | $this->getPreparedQuery('touchaddressbook')->execute(array($ctag, $id)); |
|
396 | |||
397 | 2 | return true; |
|
398 | } |
||
399 | |||
400 | /** |
||
401 | * {@inheritdoc} |
||
402 | */ |
||
403 | 2 | public function lastModifiedAddressBook($addressBookId) { |
|
404 | |||
405 | 2 | View Code Duplication | if ($this->addressBooks && isset($this->addressBooks[$addressBookId])) { |
0 ignored issues
–
show
The expression
$this->addressBooks of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
406 | 2 | return $this->addressBooks[$addressBookId]['lastmodified']; |
|
407 | } |
||
408 | |||
409 | $addressBook = $this->getAddressBook($addressBookId); |
||
410 | if($addressBook) { |
||
411 | $this->addressBooks[$addressBookId] = $addressBook; |
||
412 | } |
||
413 | return $addressBook ? $addressBook['lastmodified'] : null; |
||
414 | } |
||
415 | |||
416 | /** |
||
417 | * Returns the number of contacts in a specific address book. |
||
418 | * |
||
419 | * @param string $addressBookId |
||
420 | * @return null|integer |
||
421 | */ |
||
422 | public function numContacts($addressBookId) { |
||
423 | |||
424 | $result = $this->getPreparedQuery('numcontacts')->execute(array($addressBookId)); |
||
425 | |||
426 | View Code Duplication | if (\OCP\DB::isError($result)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
427 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
428 | return null; |
||
429 | } |
||
430 | |||
431 | return (int)$result->fetchOne(); |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * {@inheritdoc} |
||
436 | */ |
||
437 | public function getContacts($addressBookId, array $options = array()) { |
||
438 | //\OCP\Util::writeLog('contacts', __METHOD__.' addressbookid: ' . $addressBookId, \OCP\Util::DEBUG); |
||
439 | $cards = array(); |
||
440 | try { |
||
441 | $queryIdentifier = (isset($options['omitdata']) && $options['omitdata'] === true) |
||
442 | ? 'getcontactsomitdata' |
||
443 | : 'getcontacts'; |
||
444 | |||
445 | $result = $this->getPreparedQuery($queryIdentifier, $options)->execute(array($addressBookId)); |
||
446 | |||
447 | View Code Duplication | if (\OCP\DB::isError($result)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
448 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
449 | return $cards; |
||
450 | } |
||
451 | |||
452 | } catch(\Exception $e) { |
||
453 | \OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR); |
||
454 | return $cards; |
||
455 | } |
||
456 | |||
457 | if (!is_null($result)) { |
||
458 | |||
459 | while ($row = $result->fetchRow()) { |
||
460 | $row['permissions'] = \OCP\PERMISSION_ALL; |
||
461 | $cards[] = $row; |
||
462 | } |
||
463 | |||
464 | } |
||
465 | |||
466 | return $cards; |
||
467 | } |
||
468 | |||
469 | /** |
||
470 | * Returns a specific contact. |
||
471 | * |
||
472 | * NOTE: The contact $id for Database and Shared backends can be an array containing |
||
473 | * either 'id' or 'uri' to be able to play seamlessly with the |
||
474 | * CardDAV backend. |
||
475 | * NOTE: $addressbookid isn't always used in the query, so there's no access control. |
||
476 | * This is because the groups backend - \OCP\Tags - doesn't no about parent collections |
||
477 | * only object IDs. Hence a hack is made with an optional 'noCollection'. |
||
478 | * |
||
479 | * @param string $addressBookId |
||
480 | * @param string|array $id Contact ID |
||
481 | * @param array $options - Optional (backend specific options) |
||
482 | * @return array|null |
||
483 | */ |
||
484 | 2 | public function getContact($addressBookId, $id, array $options = array()) { |
|
485 | //\OCP\Util::writeLog('contacts', __METHOD__.' identifier: ' . $addressBookId . ' / ' . $id, \OCP\Util::DEBUG); |
||
486 | |||
487 | // When dealing with tags we have no idea if which address book it's in |
||
488 | // but since they're all in the same table they have unique IDs anyway |
||
489 | 2 | $noCollection = isset($options['noCollection']) ? $options['noCollection'] : false; |
|
490 | |||
491 | 2 | $queryIdentifier = 'getcontact'; |
|
492 | 2 | $queries = array(); |
|
493 | |||
494 | // When querying from CardDAV we don't have the ID, only the uri |
||
495 | 2 | if (is_array($id)) { |
|
496 | if (isset($id['id'])) { |
||
497 | $queries[] = $id['id']; |
||
498 | $queryIdentifier .= 'byid'; |
||
499 | } elseif (isset($id['uri'])) { |
||
500 | $queries[] = $id['uri']; |
||
501 | $queryIdentifier .= 'byuri'; |
||
502 | } else { |
||
503 | throw new \Exception( |
||
504 | __METHOD__ . ' If second argument is an array, either \'id\' or \'uri\' has to be set.' |
||
505 | ); |
||
506 | } |
||
507 | } else { |
||
508 | 2 | if (!trim($id)) { |
|
509 | throw new \Exception( |
||
510 | __METHOD__ . ' Missing or empty second argument \'$id\'.' |
||
511 | ); |
||
512 | } |
||
513 | 2 | $queries[] = $id; |
|
514 | 2 | $queryIdentifier .= 'byid'; |
|
515 | } |
||
516 | |||
517 | 2 | if ($noCollection) { |
|
518 | $queryIdentifier .= 'nocollection'; |
||
519 | } else { |
||
520 | 2 | $queries[] = $addressBookId; |
|
521 | } |
||
522 | |||
523 | try { |
||
524 | //\OCP\Util::writeLog('contacts', __METHOD__.', identifier: '. $queryIdentifier . ', queries: ' . implode(',', $queries), \OCP\Util::DEBUG); |
||
525 | 2 | $result = $this->getPreparedQuery($queryIdentifier)->execute($queries); |
|
526 | |||
527 | 2 | View Code Duplication | if (\OCP\DB::isError($result)) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
528 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
529 | return null; |
||
530 | } |
||
531 | |||
532 | 2 | } catch (\Exception $e) { |
|
533 | \OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR); |
||
534 | \OCP\Util::writeLog('contacts', __METHOD__.', id: '. $id, \OCP\Util::DEBUG); |
||
535 | return null; |
||
536 | } |
||
537 | |||
538 | 2 | $row = $result->fetchRow(); |
|
539 | |||
540 | 2 | if (!$row) { |
|
541 | if (is_array($id)) { |
||
542 | $idstr = implode(", ", $id); |
||
543 | } else { |
||
544 | $idstr = $id; |
||
545 | } |
||
546 | \OCP\Util::writeLog('contacts', __METHOD__.', Not found, id: '. $idstr, \OCP\Util::DEBUG); |
||
547 | return null; |
||
548 | } |
||
549 | |||
550 | 2 | $row['permissions'] = \OCP\PERMISSION_ALL; |
|
551 | 2 | return $row; |
|
552 | } |
||
553 | |||
554 | /** |
||
555 | * @param string|false $addressBookId |
||
556 | * @param false|string $id |
||
557 | */ |
||
558 | public function hasContact($addressBookId, $id) { |
||
559 | try { |
||
560 | return $this->getContact($addressBookId, $id) !== null; |
||
0 ignored issues
–
show
It seems like
$addressBookId defined by parameter $addressBookId on line 558 can also be of type false ; however, OCA\Contacts\Backend\Database::getContact() does only seem to accept string , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() It seems like
$id defined by parameter $id on line 558 can also be of type false ; however, OCA\Contacts\Backend\Database::getContact() does only seem to accept string|array , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
561 | } catch (\Exception $e) { |
||
562 | \OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR); |
||
563 | return false; |
||
564 | } |
||
565 | } |
||
566 | |||
567 | /** |
||
568 | * Creates a new contact |
||
569 | * |
||
570 | * In the Database and Shared backends contact be either a Contact object or a string |
||
571 | * with carddata to be able to play seamlessly with the CardDAV backend. |
||
572 | * If this method is called by the CardDAV backend, the carddata is already validated. |
||
573 | * NOTE: It's assumed that this method is called either from the CardDAV backend, the |
||
574 | * import script, or from the ownCloud web UI in which case either the uri parameter is |
||
575 | * set, or the contact has a UID. If neither is set, it will fail. |
||
576 | * |
||
577 | * @param string $addressBookId |
||
578 | * @param string $contact |
||
579 | * @param array $options - Optional (backend specific options) |
||
580 | * @return false|string The identifier for the new contact or false on error. |
||
581 | */ |
||
582 | 2 | public function createContact($addressBookId, $contact, array $options = array()) { |
|
583 | //\OCP\Util::writeLog('contacts', __METHOD__.' addressBookId: ' . $addressBookId, \OCP\Util::DEBUG); |
||
584 | |||
585 | 2 | $uri = isset($options['uri']) ? $options['uri'] : null; |
|
586 | |||
587 | 2 | View Code Duplication | if (!$contact instanceof VCard) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
588 | try { |
||
589 | $contact = Reader::read($contact); |
||
590 | } catch(\Exception $e) { |
||
591 | \OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR); |
||
592 | return false; |
||
593 | } |
||
594 | } |
||
595 | |||
596 | try { |
||
597 | 2 | $contact->validate(VCard::REPAIR|VCard::UPGRADE); |
|
0 ignored issues
–
show
It seems like
$contact is not always an object, but can also be of type null . Maybe add an additional type check?
If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe: function someFunction(A $objectMaybe = null)
{
if ($objectMaybe instanceof A) {
$objectMaybe->doSomething();
}
}
![]() |
|||
598 | 2 | } catch (\Exception $e) { |
|
599 | \OCP\Util::writeLog('contacts', __METHOD__ . ' ' . |
||
600 | 'Error validating vcard: ' . $e->getMessage(), \OCP\Util::ERROR); |
||
601 | return false; |
||
602 | } |
||
603 | |||
604 | 2 | $uri = is_null($uri) ? $this->uniqueURI($addressBookId, $contact->UID . '.vcf') : $uri; |
|
605 | 2 | $now = new \DateTime; |
|
606 | 2 | $contact->REV = $now->format(\DateTime::W3C); |
|
607 | |||
608 | 2 | $appinfo = \OCP\App::getAppInfo('contacts'); |
|
609 | 2 | $appversion = \OCP\App::getAppVersion('contacts'); |
|
610 | 2 | $prodid = '-//ownCloud//NONSGML ' . $appinfo['name'] . ' ' . $appversion.'//EN'; |
|
611 | 2 | $contact->PRODID = $prodid; |
|
612 | |||
613 | try { |
||
614 | 2 | $result = $this->getPreparedQuery('createcontact') |
|
615 | 2 | ->execute( |
|
616 | array( |
||
617 | 2 | $addressBookId, |
|
618 | 2 | (string)$contact->FN, |
|
619 | 2 | $contact->serialize(), |
|
620 | 2 | $uri, |
|
621 | 2 | time() |
|
622 | 2 | ) |
|
623 | 2 | ); |
|
624 | |||
625 | 2 | View Code Duplication | if (\OCP\DB::isError($result)) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
626 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
627 | return false; |
||
628 | } |
||
629 | |||
630 | 2 | } catch(\Exception $e) { |
|
631 | \OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR); |
||
632 | return false; |
||
633 | } |
||
634 | 2 | $newid = \OCP\DB::insertid($this->cardsTableName); |
|
635 | |||
636 | 2 | $this->setModifiedAddressBook($addressBookId); |
|
637 | 2 | \OCP\Util::emitHook('OCA\Contacts', 'post_createContact', |
|
638 | 2 | array('id' => $newid, 'addressBookId' => $addressBookId, 'backend' => $this->name, 'contact' => $contact) |
|
639 | 2 | ); |
|
640 | 2 | return (string)$newid; |
|
641 | } |
||
642 | |||
643 | /** |
||
644 | * Updates a contact |
||
645 | * |
||
646 | * @param string $addressBookId |
||
647 | * @param false|string $id Contact ID |
||
648 | * @param string $contact |
||
649 | * @param array $options - Optional (backend specific options) |
||
650 | * @see getContact |
||
651 | * @return bool |
||
652 | * @throws \Exception if $contact is a string but can't be parsed as a VCard |
||
653 | * @throws \Exception if the Contact to update couldn't be found |
||
654 | */ |
||
655 | public function updateContact($addressBookId, $id, $contact, array $options = array()) { |
||
656 | //\OCP\Util::writeLog('contacts', __METHOD__.' identifier: ' . $addressBookId . ' / ' . $id, \OCP\Util::DEBUG); |
||
657 | $noCollection = isset($options['noCollection']) ? $options['noCollection'] : false; |
||
658 | $isBatch = isset($options['isBatch']) ? $options['isBatch'] : false; |
||
659 | |||
660 | $updateRevision = true; |
||
661 | $isCardDAV = false; |
||
662 | |||
663 | View Code Duplication | if (!$contact instanceof VCard) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
664 | try { |
||
665 | $contact = Reader::read($contact); |
||
666 | } catch(\Exception $e) { |
||
667 | \OCP\Util::writeLog('contacts', __METHOD__.', exception: '.$e->getMessage(), \OCP\Util::ERROR); |
||
668 | return false; |
||
669 | } |
||
670 | } |
||
671 | |||
672 | if (is_array($id)) { |
||
673 | |||
674 | if (isset($id['id'])) { |
||
675 | $id = $id['id']; |
||
676 | } elseif (isset($id['uri'])) { |
||
677 | $updateRevision = false; |
||
678 | $isCardDAV = true; |
||
679 | $id = $this->getIdFromUri($addressBookId,$id['uri']); |
||
680 | |||
681 | if (is_null($id)) { |
||
682 | \OCP\Util::writeLog('contacts', __METHOD__ . ' Couldn\'t find contact', \OCP\Util::ERROR); |
||
683 | return false; |
||
684 | } |
||
685 | |||
686 | } else { |
||
687 | throw new \Exception( |
||
688 | __METHOD__ . ' If second argument is an array, either \'id\' or \'uri\' has to be set.' |
||
689 | ); |
||
690 | } |
||
691 | } |
||
692 | |||
693 | if ($updateRevision || !isset($contact->REV)) { |
||
694 | $now = new \DateTime; |
||
695 | $contact->REV = $now->format(\DateTime::W3C); |
||
696 | } |
||
697 | |||
698 | $data = $contact->serialize(); |
||
699 | |||
700 | if ($noCollection) { |
||
701 | $me = $this->getContact(null, $id, $options); |
||
702 | $addressBookId = $me['parent']; |
||
703 | } |
||
704 | |||
705 | $updates = array($contact->FN, $data, time(), $id, $addressBookId); |
||
706 | |||
707 | try { |
||
708 | |||
709 | $result = $this->getPreparedQuery('updatecontact')->execute($updates); |
||
710 | |||
711 | View Code Duplication | if (\OCP\DB::isError($result)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
712 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
713 | return false; |
||
714 | } |
||
715 | |||
716 | } catch(\Exception $e) { |
||
717 | \OCP\Util::writeLog('contacts', __METHOD__.', exception: ' |
||
718 | . $e->getMessage(), \OCP\Util::ERROR); |
||
719 | \OCP\Util::writeLog('contacts', __METHOD__.', id' . $id, \OCP\Util::DEBUG); |
||
720 | return false; |
||
721 | } |
||
722 | |||
723 | $this->setModifiedAddressBook($addressBookId); |
||
724 | |||
725 | if (!$isBatch) { |
||
726 | |||
727 | \OCP\Util::emitHook('OCA\Contacts', 'post_updateContact', |
||
728 | array( |
||
729 | 'backend' => $this->name, |
||
730 | 'addressBookId' => $addressBookId, |
||
731 | 'contactId' => $id, |
||
732 | 'contact' => $contact, |
||
733 | 'carddav' => $isCardDAV |
||
734 | ) |
||
735 | ); |
||
736 | |||
737 | } |
||
738 | |||
739 | return true; |
||
740 | } |
||
741 | |||
742 | /** |
||
743 | * Deletes a contact |
||
744 | * |
||
745 | * @param string $addressBookId |
||
746 | * @param false|string $id |
||
747 | * @param array $options - Optional (backend specific options) |
||
748 | * @see getContact |
||
749 | * @return bool |
||
750 | */ |
||
751 | public function deleteContact($addressBookId, $id, array $options = array()) { |
||
752 | // TODO: pass the uri in $options instead. |
||
753 | |||
754 | $noCollection = isset($options['noCollection']) ? $options['noCollection'] : false; |
||
755 | $isBatch = isset($options['isBatch']) ? $options['isBatch'] : false; |
||
756 | |||
757 | if (is_array($id)) { |
||
758 | |||
759 | if (isset($id['id'])) { |
||
760 | $id = $id['id']; |
||
761 | } elseif (isset($id['uri'])) { |
||
762 | |||
763 | $id = $this->getIdFromUri($addressBookId,$id['uri']); |
||
764 | |||
765 | if (is_null($id)) { |
||
766 | \OCP\Util::writeLog('contacts', __METHOD__ . ' Couldn\'t find contact', \OCP\Util::ERROR); |
||
767 | return false; |
||
768 | } |
||
769 | |||
770 | } else { |
||
771 | throw new \Exception( |
||
772 | __METHOD__ . ' If second argument is an array, either \'id\' or \'uri\' has to be set.' |
||
773 | ); |
||
774 | } |
||
775 | } |
||
776 | |||
777 | if (!$isBatch) { |
||
778 | \OCP\Util::emitHook('OCA\Contacts', 'pre_deleteContact', |
||
779 | array('id' => $id) |
||
780 | ); |
||
781 | } |
||
782 | |||
783 | if ($noCollection) { |
||
784 | $me = $this->getContact(null, $id, $options); |
||
785 | $addressBookId = $me['parent']; |
||
786 | } |
||
787 | |||
788 | try { |
||
789 | |||
790 | $result = $this->getPreparedQuery('deletecontact') |
||
791 | ->execute(array($id, $addressBookId)); |
||
792 | |||
793 | View Code Duplication | if (\OCP\DB::isError($result)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
794 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' |
||
795 | . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
796 | return false; |
||
797 | } |
||
798 | |||
799 | } catch(\Exception $e) { |
||
800 | \OCP\Util::writeLog('contacts', __METHOD__. |
||
801 | ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); |
||
802 | \OCP\Util::writeLog('contacts', __METHOD__.', id: ' |
||
803 | . $id, \OCP\Util::DEBUG); |
||
804 | return false; |
||
805 | } |
||
806 | |||
807 | $this->setModifiedAddressBook($addressBookId); |
||
808 | return true; |
||
809 | } |
||
810 | |||
811 | /** |
||
812 | * @brief Get the last modification time for a contact. |
||
813 | * |
||
814 | * Must return a UNIX time stamp or null if the backend |
||
815 | * doesn't support it. |
||
816 | * |
||
817 | * @param string $addressBookId |
||
818 | * @param mixed $id |
||
819 | * @returns int | null |
||
820 | */ |
||
821 | public function lastModifiedContact($addressBookId, $id) { |
||
822 | |||
823 | $contact = $this->getContact($addressBookId, $id); |
||
824 | return ($contact ? $contact['lastmodified'] : null); |
||
825 | |||
826 | } |
||
827 | |||
828 | /** |
||
829 | * @brief Get the contact id from the uri. |
||
830 | * |
||
831 | * @param string $addressBookId |
||
832 | * @returns int | null |
||
833 | */ |
||
834 | public function getIdFromUri($addressBookId,$uri) { |
||
835 | |||
836 | $stmt = $this->getPreparedQuery('contactidfromuri'); |
||
837 | $result = $stmt->execute(array($addressBookId,$uri)); |
||
838 | |||
839 | View Code Duplication | if (\OCP\DB::isError($result)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
840 | \OCP\Util::writeLog('contacts', __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); |
||
841 | return null; |
||
842 | } |
||
843 | |||
844 | $one = $result->fetchOne(); |
||
845 | |||
846 | View Code Duplication | if (!$one) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
847 | \OCP\Util::writeLog('contacts', __METHOD__.', Not found, uri: '. $uri, \OCP\Util::DEBUG); |
||
848 | return null; |
||
849 | } |
||
850 | |||
851 | return $one; |
||
852 | } |
||
853 | |||
854 | /** |
||
855 | * Create a unique URI based on the display name. |
||
856 | * |
||
857 | * @param string $displayName |
||
858 | * @return string |
||
859 | */ |
||
860 | 2 | private function createAddressBookURI($displayName) { |
|
861 | |||
862 | 2 | $name = str_replace(' ', '_', strtolower($displayName)); |
|
863 | |||
864 | try { |
||
865 | 2 | $stmt = $this->getPreparedQuery('addressbookuris'); |
|
866 | 2 | $result = $stmt->execute(array($this->userid)); |
|
867 | |||
868 | 2 | View Code Duplication | if (\OCP\DB::isError($result)) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
869 | \OCP\Util::writeLog('contacts', |
||
870 | __METHOD__. 'DB error: ' . \OC_DB::getErrorMessage($result), |
||
871 | \OCP\Util::ERROR |
||
872 | ); |
||
873 | return $name; |
||
874 | } |
||
875 | |||
876 | 2 | } catch(\Exception $e) { |
|
877 | \OCP\Util::writeLog('contacts', __METHOD__ . ' exception: ' . $e->getMessage(), \OCP\Util::ERROR); |
||
878 | return $name; |
||
879 | } |
||
880 | 2 | $uris = array(); |
|
881 | 2 | while ($row = $result->fetchRow()) { |
|
882 | $uris[] = $row['uri']; |
||
883 | } |
||
884 | |||
885 | 2 | $newname = $name; |
|
886 | $i = 1 |
||
887 | 2 | ; |
|
888 | 2 | while (in_array($newname, $uris)) { |
|
889 | $newname = $name.$i; |
||
890 | $i = $i + 1; |
||
891 | } |
||
892 | 2 | return $newname; |
|
893 | } |
||
894 | |||
895 | /** |
||
896 | * @brief Checks if a contact with the same URI already exist in the address book. |
||
897 | * @param string $addressBookId Address book ID. |
||
898 | * @param string $uri |
||
899 | * @returns string Unique URI |
||
900 | */ |
||
901 | 2 | protected function uniqueURI($addressBookId, $uri) { |
|
902 | 2 | $stmt = $this->getPreparedQuery('counturi'); |
|
903 | |||
904 | 2 | $result = $stmt->execute(array($addressBookId, $uri)); |
|
905 | 2 | $result = $result->fetchRow(); |
|
906 | |||
907 | 2 | if (is_array($result) && count($result) > 0 && $result['count'] > 0) { |
|
908 | |||
909 | while (true) { |
||
910 | $uri = Properties::generateUID() . '.vcf'; |
||
911 | $result = $stmt->execute(array($addressBookId, $uri)); |
||
912 | |||
913 | if (is_array($result) && count($result) > 0 && $result['count'] > 0) { |
||
914 | continue; |
||
915 | } else { |
||
916 | return $uri; |
||
917 | } |
||
918 | |||
919 | } |
||
920 | } |
||
921 | |||
922 | 2 | return $uri; |
|
923 | } |
||
924 | |||
925 | /** |
||
926 | * Collect (nearly) all queries in one place |
||
927 | * |
||
928 | * @param string $identifier |
||
929 | * @param array $options Can be used for e.g. offset/limit |
||
930 | * @throws \Exception If $identifier isn't known |
||
931 | * @return \OC_DB_StatementWrapper |
||
932 | */ |
||
933 | 2 | protected function getPreparedQuery($identifier, array $options = array()) { |
|
934 | |||
935 | 2 | if (isset(self::$preparedQueries[$identifier])) { |
|
936 | 2 | return self::$preparedQueries[$identifier]; |
|
937 | } |
||
938 | |||
939 | 1 | $args = array(); |
|
940 | |||
941 | switch ($identifier) { |
||
942 | |||
943 | 1 | case 'getaddressbooksforuser': |
|
944 | $args[] = 'SELECT `id`, `displayname`, `description`, `ctag`' |
||
945 | . ' AS `lastmodified`, `userid` AS `owner`, `uri` FROM `' |
||
946 | . $this->addressBooksTableName |
||
947 | . '` WHERE `userid` = ? ORDER BY `displayname`'; |
||
948 | break; |
||
949 | 1 | case 'getaddressbook': |
|
950 | 1 | $args[] = 'SELECT `id`, `displayname`, `description`, ' |
|
951 | . '`userid` AS `owner`, `ctag` AS `lastmodified`, `uri` FROM `' |
||
952 | 1 | . $this->addressBooksTableName |
|
953 | 1 | . '` WHERE `id` = ? AND `userid` = ?'; |
|
954 | 1 | break; |
|
955 | 1 | case 'createaddressbook': |
|
956 | 1 | $args[] = 'INSERT INTO `' |
|
957 | 1 | . $this->addressBooksTableName . '` ' |
|
958 | 1 | . '(`userid`,`displayname`,`uri`,`description`,`ctag`) ' |
|
959 | 1 | . 'VALUES(?,?,?,?,?)'; |
|
960 | 1 | break; |
|
961 | 1 | case 'deleteaddressbookcontacts': |
|
962 | $args[] = 'DELETE FROM `' . $this->cardsTableName |
||
963 | . '` WHERE `addressbookid` = ?'; |
||
964 | break; |
||
965 | 1 | case 'deleteaddressbook': |
|
966 | $args[] = 'DELETE FROM `' |
||
967 | . $this->addressBooksTableName . '` WHERE `id` = ?'; |
||
968 | break; |
||
969 | 1 | case 'touchaddressbook': |
|
970 | 1 | $args[] = 'UPDATE `' . $this->addressBooksTableName |
|
971 | 1 | . '` SET `ctag` = ? + 1 WHERE `id` = ?'; |
|
972 | 1 | break; |
|
973 | 1 | case 'counturi': |
|
974 | 1 | $args[] = 'SELECT COUNT(*) AS `count` FROM `' |
|
975 | 1 | . $this->cardsTableName |
|
976 | 1 | . '` WHERE `addressbookid` = ? AND `uri` = ?'; |
|
977 | 1 | break; |
|
978 | 1 | case 'addressbookuris': |
|
979 | 1 | $args[] = 'SELECT `uri` FROM `' |
|
980 | 1 | . $this->addressBooksTableName . '` WHERE `userid` = ? '; |
|
981 | 1 | break; |
|
982 | 1 | case 'contactidfromuri': |
|
983 | $args[] = 'SELECT `id` FROM `' |
||
984 | . $this->cardsTableName |
||
985 | . '` WHERE `addressbookid` = ? AND `uri` = ? '; |
||
986 | break; |
||
987 | 1 | case 'deletecontact': |
|
988 | $args[] = 'DELETE FROM `' |
||
989 | . $this->cardsTableName |
||
990 | . '` WHERE `id` = ? AND `addressbookid` = ?'; |
||
991 | break; |
||
992 | 1 | case 'updatecontact': |
|
993 | $args[] = 'UPDATE `' . $this->cardsTableName |
||
994 | . '` SET `fullname` = ?,`carddata` = ?, `lastmodified` = ?' |
||
995 | . ' WHERE `id` = ? AND `addressbookid` = ?'; |
||
996 | break; |
||
997 | 1 | case 'createcontact': |
|
998 | 1 | $args[] = 'INSERT INTO `' |
|
999 | 1 | . $this->cardsTableName |
|
1000 | 1 | . '` (`addressbookid`,`fullname`,`carddata`,`uri`,`lastmodified`) ' |
|
1001 | 1 | . ' VALUES(?,?,?,?,?)'; |
|
1002 | 1 | break; |
|
1003 | 1 | case 'getcontactbyid': |
|
1004 | 1 | $args[] = 'SELECT `id`, `uri`, `carddata`, `lastmodified`, ' |
|
1005 | . '`addressbookid` AS `parent`, `fullname` AS `displayname` FROM `' |
||
1006 | 1 | . $this->cardsTableName |
|
1007 | 1 | . '` WHERE `id` = ? AND `addressbookid` = ?'; |
|
1008 | 1 | break; |
|
1009 | case 'getcontactbyuri': |
||
1010 | $args[] = 'SELECT `id`, `uri`, `carddata`, `lastmodified`, ' |
||
1011 | . '`addressbookid` AS `parent`, `fullname` AS `displayname` FROM `' |
||
1012 | . $this->cardsTableName |
||
1013 | . '` WHERE `uri` = ? AND `addressbookid` = ?'; |
||
1014 | break; |
||
1015 | case 'getcontactbyidnocollection': |
||
1016 | $args[] = 'SELECT `id`, `uri`, `carddata`, `lastmodified`, ' |
||
1017 | . '`addressbookid` AS `parent`, `fullname` AS `displayname` FROM `' |
||
1018 | . $this->cardsTableName . '` WHERE `id` = ?'; |
||
1019 | break; |
||
1020 | case 'getcontactbyurinocollection': |
||
1021 | $args[] = 'SELECT `id`, `uri`, `carddata`, `lastmodified`, ' |
||
1022 | . '`addressbookid` AS `parent`, `fullname` AS `displayname` FROM `' |
||
1023 | . $this->cardsTableName . '` WHERE `uri` = ?'; |
||
1024 | break; |
||
1025 | case 'getcontactids': |
||
1026 | $args[] = 'SELECT `id` FROM `' |
||
1027 | . $this->cardsTableName . '` WHERE `addressbookid` = ?'; |
||
1028 | break; |
||
1029 | View Code Duplication | case 'getcontacts': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1030 | $args[] = 'SELECT `id`, `uri`, `carddata`, `lastmodified`, ' |
||
1031 | . '`addressbookid` AS `parent`, `fullname` AS `displayname` FROM `' |
||
1032 | . $this->cardsTableName . '` WHERE `addressbookid` = ?'; |
||
1033 | $args[] = isset($options['limit']) ? $options['limit'] : null; |
||
1034 | $args[] = isset($options['offset']) ? $options['offset'] : null; |
||
1035 | break; |
||
1036 | View Code Duplication | case 'getcontactsomitdata': |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1037 | $args[] = 'SELECT `id`, `uri`, `lastmodified`, ' |
||
1038 | . '`addressbookid` AS `parent`, `fullname` AS `displayname` FROM `' |
||
1039 | . $this->cardsTableName . '` WHERE `addressbookid` = ?'; |
||
1040 | $args[] = isset($options['limit']) ? $options['limit'] : null; |
||
1041 | $args[] = isset($options['offset']) ? $options['offset'] : null; |
||
1042 | break; |
||
1043 | case 'numcontacts': |
||
1044 | $args[] = 'SELECT COUNT(*) AS `count` FROM `' |
||
1045 | . $this->cardsTableName . '` WHERE `addressbookid` = ?'; |
||
1046 | break; |
||
1047 | default: |
||
1048 | throw new \Exception('Unknown query identifier: ' . $identifier); |
||
1049 | |||
1050 | } |
||
1051 | |||
1052 | 1 | self::$preparedQueries[$identifier] = call_user_func_array('\OCP\DB::prepare', $args); |
|
1053 | |||
1054 | 1 | return self::$preparedQueries[$identifier]; |
|
1055 | } |
||
1056 | |||
1057 | public function getSearchProvider($addressbook) { |
||
1058 | return new \OCA\Contacts\AddressbookProvider($addressbook); |
||
1059 | } |
||
1060 | |||
1061 | } |
||
1062 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.