Completed
Push — master ( 46dc92...267b49 )
by Victor
13s queued 11s
created

BackgroundScanner::getFilesForScan()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 54
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 3.024

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 54
ccs 31
cts 36
cp 0.8611
rs 9.6716
c 2
b 0
f 0
cc 3
eloc 38
nc 4
nop 0
crap 3.024

How to fix   Long Method   

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
/**
3
 * ownCloud - Files_antivirus
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Bart Visscher <[email protected]>
9
 * @author Viktar Dubiniuk <[email protected]>
10
 *
11
 * @copyright 2012 Bart Visscher <[email protected]>
12
 * @copyright Viktar Dubiniuk 2014-2018
13
 * @license AGPL-3.0
14
 */
15
16
namespace OCA\Files_Antivirus;
17
18
use Doctrine\DBAL\Platforms\MySqlPlatform;
19
use OC\Files\Filesystem;
20
use OCP\IL10N;
21
use OCP\Files\IRootFolder;
22
use OCP\IUser;
23
use OCP\IUserSession;
24
25
class BackgroundScanner {
26
27
	const BATCH_SIZE = 10;
28
29
	/**
30
	 * @var IRootFolder
31
	 */
32
	protected $rootFolder;
33
34
	/**
35
	 * @var \OCP\Files\Folder[]
36
	 */
37
	protected $userFolders;
38
39
	/**
40
	 * @var ScannerFactory
41
	 */
42
	private $scannerFactory;
43
44
	/**
45
	 * @var IL10N
46
	 */
47
	private $l10n;
48
49
	/**
50
	 * @var  AppConfig
51
	 */
52
	private $appConfig;
53
54
	/**
55
	 * @var string
56
	 */
57
	protected $currentFilesystemUser;
58
59
	/**
60
	 * @var \OCP\IUserSession
61
	 */
62
	protected $userSession;
63
64
	/**
65
	 * A constructor
66
	 *
67
	 * @param \OCA\Files_Antivirus\ScannerFactory $scannerFactory
68
	 * @param IL10N $l10n
69
	 * @param AppConfig $appConfig
70
	 * @param IRootFolder $rootFolder
71
	 * @param IUserSession $userSession
72
	 */
73 2
	public function __construct(ScannerFactory $scannerFactory,
74
								IL10N $l10n,
75
								AppConfig $appConfig,
76
								IRootFolder $rootFolder,
77
								IUserSession $userSession
78
	) {
79 2
		$this->rootFolder = $rootFolder;
80 2
		$this->scannerFactory = $scannerFactory;
81 2
		$this->l10n = $l10n;
82 2
		$this->appConfig = $appConfig;
83 2
		$this->userSession = $userSession;
84 2
	}
85
	
86
	/**
87
	 * Background scanner main job
88
	 *
89
	 * @return void
90
	 */
91 1
	public function run() {
92
93 1
		if ($this->appConfig->getAvScanBackground() !== 'true') {
94
			return;
95
		}
96
97
		// locate files that are not checked yet
98
		try {
99 1
			$result = $this->getFilesForScan();
100
		} catch(\Exception $e) {
101
			\OC::$server->getLogger()->error(
102
				__METHOD__ . ', exception: ' . $e->getMessage(),
103
				['app' => 'files_antivirus']
104
			);
105
			return;
106
		}
107
108 1
		$cnt = 0;
109 1
		while (($row = $result->fetch()) && $cnt < self::BATCH_SIZE) {
110
			try {
111
				$fileId = $row['fileid'];
112
				$userId = $row['user_id'];
113
				/** @var IUser $owner */
114
				$owner = \OC::$server->getUserManager()->get($userId);
115
				if (!$owner instanceof IUser) {
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
116
					continue;
117
				}
118
				$this->scanOneFile($owner, $fileId);
119
				// increased only for successfully scanned files
120
				$cnt = $cnt + 1;
121
			} catch (\Exception $e){
122
				\OC::$server->getLogger()->error(
123
					__METHOD__ . ', exception: ' . $e->getMessage(),
124
					['app' => 'files_antivirus']
125
				);
126
			}
127
		}
128 1
		$this->tearDownFilesystem();
129 1
	}
130
131 2
	protected function getFilesForScan() {
132 2
		$dirMimeTypeId = \OC::$server->getMimeTypeLoader()->getId(
133 2
			'httpd/unix-directory'
134
		);
135
136 2
		$dbConnection = \OC::$server->getDatabaseConnection();
137 2
		$qb = $dbConnection->getQueryBuilder();
138 2
		if ($dbConnection->getDatabasePlatform() instanceof MySqlPlatform) {
0 ignored issues
show
Bug introduced by
The class Doctrine\DBAL\Platforms\MySqlPlatform does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
139 2
			$concatFunction = $qb->createFunction(
140 2
				"CONCAT('/', mnt.user_id, '/')"
141
			);
142
		} else {
143
			$concatFunction = $qb->createFunction(
144
				"'/' || " . $qb->getColumnName('mnt.user_id') . " || '/'"
145
			);
146
		}
147
148 2
		$sizeLimit = \intval($this->appConfig->getAvMaxFileSize());
149 2
		if ($sizeLimit === -1) {
150 2
			$sizeLimitExpr = $qb->expr()->neq('fc.size', $qb->expr()->literal('0'));
151
		} else {
152
			$sizeLimitExpr = $qb->expr()->andX(
153
				$qb->expr()->neq('fc.size', $qb->expr()->literal('0')),
154
				$qb->expr()->lt('fc.size', $qb->expr()->literal((string) $sizeLimit))
155
			);
156
		}
157
158 2
		$qb->select(['fc.fileid', 'mnt.user_id'])
159 2
			->from('filecache', 'fc')
160 2
			->leftJoin('fc', 'files_antivirus', 'fa', $qb->expr()->eq('fa.fileid', 'fc.fileid'))
161 2
			->innerJoin(
162 2
				'fc',
163 2
				'mounts',
164 2
				'mnt',
165 2
				$qb->expr()->andX(
166 2
					$qb->expr()->eq('fc.storage', 'mnt.storage_id'),
167 2
					$qb->expr()->eq('mnt.mount_point', $concatFunction)
168
				)
169
			)
170 2
			->where(
171 2
				$qb->expr()->neq('fc.mimetype', $qb->expr()->literal($dirMimeTypeId))
172
			)
173 2
			->andWhere(
174 2
				$qb->expr()->orX(
175 2
					$qb->expr()->isNull('fa.fileid'),
176 2
					$qb->expr()->gt('fc.mtime', 'fa.check_time')
177
				)
178
			)
179 2
			->andWhere(
180 2
				$qb->expr()->like('fc.path', $qb->expr()->literal('files/%'))
181
			)
182 2
			->andWhere($sizeLimitExpr);
183 2
		return $qb->execute();
184
	}
185
186
	/**
187
	 * @param IUser $owner
188
	 * @param int $fileId
189
	 */
190
	protected function scanOneFile($owner, $fileId) {
191
		$this->initFilesystemForUser($owner);
192
		$view = Filesystem::getView();
193
		$path = $view->getPath($fileId);
194
		if (!\is_null($path)) {
195
			$item = new Item($this->l10n, $view, $path, $fileId);
196
			$scanner = $this->scannerFactory->getScanner();
197
			$status = $scanner->scan($item);
198
			$status->dispatch($item, true);
199
		}
200
	}
201
202
	/**
203
	 * @param \OCP\IUser $user
204
	 *
205
	 * @return \OCP\Files\Folder
206
	 */
207
	protected function getUserFolder(IUser $user) {
208
		if (!isset($this->userFolders[$user->getUID()])) {
209
			$userFolder = $this->rootFolder->getUserFolder($user->getUID());
210
			$this->userFolders[$user->getUID()] = $userFolder;
211
		}
212
		return $this->userFolders[$user->getUID()];
213
	}
214
215
	/**
216
	 * @param IUser $user
217
	 */
218
	protected function initFilesystemForUser(IUser $user) {
219
		if ($this->currentFilesystemUser !== $user->getUID()) {
220
			if ($this->currentFilesystemUser !== '') {
221
				$this->tearDownFilesystem();
222
			}
223
			Filesystem::init($user->getUID(), '/' . $user->getUID() . '/files');
224
			$this->userSession->setUser($user);
225
			$this->currentFilesystemUser = $user->getUID();
226
			Filesystem::initMountPoints($user->getUID());
227
		}
228
	}
229
230
	/**
231
	 * @return void
232
	 */
233 1
	protected function tearDownFilesystem() {
234 1
		$this->userSession->setUser(null);
235 1
		\OC_Util::tearDownFS();
236 1
	}
237
238
	/**
239
	 * @deprecated since  v8.0.0
240
	 *
241
	 * @return void
242
	 */
243
	public static function check() {
244
	}
245
}
246