PluginProbe
User Access Manager / 2.0.11
User Access Manager v2.0.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
user-access-manager / src / UserAccessManager / Controller / FrontendController.php

FrontendController.php in User Access Manager 2.0.11, at src/UserAccessManager/Controller/FrontendController.php

1,169 lines 34.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * FrontendController.php
4 *
5 * The FrontendController 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 namespace UserAccessManager\Controller;
16
17 use UserAccessManager\AccessHandler\AccessHandler;
18 use UserAccessManager\Cache\Cache;
19 use UserAccessManager\Config\Config;
20 use UserAccessManager\Database\Database;
21 use UserAccessManager\FileHandler\FileHandler;
22 use UserAccessManager\FileHandler\FileObject;
23 use UserAccessManager\FileHandler\FileObjectFactory;
24 use UserAccessManager\ObjectHandler\ObjectHandler;
25 use UserAccessManager\UserAccessManager;
26 use UserAccessManager\UserGroup\UserGroup;
27 use UserAccessManager\Util\Util;
28 use UserAccessManager\Wrapper\Php;
29 use UserAccessManager\Wrapper\Wordpress;
30
31 /**
32 * Class FrontendController
33 *
34 * @package UserAccessManager\Controller
35 */
36 class FrontendController extends Controller
37 {
38 const HANDLE_STYLE_LOGIN_FORM = 'UserAccessManagerLoginForm';
39 const POST_URL_CACHE_KEY = 'PostUrls';
40 const POST_COUNTS_CACHE_KEY = 'WpPostCounts';
41
42 /**
43 * @var Database
44 */
45 private $database;
46
47 /**
48 * @var Cache
49 */
50 private $cache;
51
52 /**
53 * @var Util
54 */
55 private $util;
56
57 /**
58 * @var ObjectHandler
59 */
60 private $objectHandler;
61
62 /**
63 * @var AccessHandler
64 */
65 private $accessHandler;
66
67 /**
68 * @var FileHandler
69 */
70 private $fileHandler;
71
72 /**
73 * @var FileObjectFactory
74 */
75 private $fileObjectFactory;
76
77 /**
78 * @var array
79 */
80 private $wordpressFilters = array();
81
82 /**
83 * FrontendController constructor.
84 *
85 * @param Php $php
86 * @param Wordpress $wordpress
87 * @param Config $config
88 * @param Database $database
89 * @param Util $util
90 * @param Cache $cache
91 * @param ObjectHandler $objectHandler
92 * @param AccessHandler $accessHandler
93 * @param FileHandler $fileHandler
94 * @param FileObjectFactory $fileObjectFactory
95 */
96 public function __construct(
97 Php $php,
98 Wordpress $wordpress,
99 Config $config,
100 Database $database,
101 Util $util,
102 Cache $cache,
103 ObjectHandler $objectHandler,
104 AccessHandler $accessHandler,
105 FileHandler $fileHandler,
106 FileObjectFactory $fileObjectFactory
107 ) {
108 parent::__construct($php, $wordpress, $config);
109 $this->database = $database;
110 $this->util = $util;
111 $this->cache = $cache;
112 $this->objectHandler = $objectHandler;
113 $this->accessHandler = $accessHandler;
114 $this->fileHandler = $fileHandler;
115 $this->fileObjectFactory = $fileObjectFactory;
116 }
117
118 /**
119 * Functions for other content.
120 */
121
122 /**
123 * Register all other styles.
124 */
125 private function registerStylesAndScripts()
126 {
127 $urlPath = $this->config->getUrlPath();
128
129 $this->wordpress->registerStyle(
130 self::HANDLE_STYLE_LOGIN_FORM,
131 $urlPath.'assets/css/uamLoginForm.css',
132 [],
133 UserAccessManager::VERSION,
134 'screen'
135 );
136 }
137
138 /**
139 * The function for the wp_enqueue_scripts action.
140 */
141 public function enqueueStylesAndScripts()
142 {
143 $this->registerStylesAndScripts();
144 $this->wordpress->enqueueStyle(self::HANDLE_STYLE_LOGIN_FORM);
145 }
146
147 /*
148 * Functions for the blog content.
149 */
150
151 /**
152 * Manipulates the wordpress query object to filter content.
153 *
154 * @param \WP_Query $wpQuery The wordpress query object.
155 */
156 public function parseQuery($wpQuery)
157 {
158 if (isset($wpQuery->query_vars['suppress_filters']) === true
159 && $wpQuery->query_vars['suppress_filters'] === true
160 ) {
161 $excludedPosts = $this->accessHandler->getExcludedPosts();
162
163 if (count($excludedPosts) > 0) {
164 $postsNotIn = (isset($wpQuery->query_vars['post__not_in']) === true) ?
165 $wpQuery->query_vars['post__not_in'] : [];
166
167 $wpQuery->query_vars['post__not_in'] = array_unique(
168 array_merge($postsNotIn, $excludedPosts)
169 );
170 }
171 }
172 }
173
174 /**
175 * Returns the admin hint.
176 *
177 * @param string $objectType The object type.
178 * @param integer $objectId The object id we want to check.
179 * @param string $text The text on which we want to append the hint.
180 *
181 * @return string
182 */
183 public function adminOutput($objectType, $objectId, $text = null)
184 {
185 $output = '';
186
187 if ($this->config->atAdminPanel() === false
188 && $this->config->blogAdminHint() === true
189 ) {
190 $hintText = $this->config->getBlogAdminHintText();
191
192 if ($text !== null && $this->util->endsWith($text, $hintText) === true) {
193 return $output;
194 }
195
196 if ($this->accessHandler->userIsAdmin($this->wordpress->getCurrentUser()->ID) === true
197 && count($this->accessHandler->getUserGroupsForObject($objectType, $objectId)) > 0
198 ) {
199 $output .= $hintText;
200 }
201 }
202
203 return $output;
204 }
205
206 /**
207 * Returns the login bar.
208 *
209 * @return string
210 */
211 public function getLoginFormHtml()
212 {
213 $loginForm = '';
214
215 if ($this->wordpress->isUserLoggedIn() === false) {
216 $loginForm = $this->getIncludeContents('LoginForm.php');
217 }
218
219 return $this->wordpress->applyFilters('uam_login_form', $loginForm);
220 }
221
222 /**
223 * If filters are suppressed we still want to filter posts, so we have to turn the suppression off,
224 * remove all other filters than the ones from the user access manager and store them to restore
225 * them later.
226 *
227 * @param array $posts
228 * @param \WP_Query $query
229 *
230 * @return mixed
231 */
232 public function postsPreQuery($posts, \WP_Query $query)
233 {
234 if (isset($query->query_vars['suppress_filters']) === true
235 && $query->query_vars['suppress_filters'] === true
236 ) {
237 $filters = $this->wordpress->getFilters();
238
239 if (isset($filters['the_posts']) === true && isset($filters['the_posts']->callbacks[10]) === true) {
240 foreach ($filters['the_posts']->callbacks[10] as $postFilter) {
241 if (is_array($postFilter['function']) === true
242 && $postFilter['function'][0] instanceof FrontendController
243 && $postFilter['function'][1] === 'showPosts'
244 ) {
245 $query->query_vars['suppress_filters'] = false;
246 $filters['the_posts']->callbacks = [10 => [$postFilter]];
247 break;
248 }
249 }
250 }
251
252 // Only unset filter if the user access filter is active
253 if ($query->query_vars['suppress_filters'] === false) {
254 $filtersToProcess = ['posts_results'];
255
256 foreach ($filtersToProcess as $filterToProcess) {
257 if (isset($filters[$filterToProcess]) === true) {
258 $this->wordpressFilters[$filterToProcess] = $filters[$filterToProcess];
259 unset($filters[$filterToProcess]);
260 }
261 }
262
263 $this->wordpress->setFilters($filters);
264 }
265 }
266
267 return $posts;
268 }
269
270 /**
271 * Restores the filters to normal.
272 */
273 private function restoreFilters()
274 {
275 if (count($this->wordpressFilters) > 0) {
276 $filters = $this->wordpress->getFilters();
277
278 foreach ($this->wordpressFilters as $filterKey => $filter) {
279 $filters[$filterKey] = $filter;
280 }
281
282 $this->wordpress->setFilters($filters);
283 $this->wordpressFilters = [];
284 }
285 }
286
287 /**
288 * Tries to get the post from the given mixed data.
289 *
290 * @param mixed $post
291 *
292 * @return false|\WP_Post
293 */
294 private function getPost($post)
295 {
296 if ($post instanceof \WP_post) {
297 return $post;
298 } elseif (is_int($post) === true) {
299 return $this->objectHandler->getPost($post);
300 } elseif ($post instanceof \stdClass && isset($post->ID)) {
301 return $this->objectHandler->getPost($post->ID);
302 }
303
304 return false;
305 }
306
307 /**
308 * Modifies the content of the post by the given settings.
309 *
310 * @param \WP_Post $post The current post.
311 * @param bool $locked
312 *
313 * @return null|\WP_Post
314 */
315 private function processPost(\WP_Post $post, &$locked = null)
316 {
317 $post->post_title .= $this->adminOutput($post->post_type, $post->ID);
318 $locked = ($this->accessHandler->checkObjectAccess($post->post_type, $post->ID) === false);
319
320 if ($locked === true) {
321 if ($this->config->hidePostType($post->post_type) === true
322 || $this->config->atAdminPanel() === true
323 ) {
324 return null;
325 }
326
327 $uamPostContent = $this->config->getPostTypeContent($post->post_type);
328
329 if ($post->post_type === 'post'
330 && $this->config->showPostContentBeforeMore() === true
331 && preg_match('/<!--more(.*?)?-->/', $post->post_content, $matches)
332 ) {
333 $uamPostContent = explode($matches[0], $post->post_content)[0]." ".$uamPostContent;
334 }
335
336 $post->post_content = stripslashes($uamPostContent);
337
338 if ($this->config->hidePostTypeTitle($post->post_type) === true) {
339 $post->post_title = $this->config->getPostTypeTitle($post->post_type);
340 }
341
342 if ($this->config->hidePostTypeComments($post->post_type) === true) {
343 $post->comment_status = 'close';
344 }
345 }
346
347 return $post;
348 }
349
350 /**
351 * The function for the the_posts filter.
352 *
353 * @param array $rawPosts The posts.
354 *
355 * @return array
356 */
357 public function showPosts($rawPosts = [])
358 {
359 $showPosts = [];
360
361 if ($this->wordpress->isFeed() === false || $this->config->protectFeed() === true) {
362 foreach ($rawPosts as $rawPost) {
363 $post = $this->getPost($rawPost);
364
365 if ($post !== false) {
366 $post = $this->processPost($post);
367
368 if ($post !== null) {
369 $showPosts[] = $post;
370 }
371 } else {
372 $showPosts[] = $rawPost;
373 }
374 }
375 } else {
376 $showPosts = $rawPosts;
377 }
378
379 $this->restoreFilters();
380
381 return $showPosts;
382 }
383
384 /**
385 * The function for the get_pages filter.
386 *
387 * @param \WP_Post[] $rawPages The pages.
388 *
389 * @return array
390 */
391 public function showPages($rawPages = [])
392 {
393 $showPages = [];
394
395 foreach ($rawPages as $rawPage) {
396 $page = $this->getPost($rawPage);
397
398 if ($page !== false) {
399 $page = $this->processPost($page);
400
401 if ($page !== null) {
402 $showPages[] = $page;
403 }
404 } else {
405 $showPages[] = $rawPage;
406 }
407 }
408
409 $rawPages = $showPages;
410
411 return $rawPages;
412 }
413
414 /**
415 * Checks the access of the attached file.
416 *
417 * @param string $file
418 * @param int $attachmentId
419 *
420 * @return bool
421 */
422 public function getAttachedFile($file, $attachmentId)
423 {
424 $hasAccess = $this->accessHandler->checkObjectAccess(ObjectHandler::ATTACHMENT_OBJECT_TYPE, $attachmentId);
425 return ($hasAccess === true) ? $file : false;
426 }
427
428 /**
429 * Needed to prevent the form against the auto <br>s of wordpress
430 *
431 * @param string $content
432 *
433 * @return string
434 */
435 public function showContent($content)
436 {
437 return (string)str_replace('[LOGIN_FORM]', $this->getLoginFormHtml(), $content);
438 }
439
440 /**
441 * The function for the posts_where_paged filter.
442 *
443 * @param string $query The where sql statement.
444 *
445 * @return string
446 */
447 public function showPostSql($query)
448 {
449 $excludedPosts = $this->accessHandler->getExcludedPosts();
450
451 if (count($excludedPosts) > 0) {
452 $excludedPostsStr = implode(', ', $excludedPosts);
453 $query .= " AND {$this->database->getPostsTable()}.ID NOT IN ($excludedPostsStr) ";
454 }
455
456 return $query;
457 }
458
459 /**
460 * Function for the wp_count_posts filter.
461 *
462 * @param \stdClass $counts
463 * @param string $type
464 * @param string $perm
465 *
466 * @return \stdClass
467 */
468 public function showPostCount($counts, $type, $perm)
469 {
470 $cachedCounts = $this->cache->getFromCache(self::POST_COUNTS_CACHE_KEY);
471
472 if ($cachedCounts === null) {
473 $excludedPosts = $this->accessHandler->getExcludedPosts();
474
475 if (count($excludedPosts) > 0) {
476 $excludedPosts = implode('\', \'', $excludedPosts);
477
478 $query = "SELECT post_status, COUNT(*) AS num_posts
479 FROM {$this->database->getPostsTable()}
480 WHERE post_type = %s
481 AND ID NOT IN ('{$excludedPosts}')";
482
483 if ('readable' === $perm && $this->wordpress->isUserLoggedIn() === true) {
484 $postTypeObject = $this->wordpress->getPostTypeObject($type);
485
486 if ($this->wordpress->currentUserCan($postTypeObject->cap->read_private_posts) === false) {
487 $query .= $this->database->prepare(
488 ' AND (post_status != \'private\' OR (post_author = %d AND post_status = \'private\'))',
489 $this->wordpress->getCurrentUser()->ID
490 );
491 }
492 }
493
494 $query .= ' GROUP BY post_status';
495
496 $results = (array)$this->database->getResults(
497 $this->database->prepare($query, $type),
498 ARRAY_A
499 );
500
501 foreach ($results as $result) {
502 if (isset($counts->{$result['post_status']})) {
503 $counts->{$result['post_status']} = $result['num_posts'];
504 }
505 }
506 }
507
508 $cachedCounts = $counts;
509 $this->cache->addToCache(self::POST_COUNTS_CACHE_KEY, $cachedCounts);
510 }
511
512 return $cachedCounts;
513 }
514
515 /**
516 * Sets the excluded terms as argument.
517 *
518 * @param array $arguments
519 *
520 * @return array
521 */
522 public function getTermArguments(array $arguments)
523 {
524 $exclude = (isset($arguments['exclude']) === true) ?
525 $this->wordpress->parseIdList($arguments['exclude']) : [];
526 $arguments['exclude'] = array_merge($exclude, $this->accessHandler->getExcludedTerms());
527 $arguments['exclude'] = array_unique($arguments['exclude']);
528
529 return $arguments;
530 }
531
532 /**
533 * The function for the comments_array filter.
534 *
535 * @param \WP_Comment[] $comments The comments.
536 *
537 * @return array
538 */
539 public function showComment($comments = [])
540 {
541 $showComments = [];
542
543 foreach ($comments as $comment) {
544 $post = $this->objectHandler->getPost($comment->comment_post_ID);
545
546 if ($post !== false
547 && $this->accessHandler->checkObjectAccess($post->post_type, $post->ID) === false
548 ) {
549 if ($this->config->hidePostTypeComments($post->post_type) === true
550 || $this->config->hidePostType($post->post_type) === true
551 || $this->config->atAdminPanel() === true
552 ) {
553 continue;
554 }
555
556 $comment->comment_content = $this->config->getPostTypeCommentContent($post->post_type);
557 }
558
559 $showComments[] = $comment;
560 }
561
562 return $showComments;
563 }
564
565 /**
566 * The function for the get_ancestors filter.
567 *
568 * @param array $ancestors
569 * @param int $objectId
570 * @param string $objectType
571 *
572 * @return array
573 */
574 public function showAncestors($ancestors, $objectId, $objectType)
575 {
576 if ($this->config->lockRecursive() === true
577 && $this->accessHandler->checkObjectAccess($objectType, $objectId) === false
578 ) {
579 return [];
580 }
581
582 foreach ($ancestors as $key => $ancestorId) {
583 if ($this->accessHandler->checkObjectAccess($objectType, $ancestorId) === false) {
584 unset($ancestors[$key]);
585 }
586 }
587
588 return $ancestors;
589 }
590
591 /**
592 * The function for the get_previous_post_where and
593 * the get_next_post_where filter.
594 *
595 * @param string $query The current sql string.
596 *
597 * @return string
598 */
599 public function showNextPreviousPost($query)
600 {
601 $excludedPosts = $this->accessHandler->getExcludedPosts();
602
603 if (count($excludedPosts) > 0) {
604 $excludedPosts = implode(', ', $excludedPosts);
605 $query .= " AND p.ID NOT IN ({$excludedPosts}) ";
606 }
607
608 return $query;
609 }
610
611 /**
612 * Returns the post count for the term.
613 *
614 * @param string $termType
615 * @param int $termId
616 *
617 * @return int
618 */
619 private function getVisibleElementsCount($termType, $termId)
620 {
621 $count = 0;
622
623 $fullTerms = [$termId => $termType];
624 $termTreeMap = $this->objectHandler->getTermTreeMap();
625
626 if (isset($termTreeMap[ObjectHandler::TREE_MAP_CHILDREN][$termType]) === true
627 && isset($termTreeMap[ObjectHandler::TREE_MAP_CHILDREN][$termType][$termId]) === true
628 ) {
629 $fullTerms += $termTreeMap[ObjectHandler::TREE_MAP_CHILDREN][$termType][$termId];
630 }
631
632 $posts = [];
633 $termPostMap = $this->objectHandler->getTermPostMap();
634
635 foreach ($fullTerms as $fullTermId => $fullTermType) {
636 if (isset($termPostMap[$fullTermId]) === true) {
637 $posts += $termPostMap[$fullTermId];
638 }
639 }
640
641 foreach ($posts as $postId => $postType) {
642 if ($this->config->hidePostType($postType) === false
643 || $this->accessHandler->checkObjectAccess(ObjectHandler::GENERAL_POST_OBJECT_TYPE, $postId) === true
644 ) {
645 $count++;
646 }
647 }
648
649 return $count;
650 }
651
652 /**
653 * Modifies the content of the term by the given settings.
654 *
655 * @param \WP_Term $term The current term.
656 * @param bool $isEmpty
657 *
658 * @return mixed
659 */
660 private function processTerm($term, &$isEmpty = null)
661 {
662 $isEmpty = false;
663
664 if (($term instanceof \WP_Term) === false) {
665 return $term;
666 }
667
668 if ($this->accessHandler->checkObjectAccess($term->taxonomy, $term->term_id) === false) {
669 return null;
670 }
671
672 $term->name .= $this->adminOutput($term->taxonomy, $term->term_id, $term->name);
673 $term->count = $this->getVisibleElementsCount($term->taxonomy, $term->term_id);
674
675 //For categories
676 if ($term->count <= 0
677 && $this->config->atAdminPanel() === false
678 && $this->config->hideEmptyTaxonomy($term->taxonomy) === true
679 ) {
680 $isEmpty = true;
681 }
682
683 if ($this->config->lockRecursive() === false) {
684 $currentTerm = $term;
685
686 while ($currentTerm->parent != 0) {
687 $currentTerm = $this->objectHandler->getTerm($currentTerm->parent);
688
689 if ($currentTerm === false) {
690 break;
691 }
692
693 $access = $this->accessHandler->checkObjectAccess(
694 $currentTerm->taxonomy,
695 $currentTerm->term_id
696 );
697
698 if ($access === true) {
699 $term->parent = $currentTerm->term_id;
700 break;
701 }
702 }
703 }
704
705 return $term;
706 }
707
708 /**
709 * The function for the get_term filter.
710 *
711 * @param \WP_Term $term
712 *
713 * @return null|object
714 */
715 public function showTerm($term)
716 {
717 return $this->processTerm($term);
718 }
719
720 /**
721 * The function for the get_terms filter.
722 *
723 * @param array $terms The terms.
724 *
725 * @return array
726 */
727 public function showTerms($terms = [])
728 {
729 foreach ($terms as $key => $term) {
730 $isNumeric = (is_numeric($term) === true);
731
732 if ($isNumeric === true) {
733 if ((int)$term === 0) {
734 unset($terms[$key]);
735 continue;
736 }
737
738 $term = $this->objectHandler->getTerm($term);
739 }
740
741 if (($term instanceof \WP_Term) === false) {
742 continue;
743 }
744
745 $term = $this->processTerm($term, $isEmpty);
746
747 if ($term !== null && $isEmpty === false) {
748 $terms[$key] = ($isNumeric === true) ? $term->term_id : $term;
749 } else {
750 unset($terms[$key]);
751 }
752 }
753
754 return $terms;
755 }
756
757 /**
758 * The function for the wp_get_nav_menu_items filter.
759 *
760 * @param array $items The menu item.
761 *
762 * @return array
763 */
764 public function showCustomMenu($items)
765 {
766 $showItems = [];
767
768 foreach ($items as $key => $item) {
769 $item->title .= $this->adminOutput($item->object, $item->object_id, $item->title);
770
771 if ($this->objectHandler->isPostType($item->object) === true) {
772 if ($this->accessHandler->checkObjectAccess($item->object, $item->object_id) === false) {
773 if ($this->config->hidePostType($item->object) === true
774 || $this->config->atAdminPanel() === true
775 ) {
776 continue;
777 }
778
779 if ($this->config->hidePostTypeTitle($item->object) === true) {
780 $item->title = $this->config->getPostTypeTitle($item->object);
781 }
782 }
783
784 $showItems[$key] = $item;
785 } elseif ($this->objectHandler->isTaxonomy($item->object) === true) {
786 $term = $this->objectHandler->getTerm($item->object_id);
787
788 if ($term !== false) {
789 $term = $this->processTerm($term, $isEmpty);
790
791 if ($term !== null && $isEmpty === false) {
792 $showItems[$key] = $item;
793 }
794 }
795 } else {
796 $showItems[$key] = $item;
797 }
798 }
799
800 return $showItems;
801 }
802
803 /**
804 * The function for the edit_post_link filter.
805 *
806 * @param string $link The edit link.
807 * @param integer $postId The _iId of the post.
808 *
809 * @return string
810 */
811 public function showGroupMembership($link, $postId)
812 {
813 $userGroups = $this->accessHandler->getFilteredUserGroupsForObject(
814 ObjectHandler::GENERAL_POST_OBJECT_TYPE,
815 $postId
816 );
817
818 if (count($userGroups) > 0) {
819 $escapedGroups = array_map(
820 function (UserGroup $group) {
821 return htmlentities($group->getName());
822 },
823 $userGroups
824 );
825
826 $link .= ' | '.TXT_UAM_ASSIGNED_GROUPS.': ';
827 $link .= implode(', ', $escapedGroups);
828 }
829
830 return $link;
831 }
832
833 /**
834 * Checks if we allowed show the login form.
835 *
836 * @return bool
837 */
838 public function showLoginForm()
839 {
840 return $this->wordpress->isSingle() === true || $this->wordpress->isPage() === true;
841 }
842
843 /**
844 * Returns the login url.
845 *
846 * @var array $parameters
847 *
848 * @return mixed
849 */
850 public function getLoginUrl(array $parameters = [])
851 {
852 $loginUrl = $this->wordpress->getBlogInfo('wpurl').'/wp-login.php';
853 $loginUrl .= (count($parameters) > 0) ? '?'.http_build_query($parameters) : '';
854 return $this->wordpress->applyFilters('uam_login_form_url', $loginUrl, $parameters);
855 }
856
857 /**
858 * Returns the login redirect url.
859 *
860 * @return mixed
861 */
862 public function getRedirectLoginUrl()
863 {
864 $loginUrl = $this->wordpress->getBlogInfo('wpurl')
865 .'/wp-login.php?redirect_to='.urlencode($_SERVER['REQUEST_URI']);
866 return $this->wordpress->applyFilters('uam_login_url', $loginUrl);
867 }
868
869 /**
870 * Returns the user login name.
871 *
872 * @return string
873 */
874 public function getUserLogin()
875 {
876 $userLogin = $this->getRequestParameter('log');
877 return $this->wordpress->escHtml(stripslashes($userLogin));
878 }
879
880
881 /*
882 * Functions for the redirection and files.
883 */
884
885 /**
886 * Returns the post by the given url.
887 *
888 * @param string $url The url of the post(attachment).
889 *
890 * @return int
891 */
892 public function getPostIdByUrl($url)
893 {
894 $postUrls = (array)$this->cache->getFromCache(self::POST_URL_CACHE_KEY);
895
896 if (isset($postUrls[$url]) === true) {
897 return $postUrls[$url];
898 }
899
900 $postUrls[$url] = null;
901
902 //Filter edit string
903 $newUrlPieces = preg_split('/-e[0-9]{1,}/', $url);
904 $newUrl = (count($newUrlPieces) === 2) ? $newUrlPieces[0].$newUrlPieces[1] : $newUrlPieces[0];
905
906 //Filter size
907 $newUrlPieces = preg_split('/-[0-9]{1,}x[0-9]{1,}(_[a-z])?/', $newUrl);
908 $newUrl = (count($newUrlPieces) === 2) ? $newUrlPieces[0].$newUrlPieces[1] : $newUrlPieces[0];
909 $newUrl = preg_replace('/\-pdf\.jpg$/', '.pdf', $newUrl);
910
911 $query = $this->database->prepare(
912 "SELECT ID
913 FROM {$this->database->getPostsTable()}
914 WHERE guid = '%s'
915 LIMIT 1",
916 $newUrl
917 );
918
919 $dbPost = $this->database->getRow($query);
920
921 if ($dbPost !== null) {
922 $postUrls[$url] = $dbPost->ID;
923 $this->cache->addToCache(self::POST_URL_CACHE_KEY, $postUrls);
924 }
925
926 return $postUrls[$url];
927 }
928
929 /**
930 * Returns the file object by the given type and url.
931 *
932 * @param string $objectType The type of the requested file.
933 * @param string $objectUrl The file url.
934 *
935 * @return null|FileObject
936 */
937 private function getFileSettingsByType($objectType, $objectUrl)
938 {
939 $fileObject = null;
940
941 if ($objectType === ObjectHandler::ATTACHMENT_OBJECT_TYPE) {
942 $uploadDirs = $this->wordpress->getUploadDir();
943 $uploadDir = str_replace(ABSPATH, '/', $uploadDirs['basedir']);
944 $regex = '/.*'.str_replace('/', '\/', $uploadDir).'\//i';
945 $cleanObjectUrl = preg_replace($regex, '', $objectUrl);
946 $uploadUrl = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
947 $objectUrl = rtrim($uploadUrl, '/').'/'.ltrim($cleanObjectUrl, '/');
948
949 $post = $this->objectHandler->getPost($this->getPostIdByUrl($objectUrl));
950
951 if ($post !== false
952 && $post->post_type === ObjectHandler::ATTACHMENT_OBJECT_TYPE
953 ) {
954 $multiPath = str_replace('/files', $uploadDir, $uploadDirs['baseurl']);
955
956 $fileObject = $this->fileObjectFactory->createFileObject(
957 $post->ID,
958 $objectType,
959 $uploadDirs['basedir'].str_replace($multiPath, '', $objectUrl),
960 $this->wordpress->attachmentIsImage($post->ID)
961 );
962 }
963 } else {
964 $extraParameter = $this->getRequestParameter('uamextra');
965
966 $fileObject = $this->wordpress->applyFilters(
967 'uam_get_file_settings_by_type',
968 $fileObject,
969 $objectType,
970 $objectUrl,
971 $extraParameter
972 );
973 }
974
975 return $fileObject;
976 }
977
978 /**
979 * Delivers the content of the requested file.
980 *
981 * @param string $objectType The type of the requested file.
982 * @param string $objectUrl The file url.
983 */
984 public function getFile($objectType, $objectUrl)
985 {
986 $fileObject = $this->getFileSettingsByType($objectType, $objectUrl);
987
988 if ($fileObject === null) {
989 return;
990 }
991
992 if ($this->accessHandler->checkObjectAccess($fileObject->getType(), $fileObject->getId()) === true) {
993 $file = $fileObject->getFile();
994 } elseif ($fileObject->isImage() === true) {
995 $realPath = $this->config->getRealPath();
996 $file = $realPath.'assets/gfx/noAccessPic.png';
997 } else {
998 $this->wordpress->wpDie(TXT_UAM_NO_RIGHTS_MESSAGE, TXT_UAM_NO_RIGHTS_TITLE, ['response' => 403]);
999 return;
1000 }
1001
1002 $this->fileHandler->getFile($file, $fileObject->isImage());
1003 }
1004
1005 /**
1006 * Redirects the user to his destination.
1007 *
1008 * @param bool $checkPosts
1009 */
1010 public function redirectUser($checkPosts = true)
1011 {
1012 if ($checkPosts === true) {
1013 $posts = (array)$this->wordpress->getWpQuery()->get_posts();
1014
1015 foreach ($posts as $post) {
1016 if ($this->accessHandler->checkObjectAccess($post->post_type, $post->ID)) {
1017 return;
1018 }
1019 }
1020 }
1021
1022 $permalink = null;
1023 $redirect = $this->config->getRedirect();
1024
1025 if ($redirect === 'custom_page') {
1026 $redirectCustomPage = $this->config->getRedirectCustomPage();
1027 $post = $this->objectHandler->getPost($redirectCustomPage);
1028 $url = null;
1029
1030 if ($post !== false) {
1031 $url = $post->guid;
1032 $permalink = $this->wordpress->getPageLink($post);
1033 }
1034 } elseif ($redirect === 'custom_url') {
1035 $url = $this->config->getRedirectCustomUrl();
1036 } else {
1037 $url = $this->wordpress->getHomeUrl('/');
1038 }
1039
1040 $currentUrl = $this->util->getCurrentUrl();
1041
1042 if ($url !== null && $url !== $currentUrl && $permalink !== $currentUrl) {
1043 $this->wordpress->wpRedirect($url);
1044 $this->php->callExit();
1045 }
1046 }
1047
1048 /**
1049 * Redirects to a page or to content.
1050 *
1051 * @param string $headers The headers which are given from wordpress.
1052 * @param object $pageParams The params of the current page.
1053 *
1054 * @return string
1055 */
1056 public function redirect($headers, $pageParams)
1057 {
1058 $fileUrl = $this->getRequestParameter('uamgetfile');
1059 $fileType = $this->getRequestParameter('uamfiletype');
1060
1061 if ($fileUrl !== null && $fileType !== null) {
1062 $this->getFile($fileType, $fileUrl);
1063 } elseif ($this->config->atAdminPanel() === false
1064 && $this->config->getRedirect() !== 'false'
1065 ) {
1066 $objectType = null;
1067 $objectId = null;
1068
1069 if (isset($pageParams->query_vars['p']) === true) {
1070 $objectType = ObjectHandler::GENERAL_POST_OBJECT_TYPE;
1071 $objectId = $pageParams->query_vars['p'];
1072 } elseif (isset($pageParams->query_vars['page_id']) === true) {
1073 $objectType = ObjectHandler::GENERAL_POST_OBJECT_TYPE;
1074 $objectId = $pageParams->query_vars['page_id'];
1075 } elseif (isset($pageParams->query_vars['cat_id']) === true) {
1076 $objectType = ObjectHandler::GENERAL_TERM_OBJECT_TYPE;
1077 $objectId = $pageParams->query_vars['cat_id'];
1078 } elseif (isset($pageParams->query_vars['name']) === true) {
1079 $postableTypes = implode('\',\'', $this->objectHandler->getPostTypes());
1080
1081 $query = $this->database->prepare(
1082 "SELECT ID
1083 FROM {$this->database->getPostsTable()}
1084 WHERE post_name = %s
1085 AND post_type IN ('{$postableTypes}')",
1086 $pageParams->query_vars['name']
1087 );
1088
1089 $objectType = ObjectHandler::GENERAL_POST_OBJECT_TYPE;
1090 $objectId = (int)$this->database->getVariable($query);
1091 } elseif (isset($pageParams->query_vars['pagename']) === true) {
1092 $object = $this->wordpress->getPageByPath($pageParams->query_vars['pagename']);
1093
1094 if ($object !== null) {
1095 $objectType = $object->post_type;
1096 $objectId = $object->ID;
1097 }
1098 }
1099
1100 if ($this->accessHandler->checkObjectAccess($objectType, $objectId) === false) {
1101 $this->redirectUser(false);
1102 }
1103 }
1104
1105 return $headers;
1106 }
1107
1108 /**
1109 * Returns the url for a locked file.
1110 *
1111 * @param string $url The base url.
1112 * @param integer $id The _iId of the file.
1113 *
1114 * @return string
1115 */
1116 public function getFileUrl($url, $id)
1117 {
1118 if ($this->config->isPermalinksActive() === false && $this->config->lockFile() === true) {
1119 $post = $this->objectHandler->getPost($id);
1120
1121 if ($post !== null) {
1122 $type = explode('/', $post->post_mime_type);
1123 $type = (isset($type[1]) === true) ? $type[1] : $type[0];
1124
1125 $lockedFileTypes = $this->config->getLockedFileTypes();
1126 $fileTypes = explode(',', $lockedFileTypes);
1127
1128 if ($lockedFileTypes === 'all' || in_array($type, $fileTypes) === true) {
1129 $url = $this->wordpress->getHomeUrl('/').'?uamfiletype=attachment&uamgetfile='.$url;
1130 }
1131 }
1132 }
1133
1134 return $url;
1135 }
1136
1137 /**
1138 * Caches the urls for the post for a later lookup.
1139 *
1140 * @param string $url The url of the post.
1141 * @param object $post The post object.
1142 *
1143 * @return string
1144 */
1145 public function cachePostLinks($url, $post)
1146 {
1147 $postUrls = (array)$this->cache->getFromCache(self::POST_URL_CACHE_KEY);
1148 $postUrls[$url] = $post->ID;
1149 $this->cache->addToCache(self::POST_URL_CACHE_KEY, $postUrls);
1150 return $url;
1151 }
1152
1153 /**
1154 * Filter for Yoast SEO Plugin
1155 *
1156 * Hides the url from the site map if the user has no access
1157 *
1158 * @param string $url The url to check
1159 * @param string $type The object type
1160 * @param object $object The object
1161 *
1162 * @return false|string
1163 */
1164 public function getWpSeoUrl($url, $type, $object)
1165 {
1166 return ($this->accessHandler->checkObjectAccess($type, $object->ID) === true) ? $url : false;
1167 }
1168 }
1169