PluginProbe
User Access Manager / 2.3.4
User Access Manager v2.3.4
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/PostController.php +13 -191 2.3.172.3.4 View file →
@@ -16,27 +16,18 @@
16 16 use UserAccessManager\UserGroup\UserGroupTypeException;
17 17 use UserAccessManager\Util\Util;
18 18 use UserAccessManager\Wrapper\Php;
19 19 use UserAccessManager\Wrapper\Wordpress;
20 -use WeakMap;
21 20 use WP_Comment;
22 -use WP_Error;
23 21 use WP_Hook;
24 22 use WP_Post;
25 23 use WP_Query;
26 -use WP_REST_Request;
27 -use WP_REST_Response;
28 24
29 25 class PostController extends ContentController
30 26 {
31 - private const REST_OBJECT_ROUTE_PATTERN = '#^/[^/]+/v\d+/([^/]+)/(\d+)(?:/(\w+))?#';
32 -
33 27 private array $wordpressFilters = [];
34 28 private stdClass|array|null $cachedCounts = [];
35 - private ?array $restBaseToPostTypeMap = null;
36 29
37 - private WeakMap $posts;
38 -
39 30 public function __construct(
40 31 Php $php,
41 32 Wordpress $wordpress,
42 33 WordpressConfig $wordpressConfig,
@@ -58,10 +49,8 @@
58 49 $userHandler,
59 50 $userGroupHandler,
60 51 $accessHandler
61 52 );
62 -
63 - $this->posts = new WeakMap();
64 53 }
65 54
66 55 public function getWordpressFilters(): array
67 56 {
@@ -73,13 +62,8 @@
73 62 return isset($wpQuery->query_vars['suppress_filters']) === true
74 63 && $wpQuery->query_vars['suppress_filters'] === true;
75 64 }
76 65
77 - private function addExcludedPosts(mixed $postsNotIn, array $excludedPosts): array
78 - {
79 - return array_unique(array_merge((array) $postsNotIn, $excludedPosts));
80 - }
81 -
82 66 /**
83 67 * @throws UserGroupTypeException
84 68 */
85 69 public function parseQuery(WP_Query $wpQuery): void
@@ -87,11 +71,13 @@
87 71 if ($this->filtersSuppressed($wpQuery) === true) {
88 72 $excludedPosts = $this->accessHandler->getExcludedPosts();
89 73
90 74 if ($excludedPosts !== []) {
91 - $wpQuery->query_vars['post__not_in'] = $this->addExcludedPosts(
92 - $wpQuery->query_vars['post__not_in'] ?? [],
93 - $excludedPosts
75 + $postsNotIn = (isset($wpQuery->query_vars['post__not_in']) === true) ?
76 + $wpQuery->query_vars['post__not_in'] : [];
77 +
78 + $wpQuery->query_vars['post__not_in'] = array_unique(
79 + array_merge($postsNotIn, $excludedPosts)
94 80 );
95 81 }
96 82 }
97 83 }
@@ -180,15 +166,15 @@
180 166
181 167 /**
182 168 * @throws UserGroupTypeException
183 169 */
184 - private function processPost(WP_Post $post): WP_Post|bool
170 + private function processPost(WP_Post $post): ?WP_Post
185 171 {
186 172 $post->post_title .= $this->adminOutput($post->post_type, $post->ID);
187 173
188 174 if ($this->accessHandler->checkObjectAccess($post->post_type, $post->ID) === false) {
189 175 if ($this->removePostFromList($post->post_type) === true) {
190 - return false;
176 + return null;
191 177 }
192 178
193 179 $post->post_content = $this->processPostContent($post);
194 180
@@ -206,17 +192,8 @@
206 192
207 193 /**
208 194 * @throws UserGroupTypeException
209 195 */
210 - private function getProcessedPost(WP_Post $post): ?WP_Post
211 - {
212 - $post = $this->posts[$post] ??= $this->processPost($post);
213 - return $post === false ? null : $post;
214 - }
215 -
216 - /**
217 - * @throws UserGroupTypeException
218 - */
219 196 private function filterRawPosts(array $rawPosts): array
220 197 {
221 198 $filteredPosts = [];
222 199
@@ -223,9 +200,9 @@
223 200 foreach ($rawPosts as $rawPost) {
224 201 $post = $this->getPost($rawPost);
225 202
226 203 if ($post !== false) {
227 - $post = $this->getProcessedPost($post);
204 + $post = $this->processPost($post);
228 205
229 206 if ($post !== null) {
230 207 $filteredPosts[] = $post;
231 208 }
@@ -259,166 +236,11 @@
259 236 {
260 237 return $this->filterRawPosts($rawPages);
261 238 }
262 239
263 - private function getRestAccessDeniedError(): WP_Error
264 - {
265 - return $this->wordpress->getWpError(
266 - 'uam_rest_access_denied',
267 - TXT_UAM_REST_ACCESS_DENIED,
268 - ['status' => $this->wordpress->isUserLoggedIn() === true ? 403 : 401]
269 - );
270 - }
271 -
272 - private function setRestField(array &$data, string $field, string $value): void
273 - {
274 - if (array_key_exists($field, $data) === false) {
275 - return;
276 - }
277 -
278 - if (is_array($data[$field]) === false) {
279 - $data[$field] = $value;
280 -
281 - return;
282 - }
283 -
284 - $restrictedValues = ['rendered' => $value, 'raw' => $value, 'protected' => false];
285 -
286 - foreach ($restrictedValues as $key => $restrictedValue) {
287 - if (array_key_exists($key, $data[$field]) === true) {
288 - $data[$field][$key] = $restrictedValue;
289 - }
290 - }
291 - }
292 -
293 240 /**
294 241 * @throws UserGroupTypeException
295 242 */
296 - public function restrictRestResponse(mixed $response, mixed $post = null, mixed $request = null): mixed
297 - {
298 - if (($response instanceof WP_REST_Response) === false
299 - || ($post instanceof WP_Post) === false
300 - || $this->accessHandler->checkObjectAccess($post->post_type, $post->ID) === true
301 - ) {
302 - return $response;
303 - }
304 -
305 - $restrictedContent = $this->processPostContent($post);
306 - $data = (array) $response->get_data();
307 -
308 - $this->setRestField($data, 'content', $restrictedContent);
309 - $this->setRestField($data, 'excerpt', $restrictedContent);
310 -
311 - if ($this->mainConfig->hidePostTypeTitle($post->post_type) === true) {
312 - $this->setRestField($data, 'title', $this->mainConfig->getPostTypeTitle($post->post_type));
313 - }
314 -
315 - $response->set_data($data);
316 -
317 - return $response;
318 - }
319 -
320 - /**
321 - * @throws UserGroupTypeException
322 - */
323 - public function excludeRestrictedPostsFromRestQuery(array $queryArgs): array
324 - {
325 - $excludedPosts = $this->accessHandler->getExcludedPosts();
326 -
327 - if ($excludedPosts !== []) {
328 - $queryArgs['post__not_in'] = $this->addExcludedPosts($queryArgs['post__not_in'] ?? [], $excludedPosts);
329 - }
330 -
331 - return $queryArgs;
332 - }
333 -
334 - private function getRestBaseToPostTypeMap(): array
335 - {
336 - if ($this->restBaseToPostTypeMap !== null) {
337 - return $this->restBaseToPostTypeMap;
338 - }
339 -
340 - $this->restBaseToPostTypeMap = [];
341 -
342 - foreach ((array) $this->objectHandler->getPostTypes() as $postType) {
343 - $restBase = $this->wordpress->getPostTypeObject($postType)?->rest_base;
344 - $this->restBaseToPostTypeMap[empty($restBase) === true ? $postType : $restBase] = $postType;
345 - }
346 -
347 - return $this->restBaseToPostTypeMap;
348 - }
349 -
350 - /**
351 - * @return null|array{type: string, id: int, addressesSubResource: bool}
352 - */
353 - private function getRestRouteTarget(WP_REST_Request $request): ?array
354 - {
355 - if (preg_match(self::REST_OBJECT_ROUTE_PATTERN, (string) $request->get_route(), $matches) !== 1) {
356 - return null;
357 - }
358 -
359 - $postType = $this->getRestBaseToPostTypeMap()[$matches[1]] ?? null;
360 -
361 - return $postType === null ? null : [
362 - 'type' => $postType,
363 - 'id' => (int) $matches[2],
364 - 'addressesSubResource' => ($matches[3] ?? '') !== ''
365 - ];
366 - }
367 -
368 - private function isReadingRestRequest(WP_REST_Request $request): bool
369 - {
370 - return in_array(strtoupper((string) $request->get_method()), Wordpress::REST_READING_METHODS, true);
371 - }
372 -
373 - private function isEditingRestRoute(bool $addressesSubResource, WP_REST_Request $request): bool
374 - {
375 - return $this->isReadingRestRequest($request) === false || $addressesSubResource === true;
376 - }
377 -
378 - /**
379 - * @throws UserGroupTypeException
380 - */
381 - private function hasRestRouteAccess(string $objectType, int $objectId, bool $isEditingRoute): bool
382 - {
383 - if ($isEditingRoute === true) {
384 - return $this->accessHandler->checkObjectAccess($objectType, $objectId, true);
385 - }
386 -
387 - return $this->removePostFromList($objectType) === false
388 - || $this->accessHandler->checkObjectAccess($objectType, $objectId);
389 - }
390 -
391 - /**
392 - * @throws UserGroupTypeException
393 - */
394 - public function restrictRestRequest(mixed $result, mixed $server = null, mixed $request = null): mixed
395 - {
396 - if (($request instanceof WP_REST_Request) === false) {
397 - return $result;
398 - }
399 -
400 - $routeTarget = $this->getRestRouteTarget($request);
401 - $isEditingRoute = $routeTarget !== null
402 - && $this->isEditingRestRoute($routeTarget['addressesSubResource'], $request);
403 -
404 - $this->wordpress->setRestRequestContext(
405 - $isEditingRoute === true || $request->get_param('context') === 'edit'
406 - );
407 -
408 - if ($result !== null || $routeTarget === null) {
409 - return $result;
410 - }
411 -
412 - ['type' => $type, 'id' => $id] = $routeTarget;
413 -
414 - return $this->hasRestRouteAccess($type, $id, $isEditingRoute) === true ?
415 - $result : $this->getRestAccessDeniedError();
416 - }
417 -
418 - /**
419 - * @throws UserGroupTypeException
420 - */
421 243 public function getAttachedFile(string $file, int|string|null $attachmentId): bool|string
422 244 {
423 245 $isImage = (bool) preg_match('/(?i)\.(jpg|jpeg|jpe|png|gif)$/', $file);
424 246
@@ -437,9 +259,9 @@
437 259 {
438 260 $excludedPosts = $this->accessHandler->getExcludedPosts();
439 261
440 262 if ($excludedPosts !== []) {
441 - $excludedPostsStr = implode(', ', array_map('intval', $excludedPosts));
263 + $excludedPostsStr = implode(', ', $excludedPosts);
442 264 $query .= " AND $table.ID NOT IN ($excludedPostsStr) ";
443 265 }
444 266
445 267 return $query;
@@ -462,13 +284,13 @@
462 284 }
463 285
464 286 private function getPostCountQuery(array $excludedPosts, string $type, string $perm): string
465 287 {
466 - $excludedPosts = implode(', ', array_map('intval', $excludedPosts));
467 - $query = "SELECT post_status, COUNT(*) AS num_posts
468 - FROM {$this->database->getPostsTable()}
288 + $excludedPosts = implode('\', \'', $excludedPosts);
289 + $query = "SELECT post_status, COUNT(*) AS num_posts
290 + FROM {$this->database->getPostsTable()}
469 291 WHERE post_type = %s
470 - AND ID NOT IN ($excludedPosts)";
292 + AND ID NOT IN ('$excludedPosts')";
471 293
472 294 if ('readable' === $perm
473 295 && $this->wordpress->isUserLoggedIn() === true
474 296 && $this->wordpress->currentUserCan(