PluginProbe
Members – Membership & User Role Editor Plugin / 3.2.24
Members – Membership & User Role Editor Plugin v3.2.24
3.2.25 3.2.26 3.2.24 3.2.23 3.2.22 3.2.21 trunk 0.1 0.1.1 0.2 0.2.1 0.2.2 0.2.3 0.2.4 0.2.5 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.1.3 2.0.0 2.0.1 2.0.2 All 66 releases
members / inc / functions-shortcodes.php

functions-shortcodes.php in Members – Membership & User Role Editor Plugin 3.2.24, at inc/functions-shortcodes.php

424 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 * Shortcodes for use within posts and other shortcode-aware areas.
4 *
5 * @package Members
6 * @subpackage Includes
7 * @author The MemberPress Team
8 * @copyright Copyright (c) 2009 - 2018, The MemberPress Team
9 * @link https://members-plugin.com/
10 * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
11 */
12 if (!defined('ABSPATH')) {
13 die('You are not allowed to call this page directly.');
14 }
15
16 # Add shortcodes.
17 add_action( 'init', 'members_register_shortcodes' );
18
19 add_filter( 'login_redirect', 'members_login_redirect', 9, 3 );
20
21 /**
22 * Registers shortcodes.
23 *
24 * @since 0.2.0
25 * @access public
26 * @return void
27 */
28 function members_register_shortcodes() {
29
30 // Add the `[members_login_form]` shortcode.
31 add_shortcode( 'members_login_form', 'members_login_form_shortcode' );
32 add_shortcode( 'login-form', 'members_login_form_shortcode' ); // @deprecated 1.0.0
33
34 // Add the `[members_access]` shortcode.
35 add_shortcode( 'members_access', 'members_access_check_shortcode' );
36 add_shortcode( 'access', 'members_access_check_shortcode' ); // @deprecated 1.0.0
37
38 // Add the `[members_feed]` shortcode.
39 add_shortcode( 'members_feed', 'members_feed_shortcode' );
40 add_shortcode( 'feed', 'members_feed_shortcode' ); // @deprecated 1.0.0
41
42 // Add the `[members_logged_in]` shortcode.
43 add_shortcode( 'members_logged_in', 'members_is_user_logged_in_shortcode' );
44 add_shortcode( 'is_user_logged_in', 'members_is_user_logged_in_shortcode' ); // @deprecated 1.0.0
45
46 // Add the `[members_not_logged_in]` shortcode.
47 add_shortcode( 'members_not_logged_in', 'members_not_logged_in_shortcode' );
48
49 // @deprecated 0.2.0.
50 add_shortcode( 'get_avatar', 'members_get_avatar_shortcode' );
51 add_shortcode( 'avatar', 'members_get_avatar_shortcode' );
52 }
53
54 /**
55 * Displays content if the user viewing it is currently logged in. This also blocks content
56 * from showing in feeds.
57 *
58 * @since 0.1.0
59 * @access public
60 * @param array $attr
61 * @param string $content
62 * @return string
63 */
64 function members_is_user_logged_in_shortcode( $attr, $content = null ) {
65
66 return is_feed() || ! is_user_logged_in() || is_null( $content ) ? '' : do_shortcode( $content );
67 }
68
69 /**
70 * Displays content if the user viewing it is not currently logged in.
71 *
72 * @since 2.0.0
73 * @access public
74 * @param array $attr
75 * @param string $content
76 * @return string
77 */
78 function members_not_logged_in_shortcode( $attr, $content = null ) {
79
80 return is_user_logged_in() || is_null( $content ) ? '' : do_shortcode( $content );
81 }
82
83 /**
84 * Content that should only be shown in feed readers. Can be useful for displaying
85 * feed-specific items.
86 *
87 * @since 0.1.0
88 * @access public
89 * @param array $attr
90 * @param string $content
91 * @return string
92 */
93 function members_feed_shortcode( $attr, $content = null ) {
94
95 return ! is_feed() || is_null( $content ) ? '' : do_shortcode( $content );
96 }
97
98 /**
99 * Provide/restrict access to specific roles or capabilities. This content should not be shown
100 * in feeds. Note that capabilities are checked first. If a capability matches, any roles
101 * added will *not* be checked. Users should choose between using either capabilities or roles
102 * for the check rather than both. The best option is to always use a capability.
103 *
104 * @since 0.1.0
105 * @access public
106 * @param array $attr
107 * @param string $content
108 * @return string
109 */
110 function members_access_check_shortcode( $attr, $content = null ) {
111
112 // If there's no content or if viewing a feed, return an empty string.
113 if ( is_null( $content ) || is_feed() )
114 return '';
115
116 $user_can = false;
117
118 // Set up the default attributes.
119 $defaults = array(
120 'capability' => '', // Single capability or comma-separated multiple capabilities.
121 'role' => '', // Single role or comma-separated multiple roles.
122 'user_id' => '', // Single user ID or comma-separated multiple IDs.
123 'user_name' => '', // Single user name or comma-separated multiple names.
124 'user_email' => '', // Single user email or comma-separated multiple emails.
125 'operator' => 'or' // Only the `!` operator is supported for now. Everything else falls back to `or`.
126 );
127
128 // Merge the input attributes and the defaults.
129 $attr = shortcode_atts( $defaults, $attr, 'members_access' );
130
131 // Get the operator.
132 $operator = strtolower( $attr['operator'] );
133
134 // If the current user has the capability, show the content.
135 if ( $attr['capability'] ) {
136
137 // Get the capabilities.
138 $caps = explode( ',', $attr['capability'] );
139
140 if ( '!' === $operator )
141 return members_current_user_can_any( $caps ) ? '' : do_shortcode( $content );
142
143 return members_current_user_can_any( $caps ) ? do_shortcode( $content ) : '';
144 }
145
146 // If the current user has the role, show the content.
147 if ( $attr['role'] ) {
148
149 // Get the roles.
150 $roles = explode( ',', $attr['role'] );
151
152 if ( '!' === $operator )
153 return members_current_user_has_role( $roles ) ? '' : do_shortcode( $content );
154
155 return members_current_user_has_role( $roles ) ? do_shortcode( $content ) : '';
156 }
157
158 $user_id = 0;
159 $user_name = $user_email = '';
160
161 if ( is_user_logged_in() ) {
162
163 $user = wp_get_current_user();
164 $user_id = get_current_user_id();
165 $user_name = $user->user_login;
166 $user_email = $user->user_email;
167 }
168
169 // If the current user has one of the user ids.
170 if ( $attr['user_id'] ) {
171
172 // Get the user IDs.
173 $ids = array_map( 'trim', explode( ',', $attr['user_id'] ) );
174
175 if ( '!' === $operator ) {
176 return in_array( $user_id, $ids ) ? '' : do_shortcode( $content );
177 }
178
179 return in_array( $user_id, $ids ) ? do_shortcode( $content ) : '';
180 }
181
182 // If the current user has one of the user names.
183 if ( $attr['user_name'] ) {
184
185 // Get the user names.
186 $names = array_map( 'trim', explode( ',', $attr['user_name'] ) );
187
188 if ( '!' === $operator ) {
189 return in_array( $user_name, $names ) ? '' : do_shortcode( $content );
190 }
191
192 return in_array( $user_name, $names ) ? do_shortcode( $content ) : '';
193 }
194
195 // If the current user has one of the user emails.
196 if ( $attr['user_email'] ) {
197
198 // Get the user emails.
199 $emails = array_map( 'trim', explode( ',', $attr['user_email'] ) );
200
201 if ( '!' === $operator ) {
202 return in_array( $user_email, $emails ) ? '' : do_shortcode( $content );
203 }
204
205 return in_array( $user_email, $emails ) ? do_shortcode( $content ) : '';
206 }
207
208 // Return an empty string if we've made it to this point.
209 return '';
210 }
211
212 /**
213 * Displays a login form.
214 *
215 * @since 0.1.0
216 * @access public
217 * @param array $attr Shortcode attributes.
218 * @return string
219 */
220 function members_login_form_shortcode( $attr = [] ) {
221 // Default attributes
222 $defaults = array(
223 'echo' => false,
224 'redirect' => ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'],
225 );
226
227 // Merge user attributes with defaults
228 $attr = shortcode_atts( $defaults, $attr, 'members_login_form' );
229
230 ob_start();
231 if ( is_user_logged_in() ) { ?>
232 <div class="members-login-form">
233 <p class="members-login-notice members-login-notice-success">
234 <?php esc_html_e('You are already logged in.', 'members'); ?>
235 </p>
236 </div>
237 <style>
238 .members-login-notice {
239 display: block !important;
240 max-width: 320px;
241 padding: 10px;
242 background: #f1f1f1;
243 border-radius: 4px;
244 border-left: 3px solid #36d651;
245 font-size: 18px;
246 font-weight: 500;
247 }
248 </style>
249 <?php } else {
250 // Add the login_form_bottom filter only for this specific Members shortcode form
251 add_filter( 'login_form_bottom', 'members_login_form_bottom' );
252 ?>
253 <div class="members-login-form">
254 <?php echo wp_login_form( $attr ); ?>
255 </div>
256 <?php
257 // Remove the filter after rendering to avoid affecting other login forms
258 remove_filter( 'login_form_bottom', 'members_login_form_bottom' );
259 ?>
260 <style>
261 .members-login-form * {
262 box-sizing: border-box;
263 }
264 .members-login-form label {
265 display: block;
266 margin-bottom: 4px;
267 font-size: 18px;
268 font-weight: 500;
269 }
270 .members-login-form input[type="text"],
271 .members-login-form input[type="password"] {
272 width: 100%;
273 max-width: 320px;
274 padding: 0.5rem 0.75rem;
275 border: 1px solid #64748b;
276 border-radius: 4px;
277 font-size: 16px;
278 }
279 .members-login-form input[type="submit"] {
280 width: 100%;
281 max-width: 320px;
282 padding: 0.75rem;
283 cursor: pointer;
284 background: #64748b;
285 border: 0;
286 border-radius: 4px;
287 color: #fff;
288 font-size: 16px;
289 font-weight: 500;
290 }
291 .members-logged-in input[type="submit"] {
292 pointer-events: none;
293 opacity: 0.4;
294 cursor: not-allowed;
295 }
296 .members-login-notice {
297 display: block !important;
298 max-width: 320px;
299 padding: 10px;
300 background: #f1f1f1;
301 border-radius: 4px;
302 border-left: 3px solid #36d651;
303 font-size: 18px;
304 font-weight: 500;
305 }
306 .members-login-error {
307 border-left-color: #d63638;
308 }
309 </style>
310 <?php
311 }
312 return ob_get_clean();
313 }
314
315 /**
316 * Filters the login redirect URL to send failed logins back to the
317 * referrer with a query arg of `login=failed`.
318 * Only applies to Members shortcode forms (verified via nonce).
319 *
320 * @since 3.2.18
321 *
322 * @param string $redirect_to The redirect destination URL.
323 * @param string $request The request URL.
324 * @param object $user The user object.
325 * @return string The redirect URL.
326 */
327 function members_login_redirect( $redirect_to, $request, $user ) {
328 // Only handle redirects for Members shortcode forms (verified by nonce)
329 if ( ! isset( $_POST['members_login_nonce'] ) ||
330 ! wp_verify_nonce( $_POST['members_login_nonce'], 'members_login_form' ) ) {
331 return $redirect_to;
332 } elseif ( empty( $user ) || is_wp_error( $user ) ) {
333 // Start session if not already started
334 if (!session_id()) {
335 session_start();
336 }
337
338 // Get the referrer URL
339 $redirect_to = $_SERVER['HTTP_REFERER'];
340
341 // If we have a WP_Error object, capture the error message
342 if (is_wp_error($user)) {
343 $error_code = $user->get_error_code();
344
345 if (empty(trim($error_code)) || $error_code == 'incorrect_password' || $error_code == 'invalid_username') {
346 // Don't store specific message, we'll use default in the display function
347 $_SESSION['members_login_error_message'] = __('Invalid username or password.', 'members');
348 } else {
349 $_SESSION['members_login_error_message'] = $user->get_error_message();
350 }
351 }
352
353 // Add login=failed parameter
354 $redirect_to = add_query_arg('login', 'failed', $redirect_to);
355
356 wp_redirect($redirect_to);
357 exit;
358 } else {
359 // On success, clear any error session data
360 if (!session_id()) {
361 session_start();
362 }
363 if (isset($_SESSION['members_login_error_message'])) {
364 unset($_SESSION['members_login_error_message']);
365 }
366
367 if (isset($_POST['redirect_to'])) {
368 return remove_query_arg('login', esc_url($_POST['redirect_to']));
369 }
370
371 // On success, return to the redirect_to URL
372 return remove_query_arg('login', $redirect_to);
373 }
374 }
375
376 /**
377 * Filters the login form bottom output to add a nonce and error message if the login has failed.
378 * This is only added to Members shortcode forms, not all WordPress login forms.
379 *
380 * @since 3.2.18
381 *
382 * @return string The HTML to output below the login form.
383 */
384 function members_login_form_bottom() {
385 // Start session if not already started
386 if (!session_id()) {
387 session_start();
388 }
389
390 // Add a nonce to verify this is a Members shortcode submission
391 $output = wp_nonce_field( 'members_login_form', 'members_login_nonce', true, false );
392
393 if ( isset( $_REQUEST['login'] ) && $_REQUEST['login'] == 'failed' ) {
394 // Get error message from session
395 if (isset($_SESSION['members_login_error_message']) && !empty($_SESSION['members_login_error_message'])) {
396 $error_message = $_SESSION['members_login_error_message'];
397 } else {
398 // Default message if no specific error is found
399 $error_message = __('Invalid username or password.', 'members');
400 }
401
402 // Allow specific HTML tags in error messages
403 $allowed_html = array(
404 'a' => array(
405 'href' => array(),
406 'title' => array(),
407 'target' => array(),
408 'rel' => array(),
409 'class' => array(),
410 ),
411 'br' => array(),
412 'em' => array(),
413 'strong' => array(),
414 'p' => array('class' => array()),
415 'span' => array('class' => array()),
416 'div' => array('class' => array()),
417 );
418
419 $output .= '<p class="members-login-notice members-login-error">' . wp_kses($error_message, $allowed_html) . '</p>';
420 }
421
422 return $output;
423 }
424