Completed
Push — master ( f91c14...61b54d )
by Maxence
02:23 queued 33s
created

FilesService   F

Complexity

Total Complexity 82

Size/Duplication

Total Lines 775
Duplicated Lines 6.19 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 82
lcom 1
cbo 11
dl 48
loc 775
rs 1.825
c 0
b 0
f 0

31 Methods

Rating   Name   Duplication   Size   Complexity  
A generateDocumentFromIndex() 0 19 2
A isDocumentUpToDate() 0 20 4
A __construct() 0 21 1
A setRunner() 0 3 1
A getFilesFromUser() 0 22 3
A initFileSystems() 0 8 2
B getFilesFromDirectory() 0 38 6
A generateFilesDocumentFromFile() 0 24 3
A getFileSource() 0 13 2
A getFileFromPath() 0 4 1
A getFileFromId() 0 16 3
A getFileFromIndex() 0 5 1
A getPathFromViewerId() 0 16 2
A generateDocument() 0 12 2
A updateDocument() 0 6 1
A updateFilesDocument() 0 11 2
A updateFilesDocumentFromFile() 0 10 1
A updateDocumentAccess() 0 15 3
B updateContentFromFile() 0 29 6
B updateShareNames() 0 31 6
A parseMimeType() 0 12 2
A parseMimeTypeText() 6 18 4
A parseMimeTypePDF() 0 7 2
A parseMimeTypeOffice() 6 19 3
A extractContentFromFileText() 0 14 3
A extractContentFromFilePDF() 18 20 4
A extractContentFromFileOffice() 18 20 4
A isSourceIndexable() 0 10 2
A impersonateOwner() 0 8 2
A updateRunnerAction() 0 7 2
A updateRunnerInfo() 0 7 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like FilesService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FilesService, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Files_FullTextSearch - Index the content of your files
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2018
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\Files_FullTextSearch\Service;
28
29
30
use Exception;
31
use OC\App\AppManager;
32
use OCA\Files_FullTextSearch\Exceptions\EmptyUserException;
33
use OCA\Files_FullTextSearch\Exceptions\FileIsNotIndexableException;
34
use OCA\Files_FullTextSearch\Exceptions\FilesNotFoundException;
35
use OCA\Files_FullTextSearch\Exceptions\KnownFileMimeTypeException;
36
use OCA\Files_FullTextSearch\Exceptions\KnownFileSourceException;
37
use OCA\Files_FullTextSearch\Model\FilesDocument;
38
use OCA\Files_FullTextSearch\Provider\FilesProvider;
39
use OCA\FullTextSearch\Model\Index;
40
use OCA\FullTextSearch\Model\IndexDocument;
41
use OCA\FullTextSearch\Model\IndexOptions;
42
use OCA\FullTextSearch\Model\Runner;
43
use OCP\AppFramework\IAppContainer;
44
use OCP\Files\File;
45
use OCP\Files\FileInfo;
46
use OCP\Files\Folder;
47
use OCP\Files\InvalidPathException;
48
use OCP\Files\IRootFolder;
49
use OCP\Files\Node;
50
use OCP\Files\NotFoundException;
51
use OCP\Files\NotPermittedException;
52
use OCP\Files\StorageNotAvailableException;
53
use OCP\IUserManager;
54
use OCP\Share\IManager;
55
use Throwable;
56
57
class FilesService {
58
59
	const MIMETYPE_TEXT = 'files_text';
60
	const MIMETYPE_PDF = 'files_pdf';
61
	const MIMETYPE_OFFICE = 'files_office';
62
	const MIMETYPE_IMAGE = 'files_image';
63
	const MIMETYPE_AUDIO = 'files_audio';
64
65
66
	/** @var IAppContainer */
67
	private $container;
68
69
	/** @var IRootFolder */
70
	private $rootFolder;
71
72
	/** @var IUserManager */
73
	private $userManager;
74
75
	/** @var AppManager */
76
	private $appManager;
77
78
	/** @var IManager */
79
	private $shareManager;
80
81
	/** @var ConfigService */
82
	private $configService;
83
84
	/** @var LocalFilesService */
85
	private $localFilesService;
86
87
	/** @var ExternalFilesService */
88
	private $externalFilesService;
89
90
	/** @var GroupFoldersService */
91
	private $groupFoldersService;
92
93
	/** @var ExtensionService */
94
	private $extensionService;
95
96
	/** @var MiscService */
97
	private $miscService;
98
99
100
	/** @var Runner */
101
	private $runner;
102
103
	/** @var int */
104
	private $sumDocuments;
105
106
	/**
107
	 * FilesService constructor.
108
	 *
109
	 * @param IAppContainer $container
110
	 * @param IRootFolder $rootFolder
111
	 * @param AppManager $appManager
112
	 * @param IUserManager $userManager
113
	 * @param IManager $shareManager
114
	 * @param ConfigService $configService
115
	 * @param LocalFilesService $localFilesService
116
	 * @param ExternalFilesService $externalFilesService
117
	 * @param GroupFoldersService $groupFoldersService
118
	 * @param ExtensionService $extensionService
119
	 * @param MiscService $miscService
120
	 *
121
	 * @internal param IProviderFactory $factory
122
	 */
123
	public function __construct(
124
		IAppContainer $container, IRootFolder $rootFolder, AppManager $appManager,
125
		IUserManager $userManager, IManager $shareManager,
126
		ConfigService $configService, LocalFilesService $localFilesService,
127
		ExternalFilesService $externalFilesService, GroupFoldersService $groupFoldersService,
128
		ExtensionService $extensionService, MiscService $miscService
129
	) {
130
		$this->container = $container;
131
		$this->rootFolder = $rootFolder;
132
		$this->appManager = $appManager;
133
		$this->userManager = $userManager;
134
		$this->shareManager = $shareManager;
135
136
		$this->configService = $configService;
137
		$this->localFilesService = $localFilesService;
138
		$this->externalFilesService = $externalFilesService;
139
		$this->groupFoldersService = $groupFoldersService;
140
		$this->extensionService = $extensionService;
141
142
		$this->miscService = $miscService;
143
	}
144
145
146
	public function setRunner(Runner $runner) {
147
		$this->runner = $runner;
148
	}
149
150
151
	/**
152
	 * @param string $userId
153
	 * @param IndexOptions $indexOptions
154
	 *
155
	 * @return FilesDocument[]
156
	 * @throws InvalidPathException
157
	 * @throws NotFoundException
158
	 */
159
	public function getFilesFromUser($userId, $indexOptions) {
160
161
		$this->initFileSystems($userId);
162
		$this->sumDocuments = 0;
163
164
		/** @var Folder $files */
165
		$files = $this->rootFolder->getUserFolder($userId)
166
								  ->get($indexOptions->getOption('path', '/'));
167
168
		if ($files instanceof Folder) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\Folder 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...
169
			$result = $this->getFilesFromDirectory($userId, $files);
170
		} else {
171
			$result = [];
172
			try {
173
				$result[] = $this->generateFilesDocumentFromFile($userId, $files);
174
			} catch (FileIsNotIndexableException $e) {
175
				/** we do nothin' */
176
			}
177
		}
178
179
		return $result;
180
	}
181
182
183
	/**
184
	 * @param string $userId
185
	 */
186
	private function initFileSystems($userId) {
187
		if ($userId === '') {
188
			return;
189
		}
190
191
		$this->externalFilesService->initExternalFilesForUser($userId);
192
		$this->groupFoldersService->initGroupSharesForUser($userId);
193
	}
194
195
196
	/**
197
	 * @param string $userId
198
	 * @param Folder $node
199
	 *
200
	 * @return FilesDocument[]
201
	 * @throws InvalidPathException
202
	 * @throws NotFoundException
203
	 * @throws Exception
204
	 */
205
	public function getFilesFromDirectory($userId, Folder $node) {
206
		$documents = [];
207
208
		$this->updateRunnerAction('generateIndexFiles');
209
		$this->updateRunnerInfo(
210
			[
211
				'info'          => $node->getPath(),
212
				'documentTotal' => $this->sumDocuments
213
			]
214
		);
215
216
		try {
217
			if ($node->nodeExists('.noindex')) {
218
				return $documents;
219
			}
220
		} catch (StorageNotAvailableException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\StorageNotAvailableException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
221
			return $documents;
222
		}
223
224
		$files = $node->getDirectoryListing();
225
		foreach ($files as $file) {
226
227
			try {
228
				$documents[] = $this->generateFilesDocumentFromFile($userId, $file);
229
				$this->sumDocuments++;
230
			} catch (FileIsNotIndexableException $e) {
231
				continue;
232
			}
233
234
			if ($file->getType() === FileInfo::TYPE_FOLDER) {
235
				/** @var $file Folder */
236
				$documents =
237
					array_merge($documents, $this->getFilesFromDirectory($userId, $file));
238
			}
239
		}
240
241
		return $documents;
242
	}
243
244
245
	/**
246
	 * @param Node $file
247
	 *
248
	 * @param string $viewerId
249
	 *
250
	 * @return FilesDocument
251
	 * @throws FileIsNotIndexableException
252
	 * @throws InvalidPathException
253
	 * @throws NotFoundException
254
	 * @throws Exception
255
	 */
256
	private function generateFilesDocumentFromFile($viewerId, Node $file) {
257
258
		$source = $this->getFileSource($file);
259
		$document = new FilesDocument(FilesProvider::FILES_PROVIDER_ID, $file->getId());
260
261
		if ($file->getId() === -1) {
262
			throw new FileIsNotIndexableException();
263
		}
264
265
		$ownerId = '';
266
		if ($file->getOwner() !== null) {
267
			$ownerId = $file->getOwner()
268
							->getUID();
269
		}
270
		$document->setType($file->getType())
271
				 ->setSource($source)
272
				 ->setOwnerId($ownerId)
273
				 ->setPath($this->getPathFromViewerId($file->getId(), $viewerId))
274
				 ->setViewerId($viewerId)
275
				 ->setModifiedTime($file->getMTime())
276
				 ->setMimetype($file->getMimetype());
277
278
		return $document;
279
	}
280
281
282
	/**
283
	 * @param Node $file
284
	 *
285
	 * @return string
286
	 * @throws FileIsNotIndexableException
287
	 * @throws NotFoundException
288
	 */
289
	private function getFileSource(Node $file) {
290
		$source = '';
291
292
		try {
293
			$this->localFilesService->getFileSource($file, $source);
294
			$this->externalFilesService->getFileSource($file, $source);
295
			$this->groupFoldersService->getFileSource($file, $source);
296
		} catch (KnownFileSourceException $e) {
297
			/** we know the source, just leave. */
298
		}
299
300
		return $source;
301
	}
302
303
304
	/**
305
	 * @param string $userId
306
	 * @param string $path
307
	 *
308
	 * @return Node
309
	 * @throws NotFoundException
310
	 */
311
	public function getFileFromPath($userId, $path) {
312
		return $this->rootFolder->getUserFolder($userId)
313
								->get($path);
314
	}
315
316
317
	/**
318
	 * @param string $userId
319
	 * @param int $fileId
320
	 *
321
	 * @return Node
322
	 * @throws FilesNotFoundException
323
	 * @throws EmptyUserException
324
	 */
325
	public function getFileFromId($userId, $fileId) {
326
327
		if ($userId === '') {
328
			throw new EmptyUserException();
329
		}
330
331
		$files = $this->rootFolder->getUserFolder($userId)
332
								  ->getById($fileId);
333
		if (sizeof($files) === 0) {
334
			throw new FilesNotFoundException();
335
		}
336
337
		$file = array_shift($files);
338
339
		return $file;
340
	}
341
342
343
	/**
344
	 * @param Index $index
345
	 *
346
	 * @return Node
347
	 * @throws EmptyUserException
348
	 * @throws FilesNotFoundException
349
	 */
350
	public function getFileFromIndex(Index $index) {
351
		$this->impersonateOwner($index);
352
353
		return $this->getFileFromId($index->getOwnerId(), $index->getDocumentId());
354
	}
355
356
357
	/**
358
	 * @param int $fileId
359
	 * @param string $viewerId
360
	 *
361
	 * @throws Exception
362
	 * @return string
363
	 */
364
	private function getPathFromViewerId($fileId, $viewerId) {
365
366
		$viewerFiles = $this->rootFolder->getUserFolder($viewerId)
367
										->getById($fileId);
368
369
		if (sizeof($viewerFiles) === 0) {
370
			return '';
371
		}
372
373
		$file = array_shift($viewerFiles);
374
375
		// TODO: better way to do this : we remove the '/userid/files/'
376
		$path = MiscService::noEndSlash(substr($file->getPath(), 8 + strlen($viewerId)));
377
378
		return $path;
379
	}
380
381
382
	/**
383
	 * @param FilesDocument $document
384
	 */
385
	public function generateDocument(FilesDocument $document) {
386
387
		try {
388
			$this->updateFilesDocument($document);
389
		} catch (Exception $e) {
390
			// TODO - update $document with a error status instead of just ignore !
391
			$document->getIndex()
392
					 ->setStatus(Index::INDEX_IGNORE);
393
			echo 'Exception: ' . json_encode($e->getTrace()) . ' - ' . $e->getMessage()
394
				 . "\n";
395
		}
396
	}
397
398
399
	/**
400
	 * @param Index $index
401
	 *
402
	 * @return FilesDocument
403
	 * @throws FileIsNotIndexableException
404
	 * @throws InvalidPathException
405
	 * @throws NotFoundException
406
	 * @throws NotPermittedException
407
	 */
408
	private function generateDocumentFromIndex(Index $index) {
409
410
		try {
411
			$file = $this->getFileFromIndex($index);
412
		} catch (Exception $e) {
413
			$index->setStatus(Index::INDEX_REMOVE);
414
			$document = new FilesDocument($index->getProviderId(), $index->getDocumentId());
415
			$document->setIndex($index);
416
417
			return $document;
418
		}
419
420
		$document = $this->generateFilesDocumentFromFile($index->getOwnerId(), $file);
421
		$document->setIndex($index);
422
423
		$this->updateFilesDocumentFromFile($document, $file);
424
425
		return $document;
426
	}
427
428
429
	/**
430
	 * @param IndexDocument $document
431
	 *
432
	 * @return bool
433
	 */
434
	public function isDocumentUpToDate($document) {
435
		$index = $document->getIndex();
436
437
		if (!$this->configService->compareIndexOptions($index)) {
438
			$index->setStatus(Index::INDEX_CONTENT);
439
			$document->setIndex($index);
440
441
			return false;
442
		}
443
444
		if ($index->getStatus() !== Index::INDEX_OK) {
445
			return false;
446
		}
447
448
		if ($index->getLastIndex() >= $document->getModifiedTime()) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $index->getLastIn...ent->getModifiedTime();.
Loading history...
449
			return true;
450
		}
451
452
		return false;
453
	}
454
455
456
	/**
457
	 * @param Index $index
458
	 *
459
	 * @return FilesDocument
460
	 * @throws InvalidPathException
461
	 * @throws NotFoundException
462
	 * @throws NotPermittedException
463
	 * @throws FileIsNotIndexableException
464
	 */
465
	public function updateDocument(Index $index) {
466
		$this->impersonateOwner($index);
467
		$this->initFileSystems($index->getOwnerId());
468
469
		return $this->generateDocumentFromIndex($index);
470
	}
471
472
473
	/**
474
	 * @param FilesDocument $document
475
	 *
476
	 * @throws InvalidPathException
477
	 * @throws NotFoundException
478
	 * @throws NotPermittedException
479
	 */
480
	private function updateFilesDocument(FilesDocument $document) {
481
		$userFolder = $this->rootFolder->getUserFolder($document->getViewerId());
482
		$file = $userFolder->get($document->getPath());
483
484
		try {
485
			$this->updateFilesDocumentFromFile($document, $file);
486
		} catch (FileIsNotIndexableException $e) {
487
			$document->getIndex()
488
					 ->setStatus(Index::INDEX_IGNORE);
489
		}
490
	}
491
492
493
	/**
494
	 * @param FilesDocument $document
495
	 * @param Node $file
496
	 *
497
	 * @throws InvalidPathException
498
	 * @throws NotFoundException
499
	 * @throws NotPermittedException
500
	 */
501
	private function updateFilesDocumentFromFile(FilesDocument $document, Node $file) {
502
503
		$document->getIndex()
504
				 ->setSource($document->getSource());
505
506
		$this->updateDocumentAccess($document, $file);
507
		$this->updateContentFromFile($document, $file);
508
509
		$document->addMetaTag($document->getSource());
510
	}
511
512
513
	/**
514
	 * @param FilesDocument $document
515
	 * @param Node $file
516
	 */
517
	private function updateDocumentAccess(FilesDocument $document, Node $file) {
518
519
		$index = $document->getIndex();
520
521
		if (!$index->isStatus(Index::INDEX_FULL)
522
			&& !$index->isStatus(FilesDocument::STATUS_FILE_ACCESS)) {
523
			return;
524
		}
525
526
		$this->localFilesService->updateDocumentAccess($document, $file);
527
		$this->externalFilesService->updateDocumentAccess($document, $file);
528
		$this->groupFoldersService->updateDocumentAccess($document, $file);
529
530
		$this->updateShareNames($document, $file);
531
	}
532
533
534
	/**
535
	 * @param FilesDocument $document
536
	 * @param Node $file
537
	 *
538
	 * @throws InvalidPathException
539
	 * @throws NotFoundException
540
	 * @throws NotPermittedException
541
	 */
542
	private function updateContentFromFile(FilesDocument $document, Node $file) {
543
544
		$document->setTitle($document->getPath());
545
546
		if (!$document->getIndex()
547
					  ->isStatus(Index::INDEX_CONTENT)
548
			|| $file->getType() !== FileInfo::TYPE_FILE) {
549
			return;
550
		}
551
552
		try {
553
			/** @var File $file */
554
			if ($file->getSize() <
555
				($this->configService->getAppValue(ConfigService::FILES_SIZE) * 1024 * 1024)) {
556
				$this->extractContentFromFileText($document, $file);
557
				$this->extractContentFromFileOffice($document, $file);
558
				$this->extractContentFromFilePDF($document, $file);
559
560
				$this->extensionService->fileIndexing($document, $file);
561
			}
562
		} catch (Throwable $t) {
0 ignored issues
show
Bug introduced by
The class Throwable does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
563
			$this->miscService->log(json_encode($t->getTrace()), 1);
564
		}
565
566
		if ($document->getContent() === null) {
567
			$document->getIndex()
568
					 ->unsetStatus(Index::INDEX_CONTENT);
569
		}
570
	}
571
572
573
	/**
574
	 * @param FilesDocument $document
575
	 * @param Node $file
576
	 *
577
	 * @return array
578
	 */
579
	private function updateShareNames(FilesDocument $document, Node $file) {
580
581
		$users = [];
582
583
		$this->localFilesService->getShareUsersFromFile($file, $users);
584
		$this->externalFilesService->getShareUsers($document, $users);
585
		$this->groupFoldersService->getShareUsers($document, $users);
586
587
		$shareNames = [];
588
		foreach ($users as $username) {
589
			try {
590
				$user = $this->userManager->get($username);
591
				if ($user === null || $user->getLastLogin() === 0) {
592
					continue;
593
				}
594
595
				$path = $this->getPathFromViewerId($file->getId(), $username);
596
				$shareNames[MiscService::secureUsername($username)] =
597
					(!is_string($path)) ? $path = '' : $path;
598
599
			} catch (Exception $e) {
600
				$this->miscService->log(
601
					'Issue while getting information on documentId:' . $document->getId(), 0
602
				);
603
			}
604
		}
605
606
		$document->setInfo('share_names', $shareNames);
607
608
		return $shareNames;
609
	}
610
611
612
	/**
613
	 * @param string $mimeType
614
	 *
615
	 * @return string
616
	 */
617
	private function parseMimeType($mimeType) {
618
619
		$parsed = '';
620
		try {
621
			$this->parseMimeTypeText($mimeType, $parsed);
622
			$this->parseMimeTypePDF($mimeType, $parsed);
623
			$this->parseMimeTypeOffice($mimeType, $parsed);
624
		} catch (KnownFileMimeTypeException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
625
		}
626
627
		return $parsed;
628
	}
629
630
631
	/**
632
	 * @param string $mimeType
633
	 * @param string $parsed
634
	 *
635
	 * @throws KnownFileMimeTypeException
636
	 */
637
	private function parseMimeTypeText($mimeType, &$parsed) {
638
639
		if (substr($mimeType, 0, 5) === 'text/') {
640
			$parsed = self::MIMETYPE_TEXT;
641
			throw new KnownFileMimeTypeException();
642
		}
643
644
		$textMimes = [
645
			'application/epub+zip'
646
		];
647
648 View Code Duplication
		foreach ($textMimes as $mime) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
649
			if (strpos($mimeType, $mime) === 0) {
650
				$parsed = self::MIMETYPE_TEXT;
651
				throw new KnownFileMimeTypeException();
652
			}
653
		}
654
	}
655
656
657
	/**
658
	 * @param string $mimeType
659
	 * @param string $parsed
660
	 *
661
	 * @throws KnownFileMimeTypeException
662
	 */
663
	private function parseMimeTypePDF($mimeType, &$parsed) {
664
665
		if ($mimeType === 'application/pdf') {
666
			$parsed = self::MIMETYPE_PDF;
667
			throw new KnownFileMimeTypeException();
668
		}
669
	}
670
671
672
	/**
673
	 * @param string $mimeType
674
	 * @param string $parsed
675
	 *
676
	 * @throws KnownFileMimeTypeException
677
	 */
678
	private function parseMimeTypeOffice($mimeType, &$parsed) {
679
680
		$officeMimes = [
681
			'application/msword',
682
			'application/vnd.oasis.opendocument',
683
			'application/vnd.sun.xml',
684
			'application/vnd.openxmlformats-officedocument',
685
			'application/vnd.ms-word',
686
			'application/vnd.ms-powerpoint',
687
			'application/vnd.ms-excel'
688
		];
689
690 View Code Duplication
		foreach ($officeMimes as $mime) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
691
			if (strpos($mimeType, $mime) === 0) {
692
				$parsed = self::MIMETYPE_OFFICE;
693
				throw new KnownFileMimeTypeException();
694
			}
695
		}
696
	}
697
698
699
	/**
700
	 * @param FilesDocument $document
701
	 * @param File $file
702
	 *
703
	 * @throws NotPermittedException
704
	 */
705
	private function extractContentFromFileText(FilesDocument $document, File $file) {
706
707
		if ($this->parseMimeType($document->getMimeType()) !== self::MIMETYPE_TEXT) {
708
			return;
709
		}
710
711
		if (!$this->isSourceIndexable($document)) {
712
			return;
713
		}
714
715
		$document->setContent(
716
			base64_encode($file->getContent()), IndexDocument::ENCODED_BASE64
717
		);
718
	}
719
720
721
	/**
722
	 * @param FilesDocument $document
723
	 * @param File $file
724
	 *
725
	 * @throws NotPermittedException
726
	 */
727 View Code Duplication
	private function extractContentFromFilePDF(FilesDocument $document, File $file) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
728
		if ($this->parseMimeType($document->getMimeType()) !== self::MIMETYPE_PDF) {
729
			return;
730
		}
731
732
		$this->configService->setDocumentIndexOption($document, ConfigService::FILES_PDF);
733
		if (!$this->isSourceIndexable($document)) {
734
			return;
735
		}
736
737
		if ($this->configService->getAppValue(ConfigService::FILES_PDF) !== '1') {
738
			$document->setContent('');
739
740
			return;
741
		}
742
743
		$document->setContent(
744
			base64_encode($file->getContent()), IndexDocument::ENCODED_BASE64
745
		);
746
	}
747
748
749
	/**
750
	 * @param FilesDocument $document
751
	 * @param File $file
752
	 *
753
	 * @throws NotPermittedException
754
	 */
755 View Code Duplication
	private function extractContentFromFileOffice(FilesDocument $document, File $file) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
756
		if ($this->parseMimeType($document->getMimeType()) !== self::MIMETYPE_OFFICE) {
757
			return;
758
		}
759
760
		$this->configService->setDocumentIndexOption($document, ConfigService::FILES_OFFICE);
761
		if (!$this->isSourceIndexable($document)) {
762
			return;
763
		}
764
765
		if ($this->configService->getAppValue(ConfigService::FILES_OFFICE) !== '1') {
766
			$document->setContent('');
767
768
			return;
769
		}
770
771
		$document->setContent(
772
			base64_encode($file->getContent()), IndexDocument::ENCODED_BASE64
773
		);
774
	}
775
776
777
	/**
778
	 * @param FilesDocument $document
779
	 *
780
	 * @return bool
781
	 */
782
	private function isSourceIndexable(FilesDocument $document) {
783
		$this->configService->setDocumentIndexOption($document, $document->getSource());
784
		if ($this->configService->getAppValue($document->getSource()) !== '1') {
785
			$document->setContent('');
786
787
			return false;
788
		}
789
790
		return true;
791
	}
792
793
794
	private function impersonateOwner(Index $index) {
795
		if ($index->getOwnerId() !== '') {
796
			return;
797
		}
798
799
		$this->groupFoldersService->impersonateOwner($index);
800
		$this->externalFilesService->impersonateOwner($index);
801
	}
802
803
804
	/**
805
	 * @param $action
806
	 * @param bool $force
807
	 *
808
	 * @throws Exception
809
	 */
810
	private function updateRunnerAction($action, $force = false) {
811
		if ($this->runner === null) {
812
			return;
813
		}
814
815
		$this->runner->updateAction($action, $force);
816
	}
817
818
819
	/**
820
	 * @param array $data
821
	 */
822
	private function updateRunnerInfo($data) {
823
		if ($this->runner === null) {
824
			return;
825
		}
826
827
		$this->runner->setInfoArray($data);
828
	}
829
830
831
}
832
833