MS_Plugin

Primary Membership plugin class.

Defined (1)

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

/membership.php  
  1. class MS_Plugin { 
  2.  
  3. /** 
  4. * Singletone instance of the plugin. 
  5. * @since 1.0.0 
  6. * @var MS_Plugin 
  7. */ 
  8. private static $instance = null; 
  9.  
  10. /** 
  11. * Modifier values. 
  12. * @since 1.1.0.5 
  13. * @var array 
  14. */ 
  15. private static $modifiers = array(); 
  16.  
  17. /** 
  18. * The WordPress internal plugin identifier. 
  19. * @since 2.0.0 
  20. * @var string 
  21. */ 
  22. private $id; 
  23.  
  24. /** 
  25. * The plugin name. 
  26. * @since 1.0.0 
  27. * @var string 
  28. */ 
  29. private $name; 
  30.  
  31. /** 
  32. * The plugin version. 
  33. * @since 1.0.0 
  34. * @var string 
  35. */ 
  36. private $version; 
  37.  
  38. /** 
  39. * The plugin file. 
  40. * @since 1.0.0 
  41. * @var string 
  42. */ 
  43. private $file; 
  44.  
  45. /** 
  46. * The plugin path. 
  47. * @since 1.0.0 
  48. * @var string 
  49. */ 
  50. private $dir; 
  51.  
  52. /** 
  53. * The plugin URL. 
  54. * @since 1.0.0 
  55. * @var string 
  56. */ 
  57. private $url; 
  58.  
  59. /** 
  60. * The plugin settings. 
  61. * @since 1.0.0 
  62. * @var MS_Model_Settings 
  63. */ 
  64. private $settings; 
  65.  
  66. /** 
  67. * The plugin add-on settings. 
  68. * @since 1.0.0 
  69. * @var MS_Model_Addon 
  70. */ 
  71. private $addon; 
  72.  
  73. /** 
  74. * The main controller of the plugin. 
  75. * @since 1.0.0 
  76. * @var MS_Controller_Plugin 
  77. */ 
  78. private $controller; 
  79.  
  80. /** 
  81. * The API controller (for convenience) 
  82. * @since 2.0.0 
  83. * @var MS_Controller_Api 
  84. */ 
  85. public static $api = null; 
  86.  
  87. /** 
  88. * Plugin constructor. 
  89. * Set properties, registers hooks and loads the plugin. 
  90. * @since 1.0.0 
  91. */ 
  92. public function __construct() { 
  93.  
  94. /** 
  95. * Actions to execute before the plugin construction starts. 
  96. * @since 2.0.0 
  97. * @param object $this The MS_Plugin object. 
  98. */ 
  99. do_action( 'ms_plugin_init', $this ); 
  100.  
  101. /** 
  102. * @since 1.0.0 
  103. * @deprecated since 2.0.0 
  104. */ 
  105. do_action( 'ms_plugin_construct_start', $this ); 
  106.  
  107. /** Setup plugin properties */ 
  108. $this->id = MS_PLUGIN; 
  109. $this->name = MS_PLUGIN_NAME; 
  110. $this->version = MS_PLUGIN_VERSION; 
  111. $this->file = __FILE__; 
  112. $this->dir = plugin_dir_path( __FILE__ ); 
  113. $this->url = plugin_dir_url( __FILE__ ); 
  114.  
  115. /** 
  116. * Filter the languages path before loading the textdomain. 
  117. * @uses load_plugin_textdomain() 
  118. * @since 1.0.0 
  119. * @param object $this The MS_Plugin object. 
  120. */ 
  121. load_plugin_textdomain( 
  122. MS_TEXT_DOMAIN,  
  123. false,  
  124. apply_filters( 
  125. 'ms_plugin_languages_path',  
  126. $this->name . '/languages/',  
  127. $this 
  128. ); 
  129.  
  130. // Creates the class autoloader. 
  131. spl_autoload_register( array( $this, 'class_loader' ) ); 
  132.  
  133. // Might refresh the Rewrite-Rules and reloads the page. 
  134. add_action( 
  135. 'wp_loaded',  
  136. array( $this, 'maybe_flush_rewrite_rules' ),  
  137. ); 
  138.  
  139. /** 
  140. * Hooks init to register custom post types. 
  141. */ 
  142. add_action( 
  143. 'init',  
  144. array( $this, 'register_custom_post_types' ),  
  145. ); 
  146.  
  147. /** 
  148. * Hooks init to add rewrite rules and tags (both work in conjunction). 
  149. */ 
  150. add_action( 'init', array( $this, 'add_rewrite_rules' ), 1 ); 
  151. add_action( 'init', array( $this, 'add_rewrite_tags' ), 1 ); 
  152.  
  153. // Plugin activation Hook 
  154. register_activation_hook( 
  155. __FILE__,  
  156. array( $this, 'plugin_activation' ) 
  157. ); 
  158.  
  159. /** 
  160. * Hooks init to create the primary plugin controller. 
  161. * We use the setup_theme hook because plugins_loaded is too early: 
  162. * wp_redirect (used by the update model) is initialized after 
  163. * plugins_loaded but before setup_theme. 
  164. */ 
  165. add_action( 
  166. 'setup_theme',  
  167. array( $this, 'ms_plugin_constructing' ) 
  168. ); 
  169.  
  170. /** 
  171. * Creates and Filters the Settings Model. 
  172. * @since 1.0.0 
  173. * @param object $this The MS_Plugin object. 
  174. */ 
  175. $this->settings = MS_Factory::load( 'MS_Model_Settings' ); 
  176.  
  177. /** 
  178. * Creates and Filters the Addon Model. 
  179. * @since 1.0.0 
  180. * @param object $this The MS_Plugin object. 
  181. */ 
  182. $this->addon = MS_Factory::load( 'MS_Model_Addon' ); 
  183.  
  184. add_filter( 
  185. 'plugin_action_links_' . MS_PLUGIN,  
  186. array( $this, 'plugin_settings_link' ) 
  187. ); 
  188.  
  189. add_filter( 
  190. 'network_admin_plugin_action_links_' . MS_PLUGIN,  
  191. array( $this, 'plugin_settings_link' ) 
  192. ); 
  193.  
  194. // Grab instance of self. 
  195. self::$instance = $this; 
  196.  
  197. /** 
  198. * Actions to execute when the Plugin object has successfully constructed. 
  199. * @since 1.0.0 
  200. * @param object $this The MS_Plugin object. 
  201. */ 
  202. do_action( 'ms_plugin_construct_end', $this ); 
  203.  
  204. /** 
  205. * Loads primary plugin controllers. 
  206. * Related Action Hooks: 
  207. * - setup_theme 
  208. * @since 1.0.0 
  209. */ 
  210. public function ms_plugin_constructing() { 
  211. /** 
  212. * Creates and Filters the Plugin Controller. 
  213. * ---> MAIN ENTRY POINT CONTROLLER FOR PLUGIN <--- 
  214. * @uses MS_Controller_Plugin 
  215. * @since 1.0.0 
  216. */ 
  217. $this->controller = MS_Factory::create( 'MS_Controller_Plugin' ); 
  218.  
  219. /** 
  220. * Register plugin custom post types. 
  221. * @since 1.0.0 
  222. */ 
  223. public function register_custom_post_types() { 
  224. do_action( 'ms_plugin_register_custom_post_types_before', $this ); 
  225.  
  226. $cpts = apply_filters( 
  227. 'ms_plugin_register_custom_post_types',  
  228. array( 
  229. MS_Model_Membership::get_post_type() => MS_Model_Membership::get_register_post_type_args(),  
  230. MS_Model_Relationship::get_post_type() => MS_Model_Relationship::get_register_post_type_args(),  
  231. MS_Model_Invoice::get_post_type() => MS_Model_Invoice::get_register_post_type_args(),  
  232. MS_Model_Communication::get_post_type() => MS_Model_Communication::get_register_post_type_args(),  
  233. MS_Model_Event::get_post_type() => MS_Model_Event::get_register_post_type_args(),  
  234. ); 
  235.  
  236. foreach ( $cpts as $cpt => $args ) { 
  237. MS_Helper_Utility::register_post_type( $cpt, $args ); 
  238.  
  239. /** 
  240. * Add rewrite rules. 
  241. * @since 1.0.0 
  242. */ 
  243. public function add_rewrite_rules() { 
  244. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  245.  
  246. // Gateway return - IPN. 
  247. add_rewrite_rule( 
  248. '^ms-payment-return/(.+)/?$',  
  249. 'index.php?paymentgateway=$matches[1]',  
  250. 'top' 
  251. ); 
  252.  
  253. // Alternative payment return URL: Membership 
  254. if ( MS_Model_Import_Membership::did_import() ) { 
  255. add_rewrite_rule( 
  256. 'paymentreturn/(.+)/?',  
  257. 'index.php?paymentgateway=$matches[1]',  
  258. 'top' 
  259. ); 
  260.  
  261. // Media / download 
  262. $mmask = $settings->downloads['masked_url']; 
  263. $mtype = $settings->downloads['protection_type']; 
  264.  
  265. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_MEDIA ) && $mmask ) { 
  266. if ( MS_Rule_Media_Model::PROTECTION_TYPE_HYBRID == $mtype ) { 
  267. add_rewrite_rule( 
  268. sprintf( '^%1$s/?$', $mmask ),  
  269. 'index.php?protectedfile=0',  
  270. 'top' 
  271. ); 
  272. } else { 
  273. add_rewrite_rule( 
  274. sprintf( '^%1$s/([^/]+)', $mmask ),  
  275. 'index.php?protectedfile=$matches[1]',  
  276. 'top' 
  277. ); 
  278. // End: Media / download 
  279.  
  280. do_action( 'ms_plugin_add_rewrite_rules', $this ); 
  281.  
  282. /** 
  283. * Add rewrite tags. 
  284. * @since 1.0.0 
  285. */ 
  286. public function add_rewrite_tags() { 
  287. // Membership site pages. 
  288. add_rewrite_tag( '%ms_page%', '(.+)' ); 
  289.  
  290. // Gateway return - IPN. 
  291. add_rewrite_tag( '%paymentgateway%', '(.+)' ); 
  292.  
  293. // Media / download 
  294. add_rewrite_tag( '%protectedfile%', '(.+)' ); 
  295.  
  296. do_action( 'ms_plugin_add_rewrite_tags', $this ); 
  297.  
  298. /** 
  299. * Actions executed in plugin activation. 
  300. * @since 1.0.0 
  301. */ 
  302. public function plugin_activation() { 
  303. // Prevent recursion during plugin activation. 
  304. $refresh = lib2()->session->get( 'refresh_url_rules' ); 
  305. if ( $refresh ) { return; } 
  306.  
  307. // Update the Membership2 database entries after activation. 
  308. MS_Model_Upgrade::update( true ); 
  309.  
  310. do_action( 'ms_plugin_activation ', $this ); 
  311.  
  312. /** 
  313. * Redirect page and request plugin to flush the WordPress rewrite rules 
  314. * on next request. 
  315. * @since 1.0.4.4 
  316. * @param string $url The URL to load after flushing the rewrite rules. 
  317. */ 
  318. static public function flush_rewrite_rules( $url = false ) { 
  319. $refresh = lib2()->session->get( 'refresh_url_rules' ); 
  320. if ( $refresh ) { return; } 
  321.  
  322. lib2()->session->add( 'refresh_url_rules', true ); 
  323. $url = esc_url_raw( 
  324. add_query_arg( 'ms_ts', time(), $url ) 
  325. ); 
  326. wp_safe_redirect( $url ); 
  327. exit; 
  328.  
  329. /** 
  330. * Flush the WordPress rewrite rules. 
  331. * @since 1.0.4.4 
  332. */ 
  333. public function maybe_flush_rewrite_rules() { 
  334. $refresh = lib2()->session->get_clear( 'refresh_url_rules' ); 
  335. if ( ! $refresh ) { return; } 
  336.  
  337. // Flush WP rewrite rules. 
  338. flush_rewrite_rules(); 
  339.  
  340. // Set up the plugin specific rewrite rules again. 
  341. $this->add_rewrite_rules(); 
  342. $this->add_rewrite_tags(); 
  343.  
  344. do_action( 'ms_plugin_flush_rewrite_rules', $this ); 
  345.  
  346. $url = esc_url_raw( remove_query_arg( 'ms_ts' ) ); 
  347. wp_safe_redirect( $url ); 
  348. exit; 
  349.  
  350. /** 
  351. * Class autoloading callback function. 
  352. * Uses the **MS_** namespace to autoload classes when called. 
  353. * Avoids creating include functions for each file in the MVC structure. 
  354. * **MS_** namespace ONLY will be based on folder structure in /app/ 
  355. * @since 1.0.0 
  356. * @param string $class Uses PHP autoloader function. 
  357. * @return boolean 
  358. */ 
  359. private function class_loader( $class ) { 
  360. static $Path_overrides = null; 
  361.  
  362. /** 
  363. * Actions to execute before the autoloader loads a class. 
  364. * @since 1.0.0 
  365. * @param object $this The MS_Plugin object. 
  366. */ 
  367. do_action( 'ms_plugin_class_loader_pre_processing', $this ); 
  368.  
  369. $basedir = dirname( __FILE__ ); 
  370. $class = trim( $class ); 
  371.  
  372. if ( null === $Path_overrides ) { 
  373. /** 
  374. * Adds and Filters class path overrides. 
  375. * @since 1.0.0 
  376. * @param object $this The MS_Plugin object. 
  377. */ 
  378. $Path_overrides = apply_filters( 'ms_class_path_overrides', array(), $this ); 
  379.  
  380. if ( array_key_exists( $class, $Path_overrides ) ) { 
  381. /** 
  382. * Case 1: The class-path is explicitly defined in $Path_overrides. 
  383. * Simply use the defined path to load the class. 
  384. */ 
  385. $file_path = $basedir . '/' . $Path_overrides[ $class ]; 
  386.  
  387. /** 
  388. * Overrides the filename and path. 
  389. * @since 1.0.0 
  390. * @param object $this The MS_Plugin object. 
  391. */ 
  392. $file_path = apply_filters( 'ms_class_file_override', $file_path, $this ); 
  393.  
  394. if ( is_file( $file_path ) ) { 
  395. include_once $file_path; 
  396.  
  397. return true; 
  398. } elseif ( 'MS_' == substr( $class, 0, 3 ) ) { 
  399. /** 
  400. * Case 2: The class-path is not explicitely defined in $Path_overrides. 
  401. * Use /app/ path and class-name to build the file-name. 
  402. */ 
  403.  
  404. $path_array = explode( '_', $class ); 
  405. array_shift( $path_array ); 
  406. $alt_dir = array_pop( $path_array ); 
  407. $sub_path = implode( '/', $path_array ); 
  408.  
  409. $filename = str_replace( '_', '-', 'class-' . $class . '.php' ); 
  410. $file_path = $basedir . '/app/' . strtolower( $sub_path . '/' . $filename ); 
  411. $file_path_alt = $basedir . '/app/' . strtolower( $sub_path . '/' . $alt_dir . '/' . $filename ); 
  412.  
  413. /** 
  414. * Overrides the filename and path. 
  415. * @since 1.0.0 
  416. * @param object $this The MS_Plugin object. 
  417. */ 
  418. $file_path = apply_filters( 'ms_class_file_override', $file_path, $this ); 
  419. $file_path_alt = apply_filters( 'ms_class_file_override', $file_path_alt, $this ); 
  420.  
  421. if ( is_file( $file_path ) ) { 
  422. include_once $file_path; 
  423. } elseif ( is_file( $file_path_alt ) ) { 
  424. include_once $file_path_alt; 
  425.  
  426. return true; 
  427.  
  428. return false; 
  429.  
  430. /** 
  431. * Add link to settings page in plugins page. 
  432. * @since 1.0.0 
  433. * @param array $links WordPress default array of links. 
  434. * @return array Array of links with settings page links added. 
  435. */ 
  436. public function plugin_settings_link( $links ) { 
  437. if ( ! is_network_admin() ) { 
  438. $text = __( 'Settings', MS_TEXT_DOMAIN ); 
  439. $url = MS_Controller_Plugin::get_admin_url( 'settings' ); 
  440.  
  441. if ( $this->settings->initial_setup ) { 
  442. $url = MS_Controller_Plugin::get_admin_url(); 
  443.  
  444. /** 
  445. * Filter the plugin settings link. 
  446. * @since 1.0.0 
  447. * @param object $this The MS_Plugin object. 
  448. */ 
  449. $settings_link = apply_filters( 
  450. 'ms_plugin_settings_link',  
  451. sprintf( '<a href="%s">%s</a>', $url, $text ),  
  452. $this 
  453. ); 
  454. array_unshift( $links, $settings_link ); 
  455.  
  456. return $links; 
  457.  
  458. /** 
  459. * Returns singleton instance of the plugin. 
  460. * @since 1.0.0 
  461. * @static 
  462. * @access public 
  463. * @return MS_Plugin 
  464. */ 
  465. public static function instance() { 
  466. if ( is_null( self::$instance ) ) { 
  467. self::$instance = new MS_Plugin(); 
  468.  
  469. self::$instance = apply_filters( 
  470. 'ms_plugin_instance',  
  471. self::$instance 
  472. ); 
  473.  
  474. return self::$instance; 
  475.  
  476. /** 
  477. * Returns plugin enabled status. 
  478. * @since 1.0.0 
  479. * @access public 
  480. * @static 
  481. * @return bool The status. 
  482. */ 
  483. public static function is_enabled() { 
  484. return self::instance()->settings->plugin_enabled; 
  485.  
  486. /** 
  487. * Returns plugin wizard status. 
  488. * @since 1.0.4.3 
  489. * @access public 
  490. * @static 
  491. * @return bool The status. 
  492. */ 
  493. public static function is_wizard() { 
  494. return ! ! self::instance()->settings->initial_setup; 
  495.  
  496. /** 
  497. * Returns the network-wide protection status. 
  498. * This flag can be changed by setting the MS_PROTECT_NETWORK flag to true 
  499. * in wp-config.php 
  500. * @since 2.0.0 
  501. * @return bool False means that only the current site is protected. 
  502. * True means that memberships are shared among all network sites. 
  503. */ 
  504. public static function is_network_wide() { 
  505. // THIS IS A PRO FEATURE: 
  506. // IN THE FREE VERSION THIS FUNCTION MUST ALWAYS RETURN FALSE! 
  507. // ELSE YOUR PROTECTION SETTINGS WILL GET MESSED UP. 
  508. return false; 
  509.  
  510. /** 
  511. * Returns a modifier option. 
  512. * This is similar to a setting but more "advanced" in a way that there is 
  513. * no UI for it. A modifier can be set by the plugin (e.g. during Import 
  514. * the "no_messages" modifier is enabled) or via a const in wp-config.php 
  515. * A modifier is never saved in the database. 
  516. * It can be defined ONLY via MS_Plugin::set_modifier() or via wp-config.php 
  517. * The set_modifier() value will always take precedence over wp-config.php 
  518. * definitions. 
  519. * @since 1.1.0.5 
  520. * @api 
  521. * @param string $key Name of the modifier. 
  522. * @return mixed The modifier value or null. 
  523. */ 
  524. public static function get_modifier( $key ) { 
  525. $res = null; 
  526.  
  527. if ( isset( self::$modifiers[$key] ) ) { 
  528. $res = self::$modifiers[$key]; 
  529. } elseif ( defined( $key ) ) { 
  530. $res = constant( $key ); 
  531.  
  532. return $res; 
  533.  
  534. /** 
  535. * Changes a modifier option. 
  536. * @see get_modifier() for more details. 
  537. * @since 1.1.0.5 
  538. * @api 
  539. * @param string $key Name of the modifier. 
  540. * @param mixed $value Value of the modifier. `null` unsets the modifier. 
  541. */ 
  542. public static function set_modifier( $key, $value = null ) { 
  543. if ( null === $value && isset( self::$modifiers[$key] ) ) { 
  544. unset( self::$modifiers[$key] ); 
  545. } else { 
  546. self::$modifiers[$key]; 
  547.  
  548. /** 
  549. * This funciton initializes the api property for easy access to the plugin 
  550. * API. This function is *only* called by MS_Controller_Api::__construct()! 
  551. * @since 2.0.0 
  552. * @internal 
  553. * @param MS_Controller_Api $controller The initialized API controller. 
  554. */ 
  555. public static function set_api( $controller ) { 
  556. self::$api = $controller; 
  557.  
  558. /** 
  559. * Returns property associated with the plugin. 
  560. * @since 1.0.0 
  561. * @access public 
  562. * @param string $property The name of a property. 
  563. * @return mixed Returns mixed value of a property or NULL if a property doesn't exist. 
  564. */ 
  565. public function __get( $property ) { 
  566. if ( property_exists( $this, $property ) ) { 
  567. return $this->$property;