Completed
Pull Request — stable9 (#52)
by Olivier
09:56
created

SearchFolderService   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 9
c 2
b 0
f 0
lcom 1
cbo 4
dl 0
loc 94
ccs 26
cts 26
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A findFolder() 0 19 3
A sendFolder() 0 12 3
A getCurrentFolder() 0 5 1
A validateLocation() 0 8 2
1
<?php
2
/**
3
 * ownCloud - galleryplus
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Olivier Paroz <[email protected]>
9
 *
10
 * @copyright Olivier Paroz 2014-2016
11
 */
12
13
namespace OCA\GalleryPlus\Service;
14
15
use OCP\Files\Folder;
16
17
use OCA\GalleryPlus\Environment\NotFoundEnvException;
18
19
/**
20
 * Looks for the folder to use, based on the request made by the client
21
 *
22
 * This is to make sure we were not:
23
 *    * given a file
24
 *    * given a folder name with a typo
25
 *
26
 * @package OCA\GalleryPlus\Service
27
 */
28
class SearchFolderService extends FilesService {
29
	/**
30
	 * @var int
31
	 */
32
	protected $virtualRootLevel = null;
33
34
	/**
35
	 * This returns what we think is the current folder node based on a given path
36
	 *
37
	 * @param string $location
38
	 * @param string[] $features
39
	 *
40
	 * @return array <string,Folder,bool>
41
	 */
42 6
	public function getCurrentFolder($location, $features) {
43 6
		$this->features = $features;
44
45 6
		return $this->findFolder($location);
46
	}
47
48
	/**
49
	 * This returns the current folder node based on a path
50
	 *
51
	 * If the path leads to a file, we'll return the node of the containing folder
52
	 *
53
	 * If we can't find anything, we try with the parent folder, up to the root or until we reach
54
	 * our recursive limit
55
	 *
56
	 * @param string $location
57
	 * @param int $depth
58
	 *
59
	 * @return array <string,Folder,bool>
60
	 */
61 7
	private function findFolder($location, $depth = 0) {
62 7
		$node = null;
63 7
		$location = $this->validateLocation($location, $depth);
64
		try {
65 7
			$node = $this->environment->getNodeFromVirtualRoot($location);
66 7
			if ($node->getType() === 'file') {
67 7
				$node = $node->getParent();
68
			}
69 2
		} catch (NotFoundEnvException $exception) {
70
			// There might be a typo in the file or folder name
71 2
			$folder = pathinfo($location, PATHINFO_DIRNAME);
72 2
			$depth++;
73
74 2
			return $this->findFolder($folder, $depth);
75
		}
76 7
		$path = $this->environment->getPathFromVirtualRoot($node);
77
78 7
		return $this->sendFolder($path, $node);
79
	}
80
81
	/**
82
	 * Makes sure we don't go too far up before giving up
83
	 *
84
	 * @param string $location
85
	 * @param int $depth
86
	 *
87
	 * @return string
88
	 */
89 9
	private function validateLocation($location, $depth) {
90 9
		if ($depth === 4) {
91
			// We can't find anything, so we decide to return data for the root folder
92 1
			$location = '';
93
		}
94
95 9
		return $location;
96
	}
97
98
	/**
99
	 * Makes sure that the folder is not empty, does meet our requirements in terms of location and
100
	 * returns details about it
101
	 *
102
	 * @param string $path
103
	 * @param Folder $node
104
	 *
105
	 * @return array <string,Folder,bool>
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string|Folder>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
106
	 * @throws ForbiddenServiceException|NotFoundServiceException
107
	 */
108 12
	private function sendFolder($path, $node) {
109 12
		if (is_null($node)) {
110
			// Something very wrong has just happened
111 1
			throw new NotFoundServiceException('Oh Nooooes!');
112 11
		} elseif (!$this->isAllowedAndAvailable($node)) {
113 2
			throw new ForbiddenServiceException(
114 2
				'The owner has placed a restriction or the storage location is unavailable'
115
			);
116
		}
117
118 9
		return [$path, $node];
119
	}
120
121
}
122