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

  1. <?php 
  2. /** 
  3. * Creates the Membership access metabox. 
  4. * 
  5. * Creates simple access control UI for Posts/Page edit pages. 
  6. * 
  7. * @since 1.0.0 
  8. * 
  9. * @package Membership2 
  10. * @subpackage Controller 
  11. */ 
  12. class MS_Controller_Metabox extends MS_Controller { 
  13.  
  14. /** 
  15. * AJAX action constants. 
  16. * 
  17. * @since 1.0.0 
  18. * 
  19. * @var string 
  20. */ 
  21. const AJAX_ACTION_TOGGLE_ACCESS = 'toggle_metabox_access'; 
  22.  
  23. /** 
  24. * The custom post type used with Memberships and access. 
  25. * 
  26. * @since 1.0.0 
  27. * 
  28. * @var array 
  29. */ 
  30. private $post_types; 
  31.  
  32. /** 
  33. * The metabox ID. 
  34. * 
  35. * @since 1.0.0 
  36. * 
  37. * @var string 
  38. */ 
  39. private $metabox_id = 'ms-membership-access'; 
  40.  
  41. /** 
  42. * The metabox title. 
  43. * 
  44. * @since 1.0.0 
  45. * 
  46. * @var string 
  47. */ 
  48. private $metabox_title; 
  49.  
  50. /** 
  51. * Context for showing the metabox. 
  52. * 
  53. * @since 1.0.0 
  54. * 
  55. * @var string 
  56. */ 
  57. private $context = 'side'; 
  58.  
  59. /** 
  60. * Metabox priority. 
  61. * 
  62. * Effects position in the metabox hierarchy. 
  63. * 
  64. * @since 1.0.0 
  65. * 
  66. * @var string 
  67. */ 
  68. private $priority = 'high'; 
  69.  
  70. /** 
  71. * Prepare the metabox. 
  72. * 
  73. * @since 1.0.0 
  74. */ 
  75. public function __construct() { 
  76. parent::__construct(); 
  77.  
  78. $this->metabox_title = __( 'Membership Access', 'membership2' ); 
  79.  
  80. $extra = array(); 
  81.  
  82.  
  83.  
  84. $post_types = array_merge( 
  85. array( 'page', 'post', 'attachment' ),  
  86. $extra 
  87. ); 
  88.  
  89. $this->post_types = apply_filters( 
  90. 'ms_controller_membership_metabox_add_meta_boxes_post_types',  
  91. $post_types 
  92. ); 
  93.  
  94. if ( ! MS_Plugin::is_enabled() ) { 
  95. return $this; 
  96.  
  97. $this->add_action( 
  98. 'add_meta_boxes',  
  99. 'add_meta_boxes',  
  100. 10 
  101. ); 
  102.  
  103. $this->add_action( 
  104. 'admin_enqueue_scripts',  
  105. 'admin_enqueue_scripts' 
  106. ); 
  107.  
  108. $this->add_ajax_action( 
  109. self::AJAX_ACTION_TOGGLE_ACCESS,  
  110. 'ajax_action_toggle_metabox_access' 
  111. ); 
  112.  
  113. // Populates the WP editor with default contents of a page 
  114. $this->add_action( 
  115. 'the_editor_content',  
  116. 'show_default_content' 
  117. ); 
  118.  
  119. /** 
  120. * Handle Ajax toggle action. 
  121. * 
  122. * Related Action Hooks: 
  123. * - wp_ajax_toggle_metabox_access 
  124. * 
  125. * @since 1.0.0 
  126. */ 
  127. public function ajax_action_toggle_metabox_access() { 
  128. $fields = array( 'membership_id', 'rule_type', 'post_id' ); 
  129.  
  130. if ( 
  131. $this->verify_nonce() 
  132. && self::validate_required( $fields ) 
  133. && $this->is_admin_user() 
  134. ) { 
  135. $this->toggle_membership_access( 
  136. $_POST['post_id'],  
  137. $_POST['rule_type'],  
  138. $_POST['membership_id'] 
  139. ); 
  140.  
  141. $post = get_post( $_POST['post_id'] ); 
  142.  
  143. // Return the updated Membership metabox html via ajax response. 
  144. $this->membership_metabox( $post ); 
  145.  
  146. do_action( 
  147. 'ms_controller_membership_metabox_ajax_action_toggle_metabox_access',  
  148. $post,  
  149. $this 
  150. ); 
  151.  
  152. exit; 
  153.  
  154. /** 
  155. * Add the metabox for defined post types. 
  156. * 
  157. * @since 1.0.0 
  158. */ 
  159. public function add_meta_boxes() { 
  160.  
  161. // Disable meta box for non-M2 admin 
  162. $user_id = get_current_user_id(); 
  163. if( ! MS_Model_Member::is_admin_user( $user_id ) ) return; 
  164.  
  165. if ( defined( 'MS_CPT_ENABLE_ACCESS_BOX' ) && MS_CPT_ENABLE_ACCESS_BOX ) { 
  166. $extra = array(); 
  167.  
  168.  
  169.  
  170. $post_types = array_merge( 
  171. array( 'page', 'post', 'attachment' ),  
  172. $extra 
  173. ); 
  174.  
  175. $this->post_types = apply_filters( 
  176. 'ms_controller_membership_metabox_add_meta_boxes_post_types',  
  177. $post_types 
  178. ); 
  179.  
  180. foreach ( $this->post_types as $post_type ) { 
  181. if ( ! $this->is_read_only( $post_type ) ) { 
  182. add_meta_box( 
  183. $this->metabox_id,  
  184. $this->metabox_title,  
  185. array( $this, 'membership_metabox' ),  
  186. $post_type,  
  187. $this->context,  
  188. $this->priority 
  189. ); 
  190.  
  191. do_action( 
  192. 'ms_controller_membership_metabox_add_meta_boxes',  
  193. $this 
  194. ); 
  195.  
  196. /** 
  197. * Membership metabox callback function for displaying the UI. 
  198. * 
  199. * @since 1.0.0 
  200. * 
  201. * @param object $post The current post object. 
  202. */ 
  203. public function membership_metabox( $post ) { 
  204. $data = array(); 
  205.  
  206. if ( MS_Model_Pages::is_membership_page() ) { 
  207. $data['special_page'] = true; 
  208. } else { 
  209. $all_memberships = MS_Model_Membership::get_memberships(); 
  210. $base = MS_Model_Membership::get_base(); 
  211. $data['base_id'] = $base->id; 
  212.  
  213. // Find the post-type of the current post. 
  214. if ( 'attachment' == $post->post_type ) { 
  215. $parent_id = $post->post_parent; 
  216. $post_type = get_post_type( $parent_id ); 
  217. } else { 
  218. $post_type = $post->post_type; 
  219.  
  220. // Get the base protection rule and check if post is protected. 
  221. $rule = $this->get_rule( $base, $post_type ); 
  222. $data['is_protected'] = ! $rule->has_access( $post->ID, false ); 
  223. $data['rule_type'] = $rule->rule_type; 
  224.  
  225. // Check each membership to see if the post is protected. 
  226. foreach ( $all_memberships as $membership ) { 
  227. if ( $membership->is_base ) { continue; } 
  228.  
  229. $rule = $this->get_rule( $membership, $post_type ); 
  230. $data['access'][ $membership->id ]['has_access'] = $rule->get_rule_value( $post->ID ); 
  231. $data['access'][ $membership->id ]['name'] = $membership->name; 
  232. $data['post_id'] = $post->ID; 
  233. $data['read_only'] = $this->is_read_only( $post->post_type ); 
  234.  
  235. $view = MS_Factory::create( 'MS_View_Metabox' ); 
  236. $view->data = apply_filters( 
  237. 'ms_view_membership_metabox_data',  
  238. $data,  
  239. $this 
  240. ); 
  241. $view->render(); 
  242.  
  243. /** 
  244. * Get rule accordingly to post type. 
  245. * 
  246. * @since 1.0.0 
  247. * 
  248. * @param MS_Model_Membership The membership to get rule from. 
  249. * @param string $post_type The post_type name of the queried post object. 
  250. * @return MS_Rule The rule model. 
  251. */ 
  252. private function get_rule( $membership, $post_type ) { 
  253. $rule = null; 
  254.  
  255. switch ( $post_type ) { 
  256. case 'post': 
  257. $rule = $membership->get_rule( MS_Rule_Post::RULE_ID ); 
  258. break; 
  259.  
  260. case 'page': 
  261. $rule = $membership->get_rule( MS_Rule_Page::RULE_ID ); 
  262. break; 
  263.  
  264. case 'attachment': 
  265. $rule = $membership->get_rule( MS_Rule_Media::RULE_ID ); 
  266. break; 
  267.  
  268. default: 
  269. $rule = $membership->get_rule( $post_type ); 
  270.  
  271.  
  272. break; 
  273.  
  274. return apply_filters( 
  275. 'ms_controller_metabox_get_rule',  
  276. $rule,  
  277. $membership,  
  278. $post_type,  
  279. $this 
  280. ); 
  281.  
  282. /** 
  283. * Toggle membership access. 
  284. * 
  285. * @since 1.0.0 
  286. * 
  287. * @param int $post_id The post id or attachment id to save access to. 
  288. * @param string $rule_type The membership rule type. 
  289. * @param array $membership_id The membership id to toggle access 
  290. */ 
  291. public function toggle_membership_access( $post_id, $rule_type, $membership_id ) { 
  292. if ( $this->is_admin_user() ) { 
  293. $membership = MS_Factory::load( 'MS_Model_Membership', $membership_id ); 
  294. $rule = $membership->get_rule( $rule_type ); 
  295. $protected = ! $rule->get_rule_value( $post_id ); 
  296.  
  297. if ( $membership->is_base() ) { 
  298. /** 
  299. * If we just modified the protection for the whole post then we 
  300. * have to update every single membership with the new rule 
  301. * value before changing the base rule itself. 
  302. */ 
  303. $all_memberships = MS_Model_Membership::get_memberships(); 
  304.  
  305. foreach ( $all_memberships as $the_membership ) { 
  306. if ( $the_membership->is_base ) { continue; } 
  307.  
  308. $the_rule = $the_membership->get_rule( $rule_type ); 
  309. if ( $protected ) { 
  310. $the_rule->give_access( $post_id ); 
  311. } else { 
  312. $the_rule->remove_access( $post_id ); 
  313.  
  314. $the_membership->set_rule( $rule_type, $the_rule ); 
  315. $the_membership->save(); 
  316.  
  317. if ( $rule ) { 
  318. if ( $protected ) { 
  319. $rule->give_access( $post_id ); 
  320. } else { 
  321. $rule->remove_access( $post_id ); 
  322.  
  323. $membership->set_rule( $rule_type, $rule ); 
  324. $membership->save(); 
  325.  
  326. do_action( 
  327. 'ms_controller_membership_metabox_toggle_membership_access',  
  328. $post_id,  
  329. $rule_type,  
  330. $membership_id,  
  331. $this 
  332. ); 
  333.  
  334. /** 
  335. * Determine whether Membership access can be changed or is read-only. 
  336. * 
  337. * @since 1.0.0 
  338. * @param string $post_type The post type of the post. 
  339. * @return bool 
  340. */ 
  341. public function is_read_only( $post_type ) { 
  342. if ( 'post' == $post_type 
  343. && ! MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_POST_BY_POST ) 
  344. ) { 
  345. $read_only = true; 
  346. } elseif ( 'attachment' == $post_type ) { 
  347. $read_only = true; 
  348.  
  349. } else { 
  350. $read_only = false; 
  351.  
  352. return apply_filters( 
  353. 'ms_controller_membership_metabox_is_read_only',  
  354. $read_only,  
  355. $post_type,  
  356. $this 
  357. ); 
  358.  
  359. /** 
  360. * Filter returns the default contents of a Membership Page if the URL param 
  361. * &ms-default=1 is set. 
  362. * 
  363. * Effectively this will display the default contents inside the Post-Editor 
  364. * without changing the page itself. Only after the user saves the content 
  365. * it will affect the Membership page 
  366. * 
  367. * @since 1.0.0 
  368. * @param string $content Default page content. 
  369. * @return string Modified page content. 
  370. */ 
  371. public function show_default_content( $content ) { 
  372. static $Message = false; 
  373. global $post, $post_type; 
  374.  
  375. if ( ! isset( $_GET['ms-default'] ) ) { return $content; } 
  376. if ( '1' != $_GET['ms-default'] ) { return $content; } 
  377. if ( 'page' != $post_type ) { return $content; } 
  378.  
  379. $ms_page = MS_Model_Pages::get_page_by( 'id', $post->ID ); 
  380.  
  381. if ( empty( $ms_page ) ) { return $content; } 
  382.  
  383. $type = MS_Model_Pages::get_page_type( $ms_page ); 
  384.  
  385. if ( ! $Message ) { 
  386. $Message = true; 
  387. lib3()->ui->admin_message( 
  388. __( 
  389. '<strong>Tipp</strong>:<br />' . 
  390. 'The page content is reset to the default content but is <em>not saved yet</em>!<br />' . 
  391. 'You can simply close this page to keep your current page contents.',  
  392. 'membership2' 
  393. ); 
  394.  
  395. return MS_Model_Pages::get_default_content( $type ); 
  396.  
  397. /** 
  398. * Load Membership Metabox specific scripts. 
  399. * 
  400. * @since 1.0.0 
  401. */ 
  402. public function admin_enqueue_scripts() { 
  403. global $post_type; 
  404.  
  405. if ( in_array( $post_type, $this->post_types ) 
  406. && ! $this->is_read_only( $post_type ) 
  407. ) { 
  408. lib3()->ui->data( 'ms_data', array( 'ms_init' => array( 'metabox' ) ) ); 
  409. wp_enqueue_script( 'ms-admin' ); 
.