MS_Controller_Plugin

Primary controller for Membership Plugin.

Defined (1)

The class is defined in the following location(s).

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