Completed
Pull Request — master (#8786)
by Morris
82:03 queued 65:47
created
lib/public/DB.php 1 patch
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -46,48 +46,48 @@
 block discarded – undo
46 46
  * @since 4.5.0
47 47
  */
48 48
 class DB {
49
-	/**
50
-	 * Prepare a SQL query
51
-	 * @param string $query Query string
52
-	 * @param int $limit Limit of the SQL statement
53
-	 * @param int $offset Offset of the SQL statement
54
-	 * @return \OC_DB_StatementWrapper prepared SQL query
55
-	 *
56
-	 * SQL query via Doctrine prepare(), needs to be execute()'d!
57
-	 * @deprecated 8.1.0 use prepare() of \OCP\IDBConnection - \OC::$server->getDatabaseConnection()
58
-	 * @since 4.5.0
59
-	 */
60
-	static public function prepare( $query, $limit=null, $offset=null ) {
61
-		return \OC_DB::prepare($query, $limit, $offset);
62
-	}
49
+    /**
50
+     * Prepare a SQL query
51
+     * @param string $query Query string
52
+     * @param int $limit Limit of the SQL statement
53
+     * @param int $offset Offset of the SQL statement
54
+     * @return \OC_DB_StatementWrapper prepared SQL query
55
+     *
56
+     * SQL query via Doctrine prepare(), needs to be execute()'d!
57
+     * @deprecated 8.1.0 use prepare() of \OCP\IDBConnection - \OC::$server->getDatabaseConnection()
58
+     * @since 4.5.0
59
+     */
60
+    static public function prepare( $query, $limit=null, $offset=null ) {
61
+        return \OC_DB::prepare($query, $limit, $offset);
62
+    }
63 63
 
64
-	/**
65
-	 * Start a transaction
66
-	 * @deprecated 8.1.0 use beginTransaction() of \OCP\IDBConnection - \OC::$server->getDatabaseConnection()
67
-	 * @since 4.5.0
68
-	 */
69
-	public static function beginTransaction() {
70
-		\OC::$server->getDatabaseConnection()->beginTransaction();
71
-	}
64
+    /**
65
+     * Start a transaction
66
+     * @deprecated 8.1.0 use beginTransaction() of \OCP\IDBConnection - \OC::$server->getDatabaseConnection()
67
+     * @since 4.5.0
68
+     */
69
+    public static function beginTransaction() {
70
+        \OC::$server->getDatabaseConnection()->beginTransaction();
71
+    }
72 72
 
73
-	/**
74
-	 * Commit the database changes done during a transaction that is in progress
75
-	 * @deprecated 8.1.0 use commit() of \OCP\IDBConnection - \OC::$server->getDatabaseConnection()
76
-	 * @since 4.5.0
77
-	 */
78
-	public static function commit() {
79
-		\OC::$server->getDatabaseConnection()->commit();
80
-	}
73
+    /**
74
+     * Commit the database changes done during a transaction that is in progress
75
+     * @deprecated 8.1.0 use commit() of \OCP\IDBConnection - \OC::$server->getDatabaseConnection()
76
+     * @since 4.5.0
77
+     */
78
+    public static function commit() {
79
+        \OC::$server->getDatabaseConnection()->commit();
80
+    }
81 81
 
82
-	/**
83
-	 * returns the error code and message as a string for logging
84
-	 * works with DoctrineException
85
-	 * @return string
86
-	 * @deprecated 8.1.0 use getError() of \OCP\IDBConnection - \OC::$server->getDatabaseConnection()
87
-	 * @since 6.0.0
88
-	 */
89
-	public static function getErrorMessage() {
90
-		return \OC::$server->getDatabaseConnection()->getError();
91
-	}
82
+    /**
83
+     * returns the error code and message as a string for logging
84
+     * works with DoctrineException
85
+     * @return string
86
+     * @deprecated 8.1.0 use getError() of \OCP\IDBConnection - \OC::$server->getDatabaseConnection()
87
+     * @since 6.0.0
88
+     */
89
+    public static function getErrorMessage() {
90
+        return \OC::$server->getDatabaseConnection()->getError();
91
+    }
92 92
 
93 93
 }
Please login to merge, or discard this patch.
lib/private/Tags.php 2 patches
Indentation   +803 added lines, -803 removed lines patch added patch discarded remove patch
@@ -50,807 +50,807 @@
 block discarded – undo
50 50
 
51 51
 class Tags implements \OCP\ITags {
52 52
 
53
-	/**
54
-	 * Tags
55
-	 *
56
-	 * @var array
57
-	 */
58
-	private $tags = array();
59
-
60
-	/**
61
-	 * Used for storing objectid/categoryname pairs while rescanning.
62
-	 *
63
-	 * @var array
64
-	 */
65
-	private static $relations = array();
66
-
67
-	/**
68
-	 * Type
69
-	 *
70
-	 * @var string
71
-	 */
72
-	private $type;
73
-
74
-	/**
75
-	 * User
76
-	 *
77
-	 * @var string
78
-	 */
79
-	private $user;
80
-
81
-	/**
82
-	 * Are we including tags for shared items?
83
-	 *
84
-	 * @var bool
85
-	 */
86
-	private $includeShared = false;
87
-
88
-	/**
89
-	 * The current user, plus any owners of the items shared with the current
90
-	 * user, if $this->includeShared === true.
91
-	 *
92
-	 * @var array
93
-	 */
94
-	private $owners = array();
95
-
96
-	/**
97
-	 * The Mapper we're using to communicate our Tag objects to the database.
98
-	 *
99
-	 * @var TagMapper
100
-	 */
101
-	private $mapper;
102
-
103
-	/**
104
-	 * The sharing backend for objects of $this->type. Required if
105
-	 * $this->includeShared === true to determine ownership of items.
106
-	 *
107
-	 * @var \OCP\Share_Backend
108
-	 */
109
-	private $backend;
110
-
111
-	const TAG_TABLE = '*PREFIX*vcategory';
112
-	const RELATION_TABLE = '*PREFIX*vcategory_to_object';
113
-
114
-	const TAG_FAVORITE = '_$!<Favorite>!$_';
115
-
116
-	/**
117
-	* Constructor.
118
-	*
119
-	* @param TagMapper $mapper Instance of the TagMapper abstraction layer.
120
-	* @param string $user The user whose data the object will operate on.
121
-	* @param string $type The type of items for which tags will be loaded.
122
-	* @param array $defaultTags Tags that should be created at construction.
123
-	* @param boolean $includeShared Whether to include tags for items shared with this user by others.
124
-	*/
125
-	public function __construct(TagMapper $mapper, $user, $type, $defaultTags = array(), $includeShared = false) {
126
-		$this->mapper = $mapper;
127
-		$this->user = $user;
128
-		$this->type = $type;
129
-		$this->includeShared = $includeShared;
130
-		$this->owners = array($this->user);
131
-		if ($this->includeShared) {
132
-			$this->owners = array_merge($this->owners, \OC\Share\Share::getSharedItemsOwners($this->user, $this->type, true));
133
-			$this->backend = \OC\Share\Share::getBackend($this->type);
134
-		}
135
-		$this->tags = $this->mapper->loadTags($this->owners, $this->type);
136
-
137
-		if(count($defaultTags) > 0 && count($this->tags) === 0) {
138
-			$this->addMultiple($defaultTags, true);
139
-		}
140
-	}
141
-
142
-	/**
143
-	* Check if any tags are saved for this type and user.
144
-	*
145
-	* @return boolean
146
-	*/
147
-	public function isEmpty() {
148
-		return count($this->tags) === 0;
149
-	}
150
-
151
-	/**
152
-	* Returns an array mapping a given tag's properties to its values:
153
-	* ['id' => 0, 'name' = 'Tag', 'owner' = 'User', 'type' => 'tagtype']
154
-	*
155
-	* @param string $id The ID of the tag that is going to be mapped
156
-	* @return array|false
157
-	*/
158
-	public function getTag($id) {
159
-		$key = $this->getTagById($id);
160
-		if ($key !== false) {
161
-			return $this->tagMap($this->tags[$key]);
162
-		}
163
-		return false;
164
-	}
165
-
166
-	/**
167
-	* Get the tags for a specific user.
168
-	*
169
-	* This returns an array with maps containing each tag's properties:
170
-	* [
171
-	* 	['id' => 0, 'name' = 'First tag', 'owner' = 'User', 'type' => 'tagtype'],
172
-	* 	['id' => 1, 'name' = 'Shared tag', 'owner' = 'Other user', 'type' => 'tagtype'],
173
-	* ]
174
-	*
175
-	* @return array
176
-	*/
177
-	public function getTags() {
178
-		if(!count($this->tags)) {
179
-			return array();
180
-		}
181
-
182
-		usort($this->tags, function($a, $b) {
183
-			return strnatcasecmp($a->getName(), $b->getName());
184
-		});
185
-		$tagMap = array();
186
-
187
-		foreach($this->tags as $tag) {
188
-			if($tag->getName() !== self::TAG_FAVORITE) {
189
-				$tagMap[] = $this->tagMap($tag);
190
-			}
191
-		}
192
-		return $tagMap;
193
-
194
-	}
195
-
196
-	/**
197
-	* Return only the tags owned by the given user, omitting any tags shared
198
-	* by other users.
199
-	*
200
-	* @param string $user The user whose tags are to be checked.
201
-	* @return array An array of Tag objects.
202
-	*/
203
-	public function getTagsForUser($user) {
204
-		return array_filter($this->tags,
205
-			function($tag) use($user) {
206
-				return $tag->getOwner() === $user;
207
-			}
208
-		);
209
-	}
210
-
211
-	/**
212
-	 * Get the list of tags for the given ids.
213
-	 *
214
-	 * @param array $objIds array of object ids
215
-	 * @return array|boolean of tags id as key to array of tag names
216
-	 * or false if an error occurred
217
-	 */
218
-	public function getTagsForObjects(array $objIds) {
219
-		$entries = array();
220
-
221
-		try {
222
-			$conn = \OC::$server->getDatabaseConnection();
223
-			$chunks = array_chunk($objIds, 900, false);
224
-			foreach ($chunks as $chunk) {
225
-				$result = $conn->executeQuery(
226
-					'SELECT `category`, `categoryid`, `objid` ' .
227
-					'FROM `' . self::RELATION_TABLE . '` r, `' . self::TAG_TABLE . '` ' .
228
-					'WHERE `categoryid` = `id` AND `uid` = ? AND r.`type` = ? AND `objid` IN (?)',
229
-					array($this->user, $this->type, $chunk),
230
-					array(null, null, IQueryBuilder::PARAM_INT_ARRAY)
231
-				);
232
-				while ($row = $result->fetch()) {
233
-					$objId = (int)$row['objid'];
234
-					if (!isset($entries[$objId])) {
235
-						$entries[$objId] = array();
236
-					}
237
-					$entries[$objId][] = $row['category'];
238
-				}
239
-				if ($result === null) {
240
-					\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
241
-					return false;
242
-				}
243
-			}
244
-		} catch(\Exception $e) {
245
-			\OC::$server->getLogger()->logException($e, [
246
-				'message' => __METHOD__,
247
-				'level' => \OCP\Util::ERROR,
248
-				'app' => 'core',
249
-			]);
250
-			return false;
251
-		}
252
-
253
-		return $entries;
254
-	}
255
-
256
-	/**
257
-	* Get the a list if items tagged with $tag.
258
-	*
259
-	* Throws an exception if the tag could not be found.
260
-	*
261
-	* @param string $tag Tag id or name.
262
-	* @return array|false An array of object ids or false on error.
263
-	* @throws \Exception
264
-	*/
265
-	public function getIdsForTag($tag) {
266
-		$result = null;
267
-		$tagId = false;
268
-		if(is_numeric($tag)) {
269
-			$tagId = $tag;
270
-		} elseif(is_string($tag)) {
271
-			$tag = trim($tag);
272
-			if($tag === '') {
273
-				\OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG);
274
-				return false;
275
-			}
276
-			$tagId = $this->getTagId($tag);
277
-		}
278
-
279
-		if($tagId === false) {
280
-			$l10n = \OC::$server->getL10N('core');
281
-			throw new \Exception(
282
-				$l10n->t('Could not find category "%s"', [$tag])
283
-			);
284
-		}
285
-
286
-		$ids = array();
287
-		$sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE
288
-			. '` WHERE `categoryid` = ?';
289
-
290
-		try {
291
-			$stmt = \OCP\DB::prepare($sql);
292
-			$result = $stmt->execute(array($tagId));
293
-			if ($result === null) {
294
-				\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
295
-				return false;
296
-			}
297
-		} catch(\Exception $e) {
298
-			\OC::$server->getLogger()->logException($e, [
299
-				'message' => __METHOD__,
300
-				'level' => \OCP\Util::ERROR,
301
-				'app' => 'core',
302
-			]);
303
-			return false;
304
-		}
305
-
306
-		if(!is_null($result)) {
307
-			while( $row = $result->fetchRow()) {
308
-				$id = (int)$row['objid'];
309
-
310
-				if ($this->includeShared) {
311
-					// We have to check if we are really allowed to access the
312
-					// items that are tagged with $tag. To that end, we ask the
313
-					// corresponding sharing backend if the item identified by $id
314
-					// is owned by any of $this->owners.
315
-					foreach ($this->owners as $owner) {
316
-						if ($this->backend->isValidSource($id, $owner)) {
317
-							$ids[] = $id;
318
-							break;
319
-						}
320
-					}
321
-				} else {
322
-					$ids[] = $id;
323
-				}
324
-			}
325
-		}
326
-
327
-		return $ids;
328
-	}
329
-
330
-	/**
331
-	* Checks whether a tag is saved for the given user,
332
-	* disregarding the ones shared with him or her.
333
-	*
334
-	* @param string $name The tag name to check for.
335
-	* @param string $user The user whose tags are to be checked.
336
-	* @return bool
337
-	*/
338
-	public function userHasTag($name, $user) {
339
-		$key = $this->array_searchi($name, $this->getTagsForUser($user));
340
-		return ($key !== false) ? $this->tags[$key]->getId() : false;
341
-	}
342
-
343
-	/**
344
-	* Checks whether a tag is saved for or shared with the current user.
345
-	*
346
-	* @param string $name The tag name to check for.
347
-	* @return bool
348
-	*/
349
-	public function hasTag($name) {
350
-		return $this->getTagId($name) !== false;
351
-	}
352
-
353
-	/**
354
-	* Add a new tag.
355
-	*
356
-	* @param string $name A string with a name of the tag
357
-	* @return false|int the id of the added tag or false on error.
358
-	*/
359
-	public function add($name) {
360
-		$name = trim($name);
361
-
362
-		if($name === '') {
363
-			\OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG);
364
-			return false;
365
-		}
366
-		if($this->userHasTag($name, $this->user)) {
367
-			\OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', \OCP\Util::DEBUG);
368
-			return false;
369
-		}
370
-		try {
371
-			$tag = new Tag($this->user, $this->type, $name);
372
-			$tag = $this->mapper->insert($tag);
373
-			$this->tags[] = $tag;
374
-		} catch(\Exception $e) {
375
-			\OC::$server->getLogger()->logException($e, [
376
-				'message' => __METHOD__,
377
-				'level' => \OCP\Util::ERROR,
378
-				'app' => 'core',
379
-			]);
380
-			return false;
381
-		}
382
-		\OCP\Util::writeLog('core', __METHOD__.', id: ' . $tag->getId(), \OCP\Util::DEBUG);
383
-		return $tag->getId();
384
-	}
385
-
386
-	/**
387
-	* Rename tag.
388
-	*
389
-	* @param string|integer $from The name or ID of the existing tag
390
-	* @param string $to The new name of the tag.
391
-	* @return bool
392
-	*/
393
-	public function rename($from, $to) {
394
-		$from = trim($from);
395
-		$to = trim($to);
396
-
397
-		if($to === '' || $from === '') {
398
-			\OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG);
399
-			return false;
400
-		}
401
-
402
-		if (is_numeric($from)) {
403
-			$key = $this->getTagById($from);
404
-		} else {
405
-			$key = $this->getTagByName($from);
406
-		}
407
-		if($key === false) {
408
-			\OCP\Util::writeLog('core', __METHOD__.', tag: ' . $from. ' does not exist', \OCP\Util::DEBUG);
409
-			return false;
410
-		}
411
-		$tag = $this->tags[$key];
412
-
413
-		if($this->userHasTag($to, $tag->getOwner())) {
414
-			\OCP\Util::writeLog('core', __METHOD__.', A tag named ' . $to. ' already exists for user ' . $tag->getOwner() . '.', \OCP\Util::DEBUG);
415
-			return false;
416
-		}
417
-
418
-		try {
419
-			$tag->setName($to);
420
-			$this->tags[$key] = $this->mapper->update($tag);
421
-		} catch(\Exception $e) {
422
-			\OC::$server->getLogger()->logException($e, [
423
-				'message' => __METHOD__,
424
-				'level' => \OCP\Util::ERROR,
425
-				'app' => 'core',
426
-			]);
427
-			return false;
428
-		}
429
-		return true;
430
-	}
431
-
432
-	/**
433
-	* Add a list of new tags.
434
-	*
435
-	* @param string[] $names A string with a name or an array of strings containing
436
-	* the name(s) of the tag(s) to add.
437
-	* @param bool $sync When true, save the tags
438
-	* @param int|null $id int Optional object id to add to this|these tag(s)
439
-	* @return bool Returns false on error.
440
-	*/
441
-	public function addMultiple($names, $sync=false, $id = null) {
442
-		if(!is_array($names)) {
443
-			$names = array($names);
444
-		}
445
-		$names = array_map('trim', $names);
446
-		array_filter($names);
447
-
448
-		$newones = array();
449
-		foreach($names as $name) {
450
-			if(!$this->hasTag($name) && $name !== '') {
451
-				$newones[] = new Tag($this->user, $this->type, $name);
452
-			}
453
-			if(!is_null($id) ) {
454
-				// Insert $objectid, $categoryid  pairs if not exist.
455
-				self::$relations[] = array('objid' => $id, 'tag' => $name);
456
-			}
457
-		}
458
-		$this->tags = array_merge($this->tags, $newones);
459
-		if($sync === true) {
460
-			$this->save();
461
-		}
462
-
463
-		return true;
464
-	}
465
-
466
-	/**
467
-	 * Save the list of tags and their object relations
468
-	 */
469
-	protected function save() {
470
-		if(is_array($this->tags)) {
471
-			foreach($this->tags as $tag) {
472
-				try {
473
-					if (!$this->mapper->tagExists($tag)) {
474
-						$this->mapper->insert($tag);
475
-					}
476
-				} catch(\Exception $e) {
477
-					\OC::$server->getLogger()->logException($e, [
478
-						'message' => __METHOD__,
479
-						'level' => \OCP\Util::ERROR,
480
-						'app' => 'core',
481
-					]);
482
-				}
483
-			}
484
-
485
-			// reload tags to get the proper ids.
486
-			$this->tags = $this->mapper->loadTags($this->owners, $this->type);
487
-			\OCP\Util::writeLog('core', __METHOD__.', tags: ' . print_r($this->tags, true),
488
-				\OCP\Util::DEBUG);
489
-			// Loop through temporarily cached objectid/tagname pairs
490
-			// and save relations.
491
-			$tags = $this->tags;
492
-			// For some reason this is needed or array_search(i) will return 0..?
493
-			ksort($tags);
494
-			$dbConnection = \OC::$server->getDatabaseConnection();
495
-			foreach(self::$relations as $relation) {
496
-				$tagId = $this->getTagId($relation['tag']);
497
-				\OCP\Util::writeLog('core', __METHOD__ . 'catid, ' . $relation['tag'] . ' ' . $tagId, \OCP\Util::DEBUG);
498
-				if($tagId) {
499
-					try {
500
-						$dbConnection->insertIfNotExist(self::RELATION_TABLE,
501
-							array(
502
-								'objid' => $relation['objid'],
503
-								'categoryid' => $tagId,
504
-								'type' => $this->type,
505
-								));
506
-					} catch(\Exception $e) {
507
-						\OC::$server->getLogger()->logException($e, [
508
-							'message' => __METHOD__,
509
-							'level' => \OCP\Util::ERROR,
510
-							'app' => 'core',
511
-						]);
512
-					}
513
-				}
514
-			}
515
-			self::$relations = array(); // reset
516
-		} else {
517
-			\OCP\Util::writeLog('core', __METHOD__.', $this->tags is not an array! '
518
-				. print_r($this->tags, true), \OCP\Util::ERROR);
519
-		}
520
-	}
521
-
522
-	/**
523
-	* Delete tags and tag/object relations for a user.
524
-	*
525
-	* For hooking up on post_deleteUser
526
-	*
527
-	* @param array $arguments
528
-	*/
529
-	public static function post_deleteUser($arguments) {
530
-		// Find all objectid/tagId pairs.
531
-		$result = null;
532
-		try {
533
-			$stmt = \OCP\DB::prepare('SELECT `id` FROM `' . self::TAG_TABLE . '` '
534
-				. 'WHERE `uid` = ?');
535
-			$result = $stmt->execute(array($arguments['uid']));
536
-			if ($result === null) {
537
-				\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
538
-			}
539
-		} catch(\Exception $e) {
540
-			\OC::$server->getLogger()->logException($e, [
541
-				'message' => __METHOD__,
542
-				'level' => \OCP\Util::ERROR,
543
-				'app' => 'core',
544
-			]);
545
-		}
546
-
547
-		if(!is_null($result)) {
548
-			try {
549
-				$stmt = \OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
550
-					. 'WHERE `categoryid` = ?');
551
-				while( $row = $result->fetchRow()) {
552
-					try {
553
-						$stmt->execute(array($row['id']));
554
-					} catch(\Exception $e) {
555
-						\OC::$server->getLogger()->logException($e, [
556
-							'message' => __METHOD__,
557
-							'level' => \OCP\Util::ERROR,
558
-							'app' => 'core',
559
-						]);
560
-					}
561
-				}
562
-			} catch(\Exception $e) {
563
-				\OC::$server->getLogger()->logException($e, [
564
-					'message' => __METHOD__,
565
-					'level' => \OCP\Util::ERROR,
566
-					'app' => 'core',
567
-				]);
568
-			}
569
-		}
570
-		try {
571
-			$stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` '
572
-				. 'WHERE `uid` = ?');
573
-			$result = $stmt->execute(array($arguments['uid']));
574
-			if ($result === null) {
575
-				\OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
576
-			}
577
-		} catch(\Exception $e) {
578
-			\OC::$server->getLogger()->logException($e, [
579
-				'message' => __METHOD__,
580
-				'level' => \OCP\Util::ERROR,
581
-				'app' => 'core',
582
-			]);
583
-		}
584
-	}
585
-
586
-	/**
587
-	* Delete tag/object relations from the db
588
-	*
589
-	* @param array $ids The ids of the objects
590
-	* @return boolean Returns false on error.
591
-	*/
592
-	public function purgeObjects(array $ids) {
593
-		if(count($ids) === 0) {
594
-			// job done ;)
595
-			return true;
596
-		}
597
-		$updates = $ids;
598
-		try {
599
-			$query = 'DELETE FROM `' . self::RELATION_TABLE . '` ';
600
-			$query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) ';
601
-			$query .= 'AND `type`= ?';
602
-			$updates[] = $this->type;
603
-			$stmt = \OCP\DB::prepare($query);
604
-			$result = $stmt->execute($updates);
605
-			if ($result === null) {
606
-				\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
607
-				return false;
608
-			}
609
-		} catch(\Exception $e) {
610
-			\OC::$server->getLogger()->logException($e, [
611
-				'message' => __METHOD__,
612
-				'level' => \OCP\Util::ERROR,
613
-				'app' => 'core',
614
-			]);
615
-			return false;
616
-		}
617
-		return true;
618
-	}
619
-
620
-	/**
621
-	* Get favorites for an object type
622
-	*
623
-	* @return array|false An array of object ids.
624
-	*/
625
-	public function getFavorites() {
626
-		try {
627
-			return $this->getIdsForTag(self::TAG_FAVORITE);
628
-		} catch(\Exception $e) {
629
-			\OC::$server->getLogger()->logException($e, [
630
-				'message' => __METHOD__,
631
-				'level' => \OCP\Util::ERROR,
632
-				'app' => 'core',
633
-			]);
634
-			return array();
635
-		}
636
-	}
637
-
638
-	/**
639
-	* Add an object to favorites
640
-	*
641
-	* @param int $objid The id of the object
642
-	* @return boolean
643
-	*/
644
-	public function addToFavorites($objid) {
645
-		if(!$this->userHasTag(self::TAG_FAVORITE, $this->user)) {
646
-			$this->add(self::TAG_FAVORITE);
647
-		}
648
-		return $this->tagAs($objid, self::TAG_FAVORITE);
649
-	}
650
-
651
-	/**
652
-	* Remove an object from favorites
653
-	*
654
-	* @param int $objid The id of the object
655
-	* @return boolean
656
-	*/
657
-	public function removeFromFavorites($objid) {
658
-		return $this->unTag($objid, self::TAG_FAVORITE);
659
-	}
660
-
661
-	/**
662
-	* Creates a tag/object relation.
663
-	*
664
-	* @param int $objid The id of the object
665
-	* @param string $tag The id or name of the tag
666
-	* @return boolean Returns false on error.
667
-	*/
668
-	public function tagAs($objid, $tag) {
669
-		if(is_string($tag) && !is_numeric($tag)) {
670
-			$tag = trim($tag);
671
-			if($tag === '') {
672
-				\OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG);
673
-				return false;
674
-			}
675
-			if(!$this->hasTag($tag)) {
676
-				$this->add($tag);
677
-			}
678
-			$tagId =  $this->getTagId($tag);
679
-		} else {
680
-			$tagId = $tag;
681
-		}
682
-		try {
683
-			\OC::$server->getDatabaseConnection()->insertIfNotExist(self::RELATION_TABLE,
684
-				array(
685
-					'objid' => $objid,
686
-					'categoryid' => $tagId,
687
-					'type' => $this->type,
688
-				));
689
-		} catch(\Exception $e) {
690
-			\OC::$server->getLogger()->logException($e, [
691
-				'message' => __METHOD__,
692
-				'level' => \OCP\Util::ERROR,
693
-				'app' => 'core',
694
-			]);
695
-			return false;
696
-		}
697
-		return true;
698
-	}
699
-
700
-	/**
701
-	* Delete single tag/object relation from the db
702
-	*
703
-	* @param int $objid The id of the object
704
-	* @param string $tag The id or name of the tag
705
-	* @return boolean
706
-	*/
707
-	public function unTag($objid, $tag) {
708
-		if(is_string($tag) && !is_numeric($tag)) {
709
-			$tag = trim($tag);
710
-			if($tag === '') {
711
-				\OCP\Util::writeLog('core', __METHOD__.', Tag name is empty', \OCP\Util::DEBUG);
712
-				return false;
713
-			}
714
-			$tagId =  $this->getTagId($tag);
715
-		} else {
716
-			$tagId = $tag;
717
-		}
718
-
719
-		try {
720
-			$sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
721
-					. 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?';
722
-			$stmt = \OCP\DB::prepare($sql);
723
-			$stmt->execute(array($objid, $tagId, $this->type));
724
-		} catch(\Exception $e) {
725
-			\OC::$server->getLogger()->logException($e, [
726
-				'message' => __METHOD__,
727
-				'level' => \OCP\Util::ERROR,
728
-				'app' => 'core',
729
-			]);
730
-			return false;
731
-		}
732
-		return true;
733
-	}
734
-
735
-	/**
736
-	* Delete tags from the database.
737
-	*
738
-	* @param string[]|integer[] $names An array of tags (names or IDs) to delete
739
-	* @return bool Returns false on error
740
-	*/
741
-	public function delete($names) {
742
-		if(!is_array($names)) {
743
-			$names = array($names);
744
-		}
745
-
746
-		$names = array_map('trim', $names);
747
-		array_filter($names);
748
-
749
-		\OCP\Util::writeLog('core', __METHOD__ . ', before: '
750
-			. print_r($this->tags, true), \OCP\Util::DEBUG);
751
-		foreach($names as $name) {
752
-			$id = null;
753
-
754
-			if (is_numeric($name)) {
755
-				$key = $this->getTagById($name);
756
-			} else {
757
-				$key = $this->getTagByName($name);
758
-			}
759
-			if ($key !== false) {
760
-				$tag = $this->tags[$key];
761
-				$id = $tag->getId();
762
-				unset($this->tags[$key]);
763
-				$this->mapper->delete($tag);
764
-			} else {
765
-				\OCP\Util::writeLog('core', __METHOD__ . 'Cannot delete tag ' . $name
766
-					. ': not found.', \OCP\Util::ERROR);
767
-			}
768
-			if(!is_null($id) && $id !== false) {
769
-				try {
770
-					$sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
771
-							. 'WHERE `categoryid` = ?';
772
-					$stmt = \OCP\DB::prepare($sql);
773
-					$result = $stmt->execute(array($id));
774
-					if ($result === null) {
775
-						\OCP\Util::writeLog('core',
776
-							__METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(),
777
-							\OCP\Util::ERROR);
778
-						return false;
779
-					}
780
-				} catch(\Exception $e) {
781
-					\OC::$server->getLogger()->logException($e, [
782
-						'message' => __METHOD__,
783
-						'level' => \OCP\Util::ERROR,
784
-						'app' => 'core',
785
-					]);
786
-					return false;
787
-				}
788
-			}
789
-		}
790
-		return true;
791
-	}
792
-
793
-	// case-insensitive array_search
794
-	protected function array_searchi($needle, $haystack, $mem='getName') {
795
-		if(!is_array($haystack)) {
796
-			return false;
797
-		}
798
-		return array_search(strtolower($needle), array_map(
799
-			function($tag) use($mem) {
800
-				return strtolower(call_user_func(array($tag, $mem)));
801
-			}, $haystack)
802
-		);
803
-	}
804
-
805
-	/**
806
-	* Get a tag's ID.
807
-	*
808
-	* @param string $name The tag name to look for.
809
-	* @return string|bool The tag's id or false if no matching tag is found.
810
-	*/
811
-	private function getTagId($name) {
812
-		$key = $this->array_searchi($name, $this->tags);
813
-		if ($key !== false) {
814
-			return $this->tags[$key]->getId();
815
-		}
816
-		return false;
817
-	}
818
-
819
-	/**
820
-	* Get a tag by its name.
821
-	*
822
-	* @param string $name The tag name.
823
-	* @return integer|bool The tag object's offset within the $this->tags
824
-	*                      array or false if it doesn't exist.
825
-	*/
826
-	private function getTagByName($name) {
827
-		return $this->array_searchi($name, $this->tags, 'getName');
828
-	}
829
-
830
-	/**
831
-	* Get a tag by its ID.
832
-	*
833
-	* @param string $id The tag ID to look for.
834
-	* @return integer|bool The tag object's offset within the $this->tags
835
-	*                      array or false if it doesn't exist.
836
-	*/
837
-	private function getTagById($id) {
838
-		return $this->array_searchi($id, $this->tags, 'getId');
839
-	}
840
-
841
-	/**
842
-	* Returns an array mapping a given tag's properties to its values:
843
-	* ['id' => 0, 'name' = 'Tag', 'owner' = 'User', 'type' => 'tagtype']
844
-	*
845
-	* @param Tag $tag The tag that is going to be mapped
846
-	* @return array
847
-	*/
848
-	private function tagMap(Tag $tag) {
849
-		return array(
850
-			'id'    => $tag->getId(),
851
-			'name'  => $tag->getName(),
852
-			'owner' => $tag->getOwner(),
853
-			'type'  => $tag->getType()
854
-		);
855
-	}
53
+    /**
54
+     * Tags
55
+     *
56
+     * @var array
57
+     */
58
+    private $tags = array();
59
+
60
+    /**
61
+     * Used for storing objectid/categoryname pairs while rescanning.
62
+     *
63
+     * @var array
64
+     */
65
+    private static $relations = array();
66
+
67
+    /**
68
+     * Type
69
+     *
70
+     * @var string
71
+     */
72
+    private $type;
73
+
74
+    /**
75
+     * User
76
+     *
77
+     * @var string
78
+     */
79
+    private $user;
80
+
81
+    /**
82
+     * Are we including tags for shared items?
83
+     *
84
+     * @var bool
85
+     */
86
+    private $includeShared = false;
87
+
88
+    /**
89
+     * The current user, plus any owners of the items shared with the current
90
+     * user, if $this->includeShared === true.
91
+     *
92
+     * @var array
93
+     */
94
+    private $owners = array();
95
+
96
+    /**
97
+     * The Mapper we're using to communicate our Tag objects to the database.
98
+     *
99
+     * @var TagMapper
100
+     */
101
+    private $mapper;
102
+
103
+    /**
104
+     * The sharing backend for objects of $this->type. Required if
105
+     * $this->includeShared === true to determine ownership of items.
106
+     *
107
+     * @var \OCP\Share_Backend
108
+     */
109
+    private $backend;
110
+
111
+    const TAG_TABLE = '*PREFIX*vcategory';
112
+    const RELATION_TABLE = '*PREFIX*vcategory_to_object';
113
+
114
+    const TAG_FAVORITE = '_$!<Favorite>!$_';
115
+
116
+    /**
117
+     * Constructor.
118
+     *
119
+     * @param TagMapper $mapper Instance of the TagMapper abstraction layer.
120
+     * @param string $user The user whose data the object will operate on.
121
+     * @param string $type The type of items for which tags will be loaded.
122
+     * @param array $defaultTags Tags that should be created at construction.
123
+     * @param boolean $includeShared Whether to include tags for items shared with this user by others.
124
+     */
125
+    public function __construct(TagMapper $mapper, $user, $type, $defaultTags = array(), $includeShared = false) {
126
+        $this->mapper = $mapper;
127
+        $this->user = $user;
128
+        $this->type = $type;
129
+        $this->includeShared = $includeShared;
130
+        $this->owners = array($this->user);
131
+        if ($this->includeShared) {
132
+            $this->owners = array_merge($this->owners, \OC\Share\Share::getSharedItemsOwners($this->user, $this->type, true));
133
+            $this->backend = \OC\Share\Share::getBackend($this->type);
134
+        }
135
+        $this->tags = $this->mapper->loadTags($this->owners, $this->type);
136
+
137
+        if(count($defaultTags) > 0 && count($this->tags) === 0) {
138
+            $this->addMultiple($defaultTags, true);
139
+        }
140
+    }
141
+
142
+    /**
143
+     * Check if any tags are saved for this type and user.
144
+     *
145
+     * @return boolean
146
+     */
147
+    public function isEmpty() {
148
+        return count($this->tags) === 0;
149
+    }
150
+
151
+    /**
152
+     * Returns an array mapping a given tag's properties to its values:
153
+     * ['id' => 0, 'name' = 'Tag', 'owner' = 'User', 'type' => 'tagtype']
154
+     *
155
+     * @param string $id The ID of the tag that is going to be mapped
156
+     * @return array|false
157
+     */
158
+    public function getTag($id) {
159
+        $key = $this->getTagById($id);
160
+        if ($key !== false) {
161
+            return $this->tagMap($this->tags[$key]);
162
+        }
163
+        return false;
164
+    }
165
+
166
+    /**
167
+     * Get the tags for a specific user.
168
+     *
169
+     * This returns an array with maps containing each tag's properties:
170
+     * [
171
+     * 	['id' => 0, 'name' = 'First tag', 'owner' = 'User', 'type' => 'tagtype'],
172
+     * 	['id' => 1, 'name' = 'Shared tag', 'owner' = 'Other user', 'type' => 'tagtype'],
173
+     * ]
174
+     *
175
+     * @return array
176
+     */
177
+    public function getTags() {
178
+        if(!count($this->tags)) {
179
+            return array();
180
+        }
181
+
182
+        usort($this->tags, function($a, $b) {
183
+            return strnatcasecmp($a->getName(), $b->getName());
184
+        });
185
+        $tagMap = array();
186
+
187
+        foreach($this->tags as $tag) {
188
+            if($tag->getName() !== self::TAG_FAVORITE) {
189
+                $tagMap[] = $this->tagMap($tag);
190
+            }
191
+        }
192
+        return $tagMap;
193
+
194
+    }
195
+
196
+    /**
197
+     * Return only the tags owned by the given user, omitting any tags shared
198
+     * by other users.
199
+     *
200
+     * @param string $user The user whose tags are to be checked.
201
+     * @return array An array of Tag objects.
202
+     */
203
+    public function getTagsForUser($user) {
204
+        return array_filter($this->tags,
205
+            function($tag) use($user) {
206
+                return $tag->getOwner() === $user;
207
+            }
208
+        );
209
+    }
210
+
211
+    /**
212
+     * Get the list of tags for the given ids.
213
+     *
214
+     * @param array $objIds array of object ids
215
+     * @return array|boolean of tags id as key to array of tag names
216
+     * or false if an error occurred
217
+     */
218
+    public function getTagsForObjects(array $objIds) {
219
+        $entries = array();
220
+
221
+        try {
222
+            $conn = \OC::$server->getDatabaseConnection();
223
+            $chunks = array_chunk($objIds, 900, false);
224
+            foreach ($chunks as $chunk) {
225
+                $result = $conn->executeQuery(
226
+                    'SELECT `category`, `categoryid`, `objid` ' .
227
+                    'FROM `' . self::RELATION_TABLE . '` r, `' . self::TAG_TABLE . '` ' .
228
+                    'WHERE `categoryid` = `id` AND `uid` = ? AND r.`type` = ? AND `objid` IN (?)',
229
+                    array($this->user, $this->type, $chunk),
230
+                    array(null, null, IQueryBuilder::PARAM_INT_ARRAY)
231
+                );
232
+                while ($row = $result->fetch()) {
233
+                    $objId = (int)$row['objid'];
234
+                    if (!isset($entries[$objId])) {
235
+                        $entries[$objId] = array();
236
+                    }
237
+                    $entries[$objId][] = $row['category'];
238
+                }
239
+                if ($result === null) {
240
+                    \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
241
+                    return false;
242
+                }
243
+            }
244
+        } catch(\Exception $e) {
245
+            \OC::$server->getLogger()->logException($e, [
246
+                'message' => __METHOD__,
247
+                'level' => \OCP\Util::ERROR,
248
+                'app' => 'core',
249
+            ]);
250
+            return false;
251
+        }
252
+
253
+        return $entries;
254
+    }
255
+
256
+    /**
257
+     * Get the a list if items tagged with $tag.
258
+     *
259
+     * Throws an exception if the tag could not be found.
260
+     *
261
+     * @param string $tag Tag id or name.
262
+     * @return array|false An array of object ids or false on error.
263
+     * @throws \Exception
264
+     */
265
+    public function getIdsForTag($tag) {
266
+        $result = null;
267
+        $tagId = false;
268
+        if(is_numeric($tag)) {
269
+            $tagId = $tag;
270
+        } elseif(is_string($tag)) {
271
+            $tag = trim($tag);
272
+            if($tag === '') {
273
+                \OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG);
274
+                return false;
275
+            }
276
+            $tagId = $this->getTagId($tag);
277
+        }
278
+
279
+        if($tagId === false) {
280
+            $l10n = \OC::$server->getL10N('core');
281
+            throw new \Exception(
282
+                $l10n->t('Could not find category "%s"', [$tag])
283
+            );
284
+        }
285
+
286
+        $ids = array();
287
+        $sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE
288
+            . '` WHERE `categoryid` = ?';
289
+
290
+        try {
291
+            $stmt = \OCP\DB::prepare($sql);
292
+            $result = $stmt->execute(array($tagId));
293
+            if ($result === null) {
294
+                \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
295
+                return false;
296
+            }
297
+        } catch(\Exception $e) {
298
+            \OC::$server->getLogger()->logException($e, [
299
+                'message' => __METHOD__,
300
+                'level' => \OCP\Util::ERROR,
301
+                'app' => 'core',
302
+            ]);
303
+            return false;
304
+        }
305
+
306
+        if(!is_null($result)) {
307
+            while( $row = $result->fetchRow()) {
308
+                $id = (int)$row['objid'];
309
+
310
+                if ($this->includeShared) {
311
+                    // We have to check if we are really allowed to access the
312
+                    // items that are tagged with $tag. To that end, we ask the
313
+                    // corresponding sharing backend if the item identified by $id
314
+                    // is owned by any of $this->owners.
315
+                    foreach ($this->owners as $owner) {
316
+                        if ($this->backend->isValidSource($id, $owner)) {
317
+                            $ids[] = $id;
318
+                            break;
319
+                        }
320
+                    }
321
+                } else {
322
+                    $ids[] = $id;
323
+                }
324
+            }
325
+        }
326
+
327
+        return $ids;
328
+    }
329
+
330
+    /**
331
+     * Checks whether a tag is saved for the given user,
332
+     * disregarding the ones shared with him or her.
333
+     *
334
+     * @param string $name The tag name to check for.
335
+     * @param string $user The user whose tags are to be checked.
336
+     * @return bool
337
+     */
338
+    public function userHasTag($name, $user) {
339
+        $key = $this->array_searchi($name, $this->getTagsForUser($user));
340
+        return ($key !== false) ? $this->tags[$key]->getId() : false;
341
+    }
342
+
343
+    /**
344
+     * Checks whether a tag is saved for or shared with the current user.
345
+     *
346
+     * @param string $name The tag name to check for.
347
+     * @return bool
348
+     */
349
+    public function hasTag($name) {
350
+        return $this->getTagId($name) !== false;
351
+    }
352
+
353
+    /**
354
+     * Add a new tag.
355
+     *
356
+     * @param string $name A string with a name of the tag
357
+     * @return false|int the id of the added tag or false on error.
358
+     */
359
+    public function add($name) {
360
+        $name = trim($name);
361
+
362
+        if($name === '') {
363
+            \OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG);
364
+            return false;
365
+        }
366
+        if($this->userHasTag($name, $this->user)) {
367
+            \OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', \OCP\Util::DEBUG);
368
+            return false;
369
+        }
370
+        try {
371
+            $tag = new Tag($this->user, $this->type, $name);
372
+            $tag = $this->mapper->insert($tag);
373
+            $this->tags[] = $tag;
374
+        } catch(\Exception $e) {
375
+            \OC::$server->getLogger()->logException($e, [
376
+                'message' => __METHOD__,
377
+                'level' => \OCP\Util::ERROR,
378
+                'app' => 'core',
379
+            ]);
380
+            return false;
381
+        }
382
+        \OCP\Util::writeLog('core', __METHOD__.', id: ' . $tag->getId(), \OCP\Util::DEBUG);
383
+        return $tag->getId();
384
+    }
385
+
386
+    /**
387
+     * Rename tag.
388
+     *
389
+     * @param string|integer $from The name or ID of the existing tag
390
+     * @param string $to The new name of the tag.
391
+     * @return bool
392
+     */
393
+    public function rename($from, $to) {
394
+        $from = trim($from);
395
+        $to = trim($to);
396
+
397
+        if($to === '' || $from === '') {
398
+            \OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG);
399
+            return false;
400
+        }
401
+
402
+        if (is_numeric($from)) {
403
+            $key = $this->getTagById($from);
404
+        } else {
405
+            $key = $this->getTagByName($from);
406
+        }
407
+        if($key === false) {
408
+            \OCP\Util::writeLog('core', __METHOD__.', tag: ' . $from. ' does not exist', \OCP\Util::DEBUG);
409
+            return false;
410
+        }
411
+        $tag = $this->tags[$key];
412
+
413
+        if($this->userHasTag($to, $tag->getOwner())) {
414
+            \OCP\Util::writeLog('core', __METHOD__.', A tag named ' . $to. ' already exists for user ' . $tag->getOwner() . '.', \OCP\Util::DEBUG);
415
+            return false;
416
+        }
417
+
418
+        try {
419
+            $tag->setName($to);
420
+            $this->tags[$key] = $this->mapper->update($tag);
421
+        } catch(\Exception $e) {
422
+            \OC::$server->getLogger()->logException($e, [
423
+                'message' => __METHOD__,
424
+                'level' => \OCP\Util::ERROR,
425
+                'app' => 'core',
426
+            ]);
427
+            return false;
428
+        }
429
+        return true;
430
+    }
431
+
432
+    /**
433
+     * Add a list of new tags.
434
+     *
435
+     * @param string[] $names A string with a name or an array of strings containing
436
+     * the name(s) of the tag(s) to add.
437
+     * @param bool $sync When true, save the tags
438
+     * @param int|null $id int Optional object id to add to this|these tag(s)
439
+     * @return bool Returns false on error.
440
+     */
441
+    public function addMultiple($names, $sync=false, $id = null) {
442
+        if(!is_array($names)) {
443
+            $names = array($names);
444
+        }
445
+        $names = array_map('trim', $names);
446
+        array_filter($names);
447
+
448
+        $newones = array();
449
+        foreach($names as $name) {
450
+            if(!$this->hasTag($name) && $name !== '') {
451
+                $newones[] = new Tag($this->user, $this->type, $name);
452
+            }
453
+            if(!is_null($id) ) {
454
+                // Insert $objectid, $categoryid  pairs if not exist.
455
+                self::$relations[] = array('objid' => $id, 'tag' => $name);
456
+            }
457
+        }
458
+        $this->tags = array_merge($this->tags, $newones);
459
+        if($sync === true) {
460
+            $this->save();
461
+        }
462
+
463
+        return true;
464
+    }
465
+
466
+    /**
467
+     * Save the list of tags and their object relations
468
+     */
469
+    protected function save() {
470
+        if(is_array($this->tags)) {
471
+            foreach($this->tags as $tag) {
472
+                try {
473
+                    if (!$this->mapper->tagExists($tag)) {
474
+                        $this->mapper->insert($tag);
475
+                    }
476
+                } catch(\Exception $e) {
477
+                    \OC::$server->getLogger()->logException($e, [
478
+                        'message' => __METHOD__,
479
+                        'level' => \OCP\Util::ERROR,
480
+                        'app' => 'core',
481
+                    ]);
482
+                }
483
+            }
484
+
485
+            // reload tags to get the proper ids.
486
+            $this->tags = $this->mapper->loadTags($this->owners, $this->type);
487
+            \OCP\Util::writeLog('core', __METHOD__.', tags: ' . print_r($this->tags, true),
488
+                \OCP\Util::DEBUG);
489
+            // Loop through temporarily cached objectid/tagname pairs
490
+            // and save relations.
491
+            $tags = $this->tags;
492
+            // For some reason this is needed or array_search(i) will return 0..?
493
+            ksort($tags);
494
+            $dbConnection = \OC::$server->getDatabaseConnection();
495
+            foreach(self::$relations as $relation) {
496
+                $tagId = $this->getTagId($relation['tag']);
497
+                \OCP\Util::writeLog('core', __METHOD__ . 'catid, ' . $relation['tag'] . ' ' . $tagId, \OCP\Util::DEBUG);
498
+                if($tagId) {
499
+                    try {
500
+                        $dbConnection->insertIfNotExist(self::RELATION_TABLE,
501
+                            array(
502
+                                'objid' => $relation['objid'],
503
+                                'categoryid' => $tagId,
504
+                                'type' => $this->type,
505
+                                ));
506
+                    } catch(\Exception $e) {
507
+                        \OC::$server->getLogger()->logException($e, [
508
+                            'message' => __METHOD__,
509
+                            'level' => \OCP\Util::ERROR,
510
+                            'app' => 'core',
511
+                        ]);
512
+                    }
513
+                }
514
+            }
515
+            self::$relations = array(); // reset
516
+        } else {
517
+            \OCP\Util::writeLog('core', __METHOD__.', $this->tags is not an array! '
518
+                . print_r($this->tags, true), \OCP\Util::ERROR);
519
+        }
520
+    }
521
+
522
+    /**
523
+     * Delete tags and tag/object relations for a user.
524
+     *
525
+     * For hooking up on post_deleteUser
526
+     *
527
+     * @param array $arguments
528
+     */
529
+    public static function post_deleteUser($arguments) {
530
+        // Find all objectid/tagId pairs.
531
+        $result = null;
532
+        try {
533
+            $stmt = \OCP\DB::prepare('SELECT `id` FROM `' . self::TAG_TABLE . '` '
534
+                . 'WHERE `uid` = ?');
535
+            $result = $stmt->execute(array($arguments['uid']));
536
+            if ($result === null) {
537
+                \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
538
+            }
539
+        } catch(\Exception $e) {
540
+            \OC::$server->getLogger()->logException($e, [
541
+                'message' => __METHOD__,
542
+                'level' => \OCP\Util::ERROR,
543
+                'app' => 'core',
544
+            ]);
545
+        }
546
+
547
+        if(!is_null($result)) {
548
+            try {
549
+                $stmt = \OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
550
+                    . 'WHERE `categoryid` = ?');
551
+                while( $row = $result->fetchRow()) {
552
+                    try {
553
+                        $stmt->execute(array($row['id']));
554
+                    } catch(\Exception $e) {
555
+                        \OC::$server->getLogger()->logException($e, [
556
+                            'message' => __METHOD__,
557
+                            'level' => \OCP\Util::ERROR,
558
+                            'app' => 'core',
559
+                        ]);
560
+                    }
561
+                }
562
+            } catch(\Exception $e) {
563
+                \OC::$server->getLogger()->logException($e, [
564
+                    'message' => __METHOD__,
565
+                    'level' => \OCP\Util::ERROR,
566
+                    'app' => 'core',
567
+                ]);
568
+            }
569
+        }
570
+        try {
571
+            $stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` '
572
+                . 'WHERE `uid` = ?');
573
+            $result = $stmt->execute(array($arguments['uid']));
574
+            if ($result === null) {
575
+                \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
576
+            }
577
+        } catch(\Exception $e) {
578
+            \OC::$server->getLogger()->logException($e, [
579
+                'message' => __METHOD__,
580
+                'level' => \OCP\Util::ERROR,
581
+                'app' => 'core',
582
+            ]);
583
+        }
584
+    }
585
+
586
+    /**
587
+     * Delete tag/object relations from the db
588
+     *
589
+     * @param array $ids The ids of the objects
590
+     * @return boolean Returns false on error.
591
+     */
592
+    public function purgeObjects(array $ids) {
593
+        if(count($ids) === 0) {
594
+            // job done ;)
595
+            return true;
596
+        }
597
+        $updates = $ids;
598
+        try {
599
+            $query = 'DELETE FROM `' . self::RELATION_TABLE . '` ';
600
+            $query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) ';
601
+            $query .= 'AND `type`= ?';
602
+            $updates[] = $this->type;
603
+            $stmt = \OCP\DB::prepare($query);
604
+            $result = $stmt->execute($updates);
605
+            if ($result === null) {
606
+                \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
607
+                return false;
608
+            }
609
+        } catch(\Exception $e) {
610
+            \OC::$server->getLogger()->logException($e, [
611
+                'message' => __METHOD__,
612
+                'level' => \OCP\Util::ERROR,
613
+                'app' => 'core',
614
+            ]);
615
+            return false;
616
+        }
617
+        return true;
618
+    }
619
+
620
+    /**
621
+     * Get favorites for an object type
622
+     *
623
+     * @return array|false An array of object ids.
624
+     */
625
+    public function getFavorites() {
626
+        try {
627
+            return $this->getIdsForTag(self::TAG_FAVORITE);
628
+        } catch(\Exception $e) {
629
+            \OC::$server->getLogger()->logException($e, [
630
+                'message' => __METHOD__,
631
+                'level' => \OCP\Util::ERROR,
632
+                'app' => 'core',
633
+            ]);
634
+            return array();
635
+        }
636
+    }
637
+
638
+    /**
639
+     * Add an object to favorites
640
+     *
641
+     * @param int $objid The id of the object
642
+     * @return boolean
643
+     */
644
+    public function addToFavorites($objid) {
645
+        if(!$this->userHasTag(self::TAG_FAVORITE, $this->user)) {
646
+            $this->add(self::TAG_FAVORITE);
647
+        }
648
+        return $this->tagAs($objid, self::TAG_FAVORITE);
649
+    }
650
+
651
+    /**
652
+     * Remove an object from favorites
653
+     *
654
+     * @param int $objid The id of the object
655
+     * @return boolean
656
+     */
657
+    public function removeFromFavorites($objid) {
658
+        return $this->unTag($objid, self::TAG_FAVORITE);
659
+    }
660
+
661
+    /**
662
+     * Creates a tag/object relation.
663
+     *
664
+     * @param int $objid The id of the object
665
+     * @param string $tag The id or name of the tag
666
+     * @return boolean Returns false on error.
667
+     */
668
+    public function tagAs($objid, $tag) {
669
+        if(is_string($tag) && !is_numeric($tag)) {
670
+            $tag = trim($tag);
671
+            if($tag === '') {
672
+                \OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG);
673
+                return false;
674
+            }
675
+            if(!$this->hasTag($tag)) {
676
+                $this->add($tag);
677
+            }
678
+            $tagId =  $this->getTagId($tag);
679
+        } else {
680
+            $tagId = $tag;
681
+        }
682
+        try {
683
+            \OC::$server->getDatabaseConnection()->insertIfNotExist(self::RELATION_TABLE,
684
+                array(
685
+                    'objid' => $objid,
686
+                    'categoryid' => $tagId,
687
+                    'type' => $this->type,
688
+                ));
689
+        } catch(\Exception $e) {
690
+            \OC::$server->getLogger()->logException($e, [
691
+                'message' => __METHOD__,
692
+                'level' => \OCP\Util::ERROR,
693
+                'app' => 'core',
694
+            ]);
695
+            return false;
696
+        }
697
+        return true;
698
+    }
699
+
700
+    /**
701
+     * Delete single tag/object relation from the db
702
+     *
703
+     * @param int $objid The id of the object
704
+     * @param string $tag The id or name of the tag
705
+     * @return boolean
706
+     */
707
+    public function unTag($objid, $tag) {
708
+        if(is_string($tag) && !is_numeric($tag)) {
709
+            $tag = trim($tag);
710
+            if($tag === '') {
711
+                \OCP\Util::writeLog('core', __METHOD__.', Tag name is empty', \OCP\Util::DEBUG);
712
+                return false;
713
+            }
714
+            $tagId =  $this->getTagId($tag);
715
+        } else {
716
+            $tagId = $tag;
717
+        }
718
+
719
+        try {
720
+            $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
721
+                    . 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?';
722
+            $stmt = \OCP\DB::prepare($sql);
723
+            $stmt->execute(array($objid, $tagId, $this->type));
724
+        } catch(\Exception $e) {
725
+            \OC::$server->getLogger()->logException($e, [
726
+                'message' => __METHOD__,
727
+                'level' => \OCP\Util::ERROR,
728
+                'app' => 'core',
729
+            ]);
730
+            return false;
731
+        }
732
+        return true;
733
+    }
734
+
735
+    /**
736
+     * Delete tags from the database.
737
+     *
738
+     * @param string[]|integer[] $names An array of tags (names or IDs) to delete
739
+     * @return bool Returns false on error
740
+     */
741
+    public function delete($names) {
742
+        if(!is_array($names)) {
743
+            $names = array($names);
744
+        }
745
+
746
+        $names = array_map('trim', $names);
747
+        array_filter($names);
748
+
749
+        \OCP\Util::writeLog('core', __METHOD__ . ', before: '
750
+            . print_r($this->tags, true), \OCP\Util::DEBUG);
751
+        foreach($names as $name) {
752
+            $id = null;
753
+
754
+            if (is_numeric($name)) {
755
+                $key = $this->getTagById($name);
756
+            } else {
757
+                $key = $this->getTagByName($name);
758
+            }
759
+            if ($key !== false) {
760
+                $tag = $this->tags[$key];
761
+                $id = $tag->getId();
762
+                unset($this->tags[$key]);
763
+                $this->mapper->delete($tag);
764
+            } else {
765
+                \OCP\Util::writeLog('core', __METHOD__ . 'Cannot delete tag ' . $name
766
+                    . ': not found.', \OCP\Util::ERROR);
767
+            }
768
+            if(!is_null($id) && $id !== false) {
769
+                try {
770
+                    $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
771
+                            . 'WHERE `categoryid` = ?';
772
+                    $stmt = \OCP\DB::prepare($sql);
773
+                    $result = $stmt->execute(array($id));
774
+                    if ($result === null) {
775
+                        \OCP\Util::writeLog('core',
776
+                            __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(),
777
+                            \OCP\Util::ERROR);
778
+                        return false;
779
+                    }
780
+                } catch(\Exception $e) {
781
+                    \OC::$server->getLogger()->logException($e, [
782
+                        'message' => __METHOD__,
783
+                        'level' => \OCP\Util::ERROR,
784
+                        'app' => 'core',
785
+                    ]);
786
+                    return false;
787
+                }
788
+            }
789
+        }
790
+        return true;
791
+    }
792
+
793
+    // case-insensitive array_search
794
+    protected function array_searchi($needle, $haystack, $mem='getName') {
795
+        if(!is_array($haystack)) {
796
+            return false;
797
+        }
798
+        return array_search(strtolower($needle), array_map(
799
+            function($tag) use($mem) {
800
+                return strtolower(call_user_func(array($tag, $mem)));
801
+            }, $haystack)
802
+        );
803
+    }
804
+
805
+    /**
806
+     * Get a tag's ID.
807
+     *
808
+     * @param string $name The tag name to look for.
809
+     * @return string|bool The tag's id or false if no matching tag is found.
810
+     */
811
+    private function getTagId($name) {
812
+        $key = $this->array_searchi($name, $this->tags);
813
+        if ($key !== false) {
814
+            return $this->tags[$key]->getId();
815
+        }
816
+        return false;
817
+    }
818
+
819
+    /**
820
+     * Get a tag by its name.
821
+     *
822
+     * @param string $name The tag name.
823
+     * @return integer|bool The tag object's offset within the $this->tags
824
+     *                      array or false if it doesn't exist.
825
+     */
826
+    private function getTagByName($name) {
827
+        return $this->array_searchi($name, $this->tags, 'getName');
828
+    }
829
+
830
+    /**
831
+     * Get a tag by its ID.
832
+     *
833
+     * @param string $id The tag ID to look for.
834
+     * @return integer|bool The tag object's offset within the $this->tags
835
+     *                      array or false if it doesn't exist.
836
+     */
837
+    private function getTagById($id) {
838
+        return $this->array_searchi($id, $this->tags, 'getId');
839
+    }
840
+
841
+    /**
842
+     * Returns an array mapping a given tag's properties to its values:
843
+     * ['id' => 0, 'name' = 'Tag', 'owner' = 'User', 'type' => 'tagtype']
844
+     *
845
+     * @param Tag $tag The tag that is going to be mapped
846
+     * @return array
847
+     */
848
+    private function tagMap(Tag $tag) {
849
+        return array(
850
+            'id'    => $tag->getId(),
851
+            'name'  => $tag->getName(),
852
+            'owner' => $tag->getOwner(),
853
+            'type'  => $tag->getType()
854
+        );
855
+    }
856 856
 }
Please login to merge, or discard this patch.
Spacing   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -134,7 +134,7 @@  discard block
 block discarded – undo
134 134
 		}
135 135
 		$this->tags = $this->mapper->loadTags($this->owners, $this->type);
136 136
 
137
-		if(count($defaultTags) > 0 && count($this->tags) === 0) {
137
+		if (count($defaultTags) > 0 && count($this->tags) === 0) {
138 138
 			$this->addMultiple($defaultTags, true);
139 139
 		}
140 140
 	}
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
 	* @return array
176 176
 	*/
177 177
 	public function getTags() {
178
-		if(!count($this->tags)) {
178
+		if (!count($this->tags)) {
179 179
 			return array();
180 180
 		}
181 181
 
@@ -184,8 +184,8 @@  discard block
 block discarded – undo
184 184
 		});
185 185
 		$tagMap = array();
186 186
 
187
-		foreach($this->tags as $tag) {
188
-			if($tag->getName() !== self::TAG_FAVORITE) {
187
+		foreach ($this->tags as $tag) {
188
+			if ($tag->getName() !== self::TAG_FAVORITE) {
189 189
 				$tagMap[] = $this->tagMap($tag);
190 190
 			}
191 191
 		}
@@ -223,25 +223,25 @@  discard block
 block discarded – undo
223 223
 			$chunks = array_chunk($objIds, 900, false);
224 224
 			foreach ($chunks as $chunk) {
225 225
 				$result = $conn->executeQuery(
226
-					'SELECT `category`, `categoryid`, `objid` ' .
227
-					'FROM `' . self::RELATION_TABLE . '` r, `' . self::TAG_TABLE . '` ' .
226
+					'SELECT `category`, `categoryid`, `objid` '.
227
+					'FROM `'.self::RELATION_TABLE.'` r, `'.self::TAG_TABLE.'` '.
228 228
 					'WHERE `categoryid` = `id` AND `uid` = ? AND r.`type` = ? AND `objid` IN (?)',
229 229
 					array($this->user, $this->type, $chunk),
230 230
 					array(null, null, IQueryBuilder::PARAM_INT_ARRAY)
231 231
 				);
232 232
 				while ($row = $result->fetch()) {
233
-					$objId = (int)$row['objid'];
233
+					$objId = (int) $row['objid'];
234 234
 					if (!isset($entries[$objId])) {
235 235
 						$entries[$objId] = array();
236 236
 					}
237 237
 					$entries[$objId][] = $row['category'];
238 238
 				}
239 239
 				if ($result === null) {
240
-					\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
240
+					\OCP\Util::writeLog('core', __METHOD__.'DB error: '.\OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
241 241
 					return false;
242 242
 				}
243 243
 			}
244
-		} catch(\Exception $e) {
244
+		} catch (\Exception $e) {
245 245
 			\OC::$server->getLogger()->logException($e, [
246 246
 				'message' => __METHOD__,
247 247
 				'level' => \OCP\Util::ERROR,
@@ -265,18 +265,18 @@  discard block
 block discarded – undo
265 265
 	public function getIdsForTag($tag) {
266 266
 		$result = null;
267 267
 		$tagId = false;
268
-		if(is_numeric($tag)) {
268
+		if (is_numeric($tag)) {
269 269
 			$tagId = $tag;
270
-		} elseif(is_string($tag)) {
270
+		} elseif (is_string($tag)) {
271 271
 			$tag = trim($tag);
272
-			if($tag === '') {
272
+			if ($tag === '') {
273 273
 				\OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG);
274 274
 				return false;
275 275
 			}
276 276
 			$tagId = $this->getTagId($tag);
277 277
 		}
278 278
 
279
-		if($tagId === false) {
279
+		if ($tagId === false) {
280 280
 			$l10n = \OC::$server->getL10N('core');
281 281
 			throw new \Exception(
282 282
 				$l10n->t('Could not find category "%s"', [$tag])
@@ -284,17 +284,17 @@  discard block
 block discarded – undo
284 284
 		}
285 285
 
286 286
 		$ids = array();
287
-		$sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE
287
+		$sql = 'SELECT `objid` FROM `'.self::RELATION_TABLE
288 288
 			. '` WHERE `categoryid` = ?';
289 289
 
290 290
 		try {
291 291
 			$stmt = \OCP\DB::prepare($sql);
292 292
 			$result = $stmt->execute(array($tagId));
293 293
 			if ($result === null) {
294
-				\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
294
+				\OCP\Util::writeLog('core', __METHOD__.'DB error: '.\OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
295 295
 				return false;
296 296
 			}
297
-		} catch(\Exception $e) {
297
+		} catch (\Exception $e) {
298 298
 			\OC::$server->getLogger()->logException($e, [
299 299
 				'message' => __METHOD__,
300 300
 				'level' => \OCP\Util::ERROR,
@@ -303,9 +303,9 @@  discard block
 block discarded – undo
303 303
 			return false;
304 304
 		}
305 305
 
306
-		if(!is_null($result)) {
307
-			while( $row = $result->fetchRow()) {
308
-				$id = (int)$row['objid'];
306
+		if (!is_null($result)) {
307
+			while ($row = $result->fetchRow()) {
308
+				$id = (int) $row['objid'];
309 309
 
310 310
 				if ($this->includeShared) {
311 311
 					// We have to check if we are really allowed to access the
@@ -359,19 +359,19 @@  discard block
 block discarded – undo
359 359
 	public function add($name) {
360 360
 		$name = trim($name);
361 361
 
362
-		if($name === '') {
362
+		if ($name === '') {
363 363
 			\OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG);
364 364
 			return false;
365 365
 		}
366
-		if($this->userHasTag($name, $this->user)) {
367
-			\OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', \OCP\Util::DEBUG);
366
+		if ($this->userHasTag($name, $this->user)) {
367
+			\OCP\Util::writeLog('core', __METHOD__.', name: '.$name.' exists already', \OCP\Util::DEBUG);
368 368
 			return false;
369 369
 		}
370 370
 		try {
371 371
 			$tag = new Tag($this->user, $this->type, $name);
372 372
 			$tag = $this->mapper->insert($tag);
373 373
 			$this->tags[] = $tag;
374
-		} catch(\Exception $e) {
374
+		} catch (\Exception $e) {
375 375
 			\OC::$server->getLogger()->logException($e, [
376 376
 				'message' => __METHOD__,
377 377
 				'level' => \OCP\Util::ERROR,
@@ -379,7 +379,7 @@  discard block
 block discarded – undo
379 379
 			]);
380 380
 			return false;
381 381
 		}
382
-		\OCP\Util::writeLog('core', __METHOD__.', id: ' . $tag->getId(), \OCP\Util::DEBUG);
382
+		\OCP\Util::writeLog('core', __METHOD__.', id: '.$tag->getId(), \OCP\Util::DEBUG);
383 383
 		return $tag->getId();
384 384
 	}
385 385
 
@@ -394,7 +394,7 @@  discard block
 block discarded – undo
394 394
 		$from = trim($from);
395 395
 		$to = trim($to);
396 396
 
397
-		if($to === '' || $from === '') {
397
+		if ($to === '' || $from === '') {
398 398
 			\OCP\Util::writeLog('core', __METHOD__.', Cannot use empty tag names', \OCP\Util::DEBUG);
399 399
 			return false;
400 400
 		}
@@ -404,21 +404,21 @@  discard block
 block discarded – undo
404 404
 		} else {
405 405
 			$key = $this->getTagByName($from);
406 406
 		}
407
-		if($key === false) {
408
-			\OCP\Util::writeLog('core', __METHOD__.', tag: ' . $from. ' does not exist', \OCP\Util::DEBUG);
407
+		if ($key === false) {
408
+			\OCP\Util::writeLog('core', __METHOD__.', tag: '.$from.' does not exist', \OCP\Util::DEBUG);
409 409
 			return false;
410 410
 		}
411 411
 		$tag = $this->tags[$key];
412 412
 
413
-		if($this->userHasTag($to, $tag->getOwner())) {
414
-			\OCP\Util::writeLog('core', __METHOD__.', A tag named ' . $to. ' already exists for user ' . $tag->getOwner() . '.', \OCP\Util::DEBUG);
413
+		if ($this->userHasTag($to, $tag->getOwner())) {
414
+			\OCP\Util::writeLog('core', __METHOD__.', A tag named '.$to.' already exists for user '.$tag->getOwner().'.', \OCP\Util::DEBUG);
415 415
 			return false;
416 416
 		}
417 417
 
418 418
 		try {
419 419
 			$tag->setName($to);
420 420
 			$this->tags[$key] = $this->mapper->update($tag);
421
-		} catch(\Exception $e) {
421
+		} catch (\Exception $e) {
422 422
 			\OC::$server->getLogger()->logException($e, [
423 423
 				'message' => __METHOD__,
424 424
 				'level' => \OCP\Util::ERROR,
@@ -438,25 +438,25 @@  discard block
 block discarded – undo
438 438
 	* @param int|null $id int Optional object id to add to this|these tag(s)
439 439
 	* @return bool Returns false on error.
440 440
 	*/
441
-	public function addMultiple($names, $sync=false, $id = null) {
442
-		if(!is_array($names)) {
441
+	public function addMultiple($names, $sync = false, $id = null) {
442
+		if (!is_array($names)) {
443 443
 			$names = array($names);
444 444
 		}
445 445
 		$names = array_map('trim', $names);
446 446
 		array_filter($names);
447 447
 
448 448
 		$newones = array();
449
-		foreach($names as $name) {
450
-			if(!$this->hasTag($name) && $name !== '') {
449
+		foreach ($names as $name) {
450
+			if (!$this->hasTag($name) && $name !== '') {
451 451
 				$newones[] = new Tag($this->user, $this->type, $name);
452 452
 			}
453
-			if(!is_null($id) ) {
453
+			if (!is_null($id)) {
454 454
 				// Insert $objectid, $categoryid  pairs if not exist.
455 455
 				self::$relations[] = array('objid' => $id, 'tag' => $name);
456 456
 			}
457 457
 		}
458 458
 		$this->tags = array_merge($this->tags, $newones);
459
-		if($sync === true) {
459
+		if ($sync === true) {
460 460
 			$this->save();
461 461
 		}
462 462
 
@@ -467,13 +467,13 @@  discard block
 block discarded – undo
467 467
 	 * Save the list of tags and their object relations
468 468
 	 */
469 469
 	protected function save() {
470
-		if(is_array($this->tags)) {
471
-			foreach($this->tags as $tag) {
470
+		if (is_array($this->tags)) {
471
+			foreach ($this->tags as $tag) {
472 472
 				try {
473 473
 					if (!$this->mapper->tagExists($tag)) {
474 474
 						$this->mapper->insert($tag);
475 475
 					}
476
-				} catch(\Exception $e) {
476
+				} catch (\Exception $e) {
477 477
 					\OC::$server->getLogger()->logException($e, [
478 478
 						'message' => __METHOD__,
479 479
 						'level' => \OCP\Util::ERROR,
@@ -484,7 +484,7 @@  discard block
 block discarded – undo
484 484
 
485 485
 			// reload tags to get the proper ids.
486 486
 			$this->tags = $this->mapper->loadTags($this->owners, $this->type);
487
-			\OCP\Util::writeLog('core', __METHOD__.', tags: ' . print_r($this->tags, true),
487
+			\OCP\Util::writeLog('core', __METHOD__.', tags: '.print_r($this->tags, true),
488 488
 				\OCP\Util::DEBUG);
489 489
 			// Loop through temporarily cached objectid/tagname pairs
490 490
 			// and save relations.
@@ -492,10 +492,10 @@  discard block
 block discarded – undo
492 492
 			// For some reason this is needed or array_search(i) will return 0..?
493 493
 			ksort($tags);
494 494
 			$dbConnection = \OC::$server->getDatabaseConnection();
495
-			foreach(self::$relations as $relation) {
495
+			foreach (self::$relations as $relation) {
496 496
 				$tagId = $this->getTagId($relation['tag']);
497
-				\OCP\Util::writeLog('core', __METHOD__ . 'catid, ' . $relation['tag'] . ' ' . $tagId, \OCP\Util::DEBUG);
498
-				if($tagId) {
497
+				\OCP\Util::writeLog('core', __METHOD__.'catid, '.$relation['tag'].' '.$tagId, \OCP\Util::DEBUG);
498
+				if ($tagId) {
499 499
 					try {
500 500
 						$dbConnection->insertIfNotExist(self::RELATION_TABLE,
501 501
 							array(
@@ -503,7 +503,7 @@  discard block
 block discarded – undo
503 503
 								'categoryid' => $tagId,
504 504
 								'type' => $this->type,
505 505
 								));
506
-					} catch(\Exception $e) {
506
+					} catch (\Exception $e) {
507 507
 						\OC::$server->getLogger()->logException($e, [
508 508
 							'message' => __METHOD__,
509 509
 							'level' => \OCP\Util::ERROR,
@@ -530,13 +530,13 @@  discard block
 block discarded – undo
530 530
 		// Find all objectid/tagId pairs.
531 531
 		$result = null;
532 532
 		try {
533
-			$stmt = \OCP\DB::prepare('SELECT `id` FROM `' . self::TAG_TABLE . '` '
533
+			$stmt = \OCP\DB::prepare('SELECT `id` FROM `'.self::TAG_TABLE.'` '
534 534
 				. 'WHERE `uid` = ?');
535 535
 			$result = $stmt->execute(array($arguments['uid']));
536 536
 			if ($result === null) {
537
-				\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
537
+				\OCP\Util::writeLog('core', __METHOD__.'DB error: '.\OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
538 538
 			}
539
-		} catch(\Exception $e) {
539
+		} catch (\Exception $e) {
540 540
 			\OC::$server->getLogger()->logException($e, [
541 541
 				'message' => __METHOD__,
542 542
 				'level' => \OCP\Util::ERROR,
@@ -544,14 +544,14 @@  discard block
 block discarded – undo
544 544
 			]);
545 545
 		}
546 546
 
547
-		if(!is_null($result)) {
547
+		if (!is_null($result)) {
548 548
 			try {
549
-				$stmt = \OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
549
+				$stmt = \OCP\DB::prepare('DELETE FROM `'.self::RELATION_TABLE.'` '
550 550
 					. 'WHERE `categoryid` = ?');
551
-				while( $row = $result->fetchRow()) {
551
+				while ($row = $result->fetchRow()) {
552 552
 					try {
553 553
 						$stmt->execute(array($row['id']));
554
-					} catch(\Exception $e) {
554
+					} catch (\Exception $e) {
555 555
 						\OC::$server->getLogger()->logException($e, [
556 556
 							'message' => __METHOD__,
557 557
 							'level' => \OCP\Util::ERROR,
@@ -559,7 +559,7 @@  discard block
 block discarded – undo
559 559
 						]);
560 560
 					}
561 561
 				}
562
-			} catch(\Exception $e) {
562
+			} catch (\Exception $e) {
563 563
 				\OC::$server->getLogger()->logException($e, [
564 564
 					'message' => __METHOD__,
565 565
 					'level' => \OCP\Util::ERROR,
@@ -568,13 +568,13 @@  discard block
 block discarded – undo
568 568
 			}
569 569
 		}
570 570
 		try {
571
-			$stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` '
571
+			$stmt = \OCP\DB::prepare('DELETE FROM `'.self::TAG_TABLE.'` '
572 572
 				. 'WHERE `uid` = ?');
573 573
 			$result = $stmt->execute(array($arguments['uid']));
574 574
 			if ($result === null) {
575
-				\OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
575
+				\OCP\Util::writeLog('core', __METHOD__.', DB error: '.\OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
576 576
 			}
577
-		} catch(\Exception $e) {
577
+		} catch (\Exception $e) {
578 578
 			\OC::$server->getLogger()->logException($e, [
579 579
 				'message' => __METHOD__,
580 580
 				'level' => \OCP\Util::ERROR,
@@ -590,23 +590,23 @@  discard block
 block discarded – undo
590 590
 	* @return boolean Returns false on error.
591 591
 	*/
592 592
 	public function purgeObjects(array $ids) {
593
-		if(count($ids) === 0) {
593
+		if (count($ids) === 0) {
594 594
 			// job done ;)
595 595
 			return true;
596 596
 		}
597 597
 		$updates = $ids;
598 598
 		try {
599
-			$query = 'DELETE FROM `' . self::RELATION_TABLE . '` ';
600
-			$query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) ';
599
+			$query = 'DELETE FROM `'.self::RELATION_TABLE.'` ';
600
+			$query .= 'WHERE `objid` IN ('.str_repeat('?,', count($ids) - 1).'?) ';
601 601
 			$query .= 'AND `type`= ?';
602 602
 			$updates[] = $this->type;
603 603
 			$stmt = \OCP\DB::prepare($query);
604 604
 			$result = $stmt->execute($updates);
605 605
 			if ($result === null) {
606
-				\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
606
+				\OCP\Util::writeLog('core', __METHOD__.'DB error: '.\OCP\DB::getErrorMessage(), \OCP\Util::ERROR);
607 607
 				return false;
608 608
 			}
609
-		} catch(\Exception $e) {
609
+		} catch (\Exception $e) {
610 610
 			\OC::$server->getLogger()->logException($e, [
611 611
 				'message' => __METHOD__,
612 612
 				'level' => \OCP\Util::ERROR,
@@ -625,7 +625,7 @@  discard block
 block discarded – undo
625 625
 	public function getFavorites() {
626 626
 		try {
627 627
 			return $this->getIdsForTag(self::TAG_FAVORITE);
628
-		} catch(\Exception $e) {
628
+		} catch (\Exception $e) {
629 629
 			\OC::$server->getLogger()->logException($e, [
630 630
 				'message' => __METHOD__,
631 631
 				'level' => \OCP\Util::ERROR,
@@ -642,7 +642,7 @@  discard block
 block discarded – undo
642 642
 	* @return boolean
643 643
 	*/
644 644
 	public function addToFavorites($objid) {
645
-		if(!$this->userHasTag(self::TAG_FAVORITE, $this->user)) {
645
+		if (!$this->userHasTag(self::TAG_FAVORITE, $this->user)) {
646 646
 			$this->add(self::TAG_FAVORITE);
647 647
 		}
648 648
 		return $this->tagAs($objid, self::TAG_FAVORITE);
@@ -666,16 +666,16 @@  discard block
 block discarded – undo
666 666
 	* @return boolean Returns false on error.
667 667
 	*/
668 668
 	public function tagAs($objid, $tag) {
669
-		if(is_string($tag) && !is_numeric($tag)) {
669
+		if (is_string($tag) && !is_numeric($tag)) {
670 670
 			$tag = trim($tag);
671
-			if($tag === '') {
671
+			if ($tag === '') {
672 672
 				\OCP\Util::writeLog('core', __METHOD__.', Cannot add an empty tag', \OCP\Util::DEBUG);
673 673
 				return false;
674 674
 			}
675
-			if(!$this->hasTag($tag)) {
675
+			if (!$this->hasTag($tag)) {
676 676
 				$this->add($tag);
677 677
 			}
678
-			$tagId =  $this->getTagId($tag);
678
+			$tagId = $this->getTagId($tag);
679 679
 		} else {
680 680
 			$tagId = $tag;
681 681
 		}
@@ -686,7 +686,7 @@  discard block
 block discarded – undo
686 686
 					'categoryid' => $tagId,
687 687
 					'type' => $this->type,
688 688
 				));
689
-		} catch(\Exception $e) {
689
+		} catch (\Exception $e) {
690 690
 			\OC::$server->getLogger()->logException($e, [
691 691
 				'message' => __METHOD__,
692 692
 				'level' => \OCP\Util::ERROR,
@@ -705,23 +705,23 @@  discard block
 block discarded – undo
705 705
 	* @return boolean
706 706
 	*/
707 707
 	public function unTag($objid, $tag) {
708
-		if(is_string($tag) && !is_numeric($tag)) {
708
+		if (is_string($tag) && !is_numeric($tag)) {
709 709
 			$tag = trim($tag);
710
-			if($tag === '') {
710
+			if ($tag === '') {
711 711
 				\OCP\Util::writeLog('core', __METHOD__.', Tag name is empty', \OCP\Util::DEBUG);
712 712
 				return false;
713 713
 			}
714
-			$tagId =  $this->getTagId($tag);
714
+			$tagId = $this->getTagId($tag);
715 715
 		} else {
716 716
 			$tagId = $tag;
717 717
 		}
718 718
 
719 719
 		try {
720
-			$sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
720
+			$sql = 'DELETE FROM `'.self::RELATION_TABLE.'` '
721 721
 					. 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?';
722 722
 			$stmt = \OCP\DB::prepare($sql);
723 723
 			$stmt->execute(array($objid, $tagId, $this->type));
724
-		} catch(\Exception $e) {
724
+		} catch (\Exception $e) {
725 725
 			\OC::$server->getLogger()->logException($e, [
726 726
 				'message' => __METHOD__,
727 727
 				'level' => \OCP\Util::ERROR,
@@ -739,16 +739,16 @@  discard block
 block discarded – undo
739 739
 	* @return bool Returns false on error
740 740
 	*/
741 741
 	public function delete($names) {
742
-		if(!is_array($names)) {
742
+		if (!is_array($names)) {
743 743
 			$names = array($names);
744 744
 		}
745 745
 
746 746
 		$names = array_map('trim', $names);
747 747
 		array_filter($names);
748 748
 
749
-		\OCP\Util::writeLog('core', __METHOD__ . ', before: '
749
+		\OCP\Util::writeLog('core', __METHOD__.', before: '
750 750
 			. print_r($this->tags, true), \OCP\Util::DEBUG);
751
-		foreach($names as $name) {
751
+		foreach ($names as $name) {
752 752
 			$id = null;
753 753
 
754 754
 			if (is_numeric($name)) {
@@ -762,22 +762,22 @@  discard block
 block discarded – undo
762 762
 				unset($this->tags[$key]);
763 763
 				$this->mapper->delete($tag);
764 764
 			} else {
765
-				\OCP\Util::writeLog('core', __METHOD__ . 'Cannot delete tag ' . $name
765
+				\OCP\Util::writeLog('core', __METHOD__.'Cannot delete tag '.$name
766 766
 					. ': not found.', \OCP\Util::ERROR);
767 767
 			}
768
-			if(!is_null($id) && $id !== false) {
768
+			if (!is_null($id) && $id !== false) {
769 769
 				try {
770
-					$sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
770
+					$sql = 'DELETE FROM `'.self::RELATION_TABLE.'` '
771 771
 							. 'WHERE `categoryid` = ?';
772 772
 					$stmt = \OCP\DB::prepare($sql);
773 773
 					$result = $stmt->execute(array($id));
774 774
 					if ($result === null) {
775 775
 						\OCP\Util::writeLog('core',
776
-							__METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage(),
776
+							__METHOD__.'DB error: '.\OCP\DB::getErrorMessage(),
777 777
 							\OCP\Util::ERROR);
778 778
 						return false;
779 779
 					}
780
-				} catch(\Exception $e) {
780
+				} catch (\Exception $e) {
781 781
 					\OC::$server->getLogger()->logException($e, [
782 782
 						'message' => __METHOD__,
783 783
 						'level' => \OCP\Util::ERROR,
@@ -791,8 +791,8 @@  discard block
 block discarded – undo
791 791
 	}
792 792
 
793 793
 	// case-insensitive array_search
794
-	protected function array_searchi($needle, $haystack, $mem='getName') {
795
-		if(!is_array($haystack)) {
794
+	protected function array_searchi($needle, $haystack, $mem = 'getName') {
795
+		if (!is_array($haystack)) {
796 796
 			return false;
797 797
 		}
798 798
 		return array_search(strtolower($needle), array_map(
Please login to merge, or discard this patch.