Completed
Pull Request — master (#31651)
by Thomas
26:18 queued 14:24
created

LockManager::lock()   F

Complexity

Conditions 16
Paths 418

Size

Total Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
nc 418
nop 4
dl 0
loc 69
rs 2.2083
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
/**
4
 * @author Thomas Müller <[email protected]>
5
 * @copyright Copyright (c) 2018, ownCloud GmbH
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 */
20
21
namespace OC\Lock\Persistent;
22
23
use OCP\IUserSession;
24
use OCP\Lock\Persistent\ILock;
25
26
class LockManager {
27
28
	/** @var LockMapper */
29
	private $lockMapper;
30
31
	/** @var IUserSession */
32
	private $userSession;
33
34
	public function __construct(LockMapper $lockMapper,
35
								IUserSession $userSession) {
36
		$this->lockMapper = $lockMapper;
37
		$this->userSession = $userSession;
38
	}
39
40
	public function lock(int $storageId, string $internalPath, int $fileId, array $lockInfo) : bool {
41
		if ($fileId <= 0) {
42
			throw new \InvalidArgumentException('Invalid file id');
43
		}
44
		if (!isset($lockInfo['token'])) {
45
			throw new \InvalidArgumentException('No token provided in $lockInfo');
46
		}
47
48
		// We're making the lock timeout 30 minutes
49
		$timeout = 30*60;
50
		if (isset($lockInfo['timeout'])) {
51
			$timeout = $lockInfo['timeout'];
52
		}
53
		$owner = $lockInfo['owner'] ?? null;
54
		if ($owner === null && $this->userSession->isLoggedIn()) {
55
			$user = $this->userSession->getUser();
56
			if ($user !== null) {
57
				$owner = $user->getDisplayName();
58
				if ($user->getEMailAddress() !== null) {
59
					$owner .= " <{$user->getEMailAddress()}>";
60
				}
61
			}
62
		}
63
64
		$locks = $this->lockMapper->getLocksByPath($storageId, $internalPath, false);
65
		$exists = false;
66
		foreach ($locks as $lock) {
67
			if ($lock->getToken() === $lockInfo['token']) {
68
				$exists = true;
69
				$lock->setCreatedAt(\time());
70
				$lock->setTimeout($timeout);
71
				if (empty($lock->getOwner())) {
72
					$lock->setOwner($owner);
0 ignored issues
show
Documentation Bug introduced by
The method setOwner does not exist on object<OC\Lock\Persistent\Lock>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
73
				}
74
				$this->lockMapper->update($lock);
75
			}
76
		}
77
78
		if ($exists) {
79
			return true;
80
		}
81
82
		$depth = 0;
83
		if (isset($lockInfo['depth'])) {
84
			$depth = $lockInfo['depth'];
85
		}
86
		$scope = ILock::LOCK_SCOPE_EXCLUSIVE;
87
		if (isset($lockInfo['scope'])) {
88
			$scope = $lockInfo['scope'];
89
		}
90
91
		$lock = new Lock();
92
		$lock->setFileId($fileId);
93
		$lock->setCreatedAt(\time());
94
		$lock->setTimeout($timeout);
95
		$lock->setOwner($owner);
0 ignored issues
show
Documentation Bug introduced by
The method setOwner does not exist on object<OC\Lock\Persistent\Lock>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
96
		$lock->setToken($lockInfo['token']);
97
		$lock->setScope($scope);
98
		$lock->setDepth($depth);
99
100
		if ($this->userSession->isLoggedIn()) {
101
			$user = $this->userSession->getUser();
102
			if ($user !== null) {
103
				$lock->setOwnerAccountId($user->getAccountId());
0 ignored issues
show
Documentation Bug introduced by
The method setOwnerAccountId does not exist on object<OC\Lock\Persistent\Lock>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
104
			}
105
		}
106
		$this->lockMapper->insert($lock);
107
		return true;
108
	}
109
110
	/**
111
	 * @param int $fileId
112
	 * @param string $token
113
	 * @return bool
114
	 */
115
	public function unlock(int $fileId, string $token) : bool {
116
		return $this->lockMapper->deleteByFileIdAndToken($fileId, $token);
117
	}
118
119
	/**
120
	 * @param int $storageId
121
	 * @param string $internalPath
122
	 * @param bool $returnChildLocks
123
	 * @return ILock[]
124
	 */
125
	public function getLocks(int $storageId, string $internalPath, bool $returnChildLocks) : array {
126
		return $this->lockMapper->getLocksByPath($storageId, $internalPath, $returnChildLocks);
127
	}
128
}
129