PluginProbe
WP-Members Membership Plugin / trunk
WP-Members Membership Plugin vtrunk
trunk 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.4.2 3.4.5 3.4.6 3.4.7 3.4.8 3.4.9 3.4.9.1 3.4.9.2 3.4.9.3 3.4.9.4 3.4.9.5 3.4.9.6 3.4.9.7 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 All 34 releases
wp-members / includes / class-wp-members.php

class-wp-members.php in WP-Members Membership Plugin trunk, at includes/class-wp-members.php

2,014 lines 55.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The WP_Members Class.
4 *
5 * This is the main WP_Members object class. This class contains functions
6 * for loading settings, shortcodes, hooks to WP, plugin dropins, constants,
7 * and registration fields. It also manages whether content should be blocked.
8 *
9 * @package WP-Members
10 * @subpackage WP_Members Object Class
11 * @since 3.0.0
12 */
13
14 // Exit if accessed directly.
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit();
17 }
18
19 class WP_Members {
20
21 /**
22 * The state of plugin install/upgrade.
23 *
24 * @since 3.5.0
25 */
26 public $install_state;
27
28 /**
29 * Plugin version.
30 *
31 * @since 3.0.0
32 * @access public
33 * @var string
34 */
35 public $version = WPMEM_VERSION;
36
37 /**
38 * Database version
39 *
40 * @since 3.2.2
41 * @access public
42 * @var string
43 */
44 public $db_version = WPMEM_DB_VERSION;
45
46 /**
47 * Plugin path.
48 *
49 * @since 3.3.0
50 * @access public
51 * @var string
52 */
53 public $path;
54
55 /**
56 * Plugin __FILE__.
57 *
58 * @since 3.3.0
59 * @access public
60 * @var string
61 */
62 public $name;
63
64 /**
65 * Plugin slug.
66 *
67 * @since 3.3.0
68 * @access public
69 * @var string
70 */
71 public $slug;
72
73 /**
74 * Plugin URL.
75 *
76 * @since 3.3.0
77 * @access public
78 * @var string
79 */
80 public $url;
81
82 /**
83 * Content block settings.
84 *
85 * @since 3.0.0
86 * @access public
87 * @var array
88 */
89 public $block;
90
91 /**
92 * Excerpt settings.
93 *
94 * @since 3.0.0
95 * @access public
96 * @var array
97 */
98 public $show_excerpt;
99
100 /**
101 * Show login form settings.
102 *
103 * @since 3.0.0
104 * @access public
105 * @var array
106 */
107 public $show_login;
108
109 /**
110 * Show registration form settings.
111 *
112 * @since 3.0.0
113 * @access public
114 * @var array
115 */
116 public $show_reg;
117
118 /**
119 * Auto-excerpt settings.
120 *
121 * @since 3.0.0
122 * @access public
123 * @var array
124 */
125 public $autoex;
126
127 /**
128 * Notify admin settings.
129 *
130 * @since 3.0.0
131 * @access public
132 * @var string
133 */
134 public $notify;
135
136 /**
137 * Moderated registration settings.
138 *
139 * @since 3.0.0
140 * @access public
141 * @var string
142 */
143 public $mod_reg;
144
145 /**
146 * Captcha settings.
147 *
148 * @since 3.0.0
149 * @access public
150 * @var array
151 */
152 public $captcha;
153
154 /**
155 * Enable expiration extension settings.
156 *
157 * @since 3.0.0
158 * @access public
159 * @var string
160 */
161 public $use_exp;
162
163 /**
164 * Expiration extension enable trial period.
165 *
166 * @since 3.0.0
167 * @access public
168 * @var string
169 */
170 public $use_trial;
171
172 /**
173 *
174 *
175 * @since 3.0.0
176 * @access public
177 * @var array
178 */
179 public $warnings;
180
181 /**
182 * Enable drop-ins setting.
183 *
184 * @since 3.1.9
185 * @access public
186 * @var string
187 */
188 public $dropins = 0;
189
190 /**
191 * Container for enabled dropins.
192 *
193 * @since 3.1.9
194 * @access public
195 * @var array
196 */
197 public $dropins_enabled = array();
198
199 /**
200 * Current plugin action container.
201 *
202 * @since 3.0.0
203 * @access public
204 * @var string
205 */
206 public $action;
207
208 /**
209 * Regchk container.
210 *
211 * @since 3.0.0
212 * @access public
213 * @var string
214 */
215 public $regchk;
216
217 /**
218 * User page settings.
219 *
220 * @since 3.0.0
221 * @access public
222 * @var array
223 */
224 public $user_pages;
225
226 /**
227 * Custom Post Type settings.
228 *
229 * @since 3.0.0
230 * @access public
231 * @var array
232 */
233 public $post_types;
234
235 /**
236 * Setting for applying texturization.
237 *
238 * @since 3.1.7
239 * @access public
240 * @var boolean
241 */
242 public $texturize;
243
244 /**
245 * Enable product creation.
246 *
247 * @since 3.2.0
248 * @access public
249 * @var boolean
250 */
251 public $enable_products;
252
253 /**
254 * Enable logged-in menu clones.
255 *
256 * @since 3.2.0
257 * @access public
258 * @var string
259 */
260 public $clone_menus;
261
262 /**
263 * Container for error messages.
264 *
265 * @since 3.2.0
266 * @access public
267 * @var stdClass
268 */
269 public $error;
270
271 /**
272 * Container for admin notices.
273 *
274 * @since 3.3.0
275 * @access public
276 * @var array
277 */
278 public $admin_notices;
279
280 /**
281 * Container for stylesheet setting.
282 *
283 * @since 3.2.7
284 * @deprecated 3.5.4
285 * @access public
286 * @var string
287 */
288 public $select_style;
289
290 /**
291 * Container for the CSS URL.
292 *
293 * @since Unknown
294 * @access public
295 * @var string
296 */
297 public $cssurl;
298
299 /**
300 * The attribution setting.
301 *
302 * @since Unknown
303 * @access public
304 * @var string
305 */
306 public $attrib;
307
308 /**
309 * Container for form tags.
310 *
311 * @since Unknown
312 * @access public
313 * @var array
314 * @todo verify @var
315 */
316 public $form_tags;
317
318 /**
319 * Container for dropin folder location.
320 *
321 * @since 3.3.0
322 * @access public
323 * @var string
324 */
325 public $dropin_dir;
326
327 /**
328 * REST conditional.
329 *
330 * @since 3.3.2
331 * @access public
332 * @var boolean
333 */
334 public $is_rest = false;
335
336 /**
337 * Temporary setting for activation link.
338 *
339 * @todo Will default to 0 until 3.4.0, then 1 until 3.5.0 at which point we'll remove the old process.
340 *
341 * @since 3.3.5
342 * @access public
343 * @var string
344 */
345 public $act_link = 0;
346
347 /**
348 * Default file upload directory.
349 *
350 * @since 3.3.8
351 * @access public
352 * @var string
353 */
354 public $upload_base = 'wpmembers';
355
356 /**
357 * Opt in to update and security notifications.
358 *
359 * @since 3.4.2
360 */
361 public $optin;
362
363 /**
364 * Container for WooCommerce-specific settings.
365 *
366 * @since Unknown
367 * @access public
368 * @var array
369 */
370 public $woo;
371
372 /**
373 * The forms object.
374 *
375 * @since Unknown
376 * @access public
377 * @var object
378 */
379 public $forms;
380
381 /**
382 * The fields object.
383 *
384 * @since Unknown
385 * @access public
386 * @var object
387 */
388 public $fields;
389
390 /**
391 * The API object.
392 *
393 * @since Unknown
394 * @access public
395 * @var object
396 */
397 public $api;
398
399 /**
400 * The shortcodes object.
401 *
402 * @since Unknown
403 * @access public
404 * @var object
405 */
406 public $shortcodes;
407
408 /**
409 * The membership object.
410 *
411 * @since Unknown
412 * @access public
413 * @var object
414 */
415 public $membership;
416
417 /**
418 * The email object.
419 *
420 * @since Unknown
421 * @access public
422 * @var object
423 */
424 public $email;
425
426 /**
427 * The user object.
428 *
429 * @since Unknown
430 * @access public
431 * @var object
432 */
433 public $user;
434
435 /**
436 * The menus object.
437 *
438 * @since Unknown
439 * @access public
440 * @var object
441 */
442 public $menus;
443
444 /**
445 * The dialogs object.
446 *
447 * @since Unknown
448 * @access public
449 * @var object
450 */
451 public $dialogs;
452
453 /**
454 * The clone menus object.
455 *
456 * @since Unknown
457 * @access public
458 * @var object
459 */
460 public $menus_clone;
461
462 /**
463 * The new account email activation object.
464 *
465 * @since Unknown
466 * @access public
467 * @var object
468 */
469 public $act_newreg;
470
471 /**
472 * The admin object class.
473 *
474 * @since Unknown
475 * @access public
476 * @var object
477 */
478 public $admin;
479
480 /**
481 * Handle the filesystem.
482 *
483 * @since 3.5.5
484 * @access public
485 * @var object
486 */
487 public $filesystem;
488
489 /**
490 * Objects for premium extensions.
491 *
492 * @access public
493 * @var object
494 */
495 public $advanced;
496 public $downloads;
497 public $editor;
498 public $invite_codes;
499 public $mailchimp;
500 public $salesforce;
501 public $security;
502 public $stop_spam;
503 public $usertrack;
504 public $user_list;
505 public $woo_connector;
506 public $excluded_meta;
507
508 // @deprecated
509 public $pwd_link;
510 public $login_error;
511 public $style; // @todo verify if this is deprecated.
512
513 /**
514 * Plugin initialization function.
515 *
516 * @since 3.0.0
517 * @since 3.1.6 Dependencies now loaded by object.
518 */
519 function __construct() {
520
521 // Constants.
522 $this->slug = 'wp-members.php';
523 $this->path = plugin_dir_path( __DIR__ );
524 $this->name = trailingslashit( $this->path ) . $this->slug;
525 $this->url = plugin_dir_url ( __DIR__ );
526
527 $settings = get_option( 'wpmembers_settings' );
528
529 // Validate that v3 settings are loaded.
530 if ( ! isset( $settings['version'] )
531 || $settings['version'] != $this->version
532 || ! isset( $settings['db_version'] )
533 || $settings['db_version'] != $this->db_version ) {
534 // Load installation routine and update settings.
535 require_once $this->path . 'includes/install.php';
536 $settings = wpmem_do_install();
537 }
538
539 /**
540 * Filter the options before they are loaded into constants.
541 *
542 * @since 2.9.0
543 * @since 3.0.0 Moved to the WP_Members class.
544 *
545 * @param array $this->settings An array of the WP-Members settings.
546 */
547 $settings = apply_filters( 'wpmem_settings', $settings );
548
549 // Assemble settings.
550 foreach ( $settings as $key => $val ) {
551 // @todo Leaving error message and password reset settings values in for now for rollback backwards compatibility.
552 // Later, we'll remove those values in the upgrade, so this can be cleaned up.
553 if ( 'pwd_link' != $key || 'login_error' != $key || 'shortcodes' != $key ) {
554 $this->{$key} = $val;
555 }
556 // @todo Check to make sure we don't have an invalid entry.
557 if ( 'cssurl' == $key ) {
558 $this->{$key} = ( 'https://' == $val || 'http://' == $val ) ? '' : $this->{$key};
559 }
560 }
561
562 // Load dependent files.
563 $this->load_dependencies();
564
565 // @todo Until I think of a better place to put this.
566 $this->optin = get_option( 'wpmembers_optin' );
567
568 // Load user pages (login, register, user profile).
569 $this->load_user_pages();
570
571 // Set the stylesheet.
572 $this->cssurl = ( '' != $settings['cssurl'] ) ? $this->cssurl : $this->url . 'assets/css/forms/generic-no-float' . wpmem_get_suffix() . '.css';
573
574 $this->forms = new WP_Members_Forms; // Load forms.
575 $this->api = new WP_Members_API; // Load api.
576 $this->shortcodes = new WP_Members_Shortcodes( $settings ); // Load shortcodes.
577 $this->membership = new WP_Members_Products(); // Load membership plans
578 $this->email = new WP_Members_Email; // Load email functions
579 $this->user = new WP_Members_User( $this ); // Load user functions.
580 $this->menus = new WP_Members_Menus();
581 $this->dialogs = new WP_Members_Dialogs();
582
583 // @deprecated Clone menus are technically deprecated, but kept in the plugin for legacy users.
584 if ( $this->clone_menus ) {
585 $this->menus_clone = new WP_Members_Clone_Menus(); // Load clone menus.
586 }
587
588 // @todo Is this a temporary fix?
589 $this->email->load_from();
590
591 /**
592 * Fires after main settings are loaded.
593 *
594 * @since 3.0
595 * @deprecated 3.2.0 Use wpmem_after_init instead.
596 */
597 do_action_deprecated( 'wpmem_settings_loaded', array(), '3.2.0', 'wpmem_after_init' );
598
599 // @deprecated 3.5.5, kept for legacy purposes. Preload the expiration module, if available.
600 $exp_active = ( function_exists( 'wpmem_exp_init' ) || function_exists( 'wpmem_set_exp' ) ) ? true : false;
601 define( 'WPMEM_EXP_MODULE', $exp_active ); // @deprecated 3.5.5, kept for legacy purposes.
602
603 // Load actions and filters.
604 $this->load_hooks();
605
606 // Load contants.
607 $this->load_constants();
608
609 // Load dropins.
610 if ( $this->dropins ) {
611 $this->load_dropins();
612 }
613 }
614
615 /**
616 * Plugin initialization function to load hooks.
617 *
618 * @since 3.0.0
619 */
620 function load_hooks() {
621
622 /**
623 * Fires before action and filter hooks load.
624 *
625 * @since 3.0.0
626 * @since 3.1.6 Fires before hooks load.
627 */
628 do_action( 'wpmem_load_hooks' );
629
630 // Add actions.
631 add_action( 'init', array( $this, 'load_textdomain' ) );
632 add_action( 'init', array( $this->membership, 'add_cpt' ), 0 ); // Adds membership plans custom post type.
633 add_action( 'init', array( $this, 'load_dependent_classes' ) );
634 add_action( 'widgets_init', array( $this, 'widget_init' ) ); // initializes the widget
635 add_action( 'rest_api_init', array( $this, 'rest_init' ) );
636 add_action( 'pre_get_posts', array( $this, 'do_hide_posts' ), 20 );
637 add_action( 'template_redirect', array( $this, 'get_action' ) );
638 add_action( 'login_enqueue_scripts', array( $this, 'enqueue_style_wp_login' ) ); // styles the native registration
639 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) ); // Enqueues the stylesheet.
640 add_action( 'wp_enqueue_scripts', array( $this, 'loginout_script' ) );
641 add_action( 'customize_register', array( $this, 'customizer_settings' ) );
642 add_action( 'wp_footer', array( $this, 'invisible_captcha' ) );
643
644 add_action( 'wpmem_after_init', array( $this, 'after_wpmem_loaded' ) );
645
646 if ( is_admin() ) {
647 add_action( 'init', array( $this, 'load_admin' ) ); // @todo Check user role to load correct dashboard
648 }
649
650 if ( is_user_logged_in() ) {
651 add_action( 'wpmem_pwd_change', array( $this->user, 'set_password' ), 9, 2 );
652 add_action( 'wpmem_pwd_change', array( $this->user, 'set_as_logged_in' ), 10 );
653 }
654
655 add_action( 'register_form', 'wpmem_wp_register_form' ); // Adds fields to the default wp registration
656
657 // Add filters.
658 add_filter( 'the_content', array( $this, 'do_securify' ), 99 );
659 add_filter( 'comments_open', array( $this, 'do_securify_comments' ), 99, 2 ); // securifies the comments
660 add_filter( 'wpmem_securify', array( $this, 'reg_securify' ) ); // adds success message on login form if redirected
661 add_filter( 'rest_prepare_post', array( $this, 'do_securify_rest' ), 10, 3 );
662 add_filter( 'rest_prepare_page', array( $this, 'do_securify_rest' ), 10, 3 );
663 foreach( $this->post_types as $post_type ) {
664 add_filter( "rest_prepare_{$post_type}", array( $this, 'do_securify_rest' ), 10, 3 );
665 }
666
667 //add_filter( 'query_vars', array( $this, 'add_query_vars' ), 10, 2 ); // adds custom query vars
668 add_filter( 'get_pages', array( $this, 'filter_get_pages' ) );
669 add_filter( 'wp_get_nav_menu_items', array( $this, 'filter_nav_menu_items' ), null, 3 );
670 add_filter( 'get_previous_post_where', array( $this, 'filter_get_adjacent_post_where' ) );
671 add_filter( 'get_next_post_where', array( $this, 'filter_get_adjacent_post_where' ) );
672 add_filter( 'allow_password_reset', array( $this->user, 'no_reset' ) ); // no password reset for non-activated users
673
674 // If registration is moderated, check for activation (blocks backend login by non-activated users).
675 if ( 1 == $this->mod_reg ) {
676 add_filter( 'authenticate', array( $this->user, 'check_activated' ), 99, 3 );
677 }
678
679 // Replace login error object, if profile page is set, AND it is not the wp-login.php page.
680 if ( isset( $this->user_pages['profile'] )
681 && '' != $this->user_pages['profile']
682 && 'wp-login.php' !== $GLOBALS['pagenow']
683 && ! wpmem_is_woo_active() ) {
684 add_filter( 'lostpassword_url', array( $this, 'lost_pwd_url' ), 10, 2 );
685 }
686
687 if ( function_exists( 'wpmem_custom_translation_strings' ) ) {
688 add_filter( 'wpmem_fields', array( $this->forms, 'localize_fields' ), 9 );
689 }
690
691 if ( 'display' == wpmem_get( 'tos', false, 'get' ) ) {
692 add_filter( 'wpmem_after_init', array( $this, 'load_tos') );
693 }
694
695 /**
696 * Fires after action and filter hooks load.
697 *
698 * @since 3.0.0
699 * @since 3.1.6 Was wpmem_load_hooks, now wpmem_hooks_loaded.
700 */
701 do_action( 'wpmem_hooks_loaded' );
702 }
703
704 /**
705 * Load drop-ins.
706 *
707 * @since 3.0.0
708 *
709 * @todo This is experimental. The function and its operation is subject to change.
710 */
711 function load_dropins() {
712
713 /**
714 * Fires before dropins load (for adding additional drop-ins).
715 *
716 * @since 3.0.0
717 * @since 3.1.6 Fires before dropins.
718 */
719 do_action( 'wpmem_load_dropins' );
720
721 /**
722 * Filters the drop-in file directory.
723 *
724 * @since 3.0.0
725 * @since 3.3.0 Filter previously unpublished, changed hook name.
726 *
727 * @param string $wpmem->dropin_dir The drop-in file directory.
728 */
729 $dir = apply_filters( 'wpmem_dropin_dir', $this->dropin_dir );
730
731 // Load any drop-ins.
732 $settings = get_option( 'wpmembers_dropins' );
733 $this->dropins_enabled = ( $settings ) ? $settings : array();
734 if ( ! empty( $this->dropins_enabled ) ) {
735 foreach ( $this->dropins_enabled as $filename ) {
736 $dropin = $dir . $filename;
737 if ( file_exists( $dropin ) ) {
738 include_once $dropin;
739 }
740 }
741 }
742
743 /**
744 * Fires before dropins load (for adding additional drop-ins).
745 *
746 * @since 3.0.0
747 * @since 3.1.6 Was wpmem_load_dropins, now wpmem_dropins_loaded.
748 */
749 do_action( 'wpmem_dropins_loaded' );
750 }
751
752 /**
753 * Loads pre-3.0 constants (included primarily for add-on compatibility).
754 *
755 * @since 3.0.0
756 * @since 3.3.0 Deprecated all but exp and trl constants.
757 *
758 * @todo Can WPMEM_MOD_REG be deprecated?
759 */
760 function load_constants() {
761 ( ! defined( 'WPMEM_MOD_REG' ) ) ? define( 'WPMEM_MOD_REG', $this->mod_reg ) : '';
762
763 // @todo these are deprecated as of PayPal extension version 0.9.9.1.
764 ( ! defined( 'WPMEM_USE_EXP' ) ) ? define( 'WPMEM_USE_EXP', $this->use_exp ) : '';
765 ( ! defined( 'WPMEM_USE_TRL' ) ) ? define( 'WPMEM_USE_TRL', $this->use_trial ) : '';
766 }
767
768 /**
769 * Load dependent files.
770 *
771 * @since 3.1.6
772 */
773 function load_dependencies() {
774
775 /**
776 * Filter the location and name of the pluggable file.
777 *
778 * @since 2.9.0
779 * @since 3.1.6 Moved in load order to come before dependencies.
780 *
781 * @param string The path to WP-Members plugin functions file.
782 */
783 $wpmem_pluggable = apply_filters( 'wpmem_plugins_file', WP_PLUGIN_DIR . '/wp-members-pluggable.php' );
784
785 // Preload any custom functions, if available.
786 if ( file_exists( $wpmem_pluggable ) ) {
787 include( $wpmem_pluggable );
788 }
789
790 require_once $this->path . 'includes/class-wp-members-api.php';
791 require_once $this->path . 'includes/class-wp-members-clone-menus.php';
792 require_once $this->path . 'includes/class-wp-members-captcha.php';
793 require_once $this->path . 'includes/class-wp-members-dialogs.php';
794 require_once $this->path . 'includes/class-wp-members-email.php';
795 require_once $this->path . 'includes/class-wp-members-forms.php';
796 require_once $this->path . 'includes/class-wp-members-menus.php';
797 require_once $this->path . 'includes/class-wp-members-products.php';
798 require_once $this->path . 'includes/class-wp-members-pwd-reset.php';
799 require_once $this->path . 'includes/class-wp-members-shortcodes.php';
800 require_once $this->path . 'includes/class-wp-members-user.php';
801 require_once $this->path . 'includes/class-wp-members-user-profile.php';
802 require_once $this->path . 'includes/class-wp-members-validation-link.php';
803 require_once $this->path . 'includes/class-wp-members-widget.php';
804 require_once $this->path . 'includes/class-wp-members-woocommerce-integration.php';
805 require_once $this->path . 'includes/api/api.php';
806 require_once $this->path . 'includes/api/api-email.php';
807 require_once $this->path . 'includes/api/api-forms.php';
808 require_once $this->path . 'includes/api/api-products.php';
809 require_once $this->path . 'includes/api/api-settings.php';
810 require_once $this->path . 'includes/api/api-users.php';
811 require_once $this->path . 'includes/api/api-utilities.php';
812
813 if ( defined( 'WP_CLI' ) && WP_CLI ) {
814 require_once $this->path . 'includes/cli/class-wp-members-cli.php';
815 }
816
817 require_once $this->path . 'includes/deprecated.php';
818 require_once $this->path . 'includes/legacy/dialogs.php'; // File is totally deprecated at this point; eval for removal.
819 }
820
821 /**
822 * Load classes that depend on the $wpmem object class to be fully loaded.
823 *
824 * @since 3.4.7
825 */
826 public function load_dependent_classes() {
827 if ( wpmem_is_woo_active() ) {
828 $this->woo = new WP_Members_WooCommerce_Integration( $this );
829 }
830 }
831
832 /**
833 * Load admin API and dependencies.
834 *
835 * Determines which scripts to load and actions to use based on the
836 * current users capabilities.
837 *
838 * @since 2.5.2
839 * @since 3.1.0 Added admin api object.
840 * @since 3.1.7 Moved from main plugin file as wpmem_chk_admin() to main object.
841 */
842 function load_admin() {
843
844 /**
845 * Fires before initialization of admin options.
846 *
847 * @since 2.9.0
848 */
849 do_action( 'wpmem_pre_admin_init' );
850
851 /**
852 * Load the admin api class.
853 *
854 * @since 3.1.0
855 */
856 require_once $this->path . 'includes/admin/class-wp-members-admin-api.php';
857 $this->admin = new WP_Members_Admin_API;
858
859 /**
860 * Fires after initialization of admin options.
861 *
862 * @since 2.9.0
863 */
864 do_action( 'wpmem_after_admin_init' );
865 }
866
867 /**
868 * Gets the requested action.
869 *
870 * @since 3.0.0
871 *
872 * @global string $wpmem_a The WP-Members action variable.
873 */
874 function get_action() {
875
876 // Get the action being done (if any).
877 $this->action = sanitize_text_field( wpmem_get( 'a', '', 'request' ) );
878
879 // For backward compatibility with processes that check $wpmem_a.
880 global $wpmem_a;
881 $wpmem_a = $this->action;
882
883 /**
884 * Fires when the wpmem action is retrieved.
885 *
886 * @since 3.1.7
887 * @since 3.4.2 Added action as a param.
888 */
889 do_action( 'wpmem_get_action', $this->action );
890
891 // Get the regchk value (if any).
892 $this->regchk = $this->get_regchk( $this->action );
893 }
894
895 /**
896 * Gets the regchk value.
897 *
898 * regchk is a legacy variable that contains information about the current
899 * action being performed. Login, logout, password, registration, profile
900 * update functions all return a specific value that is stored in regchk.
901 * This value and information about the current action can then be used to
902 * determine what content is to be displayed by the securify function.
903 *
904 * @since 3.0.0
905 *
906 * @global string $wpmem_a The WP-Members action variable.
907 *
908 * @param string $action The current action.
909 * @return string The regchk value.
910 */
911 function get_regchk( $action ) {
912
913 switch ( $action ) {
914
915 case 'login':
916 $regchk = $this->user->login();
917 break;
918
919 case 'logout':
920 $regchk = $this->user->logout();
921 break;
922
923 case 'pwdchange':
924 case 'set_password_from_key':
925 $regchk = $this->user->password_update( 'change' );
926 break;
927
928 case 'pwdreset':
929 $regchk = $this->user->password_update( 'link' );
930 break;
931
932 case 'getusername':
933 $regchk = $this->user->retrieve_username();
934 break;
935
936 case 'reconfirm':
937 $regchk = $this->user->resend_confirm();
938 break;
939
940 case 'register':
941 case 'update':
942 $regchk = wpmem_user_register( $action );
943 break;
944
945 default:
946 $regchk = ( isset( $regchk ) ) ? $regchk : '';
947 break;
948 }
949
950 /**
951 * Filter wpmem_regchk.
952 *
953 * The value of regchk is determined by functions that may be run in the get_regchk function.
954 * This value determines what happens in the wpmem_securify() function.
955 *
956 * @since 2.9.0
957 * @since 3.0.0 Moved to get_regchk() in WP_Members object.
958 *
959 * @param string $this->regchk The value of wpmem_regchk.
960 * @param string $this->action The $wpmem_a action.
961 */
962 $regchk = apply_filters( 'wpmem_regchk', $regchk, $action );
963
964 // Legacy global variable for use with older extensions.
965 global $wpmem_regchk;
966 $wpmem_regchk = $regchk;
967
968 return $regchk;
969 }
970
971 /**
972 * Determines if content should be blocked.
973 *
974 * This function was originally stand alone in the core file and
975 * was moved to the WP_Members class in 3.0.
976 *
977 * @since 3.0.0
978 * @since 3.3.0 Added $post_id
979 * @since 3.4.0 Added $is_post_check to allow for individual post checking.
980 *
981 * @global object $post The WordPress Post object.
982 *
983 * @param int $post_id
984 * @return bool $block true|false
985 */
986 function is_blocked( $post_id = false ) {
987
988 global $post;
989
990 $is_post_check = ( false == $post_id ) ? false : true;
991
992 if ( $post || $post_id ) {
993
994 $the_post = ( false == $post_id ) ? $post : get_post( $post_id );
995
996 $meta = wpmem_get_block_setting( $the_post->ID );
997
998 // Backward compatibility for old block/unblock meta.
999 if ( ! $meta ) {
1000 // Check for old meta.
1001 $old_block = get_post_meta( $the_post->ID, 'block', true );
1002 $old_unblock = get_post_meta( $the_post->ID, 'unblock', true );
1003 $meta = ( $old_block ) ? 1 : ( ( $old_unblock ) ? 0 : $meta );
1004 }
1005
1006 // Setup defaults.
1007 $defaults = array(
1008 'post_id' => $the_post->ID,
1009 'post_type' => $the_post->post_type,
1010 'block' => ( isset( $this->block[ $the_post->post_type ] ) && $this->block[ $the_post->post_type ] == 1 ) ? true : false,
1011 'block_meta' => $meta,
1012 'block_type' => ( isset( $this->block[ $the_post->post_type ] ) ) ? $this->block[ $the_post->post_type ] : 0,
1013 );
1014
1015 /**
1016 * Filter the block arguments.
1017 *
1018 * @since 2.9.8
1019 * @since 3.0.0 Moved to is_blocked() in WP_Members object.
1020 * @since 3.3.0 Passes $defaults, second argument deprecated.
1021 *
1022 * @param array $args $defaults.
1023 * @param array $defaults Deprecated 3.3.0. @todo Obsolete in 3.5.0
1024 */
1025 $args = apply_filters( 'wpmem_block_args', $defaults, $defaults );
1026
1027 // Merge $args with defaults.
1028 $args = ( wp_parse_args( $args, $defaults ) );
1029
1030 if ( $is_post_check || is_single() || is_page() || wpmem_is_rest() ) {
1031 switch( $args['block_type'] ) {
1032 case 1: // If content is blocked by default.
1033 $args['block'] = ( $args['block_meta'] == '0' ) ? false : $args['block'];
1034 break;
1035 case 0 : // If content is unblocked by default.
1036 $args['block'] = ( $args['block_meta'] == '1' ) ? true : $args['block'];
1037 break;
1038 }
1039
1040 } else {
1041 $args['block'] = false;
1042 }
1043
1044 } else {
1045 $args = array( 'block' => false );
1046 }
1047
1048 // Don't block user pages.
1049 $args['block'] = ( in_array( get_permalink(), $this->user_pages ) ) ? false : $args['block'];
1050
1051 /**
1052 * Filter the block boolean.
1053 *
1054 * @since 2.7.5
1055 *
1056 * @param bool $args['block']
1057 * @param array $args {
1058 * An array of arguments used in the function.
1059 *
1060 * @type string $post_id
1061 * @type string $post_type
1062 * @type string $block
1063 * @type string $block_meta
1064 * @tyep string $block_type
1065 * }
1066 */
1067 return apply_filters( 'wpmem_block', $args['block'], $args );
1068 }
1069
1070 /**
1071 * The Securify Content Filter.
1072 *
1073 * This is the primary function that picks up where get_action() leaves off.
1074 * Determines whether content is shown or hidden for both post and pages. This
1075 * is a filter function for the_content.
1076 *
1077 * @link https://developer.wordpress.org/reference/functions/the_content/
1078 * @link https://developer.wordpress.org/reference/hooks/the_content/
1079 *
1080 * @since 3.0.0
1081 *
1082 * @global object $post The WordPress Post object.
1083 * @global string $wpmem_themsg Contains messages to be output.
1084 * @param string $content
1085 * @return string $content
1086 */
1087 function do_securify( $content = null ) {
1088
1089 global $post, $wpmem_themsg;
1090
1091 $orig_content = $content;
1092
1093 $content = ( is_single() || is_page() ) ? $content : wpmem_do_excerpt( $content );
1094
1095 if ( $this->regchk == "captcha" ) {
1096 global $wpmem_captcha_err;
1097 $wpmem_themsg = wpmem_get_text( 'reg_captcha_err' ) . '<br /><br />' . $wpmem_captcha_err;
1098 }
1099
1100 // Block/unblock Posts.
1101 if ( ! is_user_logged_in() && true == $this->is_blocked() ) {
1102
1103 // If there is a regchk action, show the login and/or registration forms.
1104 if ( $this->regchk ) {
1105
1106 $content = wpmem_get_display_message( $this->regchk, $wpmem_themsg );
1107 $content .= ( 'loginfailed' == $this->regchk || 'success' == $this->regchk ) ? wpmem_login_form() : wpmem_register_form();
1108
1109 } else {
1110
1111 // Toggle shows excerpt above login/reg on posts/pages.
1112 global $wp_query;
1113 if ( isset( $wp_query->query_vars['page'] ) && $wp_query->query_vars['page'] > 1 ) {
1114
1115 // Shuts down excerpts on multipage posts if not on first page.
1116 $content = '';
1117
1118 } elseif ( isset( $this->show_excerpt[ $post->post_type ] ) && 1 == $this->show_excerpt[ $post->post_type ] ) {
1119
1120 // @todo Can this be condensed or eliminated?
1121 $len = strpos( $content, '<span id="more' );
1122 if ( false === $len ) {
1123 $content = wpmem_do_excerpt( $content );
1124 } else {
1125 $content = substr( $content, 0, $len );
1126 }
1127
1128 } else {
1129
1130 // Empty all content.
1131 $content = '';
1132
1133 }
1134
1135 // Build up default view based on settings.
1136 $content = $content . wpmem_restricted_message();
1137 $content = ( isset( $this->show_login[ $post->post_type ] ) && 1 == $this->show_login[ $post->post_type ] ) ? $content . wpmem_login_form() : $content;
1138 $content = ( isset( $this->show_reg[ $post->post_type ] ) && 1 == $this->show_reg[ $post->post_type ] ) ? $content . wpmem_register_form() : $content;
1139 }
1140
1141 // Protects comments if expiration module is used and user is expired.
1142 } elseif ( is_user_logged_in() && true == $this->is_blocked() ) {
1143
1144 // Allows for a view of the forms in the Customizer.
1145 if ( is_customize_preview() ) {
1146
1147 if ( get_theme_mod( 'wpmem_show_logged_out_state', false ) ) {
1148 $content = '';
1149 if ( get_theme_mod( 'wpmem_show_form_message_dialog', false ) ) {
1150 $content = $this->dialogs->login_failed();
1151 } else {
1152 $content = wpmem_restricted_message();
1153 }
1154 $content = ( isset( $this->show_login[ $post->post_type ] ) && 1 == $this->show_login[ $post->post_type ] ) ? $content . wpmem_login_form() : $content;
1155 $content = ( isset( $this->show_reg[ $post->post_type ] ) && 1 == $this->show_reg[ $post->post_type ] ) ? $content . wpmem_register_form() : $content;
1156 }
1157 } else {
1158
1159 // @todo Test with expired membership.
1160 if ( 1 == $this->use_exp && function_exists( 'wpmem_do_expmessage' ) ) {
1161 /**
1162 * Filters the user expired message used by the PayPal extension.
1163 *
1164 * @since 3.2.0
1165 *
1166 * @param string $message
1167 * @param string $content
1168 */
1169 $content = apply_filters( 'wpmem_do_expmessage', wpmem_do_expmessage( $content ), $content );
1170 }
1171 }
1172 }
1173
1174 /**
1175 * Filter the value of $content after wpmem_securify has run.
1176 *
1177 * @since 2.7.7
1178 * @since 3.0.0 Moved to new method in WP_Members Class.
1179 * @since 3.4.0 Added $orig_content param.
1180 *
1181 * @param string $content The content after securify has run.
1182 */
1183 $content = apply_filters( 'wpmem_securify', $content, $orig_content );
1184
1185 return $content;
1186
1187 }
1188
1189 /**
1190 * Securifies the comments.
1191 *
1192 * If the user is not logged in and the content is blocked
1193 * (i.e. $wpmem->is_blocked() returns true), function loads a
1194 * dummy/empty comments template.
1195 *
1196 * @since 2.9.9
1197 * @since 3.2.0 Moved wpmem_securify_comments() to main class, renamed.
1198 * @since 3.3.2 Added $post_id.
1199 *
1200 * @param bool $open Whether the current post is open for comments.
1201 * @param int $post_id The post ID.
1202 * @return bool $open True if current post is open for comments, otherwise false.
1203 */
1204 function do_securify_comments( $open, $post_id ) {
1205
1206 $open = ( ! is_user_logged_in() && wpmem_is_blocked( $post_id ) ) ? false : $open;
1207
1208 /**
1209 * Filters whether comments are open or not.
1210 *
1211 * @since 3.0.0
1212 * @since 3.2.0 Moved to main class.
1213 * @since 3.3.2 Added $post_id.
1214 *
1215 * @param bool $open true if current post is open for comments, otherwise false.
1216 */
1217 $open = apply_filters( 'wpmem_securify_comments', $open, $post_id );
1218
1219 if ( ! $open ) {
1220 /** This filter is documented in wp-includes/comment-template.php */
1221 add_filter( 'comments_array', array( $this, 'do_securify_comments_array' ), 10, 2 );
1222 }
1223
1224 return $open;
1225 }
1226
1227 /**
1228 * Empties the comments array if content is blocked.
1229 *
1230 * @since 3.0.1
1231 * @since 3.2.0 Moved wpmem_securify_comments_array() to main class, renamed.
1232 *
1233 * @param array $comments
1234 * @param int $post_id
1235 * @return array $comments The comments array.
1236 */
1237 function do_securify_comments_array( $comments , $post_id ) {
1238 // @todo This logic is checked in do_securify_comments() before the filter is added. Is it needed here?
1239 $comments = ( ! is_user_logged_in() && wpmem_is_blocked( $post_id ) ) ? array() : $comments;
1240 return $comments;
1241 }
1242
1243 /**
1244 * Handles REST request.
1245 *
1246 * @since 3.3.2
1247 *
1248 * @param WP_REST_Response $response The response object.
1249 * @param WP_Post $post Post object.
1250 * @param WP_REST_Request $request Request object.
1251 * @return
1252 */
1253 function do_securify_rest( $response, $post, $request ) {
1254
1255 // Only run if $response contains "id", otherwise we can't check it as blocked (since it would not contain a post ID).
1256 if ( isset( $response->data['id'] ) ) {
1257
1258 if ( ! is_user_logged_in() ) { // @todo This needs to be changed to check for whether the user has access (for internal requests).
1259 // Response for restricted content
1260 $block_value = wpmem_is_blocked( $response->data['id'] );
1261 if ( $block_value ) {
1262
1263 /**
1264 *
1265 *
1266 * @since 3.4.7
1267 *
1268 * @param
1269 * @param WP_REST_Response $response The response object.
1270 * @param WP_Post $post Post object.
1271 * @param WP_REST_Request $request Request object.
1272 */
1273 $drop = apply_filters( "wpmem_securify_rest_{$post->post_type}_drop_response_data", array(), $response, $post, $request );
1274
1275 foreach ( $drop as $dropped_key ) {
1276 $response->data[ $dropped_key ] = array();
1277 }
1278
1279 if ( isset( $response->data['content']['rendered'] ) ) {
1280 /**
1281 * Filters restricted content message.
1282 *
1283 * @since 3.3.2
1284 * @since 3.3.4 Added $response, $post, and $request
1285 *
1286 * @param string $message
1287 */
1288 $response->data['content']['rendered'] = apply_filters( "wpmem_securify_rest_{$post->post_type}_content", wpmem_get_text( 'rest_content_rendered' ), $response, $post, $request );
1289 }
1290 if ( isset( $response->data['excerpt']['rendered'] ) ) {
1291 /**
1292 * Filters restricted excerpt message.
1293 *
1294 * @since 3.3.2
1295 * @since 3.3.4 Added $response, $post, and $request
1296 *
1297 * @param string $message
1298 */
1299 $response->data['excerpt']['rendered'] = apply_filters( "wpmem_securify_rest_{$post->post_type}_excerpt", wpmem_get_text( 'rest_excerpt_rendered' ), $response, $post, $request );
1300 }
1301 }
1302
1303 // Response for hidden content. @todo This needs to be changed to check for whether the user has access (for internal requests).
1304 if ( ! is_admin() && in_array( $post->ID, $this->hidden_posts() ) ) {
1305 return new WP_REST_Response( wpmem_get_text( 'rest_404' ), 404 );
1306 }
1307 }
1308 }
1309 return $response;
1310 }
1311
1312 /**
1313 * Adds the successful registration message on the login page if reg_nonce validates.
1314 *
1315 * @since 3.1.7
1316 * @since 3.2.0 Moved to wpmem object, renamed reg_securify()
1317 *
1318 * @param string $content
1319 * @return string $content
1320 */
1321 function reg_securify( $content ) {
1322 global $wpmem_themsg;
1323 $nonce = wpmem_get( 'reg_nonce', false, 'get' );
1324 if ( $nonce && wp_verify_nonce( $nonce, 'register_redirect' ) ) {
1325 $content = wpmem_get_display_message( 'success', $wpmem_themsg );
1326 $content = $content . wpmem_login_form();
1327 }
1328 return $content;
1329 }
1330
1331 /**
1332 * Runs if the REST API is initialized.
1333 *
1334 * @since 3.3.2
1335 */
1336 function rest_init() {
1337 $this->is_rest = true;
1338 }
1339
1340 /**
1341 * Gets an array of hidden post IDs.
1342 *
1343 * @since 3.2.0
1344 *
1345 * @return array $hidden
1346 */
1347 function hidden_posts() {
1348 $hidden = get_option( 'wpmem_hidden_posts' );
1349 if ( false == $hidden ) {
1350 $hidden = $this->update_hidden_posts();
1351 }
1352 return $hidden;
1353 }
1354
1355 /**
1356 * Updates the hidden post array transient.
1357 *
1358 * @since 3.2.0
1359 * @since 3.3.3 Don't include posts from post types not set as handled by WP-Members.
1360 *
1361 * @global object $wpdb
1362 * @return array $hidden
1363 */
1364 function update_hidden_posts() {
1365 global $wpdb;
1366 $hidden = array();
1367 $default_post_types = array( 'post'=>'Posts', 'page'=>'Page' );
1368 $post_types = array_merge( $this->post_types, $default_post_types );
1369 // $results = $wpdb->get_results( "SELECT post_id FROM " . $wpdb->prefix . "postmeta WHERE meta_key = '_wpmem_block' AND meta_value = 2" );
1370 $results = $wpdb->get_results(
1371 "SELECT
1372 p1.id,
1373 p1.post_type,
1374 m1.meta_key AS _wpmem_block
1375 FROM " . $wpdb->prefix . "posts p1
1376 JOIN " . $wpdb->prefix . "postmeta m1 ON (m1.post_id = p1.id AND m1.meta_key = '_wpmem_block')
1377 WHERE m1.meta_value = '2';"
1378 );
1379 foreach( $results as $result ) {
1380 if ( array_key_exists( $result->post_type, $post_types ) ) {
1381 $hidden[] = $result->id;
1382 }
1383 }
1384 update_option( 'wpmem_hidden_posts', $hidden, true );
1385 return $hidden;
1386 }
1387
1388 /**
1389 * Gets an array of hidden post IDs.
1390 *
1391 * @since 3.2.0
1392 *
1393 * @global stdClass $wpdb
1394 * @return array $hidden
1395 */
1396 function get_hidden_posts() {
1397 $hidden = array();
1398
1399 // Return empty array if this is the admin and user can edit posts.
1400 if ( is_admin() && current_user_can( 'edit_posts' ) ) {
1401 return $hidden;
1402 }
1403
1404 // If the user is not logged in, return all hidden posts.
1405 if ( ! is_user_logged_in() ) {
1406 $hidden = $this->hidden_posts();
1407 } else {
1408 // If the user is logged in.
1409 if ( wpmem_is_enabled( 'enable_products' ) ) {
1410 // Get user product access.
1411 $hidden = $this->hidden_posts();
1412 $hidden = ( is_array( $hidden ) ) ? $hidden : array();
1413
1414 // Remove posts with a product the user has access to.
1415 foreach ( wpmem_get_memberships() as $key => $value ) {
1416 if ( wpmem_user_has_access( $key ) ) {
1417 foreach ( $hidden as $post_id ) {
1418 if ( 1 == get_post_meta( $post_id, wpmem_get_membership_meta( $key ), true ) ) {
1419 $hidden_key = array_search( $post_id, $hidden );
1420 unset( $hidden[ $hidden_key ] );
1421 }
1422 }
1423 }
1424 }
1425
1426 // Remove posts that don't have a product assignment (general login).
1427 foreach( $hidden as $hidden_key ) {
1428 $unattached = get_post_meta( $hidden_key, '_wpmem_products', true );
1429 if ( false == $unattached ) {
1430 $hidden_key = array_search( $hidden_key, $hidden );
1431 unset( $hidden[ $hidden_key ] );
1432 }
1433 }
1434 }
1435 }
1436 /**
1437 * Filter the hidden posts array.
1438 *
1439 * @since 3.3.4
1440 *
1441 * @param array $hidden
1442 */
1443 return apply_filters( 'wpmem_hidden_posts', $hidden );
1444 }
1445
1446 /**
1447 * Hides posts based on settings and meta.
1448 *
1449 * @since 3.2.0
1450 *
1451 * @param array $query
1452 * @return array $query
1453 */
1454 function do_hide_posts( $query ) {
1455 $hidden_posts = $this->get_hidden_posts();
1456 if ( ! empty( $hidden_posts ) ) {
1457 // Add hidden posts to post__not_in while maintaining any existing exclusions.
1458 $post__not_in = ( ! isset( $query->query_vars['post__not_in'] ) ) ? $hidden_posts : array_merge( $query->query_vars['post__not_in'], $hidden_posts );
1459 /**
1460 * Filter post__not_in.
1461 *
1462 * @since 3.3.4
1463 *
1464 * @param array $post__not_in
1465 */
1466 $post__not_in = apply_filters( 'wpmem_post__not_in', $post__not_in );
1467 $query->set( 'post__not_in', $post__not_in );
1468 }
1469 return $query;
1470 }
1471
1472 /**
1473 * Filter to hide pages for get_pages().
1474 *
1475 * @since 3.2.0
1476 *
1477 * @global object $wpdb
1478 * @param array $pages
1479 * @return array $pages
1480 */
1481 function filter_get_pages( $pages ) {
1482 $hidden_posts = $this->get_hidden_posts();
1483 if ( ! empty ( $hidden_posts ) ) {
1484 $new_pages = array();
1485 foreach ( $pages as $key => $page ) {
1486 if ( ! in_array( $page->ID, $hidden_posts ) ) {
1487 $new_pages[ $key ] = $page;
1488 }
1489 }
1490 $pages = $new_pages;
1491 }
1492 return $pages;
1493 }
1494
1495 /**
1496 * Filter to hide menu items.
1497 *
1498 * @since 3.2.0
1499 *
1500 * @param array $items
1501 * @param $menu
1502 * @param array $args
1503 * @return array $items
1504 */
1505 function filter_nav_menu_items( $items, $menu, $args ) {
1506 $hidden_posts = $this->get_hidden_posts();
1507 if ( ! empty( $hidden_posts ) ) {
1508 foreach ( $items as $key => $item ) {
1509 if ( in_array( $item->object_id, $hidden_posts ) ) {
1510 unset( $items[ $key ] );
1511 }
1512 }
1513 }
1514 return $items;
1515 }
1516
1517 /**
1518 * Filter to remove hidden posts from prev/next links.
1519 *
1520 * @since 3.2.4
1521 *
1522 * @param string $where
1523 * @return string $where
1524 */
1525 function filter_get_adjacent_post_where( $where ) {
1526 if ( ! is_user_logged_in() ) {
1527 $hidden_posts = $this->get_hidden_posts();
1528 if ( ! empty( $hidden_posts ) ) {
1529 $hidden = implode( ",", $hidden_posts );
1530 $where = $where . " AND p.ID NOT IN ( $hidden )";
1531 }
1532 }
1533 return $where;
1534 }
1535
1536 /**
1537 * Set page locations.
1538 *
1539 * Handles numeric page IDs while maintaining
1540 * compatibility with old full url settings.
1541 *
1542 * @since 3.0.8
1543 */
1544 function load_user_pages() {
1545 foreach ( $this->user_pages as $key => $val ) {
1546 if ( is_numeric( $val ) ) {
1547 if ( false !== get_post_status( $val ) ) {
1548 $this->user_pages[ $key ] = get_page_link( $val );
1549 } else {
1550 $notice = sprintf( __( 'You have a linked page in the WP-Members page settings that corresponds to a post ID that no longer exists. Please %s review and update the %s page settings %s.', 'wp-members' ), '<a href="' . esc_url( get_admin_url() . '/options-general.php?page=wpmem-settings&tab=options' ) . '">', $key, '</a>' );
1551 $this->admin_notices[] = array(
1552 'type'=>'error',
1553 'notice'=>$notice
1554 );
1555 }
1556 }
1557 }
1558 }
1559
1560 /**
1561 * Returns a requested text string.
1562 *
1563 * This function manages all of the front-end facing text.
1564 * All defaults can be filtered using wpmem_default_text_strings.
1565 *
1566 * @since 3.1.0
1567 * @deprecated 3.5.0 Use wpmem_get_text() Make sure "official" extensions do not use $wpmem->get_text() before making obsolete.
1568 *
1569 * @param string $str
1570 * @return string $text
1571 */
1572 function get_text( $str ) {
1573 return $this->dialogs->get_text( $str );
1574 }
1575
1576 /**
1577 * Initializes the WP-Members widget.
1578 *
1579 * @since 3.2.0 Replaces widget_wpmemwidget_init
1580 */
1581 public function widget_init() {
1582 // Register the WP-Members widget.
1583 register_widget( 'widget_wpmemwidget' );
1584 }
1585
1586 /**
1587 * Adds WP-Members query vars to WP's public query vars.
1588 *
1589 * @since 3.2.0
1590 *
1591 * @see https://codex.wordpress.org/Plugin_API/Filter_Reference/query_vars
1592 *
1593 * @param array $qvars
1594 */
1595 public function add_query_vars ( $qvars ) {
1596 $qvars[] = 'a'; // The WP-Members action variable.
1597 return $qvars;
1598 }
1599
1600 /**
1601 * Enqueues login/out script for the footer.
1602 *
1603 * @since 3.2.0
1604 */
1605 public function loginout_script() {
1606 if ( is_user_logged_in() ) {
1607 wp_enqueue_script( 'jquery' );
1608 add_action( 'wp_footer', array( $this, 'do_loginout_script' ), 50 );
1609 }
1610 }
1611
1612 /**
1613 * Outputs login/out script for the footer.
1614 *
1615 * @since 3.2.0
1616 */
1617 public function do_loginout_script() {
1618 $logout = wpmem_logout_link(); ?>
1619 <script type="text/javascript">
1620 jQuery(document).ready(function() {
1621 jQuery('.wpmem_loginout').html('<a class="login_button" href="<?php echo esc_url( $logout ); ?>"><?php echo wpmem_get_text( 'menu_logout' ); ?></a>');
1622 });
1623 </script><?php
1624 }
1625
1626 /**
1627 * Adds WP-Members controls to the Customizer
1628 *
1629 * @since 3.2.0
1630 *
1631 * @param object $wp_customize The Customizer object.
1632 */
1633 function customizer_settings( $wp_customize ) {
1634 $wp_customize->add_section( 'wp_members' , array(
1635 'title' => 'WP-Members',
1636 'priority' => 190,
1637 ) );
1638
1639 // Add settings for output description
1640 $wp_customize->add_setting( 'wpmem_show_logged_out_state', array(
1641 'default' => '1',
1642 'type' => 'theme_mod', //'option'
1643 'capability' => 'edit_theme_options',
1644 'transport' => 'refresh',
1645 ) );
1646
1647 // Add settings for output description
1648 $wp_customize->add_setting( 'wpmem_show_form_message_dialog', array(
1649 'default' => '1',
1650 'type' => 'theme_mod', //'option'
1651 'capability' => 'edit_theme_options',
1652 'transport' => 'refresh',
1653 ) );
1654
1655 // Add control and output for select field
1656 $wp_customize->add_control( 'wpmem_show_form_logged_out', array(
1657 'label' => __( 'Show forms as logged out', 'wp-members' ),
1658 'section' => 'wp_members',
1659 'settings' => 'wpmem_show_logged_out_state',
1660 'type' => 'checkbox',
1661 'std' => '1'
1662 ) );
1663
1664 // Add control for showing dialog
1665 $wp_customize->add_control( 'wpmem_show_form_dialog', array(
1666 'label' => __( 'Show form message dialog', 'wp-members' ),
1667 'section' => 'wp_members',
1668 'settings' => 'wpmem_show_form_message_dialog',
1669 'type' => 'checkbox',
1670 'std' => '0'
1671 ) );
1672 }
1673
1674 /**
1675 * Loads the stylesheet for tableless forms.
1676 *
1677 * @since 2.6
1678 * @since 3.2.3 Moved to WP_Members class.
1679 */
1680 function enqueue_style() {
1681 wp_enqueue_style ( 'wp-members', wpmem_force_ssl( $this->cssurl ), false, $this->version );
1682 }
1683
1684 /**
1685 * Loads the wp-login.php stylesheet.
1686 *
1687 * @since 3.3.0
1688 */
1689 function enqueue_style_wp_login() {
1690 wp_enqueue_style( 'wp-members', $this->url . 'assets/css/wp-login' . wpmem_get_suffix() . '.css', false, $this->version );
1691 }
1692
1693 /**
1694 * Creates an excerpt on the fly if there is no 'more' tag.
1695 *
1696 * @since 2.6
1697 * @since 3.2.3 Moved to WP_Members class.
1698 * @since 3.2.5 Check if post object exists.
1699 *
1700 * @global object $post The post object.
1701 *
1702 * @param string $content
1703 * @return string $content
1704 */
1705 function do_excerpt( $content ) {
1706
1707 global $post, $more;
1708
1709 if ( is_object( $post ) ) {
1710
1711 $post_id = $post->ID;
1712 $post_type = $post->post_type;
1713
1714 $autoex = ( isset( $this->autoex[ $post->post_type ] ) && 1 == $this->autoex[ $post->post_type ]['enabled'] ) ? $this->autoex[ $post->post_type ] : false;
1715
1716 // Is there already a 'more' link in the content?
1717 $has_more_link = ( stristr( $content, 'class="more-link"' ) ) ? true : false;
1718
1719 // If auto_ex is on.
1720 if ( $autoex ) {
1721
1722 // Build an excerpt if one does not exist.
1723 if ( ! $has_more_link ) {
1724
1725 $is_singular = ( is_singular( $post->post_type ) ) ? true : false;
1726
1727 if ( $is_singular ) {
1728 // If it's a single post, we don't need the 'more' link.
1729 $more_link_text = '';
1730 $more_link = '';
1731 } else {
1732 // The default $more_link_text.
1733 if ( isset( $this->autoex[ $post->post_type ]['text'] ) && '' != $this->autoex[ $post->post_type ]['text'] ) {
1734 $more_link_text = __( $this->autoex[ $post->post_type ]['text'], 'wp-members' );
1735 } else {
1736 $more_link_text = __( '(more&hellip;)' );
1737 }
1738 // The default $more_link.
1739 $more_link = ' <a href="'. esc_url( get_permalink( $post->ID ) ) . '" class="more-link">' . esc_attr( $more_link_text ) . '</a>';
1740 }
1741
1742 // Apply the_content_more_link filter if one exists (will match up all 'more' link text).
1743 /** This filter is documented in /wp-includes/post-template.php */
1744 $more_link = apply_filters( 'the_content_more_link', $more_link, $more_link_text );
1745
1746 $defaults = array(
1747 'length' => $autoex['length'],
1748 'more_link' => $more_link,
1749 'blocked_only' => false,
1750 );
1751 /**
1752 * Filter auto excerpt defaults.
1753 *
1754 * @since 3.0.9
1755 * @since 3.1.5 Deprecated add_ellipsis, strip_tags, close_tags, parse_shortcodes, strip_shortcodes.
1756 *
1757 * @param array {
1758 * An array of settings to override the function defaults.
1759 *
1760 * @type int $length The default length of the excerpt.
1761 * @type string $more_link The more link HTML.
1762 * @type boolean $blocked_only Run autoexcerpt only on blocked content. default: false.
1763 * }
1764 * @param string $post->ID The post ID.
1765 * @param string $post->post_type The content's post type.
1766 */
1767 $args = apply_filters( 'wpmem_auto_excerpt_args', $defaults, $post->ID, $post->post_type );
1768
1769 // Merge settings.
1770 $args = wp_parse_args( $args, $defaults );
1771
1772 // Are we only excerpting blocked content?
1773 if ( $args['blocked_only'] ) {
1774 $post_meta = get_post_meta( $post->ID, '_wpmem_block', true );
1775 if ( 1 == $this->block[ $post->post_type ] ) {
1776 // Post type is blocked, if post meta unblocks it, don't do excerpt.
1777 $do_excerpt = ( "0" == $post_meta ) ? false : true;
1778 } else {
1779 // Post type is unblocked, if post meta blocks it, do excerpt.
1780 $do_excerpt = ( "1" == $post_meta ) ? true : false;
1781 }
1782 } else {
1783 $do_excerpt = true;
1784 }
1785
1786 if ( true === $do_excerpt ) {
1787 $content = ( $args['length'] > 0 ) ? wp_trim_words( $content, $args['length'], $args['more_link'] ) : '';
1788 // Check if the more link was added (note: singular has no more_link):
1789 if ( ! $is_singular && ! strpos( $content, $args['more_link'] ) ) {
1790 $content = $content . $args['more_link'];
1791 }
1792 }
1793 }
1794 }
1795 } else {
1796 $post_id = false;
1797 $post_type = false;
1798 }
1799
1800 /**
1801 * Filter the auto excerpt.
1802 *
1803 * @since 2.8.1
1804 * @since 3.0.9 Added post ID and post type parameters.
1805 * @since 3.2.5 Post ID and post type may be false if there is no post object.
1806 *
1807 * @param string $content The content excerpt.
1808 * @param string $post_id The post ID.
1809 * @param string $post_type The content's post type.
1810 */
1811 $content = apply_filters( 'wpmem_auto_excerpt', $content, $post_id, $post_type );
1812
1813 // Return the excerpt.
1814 return $content;
1815 }
1816
1817 /**
1818 * Convert form tag.
1819 *
1820 * @todo This is temporary to handle form tag conversion.
1821 *
1822 * @since 3.1.7
1823 * @since 3.2.3 Moved to WP_Members class.
1824 * @since 3.3.0 Removed unnecessary tags.
1825 *
1826 * @param string $tag
1827 * @return string $tag
1828 */
1829 function convert_tag( $tag ) {
1830 switch ( $tag ) {
1831 case 'new':
1832 return 'register';
1833 break;
1834 case 'edit':
1835 case 'update':
1836 return 'profile';
1837 break;
1838 default:
1839 return $tag;
1840 break;
1841 }
1842 return $tag;
1843 }
1844
1845 /**
1846 * Loads translation files.
1847 *
1848 * @since 3.0.0
1849 * @since 3.2.5 Moved to main object, dropped wpmem_ stem.
1850 */
1851 function load_textdomain() {
1852
1853 // Plugin textdomain.
1854 $domain = 'wp-members';
1855
1856 // Wordpress locale.
1857 /** This filter is documented in wp-includes/l10n.php */
1858 $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
1859
1860 /**
1861 * Filter translation file.
1862 *
1863 * If the translate.wordpress.org language pack is available, it will
1864 * be /wp-content/languages/plugins/wp-members-{locale}.mo by default.
1865 * You can filter this if you want to load a language pack from a
1866 * different location (or different file name).
1867 *
1868 * @since 3.0.0
1869 * @since 3.2.0 Added locale as a parameter.
1870 *
1871 * @param string $file The translation file to load.
1872 * @param string $locale The current locale.
1873 */
1874 $file = apply_filters( 'wpmem_localization_file', trailingslashit( WP_LANG_DIR ) . 'plugins/' . $domain . '-' . $locale . '.mo', $locale );
1875
1876 $loaded = load_textdomain( $domain, $file );
1877 if ( true == $loaded ) {
1878 return $loaded;
1879 } else {
1880 /**
1881 * Filter translation directory.
1882 *
1883 * @since 3.0.3
1884 * @since 3.2.0 Added locale as a parameter.
1885 *
1886 * @param string $dir The translation directory.
1887 * @param string $locale The current locale.
1888 */
1889 $dir = apply_filters( 'wpmem_localization_dir', basename( $this->path ) . '/i18n/languages/', $locale );
1890 load_plugin_textdomain( $domain, FALSE, $dir );
1891 }
1892 return;
1893 }
1894
1895 /**
1896 * Load default tos template.
1897 *
1898 * @since 3.2.8
1899 */
1900 function load_default_tos() {
1901 // Check for custom template or load default.
1902 $custom_template = get_stylesheet_directory() . '/wp-members/templates/tos.php';
1903 if ( file_exists( $custom_template ) ) {
1904 require_once $custom_template;
1905 } else {
1906 require_once $this->path . 'templates/tos.php';
1907 }
1908 }
1909
1910 /**
1911 * Builds defaults for login/out links/buttons.
1912 *
1913 * @since 3.3.5
1914 *
1915 * @param array $args
1916 * @return string $html
1917 */
1918 function loginout_args( $args = array() ) {
1919 $defaults = array(
1920 'format' => ( isset( $args['format'] ) ) ? $args['format'] : 'link',
1921 'login_redirect_to' => ( isset( $args['login_redirect_to'] ) ) ? $args['login_redirect_to'] : wpmem_current_url(),
1922 'logout_redirect_to' => ( isset( $args['logout_redirect_to'] ) ) ? $args['logout_redirect_to'] : wpmem_current_url(), // @todo - This is not currently active.
1923 'login_text' => ( isset( $args['login_text'] ) ) ? $args['login_text'] : wpmem_get_text( 'loginout_login_text' ),
1924 'logout_text' => ( isset( $args['logout_text'] ) ) ? $args['logout_text'] : wpmem_get_text( 'loginout_logout_text' ),
1925 'class' => ( isset( $args['class'] ) ) ? $args['class'] : 'wpmem_loginout_link',
1926 'id' => ( isset( $args['id'] ) ) ? $args['id'] : 'wpmem_loginout_link',
1927 );
1928 $args = wp_parse_args( $args, $defaults );
1929 $redirect = ( is_user_logged_in() ) ? $args['logout_redirect_to'] : $args['login_redirect_to'];
1930 $text = ( is_user_logged_in() ) ? $args['logout_text'] : $args['login_text'];
1931 if ( is_user_logged_in() ) {
1932 $link = wpmem_logout_link();
1933 } else {
1934 $link = wpmem_login_url( $redirect );
1935 }
1936
1937 if ( 'button' == $args['format'] ) {
1938 $html = '<form action="' . esc_url( $link ) . '" id="' . esc_attr( $args['id'] ) . '" class="' . esc_attr( $args['class'] ) . '">';
1939 $html.= ( is_user_logged_in() ) ? '<input type="hidden" name="a" value="logout" />' : '';
1940 $html.= '<input type="submit" value="' . esc_attr( $text ) . '" /></form>';
1941 } else {
1942 $html = sprintf( '<a href="%s" id="%s" class="%s">%s</a>', esc_url( $link ), esc_attr( $args['id'] ), esc_attr( $args['class'] ), esc_attr( $text ) );
1943 }
1944 return $html;
1945 }
1946
1947 /**
1948 * Filters the password URL to point to the WP-Members process.
1949 *
1950 * @since 3.3.5
1951 */
1952 function lost_pwd_url( $lostpwd_url, $redirect ) {
1953 return wpmem_profile_url( 'pwdreset' );
1954 }
1955
1956 /**
1957 * Google recaptcha v3 (invisible) gives more accurate user scores
1958 * if it is loaded on all pages.
1959 *
1960 * @since 3.4.0
1961 */
1962 function invisible_captcha() {
1963 if ( 4 == $this->captcha && true !== wpmem_is_reg_form_showing() ) {
1964 echo WP_Members_Captcha::show();
1965 }
1966 }
1967
1968 /**
1969 * Check for errors.
1970 *
1971 * @since 3.4.6
1972 * @since 3.4.8 Check as WP_Error (use is_wp_error()).
1973 */
1974 public function has_errors() {
1975 return ( is_wp_error( $this->error ) && $this->error->has_errors() ) ? true : false;
1976 }
1977
1978 /**
1979 * Loads the activation object if enabled.
1980 *
1981 * @since Unknown
1982 *
1983 * @todo Can this be evaluated for loading based only when specifically
1984 * needed for the actual processed used?
1985 * @todo Apart from the above, can this load at load_dependent_classes()?
1986 */
1987 public function after_wpmem_loaded() {
1988 if ( wpmem_is_enabled( 'act_link' ) ) {
1989 $this->act_newreg = new WP_Members_Validation_Link;
1990 }
1991 }
1992
1993 /**
1994 * Loads the default TOS template.
1995 *
1996 * This is used to be part of the init routine, but after some changes
1997 * in recent versions, it needs to load after the $wpmem object is fully
1998 * initialized. It is now hooked to wpmem_after_init as a separate
1999 * method.
2000 *
2001 * @since 3.5.3
2002 * @todo Deprecate in 3.6.0, obsolete by 3.7.0 (maybe earlier)
2003 */
2004 public function load_tos() {
2005 // Check for anything that we should stop execution for (currently just the default tos).
2006 if ( 'display' == wpmem_get( 'tos', false, 'get' ) ) {
2007 // If themes are not loaded, we don't need them.
2008 $user_themes = ( ! defined( 'WP_USE_THEMES' ) ) ? define( 'WP_USE_THEMES', false ) : '';
2009 $this->load_default_tos();
2010 die();
2011 }
2012 }
2013
2014 } // End of WP_Members class.