/app/controller/class-ms-controller-plugin.php

  1. <?php 
  2. /** 
  3. * Primary controller for Membership Plugin. 
  4. * 
  5. * Responsible for flow control, navigation and invoking other controllers. 
  6. * 
  7. * @since 1.0.0 
  8. * 
  9. * @package Membership2 
  10. * @subpackage Controller 
  11. */ 
  12. class MS_Controller_Plugin extends MS_Controller { 
  13.  
  14. /** 
  15. * Plugin Menu slug. 
  16. * 
  17. * @since 1.0.0 
  18. * 
  19. * @var string 
  20. */ 
  21. const MENU_SLUG = 'membership2'; 
  22.  
  23. /** 
  24. * The slug of the top-level admin page 
  25. * 
  26. * @since 1.0.0 
  27. * 
  28. * @var string 
  29. */ 
  30. private static $base_slug = ''; 
  31.  
  32. /** 
  33. * Capability required to count as M2 'admin' user. Admin users have full 
  34. * access to all M2 features. 
  35. * 
  36. * @since 1.0.0 
  37. * 
  38. * @var $capability 
  39. */ 
  40. protected $capability = 'manage_options'; 
  41.  
  42. /** 
  43. * Instance of MS_Model_Plugin. 
  44. * 
  45. * @since 1.0.0 
  46. * 
  47. * @var $model 
  48. */ 
  49. private $model; 
  50.  
  51. /** 
  52. * Pointer array for other controllers. 
  53. * 
  54. * @since 1.0.0 
  55. * 
  56. * @var $controllers 
  57. */ 
  58. protected $controllers = array(); 
  59.  
  60. /** 
  61. * Stores the callback handler for the submenu items. 
  62. * It is set by self::route_submenu_request() and is used by 
  63. * self::handle_submenu_request() 
  64. * 
  65. * @since 1.0.0 
  66. * 
  67. * @var array 
  68. */ 
  69. private $menu_handler = null; 
  70.  
  71. /** 
  72. * Constructs the primary Plugin controller. 
  73. * 
  74. * Created by the MS_Plugin object during the setup_theme action. 
  75. * 
  76. * @since 1.0.0 
  77. */ 
  78. public function __construct() { 
  79. parent::__construct(); 
  80.  
  81. /** 
  82. * Fix for IE: This is a privacy policy which states, that we do not 
  83. * collect personal contact information without consent. 
  84. * 
  85. * Note that other plugins that output this header later will overwrite 
  86. * it! So this is a default value if no other file sends the P3P header. 
  87. * 
  88. * @since 1.0.2.2 
  89. */ 
  90. $p3p_done = false; 
  91. foreach ( headers_list() as $header ) { 
  92. if ( false !== stripos( $header, 'P3P:' ) ) { 
  93. $p3p_done = true; 
  94. break; 
  95. if ( ! $p3p_done ) { header( 'P3P:CP="NOI"' ); } 
  96.  
  97. /** 
  98. * Remove the "&msg" attribute from the URL if it was already present in 
  99. * the previous request. 
  100. */ 
  101. if ( empty( $_POST ) ) { 
  102. /** 
  103. * No form was submitted: 
  104. * It's save to redirect the request without losing form-data. 
  105. */ 
  106. if ( isset( $_GET['msg'] ) 
  107. && isset( $_SERVER['HTTP_REFERER'] ) 
  108. && MS_Helper_Utility::is_current_url( $_SERVER['HTTP_REFERER'] ) 
  109. ) { 
  110. // A msg is set AND the referer URL has the same msg flag! 
  111. $url = esc_url_raw( remove_query_arg( array( 'msg' ) ) ); 
  112. wp_safe_redirect( $url ); 
  113. exit; 
  114.  
  115. /** 
  116. * We allow two ways to modify the default Admin-Capability setting: 
  117. * 
  118. * Either by defining the constant in wp-config or by using the filter. 
  119. * The constant takes priority over the filter. 
  120. * 
  121. * @since 1.0.0 
  122. */ 
  123. if ( defined( 'MS_ADMIN_CAPABILITY' ) ) { 
  124. $this->capability = MS_ADMIN_CAPABILITY; 
  125. } else { 
  126. $this->capability = apply_filters( 
  127. 'ms_admin_user_capability',  
  128. $this->capability 
  129. ); 
  130.  
  131. // Create core controllers that are available on every page. 
  132. $this->model = MS_Factory::load( 'MS_Model_Plugin' ); 
  133. $this->dialogs = MS_Factory::load( 'MS_Controller_Dialog' ); 
  134. $this->controllers['widget'] = MS_Factory::load( 'MS_Controller_Widget' ); 
  135. $this->controllers['membership'] = MS_Factory::load( 'MS_Controller_Membership' ); 
  136. $this->controllers['protection'] = MS_Factory::load( 'MS_Controller_Protection' ); 
  137. $this->controllers['rule'] = MS_Factory::load( 'MS_Controller_Rule' ); 
  138. $this->controllers['member'] = MS_Factory::load( 'MS_Controller_Member' ); 
  139. $this->controllers['billing'] = MS_Factory::load( 'MS_Controller_Billing' ); 
  140. $this->controllers['addon'] = MS_Factory::load( 'MS_Controller_Addon' ); 
  141. $this->controllers['pages'] = MS_Factory::load( 'MS_Controller_Pages' ); 
  142. $this->controllers['settings'] = MS_Factory::load( 'MS_Controller_Settings' ); 
  143. $this->controllers['communication'] = MS_Factory::load( 'MS_Controller_Communication' ); 
  144. $this->controllers['gateway'] = MS_Factory::load( 'MS_Controller_Gateway' ); 
  145. $this->controllers['admin_bar'] = MS_Factory::load( 'MS_Controller_Adminbar' ); 
  146. $this->controllers['membership_metabox'] = MS_Factory::load( 'MS_Controller_Metabox' ); 
  147. $this->controllers['membership_shortcode'] = MS_Factory::load( 'MS_Controller_Shortcode' ); 
  148. $this->controllers['frontend'] = MS_Factory::load( 'MS_Controller_Frontend' ); 
  149. $this->controllers['import'] = MS_Factory::load( 'MS_Controller_Import' ); 
  150. $this->controllers['help'] = MS_Factory::load( 'MS_Controller_Help' ); 
  151.  
  152. // API should be the last Controller to create. 
  153. $this->controllers['api'] = MS_Controller_Api::instance(); 
  154.  
  155. // Register all available styles and scripts. Nothing is enqueued. 
  156. $this->add_action( 'wp_loaded', 'wp_loaded' ); 
  157.  
  158. // Setup plugin admin UI. 
  159. $this->add_action( 'admin_menu', 'add_menu_pages' ); 
  160. // Network-wide IS PRO ONLY! 
  161.  
  162. // Select the right page to display. 
  163. $this->add_action( 'admin_init', 'route_submenu_request' ); 
  164.  
  165. // This will do the ADMIN-SIDE initialization of the controllers 
  166. $this->add_action( 'ms_plugin_admin_setup', 'run_admin_init' ); 
  167.  
  168. // Changes the current themes "single" template to the invoice form when an invoice is displayed. 
  169. $this->add_filter( 'single_template', 'custom_single_template' ); 
  170. $this->add_filter( 'page_template', 'custom_page_template' ); 
  171.  
  172. // Register styles and javascripts for use in front-end 
  173. $this->add_action( 'ms_register_public_scripts', 'register_public_scripts' ); 
  174. $this->add_action( 'ms_register_public_scripts', 'register_public_styles' ); 
  175. $this->add_action( 'wp_enqueue_scripts', 'enqueue_plugin_styles' ); 
  176. $this->add_action( 'wp_enqueue_scripts', 'enqueue_plugin_scripts' ); 
  177.  
  178. /** 
  179. * Creates all the plugin controllers and initialize stuff. 
  180. * 
  181. * This is done after admin_menu (when in admin site) or 
  182. * after setup_theme (on front-end) 
  183. * 
  184. * @since 1.0.0 
  185. */ 
  186. public function run_admin_init() { 
  187. if ( ! is_admin() && ! is_network_admin() ) { return; } 
  188.  
  189. /** 
  190. * This function is used to redirect the user to special kind of page 
  191. * that is not available via the menu. 
  192. */ 
  193. $this->check_special_view(); 
  194.  
  195. foreach ( $this->controllers as $obj ) { 
  196. $obj->admin_init(); 
  197.  
  198. // Register styles and javascripts for use in admin-side 
  199. $this->run_action( 'ms_register_admin_scripts', 'register_admin_scripts' ); 
  200. $this->run_action( 'ms_register_admin_scripts', 'register_admin_styles' ); 
  201. $this->run_action( 'admin_enqueue_scripts', 'enqueue_plugin_admin_styles' ); 
  202. $this->run_action( 'admin_enqueue_scripts', 'enqueue_plugin_admin_scripts' ); 
  203.  
  204. /** 
  205. * If a special view is active then we ensure that it is displayed now. 
  206. * 
  207. * A special view is not accessible via the normal menu structure, like 
  208. * a Migration assistant or an overview page after updating the plugin. 
  209. * 
  210. * Special views can be set/reset/checked via these functions: 
  211. * MS_Model_Settings::set_special_view( 'name' ); 
  212. * MS_Model_Settings::get_special_view(); 
  213. * MS_Model_Settings::reset_special_view(); 
  214. * 
  215. * @since 1.0.0 
  216. */ 
  217. protected function check_special_view() { 
  218. $view_name = MS_Model_Settings::get_special_view(); 
  219.  
  220. if ( ! $view_name ) { return; } 
  221.  
  222. $view = MS_Factory::load( $view_name ); 
  223. $view->enqueue_scripts(); 
  224.  
  225. // Modify the main menu to handle our special_view for default item. 
  226. add_submenu_page( 
  227. self::$base_slug,  
  228. 'Membership 2',  
  229. 'Membership 2',  
  230. $this->capability,  
  231. self::$base_slug,  
  232. array( $this, 'handle_special_view' ) 
  233. ); 
  234.  
  235. /** 
  236. * Function is only called when a special view is defined. This function 
  237. * will load that view and display it. 
  238. * 
  239. * @since 1.0.0 
  240. */ 
  241. public function handle_special_view() { 
  242. $view_name = MS_Model_Settings::get_special_view(); 
  243. $view = MS_Factory::load( $view_name ); 
  244.  
  245. echo $view->to_html(); 
  246.  
  247. /** 
  248. * Returns the WordPress hook that identifies a Membership2 admin page. 
  249. * 
  250. * Important: In order for this function to work as expected it needs to 
  251. * be called *after* the admin-menu was registered! 
  252. * 
  253. * @since 1.0.0 
  254. * @param string $subpage 
  255. * @return string The internal hook name 
  256. */ 
  257. public static function admin_page_hook( $subpage = '' ) { 
  258. if ( empty( $subpage ) ) { 
  259. $plugin_page = self::MENU_SLUG; 
  260. } else { 
  261. $plugin_page = self::MENU_SLUG . '-' . $subpage; 
  262.  
  263. if ( ! function_exists( 'get_plugin_page_hookname' ) ) { 
  264. require_once ABSPATH . 'wp-admin/includes/plugin.php'; 
  265.  
  266. $the_parent = 'admin.php'; 
  267. $hook = get_plugin_page_hookname( $plugin_page, $the_parent ); 
  268.  
  269. return $hook; 
  270.  
  271. /** 
  272. * Register scripts and styles 
  273. * 
  274. * @since 1.0.0 
  275. */ 
  276. public function wp_loaded() { 
  277. if ( is_admin() || is_network_admin() ) { 
  278. do_action( 'ms_register_admin_scripts' ); 
  279. } else { 
  280. do_action( 'ms_register_public_scripts' ); 
  281.  
  282. /** 
  283. * Adds Dashboard navigation menus. 
  284. * 
  285. * @since 1.0.0 
  286. */ 
  287. public function add_menu_pages() { 
  288. global $submenu; 
  289. $limited_mode = false; 
  290.  
  291. $view = MS_Model_Settings::get_special_view(); 
  292. if ( $view ) { 
  293. // A special view is displayed. Do not display other menu items. 
  294. $pages = array(); 
  295.  
  296. $limited_mode = true; 
  297. } elseif ( MS_Plugin::is_wizard() ) { 
  298. // Submenus definition: Wizard mode 
  299. $pages = $this->get_setup_menu_pages(); 
  300.  
  301. $limited_mode = true; 
  302. } else { 
  303. // Submenus definition: Normal mode 
  304. $pages = $this->get_default_menu_pages(); 
  305.  
  306. if ( MS_Plugin::is_network_wide() && ! is_network_admin() ) { 
  307. $limited_mode = true; 
  308.  
  309. /** 
  310. * Allow Add-ons and other plugins to add menu pages. 
  311. * 
  312. * A menu item is defined by an array containing the following members: 
  313. * 'title' => '...',  
  314. * 'slug' => '...',  
  315. * 'function' => callback 
  316. * 
  317. * @var array 
  318. */ 
  319. $pages = apply_filters( 
  320. 'ms_plugin_menu_pages',  
  321. $pages,  
  322. $limited_mode,  
  323. $this 
  324. ); 
  325.  
  326. $page_keys = array_keys( $pages ); 
  327. $slug = ''; 
  328. if ( isset( $page_keys[0] ) && $pages[ $page_keys[0] ] ) { 
  329. $slug = $pages[ $page_keys[0] ]['slug']; 
  330. if ( empty( $slug ) ) { 
  331. self::$base_slug = self::MENU_SLUG; 
  332. } else { 
  333. self::$base_slug = self::MENU_SLUG . '-' . $slug; 
  334.  
  335. /** 
  336. * Create primary menu item: Membership. 
  337. * 
  338. * The menu title is not translatable because of a bug in WordPress core 
  339. * https://core.trac.wordpress.org/ticket/18857 
  340. * Until this bug is closed the title (2nd argument) can't be translated 
  341. */ 
  342. add_menu_page( 
  343. 'Membership 2', // no i18n! 
  344. 'Membership 2', // no i18n! 
  345. $this->capability,  
  346. self::$base_slug,  
  347. null,  
  348. 'dashicons-lock' 
  349. ); 
  350.  
  351. // Create submenus 
  352. foreach ( $pages as $page ) { 
  353. if ( ! is_array( $page ) ) { continue; } 
  354.  
  355. if ( empty( $page['link'] ) ) { 
  356. $menu_link = false; 
  357. } else { 
  358. $menu_link = $page['link']; 
  359.  
  360. $slug = self::MENU_SLUG; 
  361. if ( ! empty( $page['slug'] ) ) { 
  362. $slug .= '-' . $page['slug']; 
  363.  
  364. add_submenu_page( 
  365. self::$base_slug,  
  366. strip_tags( $page['title'] ),  
  367. $page['title'],  
  368. $this->capability,  
  369. $slug,  
  370. array( $this, 'handle_submenu_request' ) 
  371. ); 
  372.  
  373. /** 
  374. * WordPress does not support absolute URLs in the admin-menu. 
  375. * So we have to manny modify the menu-link href value if our slug 
  376. * is an absolute URL. 
  377. */ 
  378. if ( $menu_link ) { 
  379. $item = end( $submenu[self::$base_slug] ); 
  380. $key = key( $submenu[self::$base_slug] ); 
  381. $submenu[self::$base_slug][$key][2] = $menu_link; 
  382.  
  383. do_action( 'ms_controller_plugin_add_menu_pages', $this ); 
  384.  
  385. // Setup the rest of the plugin after the menu was registered. 
  386. do_action( 'ms_plugin_admin_setup' ); 
  387.  
  388. /** 
  389. * Returns the admin menu items for setting up the plugin. 
  390. * Helper function used by add_menu_pages 
  391. * 
  392. * @since 1.0.0 
  393. * @return array 
  394. */ 
  395. private function get_setup_menu_pages() { 
  396. $pages = array( 
  397. 'setup' => array( 
  398. 'title' => __( 'Set-up', 'membership2' ),  
  399. 'slug' => '',  
  400. ),  
  401. ); 
  402.  
  403. $step = $this->controllers['membership']->get_step(); 
  404. if ( MS_Controller_Membership::STEP_ADD_NEW == $step ) { 
  405. $pages['setup']['slug'] = 'setup'; 
  406.  
  407. $pages[self::MENU_SLUG] = array( 
  408. 'title' => __( 'Protection Rules', 'membership2' ),  
  409. 'slug' => '',  
  410. ); 
  411.  
  412. return $pages; 
  413.  
  414. /** 
  415. * Returns the default admin menu items for Membership2. 
  416. * Helper function used by add_menu_pages 
  417. * 
  418. * @since 1.0.0 
  419. * @return array 
  420. */ 
  421. private function get_default_menu_pages() { 
  422. $show_billing = false; 
  423.  
  424. $pages = array( 
  425. 'memberships' => array( 
  426. 'title' => __( 'Memberships', 'membership2' ),  
  427. 'slug' => '',  
  428. ),  
  429. 'protected-content' => array( 
  430. 'title' => __( 'Protection Rules', 'membership2' ),  
  431. 'slug' => 'protection',  
  432. ),  
  433. 'members' => array( 
  434. 'title' => __( 'All Members', 'membership2' ),  
  435. 'slug' => 'members',  
  436. ),  
  437. 'add-member' => array( 
  438. 'title' => __( 'Add Member', 'membership2' ),  
  439. 'slug' => 'add-member',  
  440. ),  
  441. 'billing' => false,  
  442. 'addon' => array( 
  443. 'title' => __( 'Add-ons', 'membership2' ),  
  444. 'slug' => 'addon',  
  445. ),  
  446. 'settings' => array( 
  447. 'title' => __( 'Settings', 'membership2' ),  
  448. 'slug' => 'settings',  
  449. ),  
  450. 'help' => array( 
  451. 'title' => __( 'Help', 'membership2' ),  
  452. 'slug' => 'help',  
  453. ),  
  454. ); 
  455.  
  456. $show_billing = MS_Model_Membership::have_paid_membership(); 
  457.  
  458. if ( $show_billing ) { 
  459. $bill_count = MS_Model_Invoice::get_unpaid_invoice_count( null, true ); 
  460.  
  461. if ( $bill_count > 0 ) { 
  462. $msg = '%1$s <span class="awaiting-mod count-%3$s"><span class="pending-count"><i class="hidden">(</i>%2$s<i class="hidden">)</i></span></span>'; 
  463. } else { 
  464. $msg = '%1$s'; 
  465.  
  466. $pages['billing'] = array( 
  467. 'title' => sprintf( 
  468. $msg,  
  469. __( 'Billing', 'membership2' ),  
  470. $bill_count,  
  471. sanitize_html_class( $bill_count, '0' ) 
  472. ),  
  473. 'slug' => 'billing',  
  474. ); 
  475.  
  476. /** 
  477. * This condition checks if the site has configured some payment 
  478. * gateways - if not then users cannot sign up for a membership. 
  479. * Show a notice if no payment gateway is configured/activated. 
  480. */ 
  481. $gateways = MS_Model_Gateway::get_gateways( true ); 
  482. $payment_possible = false; 
  483. foreach ( $gateways as $key => $gateway ) { 
  484. if ( 'free' == $key ) { continue; } 
  485. $payment_possible = true; 
  486. break; 
  487. if ( ! $payment_possible ) { 
  488. lib3()->ui->admin_message( 
  489. sprintf( 
  490. __( 'Oops, looks like you did not activate a payment gateway yet.<br />You need to set up and activate at least one gateway, otherwise your members cannot sign up to a paid membership.<br />%sFix this now »%s', 'membership2' ),  
  491. '<a href="' . self::get_admin_url( 'settings', array( 'tab' => MS_Controller_Settings::TAB_PAYMENT ) ) . '">',  
  492. '</a>' 
  493. ),  
  494. 'err' 
  495. ); 
  496.  
  497. return $pages; 
  498.  
  499. /** 
  500. * Handles all menu-items and calls the correct callback function. 
  501. * 
  502. * We introduce this routing function to monitor all menu-item calls so we 
  503. * can make sure that network-wide protection loads the correct blog or 
  504. * admin-area before displaing the page. 
  505. * 
  506. * This function will only handle submenu items of the Membership2 menu! 
  507. * 
  508. * @since 1.0.0 
  509. */ 
  510. public function route_submenu_request() { 
  511. global $submenu; 
  512. $handler = null; 
  513. $handle_it = false; 
  514.  
  515. if ( ! isset( $_GET['page'] ) ) { return; } 
  516. if ( $_GET['page'] === self::$base_slug ) { 
  517. $handle_it = true; 
  518. } elseif ( isset( $submenu[self::$base_slug] ) ) { 
  519. foreach ( $submenu[self::$base_slug] as $item ) { 
  520. if ( $_GET['page'] === $item[2] ) { $handle_it = true; break; } 
  521. if ( ! $handle_it ) { return; } 
  522.  
  523. if ( MS_Plugin::is_wizard() ) { 
  524. $step_add = MS_Controller_Membership::STEP_ADD_NEW == MS_Plugin::instance()->settings->wizard_step; 
  525.  
  526. if ( ! $step_add || self::is_page( 'setup' ) ) { 
  527. $handler = array( 
  528. 'any',  
  529. array( $this->controllers['membership'], 'admin_page_router' ),  
  530. ); 
  531. } else { 
  532. $handler = array( 
  533. 'site',  
  534. array( $this->controllers['protection'], 'admin_page' ),  
  535. ); 
  536. } else { 
  537. if ( self::is_page( '' ) ) { 
  538. $handler = array( 
  539. 'network',  
  540. array( $this->controllers['membership'], 'admin_page_router' ),  
  541. ); 
  542. } elseif ( self::is_page( 'protection' ) ) { 
  543. $handler = array( 
  544. 'site',  
  545. array( $this->controllers['protection'], 'admin_page' ),  
  546. ); 
  547. } elseif ( self::is_page( 'members' ) ) { 
  548. $handler = array( 
  549. 'network',  
  550. array( $this->controllers['member'], 'admin_page' ),  
  551. ); 
  552. } elseif ( self::is_page( 'add-member' ) ) { 
  553. $handler = array( 
  554. 'network',  
  555. array( $this->controllers['member'], 'admin_page_editor' ),  
  556. ); 
  557. } elseif ( self::is_page( 'addon' ) ) { 
  558. $handler = array( 
  559. 'network',  
  560. array( $this->controllers['addon'], 'admin_page' ),  
  561. ); 
  562. } elseif ( self::is_page( 'settings' ) ) { 
  563. $handler = array( 
  564. 'network',  
  565. array( $this->controllers['settings'], 'admin_page' ),  
  566. ); 
  567. } elseif ( self::is_page( 'help' ) ) { 
  568. $handler = array( 
  569. 'any',  
  570. array( $this->controllers['help'], 'admin_page' ),  
  571. ); 
  572. } elseif ( self::is_page( 'billing' ) ) { 
  573. $handler = array( 
  574. 'network',  
  575. array( $this->controllers['billing'], 'admin_page' ),  
  576. ); 
  577.  
  578. /** 
  579. * Filter that allows Add-ons to add their own sub-menu handlers. 
  580. * 
  581. * @since 1.0.0 
  582. */ 
  583. $handler = apply_filters( 
  584. 'ms_route_submenu_request',  
  585. $handler,  
  586. $this 
  587. ); 
  588.  
  589. // Provide a fallback handler in case we could not identify the handler. 
  590. if ( ! $handler ) { 
  591. $handler = array( 
  592. 'network',  
  593. array( $this->controllers['membership'], 'membership_admin_page_router' ),  
  594. ); 
  595.  
  596. // Handle the target attribute specified in $handler[0] 
  597. if ( MS_Plugin::is_network_wide() && 'any' != $handler[0] ) { 
  598. $redirect = false; 
  599. $admin_script = 'admin.php?' . $_SERVER['QUERY_STRING']; 
  600.  
  601. if ( 'network' == $handler[0] && ! is_network_admin() ) { 
  602. $redirect = network_admin_url( $admin_script ); 
  603. } elseif ( 'site' == $handler[0] && is_network_admin() ) { 
  604. $redirect = admin_url( $admin_script ); 
  605.  
  606. if ( $redirect ) { 
  607. if ( headers_sent() ) { 
  608. echo '<script>location.href=' . json_encode( $redirect ) . ';</script>'; 
  609. } else { 
  610. wp_safe_redirect( $redirect ); 
  611.  
  612. exit; 
  613.  
  614. $this->menu_handler = $handler; 
  615.  
  616. /** 
  617. * Simply calls the menu-handler callback function. 
  618. * 
  619. * This function was determined by the previous call to 
  620. * self::route_submenu_request() during the admin_init hook. 
  621. * 
  622. * @since 1.0.0 
  623. */ 
  624. public function handle_submenu_request() { 
  625. if ( ! empty( $this->menu_handler ) ) { 
  626. // This function will actually render the requested page! 
  627. call_user_func( $this->menu_handler[1] ); 
  628.  
  629. /** 
  630. * Checks if the current user is on the specified Membership2 admin page. 
  631. * 
  632. * @since 1.0.0 
  633. * @param string $slug The membership2 slug (without the menu-slug prefix) 
  634. * @return bool 
  635. */ 
  636. public static function is_page( $slug ) { 
  637. $curpage = false; 
  638. if ( isset( $_REQUEST['page'] ) ) { 
  639. $curpage = sanitize_html_class( $_REQUEST['page'] ); 
  640.  
  641. if ( empty( $slug ) ) { 
  642. $slug = self::$base_slug; 
  643. } else { 
  644. $slug = self::MENU_SLUG . '-' . $slug; 
  645.  
  646. return $curpage == $slug; 
  647.  
  648. /** 
  649. * Get admin url. 
  650. * 
  651. * @since 1.0.0 
  652. * @param string $slug Optional. Slug of the admin page, if empty the link 
  653. * points to the main admin page. 
  654. * @return string The full URL to the admin page. 
  655. */ 
  656. public static function get_admin_url( $slug = '', $args = null ) { 
  657. $base_slug = self::$base_slug; 
  658.  
  659. // These slugs are opened in network-admin for network-wide protection. 
  660. $global_slugs = array( 
  661. 'memberships',  
  662. 'addon',  
  663. 'settings',  
  664. ); 
  665.  
  666. // Determine if the slug is opened in network-admin or site admin. 
  667. $network_slug = false; 
  668.  
  669. if ( $network_slug ) { 
  670. $base_slug = self::MENU_SLUG; 
  671. if ( 'memberships' === $slug ) { $slug = ''; } 
  672.  
  673. if ( 'MENU_SLUG' == $slug ) { 
  674. $slug = self::MENU_SLUG; 
  675. } elseif ( empty( $slug ) ) { 
  676. $slug = self::$base_slug; 
  677. } else { 
  678. $slug = self::MENU_SLUG . '-' . $slug; 
  679.  
  680. if ( ! $slug ) { 
  681. $slug = self::MENU_SLUG; 
  682.  
  683. if ( $network_slug ) { 
  684. $url = network_admin_url( 'admin.php?page=' . $slug ); 
  685. } else { 
  686. $url = admin_url( 'admin.php?page=' . $slug ); 
  687.  
  688. if ( $args ) { 
  689. $url = esc_url_raw( add_query_arg( $args, $url ) ); 
  690.  
  691. return apply_filters( 
  692. 'ms_controller_plugin_get_admin_url',  
  693. $url 
  694. ); 
  695.  
  696. /** 
  697. * Get admin settings url. 
  698. * 
  699. * @since 1.0.0 
  700. * 
  701. */ 
  702. public static function get_admin_settings_url() { 
  703. return apply_filters( 
  704. 'ms_controller_plugin_get_admin_url',  
  705. admin_url( 'admin.php?page=' . self::MENU_SLUG . '-settings' ) 
  706. ); 
  707.  
  708. /** 
  709. * Use a special template for our custom post types. 
  710. * 
  711. * Invoices: 
  712. * Replaces the themes "Single" template with our invoice template when an 
  713. * invoice is displayed. The theme can override this by defining its own 
  714. * m2-invoice.php / single-ms_invoice.php template. 
  715. * 
  716. * You can even specifiy a membership ID in the page template to create 
  717. * a custom invoice form based on the membership that is billed. 
  718. * Example: 
  719. * m2-invoice-100.php (Invoice form for membership 100) 
  720. * 
  721. * @since 1.0.0 
  722. * @see filter single_template 
  723. * 
  724. * @param string $template The template path to filter. 
  725. * @return string The template path. 
  726. */ 
  727. public function custom_single_template( $default_template ) { 
  728. global $post; 
  729. $template = ''; 
  730.  
  731. // Checks for invoice single template. 
  732. if ( $post->post_type == MS_Model_Invoice::get_post_type() ) { 
  733. $invoice = MS_Factory::load( 'MS_Model_Invoice', $post->ID ); 
  734.  
  735. // First look for themes 'm2-invoice-100.php' template (membership ID). 
  736. $template = get_query_template( 
  737. 'm2',  
  738. 'm2-invoice-' . $invoice->membership_id . '.php' 
  739. ); 
  740.  
  741. // Fallback to themes 'm2-invoice.php' template. 
  742. if ( ! $template ) { 
  743. $template = get_query_template( 
  744. 'm2',  
  745. 'm2-invoice.php' 
  746. ); 
  747.  
  748. // Second look for themes 'single-ms_invoice.php' template. 
  749. if ( ! $template && strpos( $default_template, '/single-ms_invoice.php' ) ) { 
  750. $template = $default_template; 
  751.  
  752. // Last: Use the default M2 invoice template. 
  753. if ( ! $template ) { 
  754. $invoice_template = apply_filters( 
  755. 'ms_controller_plugin_invoice_template',  
  756. MS_Plugin::instance()->dir . 'app/template/single-ms_invoice.php' 
  757. ); 
  758.  
  759. if ( file_exists( $invoice_template ) ) { 
  760. $template = $invoice_template; 
  761.  
  762. if ( ! $template ) { 
  763. $template = $default_template; 
  764.  
  765. return $template; 
  766.  
  767. /** 
  768. * Use a special template for our membership pages. 
  769. * 
  770. * Recognized templates are: 
  771. * m2-memberships.php 
  772. * m2-protected-content.php 
  773. * m2-account.php 
  774. * m2-register.php 
  775. * m2-registration-complete.php 
  776. * 
  777. * Note that certain pages receive a membership-ID when they are loaded 
  778. * (like the m2-registration-complete or m2-register pages). 
  779. * You can even specify special pages for each membership. 
  780. * 
  781. * Example: 
  782. * m2-register-100.php (register form for membership 100) 
  783. * m2-registration-complete-100.php (thank you page for membership 100) 
  784. * 
  785. * @since 1.0.1.0 
  786. * @see filter page_template 
  787. * 
  788. * @param string $template The default template path to filter. 
  789. * @return string The custom template path. 
  790. */ 
  791. public function custom_page_template( $default_template ) { 
  792. $template = ''; 
  793.  
  794. // Checks for invoice single template. 
  795. if ( $type = MS_Model_Pages::is_membership_page() ) { 
  796. $membership_id = apply_filters( 'ms_detect_membership_id', 0, true ); 
  797.  
  798. if ( $membership_id ) { 
  799. $template = get_query_template( 
  800. 'm2',  
  801. 'm2-' . $type . '-' . $membership_id . '.php' 
  802. ); 
  803.  
  804. if ( ! $template ) { 
  805. $template = get_query_template( 
  806. 'm2',  
  807. 'm2-' . $type . '.php' 
  808. ); 
  809.  
  810. if ( ! $template ) { 
  811. $template = $default_template; 
  812.  
  813. return $template; 
  814.  
  815. /** 
  816. * Returns information on current memberships and access to current page. 
  817. * 
  818. * Wrapper for MS_Model_Plugin->get_access_info() 
  819. * 
  820. * @since 1.0.0 
  821. * @return array 
  822. */ 
  823. public function get_access_info() { 
  824. return $this->model->get_access_info(); 
  825.  
  826. /** 
  827. * Returns a list with complete admin menu items. 
  828. * 
  829. * Wrapper for MS_Model_Plugin->get_admin_menu() 
  830. * 
  831. * @since 1.0.0 
  832. * @return array 
  833. */ 
  834. public function get_admin_menu() { 
  835. return $this->model->get_admin_menu(); 
  836.  
  837. /** 
  838. * Register scripts that are used on the dashboard. 
  839. * 
  840. * @since 1.0.0 
  841. */ 
  842. public function register_admin_scripts() { 
  843. $plugin_url = MS_Plugin::instance()->url; 
  844. $version = MS_Plugin::instance()->version; 
  845.  
  846. // The main plugin script. 
  847. wp_register_script( 
  848. 'ms-admin',  
  849. $plugin_url . 'app/assets/js/ms-admin.js',  
  850. array( 'jquery', 'jquery-validate', 'jquery-plugins' ), $version 
  851. ); 
  852.  
  853. wp_register_script( 
  854. 'jquery-plugins',  
  855. $plugin_url . 'app/assets/js/jquery.m2.plugins.js',  
  856. array( 'jquery' ), $version 
  857. ); 
  858. wp_register_script( 
  859. 'jquery-validate',  
  860. $plugin_url . 'app/assets/js/jquery.m2.validate.js',  
  861. array( 'jquery' ), $version 
  862. ); 
  863.  
  864. /** 
  865. * Register styles that are used on the dashboard. 
  866. * 
  867. * @since 1.0.0 
  868. */ 
  869. public function register_admin_styles() { 
  870. $plugin_url = MS_Plugin::instance()->url; 
  871. $version = MS_Plugin::instance()->version; 
  872.  
  873. // The main plugin style. 
  874. wp_register_style( 
  875. 'ms-admin-styles',  
  876. $plugin_url . 'app/assets/css/ms-admin.css',  
  877. null, $version 
  878. ); 
  879.  
  880. /** 
  881. * Register scripts that are used on the front-end. 
  882. * 
  883. * @since 1.0.0 
  884. */ 
  885. public function register_public_scripts() { 
  886. $plugin_url = MS_Plugin::instance()->url; 
  887. $version = MS_Plugin::instance()->version; 
  888.  
  889. // The main plugin script. 
  890. wp_register_script( 
  891. 'ms-admin',  
  892. $plugin_url . 'app/assets/js/ms-admin.js',  
  893. array( 'jquery', 'jquery-validate', 'jquery-plugins' ), $version 
  894. ); 
  895. wp_register_script( 
  896. 'ms-ajax-login',  
  897. $plugin_url . 'app/assets/js/ms-public-ajax.js',  
  898. array( 'jquery' ), $version, true // last param forces script to load in footer 
  899. ); 
  900. wp_register_script( 
  901. 'ms-public',  
  902. $plugin_url . 'app/assets/js/ms-public.js',  
  903. array( 'jquery' ), $version 
  904. ); 
  905.  
  906. wp_register_script( 
  907. 'jquery-plugins',  
  908. $plugin_url . 'app/assets/js/jquery.m2.plugins.js',  
  909. array( 'jquery' ), $version 
  910. ); 
  911. wp_register_script( 
  912. 'jquery-validate',  
  913. $plugin_url . 'app/assets/js/jquery.m2.validate.js',  
  914. array( 'jquery' ), $version 
  915. ); 
  916.  
  917. /** 
  918. * Register styles that are used on the front-end. 
  919. * 
  920. * @since 1.0.0 
  921. */ 
  922. public function register_public_styles() { 
  923. $plugin_url = MS_Plugin::instance()->url; 
  924. $version = MS_Plugin::instance()->version; 
  925.  
  926. // The main plugin style. 
  927. wp_register_style( 
  928. 'ms-styles',  
  929. $plugin_url . 'app/assets/css/ms-public.css',  
  930. array(),  
  931. $version 
  932. ); 
  933.  
  934. /** 
  935. * Adds CSS for Membership settings pages. 
  936. * 
  937. * @since 1.0.0 
  938. */ 
  939. public function enqueue_plugin_admin_styles() { 
  940. lib3()->ui->css( 'ms-admin-styles' ); 
  941. lib3()->ui->add( 'core' ); 
  942. lib3()->ui->add( 'select' ); 
  943. lib3()->ui->add( 'fontawesome' ); 
  944.  
  945. /** 
  946. * Adds CSS for Membership pages used in the front end. 
  947. * 
  948. * @since 1.0.0 
  949. * 
  950. * @return void 
  951. */ 
  952. public function enqueue_plugin_styles() { 
  953. // Front-End styles are enqueued by MS_Controller_Frontend. 
  954.  
  955. /** 
  956. * Register JavasSript for Membership settings pages. 
  957. * 
  958. * @since 1.0.0 
  959. * 
  960. * @return void 
  961. */ 
  962. public function enqueue_plugin_admin_scripts() { 
  963. lib3()->ui->add( 'select' ); 
  964.  
  965. /** 
  966. * Adds JavasSript for Membership pages used in the front end. 
  967. * 
  968. * @since 1.0.0 
  969. * 
  970. * @return void 
  971. */ 
  972. public function enqueue_plugin_scripts() { 
  973. // Front-End scripts are enqueued by MS_Controller_Frontend. 
  974.  
  975. /** 
  976. * Adds a javascript to the page that will translate the jQuery validator 
  977. * messages. 
  978. * 
  979. * @since 1.0.0 
  980. */ 
  981. static public function translate_jquery_validator() { 
  982. ob_start(); 
  983. ?> 
  984. jQuery.extend( jQuery.validator.messages, { 
  985. required: "<?php _e( 'This field is required.', 'membership2' ); ?>",  
  986. remote: "<?php _e( 'Please fix this field.', 'membership2' ); ?>",  
  987. email: "<?php _e( 'Please enter a valid email address.', 'membership2' ); ?>",  
  988. url: "<?php _e( 'Please enter a valid URL.', 'membership2' ); ?>",  
  989. date: "<?php _e( 'Please enter a valid date.', 'membership2' ); ?>",  
  990. dateISO: "<?php _e( 'Please enter a valid date ( ISO ).', 'membership2' ); ?>",  
  991. number: "<?php _e( 'Please enter a valid number.', 'membership2' ); ?>",  
  992. digits: "<?php _e( 'Please enter only digits.', 'membership2' ); ?>",  
  993. creditcard: "<?php _e( 'Please enter a valid credit card number.', 'membership2' ); ?>",  
  994. equalTo: "<?php _e( 'Please enter the same value again.', 'membership2' ); ?>",  
  995. maxlength: jQuery.validator.format( "<?php _e( 'Please enter no more than {0} characters.', 'membership2' ); ?>" ),  
  996. minlength: jQuery.validator.format( "<?php _e( 'Please enter at least {0} characters.', 'membership2' ); ?>" ),  
  997. rangelength: jQuery.validator.format( "<?php _e( 'Please enter a value between {0} and {1} characters long.', 'membership2' ); ?>" ),  
  998. range: jQuery.validator.format( "<?php _e( 'Please enter a value between {0} and {1}.', 'membership2' ); ?>" ),  
  999. max: jQuery.validator.format( "<?php _e( 'Please enter a value less than or equal to {0}.', 'membership2' ); ?>" ),  
  1000. min: jQuery.validator.format( "<?php _e( 'Please enter a value greater than or equal to {0}.', 'membership2' ); ?>" ) 
  1001. }); 
  1002. <?php 
  1003. $script = ob_get_clean(); 
  1004. lib3()->ui->script( $script ); 
.