Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
43 | class FederatedShareProvider implements IShareProvider { |
||
44 | |||
45 | const SHARE_TYPE_REMOTE = 6; |
||
46 | |||
47 | /** @var IDBConnection */ |
||
48 | private $dbConnection; |
||
49 | |||
50 | /** @var AddressHandler */ |
||
51 | private $addressHandler; |
||
52 | |||
53 | /** @var Notifications */ |
||
54 | private $notifications; |
||
55 | |||
56 | /** @var TokenHandler */ |
||
57 | private $tokenHandler; |
||
58 | |||
59 | /** @var IL10N */ |
||
60 | private $l; |
||
61 | |||
62 | /** @var ILogger */ |
||
63 | private $logger; |
||
64 | |||
65 | /** @var IRootFolder */ |
||
66 | private $rootFolder; |
||
67 | |||
68 | /** |
||
69 | * DefaultShareProvider constructor. |
||
70 | * |
||
71 | * @param IDBConnection $connection |
||
72 | * @param AddressHandler $addressHandler |
||
73 | * @param Notifications $notifications |
||
74 | * @param TokenHandler $tokenHandler |
||
75 | * @param IL10N $l10n |
||
76 | * @param ILogger $logger |
||
77 | 10 | * @param IRootFolder $rootFolder |
|
78 | */ |
||
79 | public function __construct( |
||
96 | |||
97 | /** |
||
98 | * Return the identifier of this provider. |
||
99 | * |
||
100 | 8 | * @return string Containing only [a-zA-Z0-9] |
|
101 | 8 | */ |
|
102 | public function identifier() { |
||
105 | |||
106 | /** |
||
107 | * Share a path |
||
108 | * |
||
109 | * @param IShare $share |
||
110 | * @return IShare The share object |
||
111 | * @throws ShareNotFound |
||
112 | 9 | * @throws \Exception |
|
113 | */ |
||
114 | 9 | public function create(IShare $share) { |
|
172 | |||
173 | /** |
||
174 | * add share to the database and return the ID |
||
175 | * |
||
176 | * @param int $itemSource |
||
177 | * @param string $itemType |
||
178 | * @param string $shareWith |
||
179 | * @param string $sharedBy |
||
180 | * @param string $uidOwner |
||
181 | * @param int $permissions |
||
182 | * @param string $token |
||
183 | 8 | * @return int |
|
184 | 8 | */ |
|
185 | 8 | private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token) { |
|
210 | |||
211 | /** |
||
212 | * Update a share |
||
213 | * |
||
214 | * @param IShare $share |
||
215 | 1 | * @return IShare The share object |
|
216 | */ |
||
217 | View Code Duplication | public function update(IShare $share) { |
|
231 | |||
232 | /** |
||
233 | * @inheritdoc |
||
234 | */ |
||
235 | public function move(IShare $share, $recipient) { |
||
242 | |||
243 | /** |
||
244 | * Get all children of this share |
||
245 | * |
||
246 | * @param IShare $parent |
||
247 | * @return IShare[] |
||
248 | */ |
||
249 | View Code Duplication | public function getChildren(IShare $parent) { |
|
267 | |||
268 | /** |
||
269 | * Delete a share |
||
270 | * |
||
271 | 1 | * @param IShare $share |
|
272 | 1 | */ |
|
273 | 1 | public function delete(IShare $share) { |
|
282 | |||
283 | /** |
||
284 | * @inheritdoc |
||
285 | */ |
||
286 | public function deleteFromSelf(IShare $share, $recipient) { |
||
293 | |||
294 | /** |
||
295 | 6 | * @inheritdoc |
|
296 | 6 | */ |
|
297 | 6 | public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) { |
|
298 | 6 | $qb = $this->dbConnection->getQueryBuilder(); |
|
299 | $qb->select('*') |
||
300 | 6 | ->from('share'); |
|
301 | |||
302 | $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))); |
||
303 | |||
304 | /** |
||
305 | 6 | * Reshares for this user are shares where they are the owner. |
|
306 | */ |
||
307 | 2 | if ($reshares === false) { |
|
308 | 2 | //Special case for old shares created via the web UI |
|
309 | 2 | $or1 = $qb->expr()->andX( |
|
310 | 2 | $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), |
|
311 | $qb->expr()->isNull('uid_initiator') |
||
|
|||
312 | 2 | ); |
|
313 | 2 | ||
314 | 2 | $qb->andWhere( |
|
315 | $qb->expr()->orX( |
||
316 | 2 | $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)), |
|
317 | 2 | $or1 |
|
318 | 2 | ) |
|
319 | 4 | ); |
|
320 | 4 | } else { |
|
321 | 4 | $qb->andWhere( |
|
322 | 4 | $qb->expr()->orX( |
|
323 | 4 | $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), |
|
324 | 4 | $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) |
|
325 | ) |
||
326 | ); |
||
327 | 6 | } |
|
328 | 1 | ||
329 | 1 | if ($node !== null) { |
|
330 | $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId()))); |
||
331 | 6 | } |
|
332 | 1 | ||
333 | 1 | if ($limit !== -1) { |
|
334 | $qb->setMaxResults($limit); |
||
335 | 6 | } |
|
336 | 6 | ||
337 | $qb->setFirstResult($offset); |
||
338 | 6 | $qb->orderBy('id'); |
|
339 | 6 | ||
340 | 6 | $cursor = $qb->execute(); |
|
341 | 4 | $shares = []; |
|
342 | 4 | while($data = $cursor->fetch()) { |
|
343 | 6 | $shares[] = $this->createShare($data); |
|
344 | } |
||
345 | 6 | $cursor->closeCursor(); |
|
346 | |||
347 | return $shares; |
||
348 | } |
||
349 | |||
350 | /** |
||
351 | 1 | * @inheritdoc |
|
352 | 1 | */ |
|
353 | View Code Duplication | public function getShareById($id, $recipientId = null) { |
|
377 | |||
378 | /** |
||
379 | * Get shares for a given path |
||
380 | * |
||
381 | * @param \OCP\Files\Node $path |
||
382 | * @return IShare[] |
||
383 | */ |
||
384 | View Code Duplication | public function getSharesByPath(Node $path) { |
|
401 | |||
402 | /** |
||
403 | 9 | * @inheritdoc |
|
404 | */ |
||
405 | 9 | public function getSharedWith($userId, $shareType, $node, $limit, $offset) { |
|
441 | |||
442 | /** |
||
443 | * Get a share by token |
||
444 | * |
||
445 | * @param string $token |
||
446 | * @return IShare |
||
447 | * @throws ShareNotFound |
||
448 | */ |
||
449 | View Code Duplication | public function getShareByToken($token) { |
|
472 | |||
473 | /** |
||
474 | * get database row of a give share |
||
475 | * |
||
476 | * @param $id |
||
477 | * @return array |
||
478 | 8 | * @throws ShareNotFound |
|
479 | */ |
||
480 | View Code Duplication | private function getRawShare($id) { |
|
498 | |||
499 | /** |
||
500 | * Create a share object from an database row |
||
501 | * |
||
502 | * @param array $data |
||
503 | * @return IShare |
||
504 | * @throws InvalidShare |
||
505 | 8 | * @throws ShareNotFound |
|
506 | */ |
||
507 | 8 | private function createShare($data) { |
|
541 | |||
542 | /** |
||
543 | * Get the node with file $id for $user |
||
544 | * |
||
545 | * @param string $userId |
||
546 | * @param int $id |
||
547 | * @return \OCP\Files\File|\OCP\Files\Folder |
||
548 | * @throws InvalidShare |
||
549 | */ |
||
550 | private function getNode($userId, $id) { |
||
565 | |||
566 | /** |
||
567 | * A user is deleted from the system |
||
568 | * So clean up the relevant shares. |
||
569 | * |
||
570 | * @param string $uid |
||
571 | * @param int $shareType |
||
572 | */ |
||
573 | View Code Duplication | public function userDeleted($uid, $shareType) { |
|
583 | } |
||
584 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.