PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / 5.0
Advanced Access Manager – Access Governance for WordPress v5.0
6.8.4 6.8.5 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13 6.9.14 6.9.15 6.9.16 6.9.17 6.9.18 6.9.19 6.9.2 6.9.20 6.9.21 6.9.22 6.9.23 6.9.24 6.9.25 6.9.26 6.9.27 6.9.28 6.9.29 6.9.3 6.9.30 6.9.31 6.9.32 6.9.33 6.9.34 6.9.35 6.9.36 6.9.37 6.9.38 6.9.39 6.9.4 6.9.41 6.9.42 6.9.43 6.9.44 6.9.45 6.9.46 6.9.47 6.9.48 6.9.49 6.9.5 6.9.51 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.0-alpha.6 7.0.0-alpha.7 7.0.0-beta.1 7.0.0-rc1 7.0.0-rc2 7.0.0-rc3 7.0.1 7.0.10 7.0.11 7.0.2 7.0.3 7.0.4 7.0.5 7.0.6 7.0.7 7.0.8 7.0.9 7.1.0 7.1.1 trunk 3.0 4.0 4.0.1 4.1 4.2 4.3 4.4 4.4.1 4.5 4.6 4.6.1 4.6.2 4.7 4.7.1 4.7.2 4.7.5 4.7.6 4.8 4.8.1 4.9 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.5.1 4.9.5.2 5.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1 5.1.1 5.10 5.11 5.2 5.2.1 5.2.5 5.2.6 5.2.7 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.4 5.4.1 5.4.2 5.4.3 5.4.3.1 5.4.3.2 5.5 5.5.1 5.5.2 5.6 5.6.1 5.6.1.1 5.7 5.7.1 5.7.2 5.7.3 5.8 5.8.1 5.8.2 5.8.3 5.9 5.9.1 5.9.1.1 5.9.2 5.9.2.1 5.9.3 5.9.4 5.9.5 5.9.6 5.9.6.1 5.9.6.2 5.9.6.3 5.9.7 5.9.7.1 5.9.7.2 5.9.7.3 5.9.8 5.9.8.1 5.9.9 5.9.9.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.2.0 6.2.1 6.2.2 6.3.0 6.3.1 6.3.2 6.3.3 6.4.0 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.6.0 6.6.1 6.6.2 6.6.3 6.6.4 6.7.0 6.7.1 6.7.2 6.7.3 6.7.4 6.7.5 6.7.6 6.7.7 6.7.8 6.7.9 6.8.0 6.8.1 6.8.2 6.8.3
advanced-access-manager / Application / Frontend / Filter.php
advanced-access-manager / Application / Frontend Last commit date
phtml 8 years ago Authorization.php 8 years ago Filter.php 8 years ago Manager.php 8 years ago
Filter.php
348 lines
1 <?php
2
3 /**
4 * ======================================================================
5 * LICENSE: This file is subject to the terms and conditions defined in *
6 * file 'license.txt', which is part of this source code package. *
7 * ======================================================================
8 */
9
10 /**
11 * AAM frontend filter
12 *
13 * @package AAM
14 * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15 */
16 class AAM_Frontend_Filter {
17
18 /**
19 * Instance of itself
20 *
21 * @var AAM_Frontend_Filter
22 *
23 * @access private
24 */
25 private static $_instance = null;
26
27 /**
28 * Constructor
29 *
30 * @return void
31 *
32 * @access protected
33 */
34 protected function __construct() {
35 //bootstrap authorization layer
36 AAM_Frontend_Authorization::bootstrap();
37
38 //manage access to frontend posts & pages
39 add_action('wp', array($this, 'wp'), 999);
40 add_action('404_template', array($this, 'themeRedirect'), 999);
41
42 //important to keep this option optional for optimization reasons
43 if (AAM_Core_Config::get('check-post-visibility', true)) {
44 //filter navigation pages & taxonomies
45 add_filter('get_pages', array($this, 'filterPostList'), 999);
46 add_filter('wp_get_nav_menu_items', array($this, 'getNavigationMenu'), 999);
47
48 //add post filter for LIST restriction
49 add_filter('the_posts', array($this, 'filterPostList'), 999);
50 add_action('pre_get_posts', array($this, 'preparePostQuery'), 999);
51 }
52
53 //password protected filter
54 add_filter('post_password_required', array($this, 'isPassProtected'), 10, 2);
55 //manage password check expiration
56 add_filter('post_password_expires', array($this, 'checkPassExpiration'));
57
58 //widget filters
59 add_filter('sidebars_widgets', array($this, 'filterWidgets'), 999);
60
61 //get control over commenting stuff
62 add_filter('comments_open', array($this, 'commentOpen'), 10, 2);
63
64 //filter post content
65 add_filter('the_content', array($this, 'filterPostContent'), 999);
66 }
67
68 /**
69 * Main frontend access control hook
70 *
71 * @return void
72 *
73 * @access public
74 * @global WP_Post $post
75 */
76 public function wp() {
77 global $wp_query;
78
79 if ($wp_query->is_404) { // Handle 404 redirect
80 $type = AAM_Core_Config::get('frontend.404redirect.type', 'default');
81 do_action('aam-rejected-action', 'frontend', array(
82 'hook' => 'aam_404',
83 'uri' => AAM_Core_Request::server('REQUEST_URI')
84 ));
85
86 if ($type != 'default') {
87 AAM_Core_API::redirect(
88 AAM_Core_Config::get("frontend.404redirect.{$type}")
89 );
90 }
91 } elseif ($wp_query->is_single || $wp_query->is_page
92 || $wp_query->is_posts_page || $wp_query->is_home) {
93 $post = AAM_Core_API::getCurrentPost();
94
95 if ($post) {
96 AAM_Frontend_Authorization::getInstance()->post($post);
97 }
98 }
99 }
100
101 /**
102 * Theme redirect
103 *
104 * Super important function that cover the 404 redirect that triggered by theme
105 * when page is not found. This covers the scenario when page is restricted from
106 * listing and read.
107 *
108 * @global type $wp_query
109 *
110 * @param type $template
111 *
112 * @return string
113 *
114 * @access public
115 */
116 public function themeRedirect($template) {
117 $post = AAM_Core_API::getCurrentPost();
118
119 if ($post) {
120 AAM_Frontend_Authorization::getInstance()->post($post);
121 }
122
123 return $template;
124 }
125
126 /**
127 * Filter posts from the list
128 *
129 * @param array $posts
130 *
131 * @return array
132 *
133 * @access public
134 */
135 public function filterPostList($posts) {
136 $current = AAM_Core_API::getCurrentPost();
137
138 if (is_array($posts) && !$this->isMainWP()) {
139 foreach ($posts as $i => $post) {
140 if ($current && ($current->ID == $post->ID)) { continue; }
141
142 if (AAM_Core_API::isHiddenPost($post, $post->post_type)) {
143 unset($posts[$i]);
144 }
145 }
146
147 $posts = array_values($posts);
148 }
149
150 return $posts;
151 }
152
153 /**
154 * Filter Navigation menu
155 *
156 * @param array $pages
157 *
158 * @return array
159 *
160 * @access public
161 */
162 public function getNavigationMenu($pages) {
163 if (is_array($pages)) {
164 foreach ($pages as $i => $page) {
165 if (in_array($page->type, array('post_type', 'custom'))) {
166 $post = get_post($page->object_id);
167 if (AAM_Core_API::isHiddenPost($post, $post->post_type)) {
168 unset($pages[$i]);
169 }
170 }
171 }
172 }
173
174 return $pages;
175 }
176
177 /**
178 * Build pre-post query request
179 *
180 * This is used to solve the problem or pagination
181 *
182 * @param stdClass $query
183 *
184 * @return void
185 *
186 * @access public
187 */
188 public function preparePostQuery($query) {
189 static $skip = false;
190
191 if (($skip === false) && $this->isMainWP()) { // avoid loop
192 $skip = true;
193 $filtered = AAM_Core_API::getFilteredPostList($query);
194 $skip = false;
195
196 if (isset($query->query_vars['post__not_in'])
197 && is_array($query->query_vars['post__not_in'])) {
198 $query->query_vars['post__not_in'] = array_merge(
199 $query->query_vars['post__not_in'], $filtered
200 );
201 } else {
202 $query->query_vars['post__not_in'] = $filtered;
203 }
204 }
205 }
206
207 /**
208 * Check if post is password protected
209 *
210 * @param boolean $res
211 * @param WP_Post $post
212 *
213 * @return boolean
214 *
215 * @access public
216 */
217 public function isPassProtected($res, $post) {
218 if (is_a($post, 'WP_Post')) {
219 $object = AAM::getUser()->getObject('post', $post->ID);
220
221 if ($object->has('frontend.protected')) {
222 require_once( ABSPATH . 'wp-includes/class-phpass.php' );
223 $hasher = new PasswordHash( 8, true );
224 $pass = $object->get('frontend.password');
225 $hash = wp_unslash(
226 AAM_Core_Request::cookie('wp-postpass_' . COOKIEHASH)
227 );
228
229 $res = empty($hash) ? true : !$hasher->CheckPassword($pass, $hash);
230 }
231 }
232
233 return $res;
234 }
235
236 /**
237 * Get password expiration TTL
238 *
239 * @param int $expire
240 *
241 * @return int
242 *
243 * @access public
244 */
245 public function checkPassExpiration($expire) {
246 $overwrite = AAM_Core_Config::get('post.password.expires', null);
247
248 if ($overwrite !== null) {
249 $expire = ($overwrite ? time() + strtotime($overwrite) : 0);
250 }
251
252 return $expire;
253 }
254
255 /**
256 * Filter frontend widgets
257 *
258 * @param array $widgets
259 *
260 * @return array
261 *
262 * @access public
263 */
264 public function filterWidgets($widgets) {
265 return AAM::getUser()->getObject('metabox')->filterFrontend($widgets);
266 }
267
268 /**
269 * Control frontend commenting feature
270 *
271 * @param boolean $open
272 * @param int $post_id
273 *
274 * @return boolean
275 *
276 * @access public
277 */
278 public function commentOpen($open, $post_id) {
279 $object = AAM::getUser()->getObject('post', $post_id);
280
281 return ($object->has('frontend.comment') ? false : $open);
282 }
283
284 /**
285 * Filter post content
286 *
287 * @param string $content
288 *
289 * @return string
290 *
291 * @access public
292 * @global WP_Post $post
293 */
294 public function filterPostContent($content) {
295 $post = AAM_Core_API::getCurrentPost();
296
297 if ($post && $post->has('frontend.limit')) {
298 if ($post->has('frontend.teaser')) {
299 $message = $post->get('frontend.teaser');
300 } else {
301 $message = __('[No teaser message provided]', AAM_KEY);
302 }
303
304 $content = do_shortcode(stripslashes($message));
305 }
306
307 return $content;
308 }
309
310 /**
311 * Check if request comes from wp()
312 *
313 * Super important method is used to solve the problem with hidden posts
314 *
315 * @return boolean
316 *
317 * @access protected
318 */
319 protected function isMainWP() {
320 $result = false;
321
322 foreach(debug_backtrace() as $level) {
323 $class = (isset($level['class']) ? $level['class'] : null);
324 $func = (isset($level['function']) ? $level['function'] : null);
325
326 if ($class == 'WP' && $func == 'main') {
327 $result = true;
328 break;
329 }
330 }
331
332 return $result;
333 }
334
335 /**
336 * Register backend filters and actions
337 *
338 * @return void
339 *
340 * @access public
341 */
342 public static function register() {
343 if (is_null(self::$_instance)) {
344 self::$_instance = new self;
345 }
346 }
347
348 }