PluginProbe
User Access Manager / 2.1.11
User Access Manager v2.1.11
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
← All changes | src/Controller/Frontend/RedirectController.php +217 -164 2.3.18 → 2.1.11 View file →
@@ -1,56 +1,140 @@
1 1 <?php
2 -
3 -declare(strict_types=1);
4 -
2 +/**
3 + * FrontendRedirectController.php
4 + *
5 + * The FrontendRedirectController class file.
6 + *
7 + * PHP versions 5
8 + *
9 + * @author Alexander Schneider <[email protected]>
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 + */
5 15 namespace UserAccessManager\Controller\Frontend;
6 16
7 -use JetBrains\PhpStorm\NoReturn;
8 17 use UserAccessManager\Access\AccessHandler;
9 18 use UserAccessManager\Cache\Cache;
10 19 use UserAccessManager\Config\MainConfig;
11 20 use UserAccessManager\Config\WordpressConfig;
12 21 use UserAccessManager\Controller\Controller;
13 -use UserAccessManager\Controller\Frontend\Authentication\LoginControllerTrait;
14 22 use UserAccessManager\Database\Database;
15 23 use UserAccessManager\File\FileHandler;
16 -use UserAccessManager\File\Delivery\FileObject;
17 -use UserAccessManager\File\Delivery\FileObjectFactory;
24 +use UserAccessManager\File\FileObject;
25 +use UserAccessManager\File\FileObjectFactory;
18 26 use UserAccessManager\Object\ObjectHandler;
19 -use UserAccessManager\UserGroup\UserGroupTypeException;
20 27 use UserAccessManager\Util\Util;
21 28 use UserAccessManager\Wrapper\Php;
22 29 use UserAccessManager\Wrapper\Wordpress;
23 30
31 +/**
32 + * Class FrontendRedirectController
33 + *
34 + * @package UserAccessManager\Controller
35 + */
24 36 class RedirectController extends Controller
25 37 {
26 38 use LoginControllerTrait;
27 39
28 - public const POST_URL_CACHE_KEY = 'PostUrls';
29 - public const REDIRECT_TO_PARAMETER = 'redirect_to';
40 + const POST_URL_CACHE_KEY = 'PostUrls';
30 41
42 + /**
43 + * @var MainConfig
44 + */
45 + private $mainConfig;
46 +
47 + /**
48 + * @var Database
49 + */
50 + private $database;
51 +
52 + /**
53 + * @var Cache
54 + */
55 + private $cache;
56 +
57 + /**
58 + * @var Util
59 + */
60 + private $util;
61 +
62 + /**
63 + * @var ObjectHandler
64 + */
65 + private $objectHandler;
66 +
67 + /**
68 + * @var AccessHandler
69 + */
70 + private $accessHandler;
71 +
72 + /**
73 + * @var FileHandler
74 + */
75 + private $fileHandler;
76 +
77 + /**
78 + * @var FileObjectFactory
79 + */
80 + private $fileObjectFactory;
81 +
82 + /**
83 + * RedirectController constructor.
84 + *
85 + * @param Php $php
86 + * @param Wordpress $wordpress
87 + * @param WordpressConfig $wordpressConfig
88 + * @param MainConfig $mainConfig
89 + * @param Database $database
90 + * @param Util $util
91 + * @param Cache $cache
92 + * @param ObjectHandler $objectHandler
93 + * @param AccessHandler $accessHandler
94 + * @param FileHandler $fileHandler
95 + * @param FileObjectFactory $fileObjectFactory
96 + */
31 97 public function __construct(
32 98 Php $php,
33 99 Wordpress $wordpress,
34 100 WordpressConfig $wordpressConfig,
35 - private MainConfig $mainConfig,
36 - private Database $database,
37 - private Util $util,
38 - private Cache $cache,
39 - private ObjectHandler $objectHandler,
40 - private AccessHandler $accessHandler,
41 - private FileHandler $fileHandler,
42 - private FileObjectFactory $fileObjectFactory
101 + MainConfig $mainConfig,
102 + Database $database,
103 + Util $util,
104 + Cache $cache,
105 + ObjectHandler $objectHandler,
106 + AccessHandler $accessHandler,
107 + FileHandler $fileHandler,
108 + FileObjectFactory $fileObjectFactory
43 109 ) {
44 110 parent::__construct($php, $wordpress, $wordpressConfig);
111 + $this->mainConfig = $mainConfig;
112 + $this->database = $database;
113 + $this->util = $util;
114 + $this->cache = $cache;
115 + $this->objectHandler = $objectHandler;
116 + $this->accessHandler = $accessHandler;
117 + $this->fileHandler = $fileHandler;
118 + $this->fileObjectFactory = $fileObjectFactory;
45 119 }
46 120
47 - protected function getWordpress(): Wordpress
121 + /**
122 + * @return Wordpress
123 + */
124 + protected function getWordpress()
48 125 {
49 126 return $this->wordpress;
50 127 }
51 128
52 - public function getPostIdByUrl(string $url): int
129 + /**
130 + * Returns the post by the given url.
131 + *
132 + * @param string $url The url of the post(attachment).
133 + *
134 + * @return int
135 + */
136 + public function getPostIdByUrl($url)
53 137 {
54 138 $postUrls = (array)$this->cache->getFromRuntimeCache(self::POST_URL_CACHE_KEY);
55 139
56 140 if (isset($postUrls[$url]) === true) {
@@ -57,144 +141,74 @@
57 141 return $postUrls[$url];
58 142 }
59 143
60 144 //Filter size
61 - $newUrlPieces = preg_split('/-[0-9]+x[0-9]+(_[a-z])?/', $url);
62 - $newUrl = (count($newUrlPieces) === 2) ? $newUrlPieces[0] . $newUrlPieces[1] : $newUrlPieces[0];
63 - $newUrl = preg_replace('/-pdf\.jpg$/', '.pdf', $newUrl);
145 + $newUrlPieces = preg_split('/-[0-9]{1,}x[0-9]{1,}(_[a-z])?/', $url);
146 + $newUrl = (count($newUrlPieces) === 2) ? $newUrlPieces[0].$newUrlPieces[1] : $newUrlPieces[0];
147 + $newUrl = preg_replace('/\-pdf\.jpg$/', '.pdf', $newUrl);
64 148
65 - $postId = $this->wordpress->attachmentUrlToPostId($newUrl);
66 -
67 - if ($postId === 0) {
68 - $newUrl = preg_replace('/(\\.[^.\\s]{3,4})$/', '-scaled$1', $newUrl);
69 - $postId = $this->wordpress->attachmentUrlToPostId($newUrl);
70 - }
71 -
72 - $postUrls[$url] = $postId;
149 + $postUrls[$url] = $this->wordpress->attachmentUrlToPostId($newUrl);
73 150 $this->cache->addToRuntimeCache(self::POST_URL_CACHE_KEY, $postUrls);
74 151
75 152 return $postUrls[$url];
76 153 }
77 154
78 - private function normalizeAttachmentUrl(array $uploadDirs, string $objectUrl): string
79 - {
80 - $uploadDir = str_replace(ABSPATH, '/', $uploadDirs['basedir']);
81 - $regex = '/.*' . str_replace('/', '\/', $uploadDir) . '\//i';
82 - $cleanObjectUrl = preg_replace($regex, '', $objectUrl);
83 - $uploadUrl = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
84 -
85 - return rtrim($uploadUrl, '/') . '/' . ltrim($cleanObjectUrl, '/');
86 - }
87 -
88 - private function isRegisteredSize(int $attachmentId, string $fileName): bool
89 - {
90 - $metaData = $this->wordpress->getAttachmentMetadata($attachmentId);
91 - $sizes = is_array($metaData) === true ? (array) ($metaData['sizes'] ?? []) : [];
92 -
93 - return in_array($fileName, array_column($sizes, 'file'), true);
94 - }
95 -
96 155 /**
97 - * Returns the file the request asks for and tells through $isImage whether it can be shown as image.
98 - * A requested generated size is only used if it is registered at the attachment and stored inside the
99 - * upload directory, so no arbitrary and no missing file becomes reachable. Generated sizes are always
100 - * images, also for documents like PDFs, where they are the preview images shown in the media library.
156 + * Returns the file object by the given type and url.
157 + *
158 + * @param string $objectType The type of the requested file.
159 + * @param string $objectUrl The file url.
160 + *
161 + * @return null|FileObject
101 162 */
102 - private function getAttachmentFile(
103 - int $attachmentId,
104 - string $attachedFile,
105 - string $requestedUrl,
106 - string $uploadBaseDir,
107 - ?bool &$isImage
108 - ): string {
109 - $requestedFileName = basename((string) parse_url($requestedUrl, PHP_URL_PATH));
110 - $sizeFile = dirname($attachedFile) . DIRECTORY_SEPARATOR . $requestedFileName;
111 -
112 - if ($requestedFileName !== basename($attachedFile)
113 - && $this->isRegisteredSize($attachmentId, $requestedFileName) === true
114 - && $this->isInsideUploadDirectory($sizeFile, $uploadBaseDir) === true
115 - ) {
116 - $isImage = true;
117 -
118 - return $sizeFile;
119 - }
120 -
121 - $isImage = $this->wordpress->attachmentIsImage($attachmentId);
122 -
123 - return $attachedFile;
124 - }
125 -
126 - private function getAttachmentFileObject(string $objectUrl): ?FileObject
163 + private function getFileSettingsByType($objectType, $objectUrl)
127 164 {
128 - $uploadDirs = $this->wordpress->getUploadDir();
129 - $requestedUrl = $this->normalizeAttachmentUrl($uploadDirs, $objectUrl);
130 - $postId = $this->getPostIdByUrl($requestedUrl);
165 + $fileObject = null;
131 166
132 - if ($postId < 1) {
133 - return null;
134 - }
167 + if ($objectType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
168 + $uploadDirs = $this->wordpress->getUploadDir();
169 + $uploadDir = str_replace(ABSPATH, '/', $uploadDirs['basedir']);
170 + $regex = '/.*'.str_replace('/', '\/', $uploadDir).'\//i';
171 + $cleanObjectUrl = preg_replace($regex, '', $objectUrl);
172 + $uploadUrl = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
173 + $objectUrl = rtrim($uploadUrl, '/').'/'.ltrim($cleanObjectUrl, '/');
135 174
136 - $post = $this->objectHandler->getPost($postId);
175 + $post = $this->objectHandler->getPost($this->getPostIdByUrl($objectUrl));
137 176
138 - if (($post->post_type ?? '') !== ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
139 - return null;
140 - }
177 + if ($post !== false
178 + && $post->post_type === ObjectHandler::ATTACHMENT_OBJECT_TYPE
179 + ) {
180 + $multiPath = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
141 181
142 - $attachedFile = $this->wordpress->getAttachedFile($post->ID);
182 + $fileObject = $this->fileObjectFactory->createFileObject(
183 + $post->ID,
184 + $objectType,
185 + $uploadDirs['basedir'].str_replace($multiPath, '', $objectUrl),
186 + $this->wordpress->attachmentIsImage($post->ID)
187 + );
188 + }
189 + } else {
190 + $extraParameter = $this->getRequestParameter('uamextra');
143 191
144 - if ($attachedFile === false
145 - || $this->isInsideUploadDirectory($attachedFile, $uploadDirs['basedir']) === false
146 - ) {
147 - return null;
192 + $fileObject = $this->wordpress->applyFilters(
193 + 'uam_get_file_settings_by_type',
194 + $fileObject,
195 + $objectType,
196 + $objectUrl,
197 + $extraParameter
198 + );
148 199 }
149 200
150 - $file = $this->getAttachmentFile(
151 - $post->ID,
152 - $attachedFile,
153 - $requestedUrl,
154 - $uploadDirs['basedir'],
155 - $isImage
156 - );
157 -
158 - return $this->fileObjectFactory->createFileObject(
159 - $post->ID,
160 - ObjectHandler::ATTACHMENT_OBJECT_TYPE,
161 - $file,
162 - $isImage
163 - );
201 + return $fileObject;
164 202 }
165 203
166 - private function isInsideUploadDirectory(string $file, string $uploadBaseDir): bool
167 - {
168 - $realFile = $this->php->realpath($file);
169 - $realUploadBaseDir = $this->php->realpath($uploadBaseDir);
170 -
171 - return $realFile !== false
172 - && $realUploadBaseDir !== false
173 - && str_starts_with($realFile, $realUploadBaseDir . DIRECTORY_SEPARATOR);
174 - }
175 -
176 - private function getFileSettingsByType(string $objectType, string $objectUrl): ?FileObject
177 - {
178 - if ($objectType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
179 - return $this->getAttachmentFileObject($objectUrl);
180 - }
181 -
182 - $extraParameter = $this->getRequestParameter('uamextra');
183 -
184 - return $this->wordpress->applyFilters(
185 - 'uam_get_file_settings_by_type',
186 - null,
187 - $objectType,
188 - $objectUrl,
189 - $extraParameter
190 - );
191 - }
192 -
193 204 /**
194 - * @throws UserGroupTypeException
205 + * Delivers the content of the requested file.
206 + *
207 + * @param string $objectType The type of the requested file.
208 + * @param string $objectUrl The file url.
195 209 */
196 - public function getFile(string $objectType, string $objectUrl): void
210 + public function getFile($objectType, $objectUrl)
197 211 {
198 212 $fileObject = $this->getFileSettingsByType($objectType, $objectUrl);
199 213
200 214 if ($fileObject === null) {
@@ -207,9 +221,9 @@
207 221 if ($this->mainConfig->getNoAccessImageType() === 'custom') {
208 222 $file = $this->mainConfig->getCustomNoAccessImage();
209 223 } else {
210 224 $realPath = $this->wordpressConfig->getRealPath();
211 - $file = $realPath . 'assets' . DIRECTORY_SEPARATOR . 'gfx' . DIRECTORY_SEPARATOR . 'noAccessPic.png';
225 + $file = $realPath.'assets'.DIRECTORY_SEPARATOR.'gfx'.DIRECTORY_SEPARATOR.'noAccessPic.png';
212 226 }
213 227 } else {
214 228 $this->wordpress->wpDie(TXT_UAM_NO_RIGHTS_MESSAGE, TXT_UAM_NO_RIGHTS_TITLE, ['response' => 403]);
215 229 return;
@@ -217,9 +231,16 @@
217 231
218 232 $this->fileHandler->getFile($file, $fileObject->isImage());
219 233 }
220 234
221 - private function getRedirectUrlAndPermalink(?string &$permalink): ?string
235 + /**
236 + * Returns the redirect url and the permalink of the post if exists.
237 + *
238 + * @param null|string $permalink
239 + *
240 + * @return null|string
241 + */
242 + private function getRedirectUrlAndPermalink(&$permalink)
222 243 {
223 244 $permalink = null;
224 245 $redirect = $this->mainConfig->getRedirect();
225 246
@@ -235,11 +256,8 @@
235 256 } elseif ($redirect === 'custom_url') {
236 257 $url = $this->mainConfig->getRedirectCustomUrl();
237 258 } elseif ($redirect === 'login') {
238 259 $url = $this->getLoginUrl();
239 - } elseif ($redirect === 'origin') {
240 - $referer = $this->wordpress->getReferer();
241 - $url = $referer !== false ? $referer : $this->wordpress->getHomeUrl('/');
242 260 } else {
243 261 $url = $this->wordpress->getHomeUrl('/');
244 262 }
245 263
@@ -246,14 +264,16 @@
246 264 return $url;
247 265 }
248 266
249 267 /**
250 - * @throws UserGroupTypeException
268 + * Redirects the user to his destination.
269 + *
270 + * @param bool $checkPosts
251 271 */
252 - public function redirectUser(bool $checkPosts = true): void
272 + public function redirectUser($checkPosts = true)
253 273 {
254 274 if ($checkPosts === true) {
255 - $posts = $this->wordpress->getWpQuery()->get_posts();
275 + $posts = (array)$this->wordpress->getWpQuery()->get_posts();
256 276
257 277 foreach ($posts as $post) {
258 278 if ($this->accessHandler->checkObjectAccess($post->post_type, $post->ID)) {
259 279 return;
@@ -264,18 +284,21 @@
264 284 $url = $this->getRedirectUrlAndPermalink($permalink);
265 285 $currentUrl = $this->util->getCurrentUrl();
266 286
267 287 if ($url !== null && $url !== $currentUrl && $permalink !== $currentUrl) {
268 - if ($this->mainConfig->appendRedirectToParameter() === true) {
269 - $url = $this->wordpress->addQueryArg([self::REDIRECT_TO_PARAMETER => $currentUrl], $url);
270 - }
271 -
272 288 $this->wordpress->wpRedirect($url);
273 289 $this->php->callExit();
274 290 }
275 291 }
276 292
277 - private function getPostIdByName(string $name): int
293 + /**
294 + * Returns the post id by the post name.
295 + *
296 + * @param string $name
297 + *
298 + * @return int
299 + */
300 + private function getPostIdByName($name)
278 301 {
279 302 $postableTypes = implode('\',\'', $this->objectHandler->getPostTypes());
280 303
281 304 $query = $this->database->prepare(
@@ -281,16 +304,23 @@
281 304 $query = $this->database->prepare(
282 305 "SELECT ID
283 306 FROM {$this->database->getPostsTable()}
284 307 WHERE post_name = %s
285 - AND post_type IN ('$postableTypes')",
308 + AND post_type IN ('{$postableTypes}')",
286 309 $name
287 310 );
288 311
289 - return (int) $this->database->getVariable($query);
312 + return (int)$this->database->getVariable($query);
290 313 }
291 314
292 - private function extractObjectTypeAndId(mixed $pageParams, ?string &$objectType, int|string|null &$objectId): void
315 + /**
316 + * Extracts the object type and id.
317 + *
318 + * @param object $pageParams
319 + * @param null|string $objectType
320 + * @param null|string $objectId
321 + */
322 + private function extractObjectTypeAndId($pageParams, &$objectType, &$objectId)
293 323 {
294 324 $objectType = null;
295 325 $objectId = null;
296 326
@@ -313,18 +343,23 @@
313 343 } elseif (isset($pageParams->query_vars['pagename']) === true) {
314 344 $object = $this->wordpress->getPageByPath($pageParams->query_vars['pagename']);
315 345
316 346 if ($object !== null) {
317 - $objectType = $object->post_type ?? null;
318 - $objectId = $object->ID ?? null;
347 + $objectType = $object->post_type;
348 + $objectId = $object->ID;
319 349 }
320 350 }
321 351 }
322 352
323 353 /**
324 - * @throws UserGroupTypeException
354 + * Redirects to a page or to content.
355 + *
356 + * @param string $headers The headers which are given from wordpress.
357 + * @param object $pageParams The params of the current page.
358 + *
359 + * @return string
325 360 */
326 - public function redirect(?array $headers, mixed $pageParams): ?array
361 + public function redirect($headers, $pageParams)
327 362 {
328 363 $fileUrl = $this->getRequestParameter('uamgetfile');
329 364 $fileType = $this->getRequestParameter('uamfiletype');
330 365
@@ -342,9 +377,17 @@
342 377
343 378 return $headers;
344 379 }
345 380
346 - public function getFileUrl(string $url, int|string|null $id): string
381 + /**
382 + * Returns the url for a locked file.
383 + *
384 + * @param string $url The base url.
385 + * @param integer $id The _iId of the file.
386 + *
387 + * @return string
388 + */
389 + public function getFileUrl($url, $id)
347 390 {
348 391 // Nginx always supports real urls so we need the new urls only
349 392 // if we don't use nginx and mod_rewrite is disabled
350 393 if ($this->mainConfig->lockFile() === true
@@ -352,17 +395,17 @@
352 395 && $this->wordpress->gotModRewrite() === false
353 396 ) {
354 397 $post = $this->objectHandler->getPost($id);
355 398
356 - if ($post !== false) {
399 + if ($post !== null) {
357 400 $type = explode('/', $post->post_mime_type);
358 - $type = $type[1] ?? $type[0];
401 + $type = (isset($type[1]) === true) ? $type[1] : $type[0];
359 402
360 403 $lockedFileTypes = $this->mainConfig->getLockedFiles();
361 404 $fileTypes = explode(',', $lockedFileTypes);
362 405
363 406 if ($lockedFileTypes === 'all' || in_array($type, $fileTypes) === true) {
364 - $url = $this->wordpress->getHomeUrl('/') . '?uamfiletype=attachment&uamgetfile=' . $url;
407 + $url = $this->wordpress->getHomeUrl('/').'?uamfiletype=attachment&uamgetfile='.$url;
365 408 }
366 409 }
367 410 }
368 411
@@ -368,18 +411,28 @@
368 411
369 412 return $url;
370 413 }
371 414
372 - public function cachePostLinks(string $url, object $post): string
415 + /**
416 + * Caches the urls for the post for a later lookup.
417 + *
418 + * @param string $url The url of the post.
419 + * @param object $post The post object.
420 + *
421 + * @return string
422 + */
423 + public function cachePostLinks($url, $post)
373 424 {
374 - $postUrls = (array) $this->cache->getFromRuntimeCache(self::POST_URL_CACHE_KEY);
425 + $postUrls = (array)$this->cache->getFromRuntimeCache(self::POST_URL_CACHE_KEY);
375 426 $postUrls[$url] = $post->ID;
376 427 $this->cache->addToRuntimeCache(self::POST_URL_CACHE_KEY, $postUrls);
377 428 return $url;
378 429 }
379 430
380 - #[NoReturn]
381 - public function testXSendFile(): void
431 + /**
432 + * Tries to load the file via x send file
433 + */
434 + public function testXSendFile()
382 435 {
383 436 $this->fileHandler->deliverXSendFileTestFile();
384 437 }
385 438 }