Test Failed
Push — 3.x ( e8e622...cd01f1 )
by Jerome
63:10 queued 11s
created

PageOwnerService::detectLegacyPageOwner()   C

Complexity

Conditions 17
Paths 3

Size

Total Lines 55
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 35
nc 3
nop 0
dl 0
loc 55
rs 5.2166
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
3
namespace Elgg\Page;
4
5
use Elgg\Http\Request;
6
use Elgg\Database\EntityTable;
7
use Elgg\Router\Route;
8
use Elgg\PluginHooksService;
9
use Elgg\Database\UsersTable;
10
use Elgg\Invoker;
11
12
/**
13
 * Holds page owner related functions
14
 *
15
 * @internal
16
 *
17
 * @since 3.1
18
 */
19
class PageOwnerService {
20
21
	/**
22
	 * @var Request
23
	 */
24
	protected $request;
25
26
	/**
27
	 * @var EntityTable
28
	 */
29
	protected $entity_table;
30
31
	/**
32
	 * @var UsersTable
33
	 */
34
	protected $users_table;
35
36
	/**
37
	 * @var PluginHooksService
38
	 */
39
	protected $hooks;
40
41
	/**
42
	 * @var Invoker
43
	 */
44
	protected $invoker;
45
46
	/**
47
	 * @var int
48
	 */
49
	protected $page_owner_guid = 0;
50
	
51
	/**
52
	 * Constructor
53
	 *
54
	 * @param Request            $request      Request
55
	 * @param EntityTable        $entity_table Entity table
56
	 * @param PluginHooksService $hooks        Hooks
57
	 * @param UsersTable         $users_table  Users table
58
	 * @param Invoker            $invoker      Invoker
59
	 */
60
	public function __construct(
61
			Request $request,
62
			EntityTable $entity_table,
63
			PluginHooksService $hooks,
64
			UsersTable $users_table,
65
			Invoker $invoker
66
	) {
67
		$this->request = $request;
68
		$this->entity_table = $entity_table;
69
		$this->hooks = $hooks;
70
		$this->users_table = $users_table;
71
		$this->invoker = $invoker;
72
		
73
		$this->initializePageOwner();
74
	}
75
	
76
	/**
77
	 * Initialize the page owner by trying to autodetect or let a hook to provide the page owner
78
	 *
79
	 * @return void
80
	 */
81
	protected function initializePageOwner() {
82
		
83
		$page_owner_guid = $this->detectPageOwnerFromRoute();
84
		if (!empty($page_owner_guid)) {
85
			$this->page_owner_guid = $page_owner_guid;
86
			return;
87
		}
88
		
89
		$page_owner_guid = $this->detectLegacyPageOwner();
90
		if (!empty($page_owner_guid)) {
91
			$this->page_owner_guid = $page_owner_guid;
92
			return;
93
		}
94
		
95
		$this->page_owner_guid = (int) $this->hooks->trigger('page_owner', 'system', null, $this->page_owner_guid);
96
	}
97
	
98
	/**
99
	 * Detects page owner from route
100
	 *
101
	 * @return int|void detected page owner guid or void if none detected
102
	 */
103
	protected function detectPageOwnerFromRoute() {
104
		$route = $this->request->getRoute();
105
		if (!$route instanceof Route) {
1 ignored issue
show
introduced by
$route is always a sub-type of Elgg\Router\Route.
Loading history...
106
			return;
107
		}
108
		
109
		$page_owner = $route->resolvePageOwner();
110
		if (!$page_owner instanceof \ElggEntity) {
111
			return;
112
		}
113
		
114
		return $page_owner->guid;
115
	}
116
	
117
	/**
118
	 * Sets the page owner based on request
119
	 *
120
	 * Tries to figure out the page owner by looking at the URL or a request
121
	 * parameter. The request parameters used are 'username' and 'owner_guid'.
122
	 * Otherwise, this function attempts to figure out the owner if the url
123
	 * fits the patterns of:
124
	 *   <identifier>/owner/<username>
125
	 *   <identifier>/friends/<username>
126
	 *   <identifier>/view/<entity guid>
127
	 *   <identifier>/add/<container guid>
128
	 *   <identifier>/edit/<entity guid>
129
	 *   <identifier>/group/<group guid>
130
	 *
131
	 * @note Access is disabled while finding the page owner for the group gatekeeper functions.
132
	 *
133
	 * @return int|void
134
	 * @access private
135
	 */
136
	private function detectLegacyPageOwner() {
137
	
138
		$guid = $this->invoker->call(ELGG_IGNORE_ACCESS, function() {
139
		
140
			$username = $this->request->getParam('username');
141
			if ($user = $this->users_table->getByUsername($username)) {
142
				return $user->guid;
143
			}
144
		
145
			$owner = $this->request->getParam('owner_guid');
146
			if (is_numeric($owner)) {
147
				if ($user = $this->entity_table->get((int) $owner)) {
148
					return $user->guid;
149
				}
150
			}
151
		});
152
		
153
		if (is_int($guid)) {
154
			return $guid;
155
		}
156
		
157
		// @todo feels hacky
158
		$guid = $this->invoker->call(ELGG_IGNORE_ACCESS, function() {
159
			$segments = $this->request->getUrlSegments();
160
			if (!isset($segments[1]) || !isset($segments[2])) {
161
				return;
162
			}
163
			
164
			switch ($segments[1]) {
165
				case 'owner':
166
				case 'friends':
167
					$user = $this->users_table->getByUsername($segments[2]);
168
					if ($user) {
169
						return $user->guid;
170
					}
171
					break;
172
				case 'view':
173
				case 'edit':
174
					$entity = $this->entity_table->get($segments[2]);
1 ignored issue
show
Bug introduced by
$segments[2] of type string is incompatible with the type integer expected by parameter $guid of Elgg\Database\EntityTable::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

174
					$entity = $this->entity_table->get(/** @scrutinizer ignore-type */ $segments[2]);
Loading history...
175
					if ($entity) {
176
						return $entity->container_guid;
177
					}
178
					break;
179
				case 'add':
180
				case 'group':
181
					$entity = $this->entity_table->get($segments[2]);
182
					if ($entity) {
183
						return $entity->guid;
184
					}
185
					break;
186
			}
187
		});
188
	
189
		if (is_int($guid)) {
190
			return $guid;
191
		}
192
	}
193
	
194
	/**
195
	 * Sets a new page owner guid
196
	 *
197
	 * @param int $guid the new page owner
198
	 *
199
	 * @throws \InvalidArgumentException
200
	 *
201
	 * @return void
202
	 */
203
	public function setPageOwnerGuid(int $guid = 0) {
204
		if ($guid < 0) {
205
			throw new \InvalidArgumentException(__METHOD__ . ' requires a positive integer.');
206
		}
207
		$this->page_owner_guid = $guid;
208
	}
209
	
210
	/**
211
	 * Return the current page owner guid
212
	 *
213
	 * @return int
214
	 */
215
	public function getPageOwnerGuid() {
216
		return $this->page_owner_guid;
217
	}
218
	
219
	/**
220
	 * Returns the page owner entity
221
	 *
222
	 * @return ElggEntity|false the current page owner or false if none.
0 ignored issues
show
Bug introduced by
The type Elgg\Page\ElggEntity was not found. Did you mean ElggEntity? If so, make sure to prefix the type with \.
Loading history...
223
	 */
224
	public function getPageOwnerEntity() {
225
		return $this->entity_table->get($this->getPageOwnerGuid());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->entity_tab...is->getPageOwnerGuid()) also could return the type ElggEntity which is incompatible with the documented return type Elgg\Page\ElggEntity|false.
Loading history...
226
	}
227
}
228