LinkChecker::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 4
cts 4
cp 1
rs 9.9
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
/**
3
 * LinkChecker.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        https://www.ipublikuj.eu
7
 * @author         Adam Kadlec <[email protected]>
8
 * @package        iPublikuj:Permissions!
9
 * @subpackage     Access
10
 * @since          1.0.0
11
 *
12
 * @date           13.10.14
13
 */
14
15
declare(strict_types = 1);
16
17
namespace IPub\Permissions\Access;
18
19
use Nette;
20
use Nette\Application;
21
use Nette\Application\UI;
22
23
/**
24
 * Create link access checker
25
 *
26
 * @package        iPublikuj:Permissions!
27
 * @subpackage     Access
28
 *
29
 * @author         Adam Kadlec <[email protected]>
30
 */
31 1
final class LinkChecker implements IChecker
32
{
33
	/**
34
	 * Implement nette smart magic
35
	 */
36 1
	use Nette\SmartObject;
37
38
	/**
39
	 * @var Application\IPresenterFactory
40
	 */
41
	private $presenterFactory;
42
43
	/**
44
	 * @var Application\Application
45
	 */
46
	private $application;
47
48
	/**
49
	 * @var ICheckRequirements
50
	 */
51
	private $requirementsChecker;
52
53
	/**
54
	 * @param Application\IPresenterFactory $presenterFactory
55
	 * @param Application\Application $application
56
	 * @param ICheckRequirements $requirementsChecker
57
	 */
58
	function __construct(
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
59
		Application\IPresenterFactory $presenterFactory,
60
		Application\Application $application,
61
		ICheckRequirements $requirementsChecker
62
	) {
63 1
		$this->presenterFactory = $presenterFactory;
64 1
		$this->application = $application;
65
66
		// Permission annotation access checker
67 1
		$this->requirementsChecker = $requirementsChecker;
68 1
	}
69
70
	/**
71
	 * Check whenever current user is allowed to use given link
72
	 *
73
	 * @param string $element etc "this", ":Admin:Show:default"
74
	 *
75
	 * @return bool
76
	 *
77
	 * @throws Application\InvalidPresenterException
78
	 * @throws \ReflectionException
79
	 */
80
	public function isAllowed($element) : bool
81
	{
82
		list($presenter, $action) = $this->formatLink($element);
83
84
		$presenterReflection = new UI\ComponentReflection($this->presenterFactory->getPresenterClass($presenter));
85
86
		if (!$this->requirementsChecker->isAllowed($presenterReflection)) {
87
			return FALSE;
88
		}
89
90
		$actionKey = UI\Presenter::ACTION_KEY . ucfirst($action);
91
92
		if ($presenterReflection->hasMethod($actionKey) && !$this->requirementsChecker->isAllowed($presenterReflection->getMethod($actionKey))) {
93
			return FALSE;
94
		}
95
96
		return TRUE;
97
	}
98
99
	/**
100
	 * Format link to format array('module:submodule:presenter', 'action')
101
	 *
102
	 * @param string $destination
103
	 *
104
	 * @return array(presenter, action)
0 ignored issues
show
Documentation introduced by
The doc-type array(presenter, could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
105
	 */
106
	public function formatLink(string $destination) : array
107
	{
108
		if ($destination === 'this') {
109
			return [$this->application->getPresenter()->getName(), $this->application->getPresenter()->getAction()];
110
		}
111
112
		$parts = explode(':', $destination);
113
114
		if ($destination[0] != ':') {
115
			$current = explode(':', $this->application->getPresenter()->getName());
116
117
			if (strpos($destination, ':') !== FALSE) {
118
				// Remove presenter
119
				array_pop($current);
120
			}
121
122
			$parts = array_merge($current, $parts);
123
124
		} else {
125
			// Remove empty
126
			array_shift($parts);
127
		}
128
129
		if ($destination[strlen($destination) - 1] == ':') {
130
			// Remove empty
131
			array_pop($parts);
132
133
			$action = UI\Presenter::DEFAULT_ACTION;
134
135
		} else {
136
			$action = array_pop($parts);
137
		}
138
139
		return [implode(':', $parts), $action];
140
	}
141
}
142