PluginProbe
User Access Manager / 2.2.14
User Access Manager v2.2.14
2.3.20 2.3.19 2.3.18 2.3.17 2.3.16 2.3.15 2.3.14 2.3.13 trunk 0.6 0.6.1 0.6.2 0.7 0.7 Beta 0.7.0.1 0.8 0.8.0.1 0.8.0.2 0.9 0.9.1 0.9.1.1 0.9.1.2 0.9.1.3 0.9.1.4 1.0 All 136 releases
user-access-manager / src / Controller / Frontend / RedirectController.php

RedirectController.php in User Access Manager 2.2.14, at src/Controller/Frontend/RedirectController.php

427 lines 13.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * FrontendRedirectController.php
4 *
5 * The FrontendRedirectController class file.
6 *
7 * PHP versions 5
8 *
9 * @author Alexander Schneider <alexanderschneider85@gmail.com>
10 * @copyright 2008-2017 Alexander Schneider
11 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2
12 * @version SVN: $id$
13 * @link http://wordpress.org/extend/plugins/user-access-manager/
14 */
15
16 declare(strict_types=1);
17
18 namespace UserAccessManager\Controller\Frontend;
19
20 use UserAccessManager\Access\AccessHandler;
21 use UserAccessManager\Cache\Cache;
22 use UserAccessManager\Config\MainConfig;
23 use UserAccessManager\Config\WordpressConfig;
24 use UserAccessManager\Controller\Controller;
25 use UserAccessManager\Database\Database;
26 use UserAccessManager\File\FileHandler;
27 use UserAccessManager\File\FileObject;
28 use UserAccessManager\File\FileObjectFactory;
29 use UserAccessManager\Object\ObjectHandler;
30 use UserAccessManager\UserGroup\UserGroupTypeException;
31 use UserAccessManager\Util\Util;
32 use UserAccessManager\Wrapper\Php;
33 use UserAccessManager\Wrapper\Wordpress;
34
35 /**
36 * Class FrontendRedirectController
37 *
38 * @package UserAccessManager\Controller
39 */
40 class RedirectController extends Controller
41 {
42 use LoginControllerTrait;
43
44 const POST_URL_CACHE_KEY = 'PostUrls';
45
46 /**
47 * @var MainConfig
48 */
49 private $mainConfig;
50
51 /**
52 * @var Database
53 */
54 private $database;
55
56 /**
57 * @var Cache
58 */
59 private $cache;
60
61 /**
62 * @var Util
63 */
64 private $util;
65
66 /**
67 * @var ObjectHandler
68 */
69 private $objectHandler;
70
71 /**
72 * @var AccessHandler
73 */
74 private $accessHandler;
75
76 /**
77 * @var FileHandler
78 */
79 private $fileHandler;
80
81 /**
82 * @var FileObjectFactory
83 */
84 private $fileObjectFactory;
85
86 /**
87 * RedirectController constructor.
88 * @param Php $php
89 * @param Wordpress $wordpress
90 * @param WordpressConfig $wordpressConfig
91 * @param MainConfig $mainConfig
92 * @param Database $database
93 * @param Util $util
94 * @param Cache $cache
95 * @param ObjectHandler $objectHandler
96 * @param AccessHandler $accessHandler
97 * @param FileHandler $fileHandler
98 * @param FileObjectFactory $fileObjectFactory
99 */
100 public function __construct(
101 Php $php,
102 Wordpress $wordpress,
103 WordpressConfig $wordpressConfig,
104 MainConfig $mainConfig,
105 Database $database,
106 Util $util,
107 Cache $cache,
108 ObjectHandler $objectHandler,
109 AccessHandler $accessHandler,
110 FileHandler $fileHandler,
111 FileObjectFactory $fileObjectFactory
112 ) {
113 parent::__construct($php, $wordpress, $wordpressConfig);
114 $this->mainConfig = $mainConfig;
115 $this->database = $database;
116 $this->util = $util;
117 $this->cache = $cache;
118 $this->objectHandler = $objectHandler;
119 $this->accessHandler = $accessHandler;
120 $this->fileHandler = $fileHandler;
121 $this->fileObjectFactory = $fileObjectFactory;
122 }
123
124 /**
125 * @return Wordpress
126 */
127 protected function getWordpress(): Wordpress
128 {
129 return $this->wordpress;
130 }
131
132 /**
133 * Returns the post by the given url.
134 * @param string $url The url of the post(attachment).
135 * @return int
136 */
137 public function getPostIdByUrl(string $url): int
138 {
139 $postUrls = (array)$this->cache->getFromRuntimeCache(self::POST_URL_CACHE_KEY);
140
141 if (isset($postUrls[$url]) === true) {
142 return $postUrls[$url];
143 }
144
145 //Filter size
146 $newUrlPieces = preg_split('/-[0-9]+x[0-9]+(_[a-z])?/', $url);
147 $newUrl = (count($newUrlPieces) === 2) ? $newUrlPieces[0] . $newUrlPieces[1] : $newUrlPieces[0];
148 $newUrl = preg_replace('/-pdf\.jpg$/', '.pdf', $newUrl);
149
150 $postUrls[$url] = $this->wordpress->attachmentUrlToPostId($newUrl);
151 $this->cache->addToRuntimeCache(self::POST_URL_CACHE_KEY, $postUrls);
152
153 return $postUrls[$url];
154 }
155
156 /**
157 * Returns the file object by the given type and url.
158 * @param string $objectType The type of the requested file.
159 * @param string $objectUrl The file url.
160 * @return null|FileObject
161 */
162 private function getFileSettingsByType(string $objectType, string $objectUrl): ?FileObject
163 {
164 $fileObject = null;
165
166 if ($objectType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
167 $uploadDirs = $this->wordpress->getUploadDir();
168 $uploadDir = str_replace(ABSPATH, '/', $uploadDirs['basedir']);
169 $regex = '/.*' . str_replace('/', '\/', $uploadDir) . '\//i';
170 $cleanObjectUrl = preg_replace($regex, '', $objectUrl);
171 $uploadUrl = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
172 $objectUrl = rtrim($uploadUrl, '/') . '/' . ltrim($cleanObjectUrl, '/');
173
174 $post = $this->objectHandler->getPost($this->getPostIdByUrl($objectUrl));
175 $postType = $post->post_type ?? '';
176
177 if ($postType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
178 $multiPath = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
179
180 $fileObject = $this->fileObjectFactory->createFileObject(
181 $post->ID,
182 $objectType,
183 $uploadDirs['basedir'] . str_replace($multiPath, '', $objectUrl),
184 $this->wordpress->attachmentIsImage($post->ID)
185 );
186 }
187 } else {
188 $extraParameter = $this->getRequestParameter('uamextra');
189
190 $fileObject = $this->wordpress->applyFilters(
191 'uam_get_file_settings_by_type',
192 $fileObject,
193 $objectType,
194 $objectUrl,
195 $extraParameter
196 );
197 }
198
199 return $fileObject;
200 }
201
202 /**
203 * Delivers the content of the requested file.
204 * @param string $objectType The type of the requested file.
205 * @param string $objectUrl The file url.
206 * @throws UserGroupTypeException
207 */
208 public function getFile(string $objectType, string $objectUrl)
209 {
210 $fileObject = $this->getFileSettingsByType($objectType, $objectUrl);
211
212 if ($fileObject === null) {
213 return;
214 }
215
216 if ($this->accessHandler->checkObjectAccess($fileObject->getType(), $fileObject->getId()) === true) {
217 $file = $fileObject->getFile();
218 } elseif ($fileObject->isImage() === true) {
219 if ($this->mainConfig->getNoAccessImageType() === 'custom') {
220 $file = $this->mainConfig->getCustomNoAccessImage();
221 } else {
222 $realPath = $this->wordpressConfig->getRealPath();
223 $file = $realPath . 'assets' . DIRECTORY_SEPARATOR . 'gfx' . DIRECTORY_SEPARATOR . 'noAccessPic.png';
224 }
225 } else {
226 $this->wordpress->wpDie(TXT_UAM_NO_RIGHTS_MESSAGE, TXT_UAM_NO_RIGHTS_TITLE, ['response' => 403]);
227 return;
228 }
229
230 $this->fileHandler->getFile($file, $fileObject->isImage());
231 }
232
233 /**
234 * Returns the redirect url and the permalink of the post if exists.
235 * @param null|string $permalink
236 * @return null|string
237 */
238 private function getRedirectUrlAndPermalink(?string &$permalink): ?string
239 {
240 $permalink = null;
241 $redirect = $this->mainConfig->getRedirect();
242
243 if ($redirect === 'custom_page') {
244 $redirectCustomPage = $this->mainConfig->getRedirectCustomPage();
245 $post = $this->objectHandler->getPost($redirectCustomPage);
246 $url = null;
247
248 if ($post !== false) {
249 $url = $post->guid;
250 $permalink = $this->wordpress->getPageLink($post);
251 }
252 } elseif ($redirect === 'custom_url') {
253 $url = $this->mainConfig->getRedirectCustomUrl();
254 } elseif ($redirect === 'login') {
255 $url = $this->getLoginUrl();
256 } else {
257 $url = $this->wordpress->getHomeUrl('/');
258 }
259
260 return $url;
261 }
262
263 /**
264 * Redirects the user to his destination.
265 * @param bool $checkPosts
266 * @throws UserGroupTypeException
267 */
268 public function redirectUser($checkPosts = true)
269 {
270 if ($checkPosts === true) {
271 $posts = (array)$this->wordpress->getWpQuery()->get_posts();
272
273 foreach ($posts as $post) {
274 if ($this->accessHandler->checkObjectAccess($post->post_type, $post->ID)) {
275 return;
276 }
277 }
278 }
279
280 $url = $this->getRedirectUrlAndPermalink($permalink);
281 $currentUrl = $this->util->getCurrentUrl();
282
283 if ($url !== null && $url !== $currentUrl && $permalink !== $currentUrl) {
284 $this->wordpress->wpRedirect($url);
285 $this->php->callExit();
286 }
287 }
288
289 /**
290 * Returns the post id by the post name.
291 * @param string $name
292 * @return int
293 */
294 private function getPostIdByName(string $name): int
295 {
296 $postableTypes = implode('\',\'', $this->objectHandler->getPostTypes());
297
298 $query = $this->database->prepare(
299 "SELECT ID
300 FROM {$this->database->getPostsTable()}
301 WHERE post_name = %s
302 AND post_type IN ('{$postableTypes}')",
303 $name
304 );
305
306 return (int) $this->database->getVariable($query);
307 }
308
309 /**
310 * Extracts the object type and id.
311 * @param mixed $pageParams
312 * @param null|string $objectType
313 * @param null|int|string $objectId
314 */
315 private function extractObjectTypeAndId($pageParams, ?string &$objectType, ?string &$objectId)
316 {
317 $objectType = null;
318 $objectId = null;
319
320 $simpleTypes = [
321 'p' => ObjectHandler::GENERAL_POST_OBJECT_TYPE,
322 'page_id' => ObjectHandler::GENERAL_POST_OBJECT_TYPE,
323 'cat_id' => ObjectHandler::GENERAL_TERM_OBJECT_TYPE
324 ];
325
326 foreach ($simpleTypes as $queryVar => $newObjectType) {
327 if (isset($pageParams->query_vars[$queryVar]) === true) {
328 $objectType = $newObjectType;
329 $objectId = $pageParams->query_vars[$queryVar];
330 }
331 }
332
333 if (isset($pageParams->query_vars['name']) === true) {
334 $objectType = ObjectHandler::GENERAL_POST_OBJECT_TYPE;
335 $objectId = $this->getPostIdByName($pageParams->query_vars['name']);
336 } elseif (isset($pageParams->query_vars['pagename']) === true) {
337 $object = $this->wordpress->getPageByPath($pageParams->query_vars['pagename']);
338
339 if ($object !== null) {
340 $objectType = $object->post_type ?? null;
341 $objectId = $object->ID ?? null;
342 }
343 }
344 }
345
346 /**
347 * Redirects to a page or to content.
348 * @param array|null $headers The headers which are given from wordpress.
349 * @param mixed $pageParams The params of the current page.
350 * @return array
351 * @throws UserGroupTypeException
352 */
353 public function redirect(?array $headers, $pageParams): array
354 {
355 $fileUrl = $this->getRequestParameter('uamgetfile');
356 $fileType = $this->getRequestParameter('uamfiletype');
357
358 if ($fileUrl !== null && $fileType !== null) {
359 $this->getFile($fileType, $fileUrl);
360 } elseif ($this->wordpressConfig->atAdminPanel() === false
361 && $this->mainConfig->getRedirect() !== 'false'
362 ) {
363 $this->extractObjectTypeAndId($pageParams, $objectType, $objectId);
364
365 if ($this->accessHandler->checkObjectAccess($objectType, $objectId) === false) {
366 $this->redirectUser(false);
367 }
368 }
369
370 return $headers;
371 }
372
373 /**
374 * Returns the url for a locked file.
375 * @param string $url The base url.
376 * @param int|string $id The id of the file.
377 * @return string
378 */
379 public function getFileUrl(string $url, $id): string
380 {
381 // Nginx always supports real urls so we need the new urls only
382 // if we don't use nginx and mod_rewrite is disabled
383 if ($this->mainConfig->lockFile() === true
384 && $this->wordpress->isNginx() === false
385 && $this->wordpress->gotModRewrite() === false
386 ) {
387 $post = $this->objectHandler->getPost($id);
388
389 if ($post !== null) {
390 $type = explode('/', $post->post_mime_type);
391 $type = $type[1] ?? $type[0];
392
393 $lockedFileTypes = $this->mainConfig->getLockedFiles();
394 $fileTypes = explode(',', $lockedFileTypes);
395
396 if ($lockedFileTypes === 'all' || in_array($type, $fileTypes) === true) {
397 $url = $this->wordpress->getHomeUrl('/') . '?uamfiletype=attachment&uamgetfile=' . $url;
398 }
399 }
400 }
401
402 return $url;
403 }
404
405 /**
406 * Caches the urls for the post for a later lookup.
407 * @param string $url The url of the post.
408 * @param object $post The post object.
409 * @return string
410 */
411 public function cachePostLinks(string $url, object $post): string
412 {
413 $postUrls = (array) $this->cache->getFromRuntimeCache(self::POST_URL_CACHE_KEY);
414 $postUrls[$url] = $post->ID;
415 $this->cache->addToRuntimeCache(self::POST_URL_CACHE_KEY, $postUrls);
416 return $url;
417 }
418
419 /**
420 * Tries to load the file via x send file
421 */
422 public function testXSendFile()
423 {
424 $this->fileHandler->deliverXSendFileTestFile();
425 }
426 }
427