PluginProbe
User Access Manager / 2.2.25
User Access Manager v2.2.25
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.25, at src/Controller/Frontend/RedirectController.php

434 lines 13.5 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 $postId = $this->wordpress->attachmentUrlToPostId($newUrl);
151
152 if ($postId === 0) {
153 $newUrl = preg_replace('/(\\.[^.\\s]{3,4})$/', '-scaled$1', $newUrl);
154 $postId = $this->wordpress->attachmentUrlToPostId($newUrl);
155 }
156
157 $postUrls[$url] = $postId;
158 $this->cache->addToRuntimeCache(self::POST_URL_CACHE_KEY, $postUrls);
159
160 return $postUrls[$url];
161 }
162
163 /**
164 * Returns the file object by the given type and url.
165 * @param string $objectType The type of the requested file.
166 * @param string $objectUrl The file url.
167 * @return null|FileObject
168 */
169 private function getFileSettingsByType(string $objectType, string $objectUrl): ?FileObject
170 {
171 $fileObject = null;
172
173 if ($objectType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
174 $uploadDirs = $this->wordpress->getUploadDir();
175 $uploadDir = str_replace(ABSPATH, '/', $uploadDirs['basedir']);
176 $regex = '/.*' . str_replace('/', '\/', $uploadDir) . '\//i';
177 $cleanObjectUrl = preg_replace($regex, '', $objectUrl);
178 $uploadUrl = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
179 $objectUrl = rtrim($uploadUrl, '/') . '/' . ltrim($cleanObjectUrl, '/');
180
181 $post = $this->objectHandler->getPost($this->getPostIdByUrl($objectUrl));
182 $postType = $post->post_type ?? '';
183
184 if ($postType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
185 $multiPath = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
186
187 $fileObject = $this->fileObjectFactory->createFileObject(
188 $post->ID,
189 $objectType,
190 $uploadDirs['basedir'] . str_replace($multiPath, '', $objectUrl),
191 $this->wordpress->attachmentIsImage($post->ID)
192 );
193 }
194 } else {
195 $extraParameter = $this->getRequestParameter('uamextra');
196
197 $fileObject = $this->wordpress->applyFilters(
198 'uam_get_file_settings_by_type',
199 $fileObject,
200 $objectType,
201 $objectUrl,
202 $extraParameter
203 );
204 }
205
206 return $fileObject;
207 }
208
209 /**
210 * Delivers the content of the requested file.
211 * @param string $objectType The type of the requested file.
212 * @param string $objectUrl The file url.
213 * @throws UserGroupTypeException
214 */
215 public function getFile(string $objectType, string $objectUrl)
216 {
217 $fileObject = $this->getFileSettingsByType($objectType, $objectUrl);
218
219 if ($fileObject === null) {
220 return;
221 }
222
223 if ($this->accessHandler->checkObjectAccess($fileObject->getType(), $fileObject->getId()) === true) {
224 $file = $fileObject->getFile();
225 } elseif ($fileObject->isImage() === true) {
226 if ($this->mainConfig->getNoAccessImageType() === 'custom') {
227 $file = $this->mainConfig->getCustomNoAccessImage();
228 } else {
229 $realPath = $this->wordpressConfig->getRealPath();
230 $file = $realPath . 'assets' . DIRECTORY_SEPARATOR . 'gfx' . DIRECTORY_SEPARATOR . 'noAccessPic.png';
231 }
232 } else {
233 $this->wordpress->wpDie(TXT_UAM_NO_RIGHTS_MESSAGE, TXT_UAM_NO_RIGHTS_TITLE, ['response' => 403]);
234 return;
235 }
236
237 $this->fileHandler->getFile($file, $fileObject->isImage());
238 }
239
240 /**
241 * Returns the redirect url and the permalink of the post if exists.
242 * @param null|string $permalink
243 * @return null|string
244 */
245 private function getRedirectUrlAndPermalink(?string &$permalink): ?string
246 {
247 $permalink = null;
248 $redirect = $this->mainConfig->getRedirect();
249
250 if ($redirect === 'custom_page') {
251 $redirectCustomPage = $this->mainConfig->getRedirectCustomPage();
252 $post = $this->objectHandler->getPost($redirectCustomPage);
253 $url = null;
254
255 if ($post !== false) {
256 $url = $post->guid;
257 $permalink = $this->wordpress->getPageLink($post);
258 }
259 } elseif ($redirect === 'custom_url') {
260 $url = $this->mainConfig->getRedirectCustomUrl();
261 } elseif ($redirect === 'login') {
262 $url = $this->getLoginUrl();
263 } else {
264 $url = $this->wordpress->getHomeUrl('/');
265 }
266
267 return $url;
268 }
269
270 /**
271 * Redirects the user to his destination.
272 * @param bool $checkPosts
273 * @throws UserGroupTypeException
274 */
275 public function redirectUser($checkPosts = true)
276 {
277 if ($checkPosts === true) {
278 $posts = (array)$this->wordpress->getWpQuery()->get_posts();
279
280 foreach ($posts as $post) {
281 if ($this->accessHandler->checkObjectAccess($post->post_type, $post->ID)) {
282 return;
283 }
284 }
285 }
286
287 $url = $this->getRedirectUrlAndPermalink($permalink);
288 $currentUrl = $this->util->getCurrentUrl();
289
290 if ($url !== null && $url !== $currentUrl && $permalink !== $currentUrl) {
291 $this->wordpress->wpRedirect($url);
292 $this->php->callExit();
293 }
294 }
295
296 /**
297 * Returns the post id by the post name.
298 * @param string $name
299 * @return int
300 */
301 private function getPostIdByName(string $name): int
302 {
303 $postableTypes = implode('\',\'', $this->objectHandler->getPostTypes());
304
305 $query = $this->database->prepare(
306 "SELECT ID
307 FROM {$this->database->getPostsTable()}
308 WHERE post_name = %s
309 AND post_type IN ('{$postableTypes}')",
310 $name
311 );
312
313 return (int) $this->database->getVariable($query);
314 }
315
316 /**
317 * Extracts the object type and id.
318 * @param mixed $pageParams
319 * @param null|string $objectType
320 * @param null|int|string $objectId
321 */
322 private function extractObjectTypeAndId($pageParams, ?string &$objectType, ?string &$objectId)
323 {
324 $objectType = null;
325 $objectId = null;
326
327 $simpleTypes = [
328 'p' => ObjectHandler::GENERAL_POST_OBJECT_TYPE,
329 'page_id' => ObjectHandler::GENERAL_POST_OBJECT_TYPE,
330 'cat_id' => ObjectHandler::GENERAL_TERM_OBJECT_TYPE
331 ];
332
333 foreach ($simpleTypes as $queryVar => $newObjectType) {
334 if (isset($pageParams->query_vars[$queryVar]) === true) {
335 $objectType = $newObjectType;
336 $objectId = $pageParams->query_vars[$queryVar];
337 }
338 }
339
340 if (isset($pageParams->query_vars['name']) === true) {
341 $objectType = ObjectHandler::GENERAL_POST_OBJECT_TYPE;
342 $objectId = $this->getPostIdByName($pageParams->query_vars['name']);
343 } elseif (isset($pageParams->query_vars['pagename']) === true) {
344 $object = $this->wordpress->getPageByPath($pageParams->query_vars['pagename']);
345
346 if ($object !== null) {
347 $objectType = $object->post_type ?? null;
348 $objectId = $object->ID ?? null;
349 }
350 }
351 }
352
353 /**
354 * Redirects to a page or to content.
355 * @param array|null $headers The headers which are given from wordpress.
356 * @param mixed $pageParams The params of the current page.
357 * @return array|null
358 * @throws UserGroupTypeException
359 */
360 public function redirect(?array $headers, $pageParams): ?array
361 {
362 $fileUrl = $this->getRequestParameter('uamgetfile');
363 $fileType = $this->getRequestParameter('uamfiletype');
364
365 if ($fileUrl !== null && $fileType !== null) {
366 $this->getFile($fileType, $fileUrl);
367 } elseif ($this->wordpressConfig->atAdminPanel() === false
368 && $this->mainConfig->getRedirect() !== 'false'
369 ) {
370 $this->extractObjectTypeAndId($pageParams, $objectType, $objectId);
371
372 if ($this->accessHandler->checkObjectAccess($objectType, $objectId) === false) {
373 $this->redirectUser(false);
374 }
375 }
376
377 return $headers;
378 }
379
380 /**
381 * Returns the url for a locked file.
382 * @param string $url The base url.
383 * @param int|string $id The id of the file.
384 * @return string
385 */
386 public function getFileUrl(string $url, $id): string
387 {
388 // Nginx always supports real urls so we need the new urls only
389 // if we don't use nginx and mod_rewrite is disabled
390 if ($this->mainConfig->lockFile() === true
391 && $this->wordpress->isNginx() === false
392 && $this->wordpress->gotModRewrite() === false
393 ) {
394 $post = $this->objectHandler->getPost($id);
395
396 if ($post !== null) {
397 $type = explode('/', $post->post_mime_type);
398 $type = $type[1] ?? $type[0];
399
400 $lockedFileTypes = $this->mainConfig->getLockedFiles();
401 $fileTypes = explode(',', $lockedFileTypes);
402
403 if ($lockedFileTypes === 'all' || in_array($type, $fileTypes) === true) {
404 $url = $this->wordpress->getHomeUrl('/') . '?uamfiletype=attachment&uamgetfile=' . $url;
405 }
406 }
407 }
408
409 return $url;
410 }
411
412 /**
413 * Caches the urls for the post for a later lookup.
414 * @param string $url The url of the post.
415 * @param object $post The post object.
416 * @return string
417 */
418 public function cachePostLinks(string $url, object $post): string
419 {
420 $postUrls = (array) $this->cache->getFromRuntimeCache(self::POST_URL_CACHE_KEY);
421 $postUrls[$url] = $post->ID;
422 $this->cache->addToRuntimeCache(self::POST_URL_CACHE_KEY, $postUrls);
423 return $url;
424 }
425
426 /**
427 * Tries to load the file via x send file
428 */
429 public function testXSendFile()
430 {
431 $this->fileHandler->deliverXSendFileTestFile();
432 }
433 }
434