Completed
Push — 3.x ( 668272...4d1768 )
by Jeroen
156:21 queued 83:40
created

engine/classes/Elgg/Page/PageOwnerService.php (4 issues)

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 64
	public function __construct(
61
			Request $request,
62
			EntityTable $entity_table,
63
			PluginHooksService $hooks,
64
			UsersTable $users_table,
65
			Invoker $invoker
66
	) {
67 64
		$this->request = $request;
68 64
		$this->entity_table = $entity_table;
69 64
		$this->hooks = $hooks;
70 64
		$this->users_table = $users_table;
71 64
		$this->invoker = $invoker;
72
		
73 64
		$this->initializePageOwner();
74 64
	}
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 64
	protected function initializePageOwner() {
82
		
83 64
		$page_owner_guid = $this->detectPageOwnerFromRoute();
84 64
		if (!empty($page_owner_guid)) {
85 26
			$this->page_owner_guid = $page_owner_guid;
86 26
			return;
87
		}
88
		
89 38
		$page_owner_guid = $this->detectLegacyPageOwner();
90 38
		if (!empty($page_owner_guid)) {
91 6
			$this->page_owner_guid = $page_owner_guid;
92 6
			return;
93
		}
94
		
95 32
		$this->page_owner_guid = (int) $this->hooks->trigger('page_owner', 'system', null, $this->page_owner_guid);
96 32
	}
97
	
98
	/**
99
	 * Detects page owner from route
100
	 *
101
	 * @return int|void detected page owner guid or void if none detected
102
	 */
103 64
	protected function detectPageOwnerFromRoute() {
104 64
		$route = $this->request->getRoute();
105 64
		if (!$route instanceof Route) {
1 ignored issue
show
$route is always a sub-type of Elgg\Router\Route.
Loading history...
106 21
			return;
107
		}
108
		
109 43
		$page_owner = $route->resolvePageOwner();
110 43
		if (!$page_owner instanceof \ElggEntity) {
111 17
			return;
112
		}
113
		
114 26
		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
	 */
135
	private function detectLegacyPageOwner() {
136
	
137 38
		$guid = $this->invoker->call(ELGG_IGNORE_ACCESS, function() {
138
		
139 38
			$username = $this->request->getParam('username');
140 38
			if ($user = $this->users_table->getByUsername($username)) {
141 1
				return $user->guid;
142
			}
143
		
144 37
			$owner = $this->request->getParam('owner_guid');
145 37
			if (is_numeric($owner)) {
146 1
				if ($user = $this->entity_table->get((int) $owner)) {
147 1
					return $user->guid;
148
				}
149
			}
150 38
		});
151
		
152 38
		if (is_int($guid)) {
153 2
			return $guid;
154
		}
155
		
156
		// @todo feels hacky
157 36
		$guid = $this->invoker->call(ELGG_IGNORE_ACCESS, function() {
158 36
			$segments = $this->request->getUrlSegments();
159 36
			if (!isset($segments[1]) || !isset($segments[2])) {
160 25
				return;
161
			}
162
			
163 11
			switch ($segments[1]) {
164 11
				case 'owner':
165 10
				case 'friends':
166 2
					$user = $this->users_table->getByUsername($segments[2]);
167 2
					if ($user) {
168 2
						return $user->guid;
169
					}
170
					break;
171 9
				case 'view':
172 8
				case 'edit':
173 6
					$entity = $this->entity_table->get($segments[2]);
1 ignored issue
show
$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

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