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

310 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace UserAccessManager\Controller\Frontend;
6
7 use JetBrains\PhpStorm\NoReturn;
8 use UserAccessManager\Access\AccessHandler;
9 use UserAccessManager\Cache\Cache;
10 use UserAccessManager\Config\MainConfig;
11 use UserAccessManager\Config\WordpressConfig;
12 use UserAccessManager\Controller\Controller;
13 use UserAccessManager\Database\Database;
14 use UserAccessManager\File\FileHandler;
15 use UserAccessManager\File\FileObject;
16 use UserAccessManager\File\FileObjectFactory;
17 use UserAccessManager\Object\ObjectHandler;
18 use UserAccessManager\UserGroup\UserGroupTypeException;
19 use UserAccessManager\Util\Util;
20 use UserAccessManager\Wrapper\Php;
21 use UserAccessManager\Wrapper\Wordpress;
22
23 class RedirectController extends Controller
24 {
25 use LoginControllerTrait;
26
27 public const POST_URL_CACHE_KEY = 'PostUrls';
28 public const REDIRECT_TO_PARAMETER = 'redirect_to';
29
30 public function __construct(
31 Php $php,
32 Wordpress $wordpress,
33 WordpressConfig $wordpressConfig,
34 private MainConfig $mainConfig,
35 private Database $database,
36 private Util $util,
37 private Cache $cache,
38 private ObjectHandler $objectHandler,
39 private AccessHandler $accessHandler,
40 private FileHandler $fileHandler,
41 private FileObjectFactory $fileObjectFactory
42 ) {
43 parent::__construct($php, $wordpress, $wordpressConfig);
44 }
45
46 protected function getWordpress(): Wordpress
47 {
48 return $this->wordpress;
49 }
50
51 public function getPostIdByUrl(string $url): int
52 {
53 $postUrls = (array)$this->cache->getFromRuntimeCache(self::POST_URL_CACHE_KEY);
54
55 if (isset($postUrls[$url]) === true) {
56 return $postUrls[$url];
57 }
58
59 //Filter size
60 $newUrlPieces = preg_split('/-[0-9]+x[0-9]+(_[a-z])?/', $url);
61 $newUrl = (count($newUrlPieces) === 2) ? $newUrlPieces[0] . $newUrlPieces[1] : $newUrlPieces[0];
62 $newUrl = preg_replace('/-pdf\.jpg$/', '.pdf', $newUrl);
63
64 $postId = $this->wordpress->attachmentUrlToPostId($newUrl);
65
66 if ($postId === 0) {
67 $newUrl = preg_replace('/(\\.[^.\\s]{3,4})$/', '-scaled$1', $newUrl);
68 $postId = $this->wordpress->attachmentUrlToPostId($newUrl);
69 }
70
71 $postUrls[$url] = $postId;
72 $this->cache->addToRuntimeCache(self::POST_URL_CACHE_KEY, $postUrls);
73
74 return $postUrls[$url];
75 }
76
77 private function getFileSettingsByType(string $objectType, string $objectUrl): ?FileObject
78 {
79 $fileObject = null;
80
81 if ($objectType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
82 $uploadDirs = $this->wordpress->getUploadDir();
83 $uploadDir = str_replace(ABSPATH, '/', $uploadDirs['basedir']);
84 $regex = '/.*' . str_replace('/', '\/', $uploadDir) . '\//i';
85 $cleanObjectUrl = preg_replace($regex, '', $objectUrl);
86 $uploadUrl = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
87 $objectUrl = rtrim($uploadUrl, '/') . '/' . ltrim($cleanObjectUrl, '/');
88
89 $post = $this->objectHandler->getPost($this->getPostIdByUrl($objectUrl));
90 $postType = $post->post_type ?? '';
91
92 if ($postType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
93 $multiPath = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
94
95 $fileObject = $this->fileObjectFactory->createFileObject(
96 $post->ID,
97 $objectType,
98 $uploadDirs['basedir'] . str_replace($multiPath, '', $objectUrl),
99 $this->wordpress->attachmentIsImage($post->ID)
100 );
101 }
102 } else {
103 $extraParameter = $this->getRequestParameter('uamextra');
104
105 $fileObject = $this->wordpress->applyFilters(
106 'uam_get_file_settings_by_type',
107 $fileObject,
108 $objectType,
109 $objectUrl,
110 $extraParameter
111 );
112 }
113
114 return $fileObject;
115 }
116
117 /**
118 * @throws UserGroupTypeException
119 */
120 public function getFile(string $objectType, string $objectUrl): void
121 {
122 $fileObject = $this->getFileSettingsByType($objectType, $objectUrl);
123
124 if ($fileObject === null) {
125 return;
126 }
127
128 if ($this->accessHandler->checkObjectAccess($fileObject->getType(), $fileObject->getId()) === true) {
129 $file = $fileObject->getFile();
130 } elseif ($fileObject->isImage() === true) {
131 if ($this->mainConfig->getNoAccessImageType() === 'custom') {
132 $file = $this->mainConfig->getCustomNoAccessImage();
133 } else {
134 $realPath = $this->wordpressConfig->getRealPath();
135 $file = $realPath . 'assets' . DIRECTORY_SEPARATOR . 'gfx' . DIRECTORY_SEPARATOR . 'noAccessPic.png';
136 }
137 } else {
138 $this->wordpress->wpDie(TXT_UAM_NO_RIGHTS_MESSAGE, TXT_UAM_NO_RIGHTS_TITLE, ['response' => 403]);
139 return;
140 }
141
142 $this->fileHandler->getFile($file, $fileObject->isImage());
143 }
144
145 private function getRedirectUrlAndPermalink(?string &$permalink): ?string
146 {
147 $permalink = null;
148 $redirect = $this->mainConfig->getRedirect();
149
150 if ($redirect === 'custom_page') {
151 $redirectCustomPage = $this->mainConfig->getRedirectCustomPage();
152 $post = $this->objectHandler->getPost($redirectCustomPage);
153 $url = null;
154
155 if ($post !== false) {
156 $url = $post->guid;
157 $permalink = $this->wordpress->getPageLink($post);
158 }
159 } elseif ($redirect === 'custom_url') {
160 $url = $this->mainConfig->getRedirectCustomUrl();
161 } elseif ($redirect === 'login') {
162 $url = $this->getLoginUrl();
163 } elseif ($redirect === 'origin') {
164 $referer = $this->wordpress->getReferer();
165 $url = $referer !== false ? $referer : $this->wordpress->getHomeUrl('/');
166 } else {
167 $url = $this->wordpress->getHomeUrl('/');
168 }
169
170 return $url;
171 }
172
173 /**
174 * @throws UserGroupTypeException
175 */
176 public function redirectUser(bool $checkPosts = true): void
177 {
178 if ($checkPosts === true) {
179 $posts = $this->wordpress->getWpQuery()->get_posts();
180
181 foreach ($posts as $post) {
182 if ($this->accessHandler->checkObjectAccess($post->post_type, $post->ID)) {
183 return;
184 }
185 }
186 }
187
188 $url = $this->getRedirectUrlAndPermalink($permalink);
189 $currentUrl = $this->util->getCurrentUrl();
190
191 if ($url !== null && $url !== $currentUrl && $permalink !== $currentUrl) {
192 if ($this->mainConfig->appendRedirectToParameter() === true) {
193 $url = $this->wordpress->addQueryArg([self::REDIRECT_TO_PARAMETER => $currentUrl], $url);
194 }
195
196 $this->wordpress->wpRedirect($url);
197 $this->php->callExit();
198 }
199 }
200
201 private function getPostIdByName(string $name): int
202 {
203 $postableTypes = implode('\',\'', $this->objectHandler->getPostTypes());
204
205 $query = $this->database->prepare(
206 "SELECT ID
207 FROM {$this->database->getPostsTable()}
208 WHERE post_name = %s
209 AND post_type IN ('$postableTypes')",
210 $name
211 );
212
213 return (int) $this->database->getVariable($query);
214 }
215
216 private function extractObjectTypeAndId(mixed $pageParams, ?string &$objectType, int|string|null &$objectId): void
217 {
218 $objectType = null;
219 $objectId = null;
220
221 $simpleTypes = [
222 'p' => ObjectHandler::GENERAL_POST_OBJECT_TYPE,
223 'page_id' => ObjectHandler::GENERAL_POST_OBJECT_TYPE,
224 'cat_id' => ObjectHandler::GENERAL_TERM_OBJECT_TYPE
225 ];
226
227 foreach ($simpleTypes as $queryVar => $newObjectType) {
228 if (isset($pageParams->query_vars[$queryVar]) === true) {
229 $objectType = $newObjectType;
230 $objectId = $pageParams->query_vars[$queryVar];
231 }
232 }
233
234 if (isset($pageParams->query_vars['name']) === true) {
235 $objectType = ObjectHandler::GENERAL_POST_OBJECT_TYPE;
236 $objectId = $this->getPostIdByName($pageParams->query_vars['name']);
237 } elseif (isset($pageParams->query_vars['pagename']) === true) {
238 $object = $this->wordpress->getPageByPath($pageParams->query_vars['pagename']);
239
240 if ($object !== null) {
241 $objectType = $object->post_type ?? null;
242 $objectId = $object->ID ?? null;
243 }
244 }
245 }
246
247 /**
248 * @throws UserGroupTypeException
249 */
250 public function redirect(?array $headers, mixed $pageParams): ?array
251 {
252 $fileUrl = $this->getRequestParameter('uamgetfile');
253 $fileType = $this->getRequestParameter('uamfiletype');
254
255 if ($fileUrl !== null && $fileType !== null) {
256 $this->getFile($fileType, $fileUrl);
257 } elseif ($this->wordpressConfig->atAdminPanel() === false
258 && $this->mainConfig->getRedirect() !== 'false'
259 ) {
260 $this->extractObjectTypeAndId($pageParams, $objectType, $objectId);
261
262 if ($this->accessHandler->checkObjectAccess($objectType, $objectId) === false) {
263 $this->redirectUser(false);
264 }
265 }
266
267 return $headers;
268 }
269
270 public function getFileUrl(string $url, int|string|null $id): string
271 {
272 // Nginx always supports real urls so we need the new urls only
273 // if we don't use nginx and mod_rewrite is disabled
274 if ($this->mainConfig->lockFile() === true
275 && $this->wordpress->isNginx() === false
276 && $this->wordpress->gotModRewrite() === false
277 ) {
278 $post = $this->objectHandler->getPost($id);
279
280 if ($post !== false) {
281 $type = explode('/', $post->post_mime_type);
282 $type = $type[1] ?? $type[0];
283
284 $lockedFileTypes = $this->mainConfig->getLockedFiles();
285 $fileTypes = explode(',', $lockedFileTypes);
286
287 if ($lockedFileTypes === 'all' || in_array($type, $fileTypes) === true) {
288 $url = $this->wordpress->getHomeUrl('/') . '?uamfiletype=attachment&uamgetfile=' . $url;
289 }
290 }
291 }
292
293 return $url;
294 }
295
296 public function cachePostLinks(string $url, object $post): string
297 {
298 $postUrls = (array) $this->cache->getFromRuntimeCache(self::POST_URL_CACHE_KEY);
299 $postUrls[$url] = $post->ID;
300 $this->cache->addToRuntimeCache(self::POST_URL_CACHE_KEY, $postUrls);
301 return $url;
302 }
303
304 #[NoReturn]
305 public function testXSendFile(): void
306 {
307 $this->fileHandler->deliverXSendFileTestFile();
308 }
309 }
310