/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. if ( defined( 'MS_CPT_ENABLE_ACCESS_BOX' ) && MS_CPT_ENABLE_ACCESS_BOX ) { 
  161. $extra = array(); 
  162.  
  163.  
  164.  
  165. $post_types = array_merge( 
  166. array( 'page', 'post', 'attachment' ),  
  167. $extra 
  168. ); 
  169.  
  170. $this->post_types = apply_filters( 
  171. 'ms_controller_membership_metabox_add_meta_boxes_post_types',  
  172. $post_types 
  173. ); 
  174.  
  175. foreach ( $this->post_types as $post_type ) { 
  176. if ( ! $this->is_read_only( $post_type ) ) { 
  177. add_meta_box( 
  178. $this->metabox_id,  
  179. $this->metabox_title,  
  180. array( $this, 'membership_metabox' ),  
  181. $post_type,  
  182. $this->context,  
  183. $this->priority 
  184. ); 
  185.  
  186. do_action( 
  187. 'ms_controller_membership_metabox_add_meta_boxes',  
  188. $this 
  189. ); 
  190.  
  191. /** 
  192. * Membership metabox callback function for displaying the UI. 
  193. * 
  194. * @since 1.0.0 
  195. * 
  196. * @param object $post The current post object. 
  197. */ 
  198. public function membership_metabox( $post ) { 
  199. $data = array(); 
  200.  
  201. if ( MS_Model_Pages::is_membership_page() ) { 
  202. $data['special_page'] = true; 
  203. } else { 
  204. $all_memberships = MS_Model_Membership::get_memberships(); 
  205. $base = MS_Model_Membership::get_base(); 
  206. $data['base_id'] = $base->id; 
  207.  
  208. // Find the post-type of the current post. 
  209. if ( 'attachment' == $post->post_type ) { 
  210. $parent_id = $post->post_parent; 
  211. $post_type = get_post_type( $parent_id ); 
  212. } else { 
  213. $post_type = $post->post_type; 
  214.  
  215. // Get the base protection rule and check if post is protected. 
  216. $rule = $this->get_rule( $base, $post_type ); 
  217. $data['is_protected'] = ! $rule->has_access( $post->ID, false ); 
  218. $data['rule_type'] = $rule->rule_type; 
  219.  
  220. // Check each membership to see if the post is protected. 
  221. foreach ( $all_memberships as $membership ) { 
  222. if ( $membership->is_base ) { continue; } 
  223.  
  224. $rule = $this->get_rule( $membership, $post_type ); 
  225. $data['access'][ $membership->id ]['has_access'] = $rule->get_rule_value( $post->ID ); 
  226. $data['access'][ $membership->id ]['name'] = $membership->name; 
  227. $data['post_id'] = $post->ID; 
  228. $data['read_only'] = $this->is_read_only( $post->post_type ); 
  229.  
  230. $view = MS_Factory::create( 'MS_View_Metabox' ); 
  231. $view->data = apply_filters( 
  232. 'ms_view_membership_metabox_data',  
  233. $data,  
  234. $this 
  235. ); 
  236. $view->render(); 
  237.  
  238. /** 
  239. * Get rule accordingly to post type. 
  240. * 
  241. * @since 1.0.0 
  242. * 
  243. * @param MS_Model_Membership The membership to get rule from. 
  244. * @param string $post_type The post_type name of the queried post object. 
  245. * @return MS_Rule The rule model. 
  246. */ 
  247. private function get_rule( $membership, $post_type ) { 
  248. $rule = null; 
  249.  
  250. switch ( $post_type ) { 
  251. case 'post': 
  252. $rule = $membership->get_rule( MS_Rule_Post::RULE_ID ); 
  253. break; 
  254.  
  255. case 'page': 
  256. $rule = $membership->get_rule( MS_Rule_Page::RULE_ID ); 
  257. break; 
  258.  
  259. case 'attachment': 
  260. $rule = $membership->get_rule( MS_Rule_Media::RULE_ID ); 
  261. break; 
  262.  
  263. default: 
  264. $rule = $membership->get_rule( $post_type ); 
  265.  
  266.  
  267. break; 
  268.  
  269. return apply_filters( 
  270. 'ms_controller_metabox_get_rule',  
  271. $rule,  
  272. $membership,  
  273. $post_type,  
  274. $this 
  275. ); 
  276.  
  277. /** 
  278. * Toggle membership access. 
  279. * 
  280. * @since 1.0.0 
  281. * 
  282. * @param int $post_id The post id or attachment id to save access to. 
  283. * @param string $rule_type The membership rule type. 
  284. * @param array $membership_id The membership id to toggle access 
  285. */ 
  286. public function toggle_membership_access( $post_id, $rule_type, $membership_id ) { 
  287. if ( $this->is_admin_user() ) { 
  288. $membership = MS_Factory::load( 'MS_Model_Membership', $membership_id ); 
  289. $rule = $membership->get_rule( $rule_type ); 
  290. $protected = ! $rule->get_rule_value( $post_id ); 
  291.  
  292. if ( $membership->is_base() ) { 
  293. /** 
  294. * If we just modified the protection for the whole post then we 
  295. * have to update every single membership with the new rule 
  296. * value before changing the base rule itself. 
  297. */ 
  298. $all_memberships = MS_Model_Membership::get_memberships(); 
  299.  
  300. foreach ( $all_memberships as $the_membership ) { 
  301. if ( $the_membership->is_base ) { continue; } 
  302.  
  303. $the_rule = $the_membership->get_rule( $rule_type ); 
  304. if ( $protected ) { 
  305. $the_rule->give_access( $post_id ); 
  306. } else { 
  307. $the_rule->remove_access( $post_id ); 
  308.  
  309. $the_membership->set_rule( $rule_type, $the_rule ); 
  310. $the_membership->save(); 
  311.  
  312. if ( $rule ) { 
  313. if ( $protected ) { 
  314. $rule->give_access( $post_id ); 
  315. } else { 
  316. $rule->remove_access( $post_id ); 
  317.  
  318. $membership->set_rule( $rule_type, $rule ); 
  319. $membership->save(); 
  320.  
  321. do_action( 
  322. 'ms_controller_membership_metabox_toggle_membership_access',  
  323. $post_id,  
  324. $rule_type,  
  325. $membership_id,  
  326. $this 
  327. ); 
  328.  
  329. /** 
  330. * Determine whether Membership access can be changed or is read-only. 
  331. * 
  332. * @since 1.0.0 
  333. * @param string $post_type The post type of the post. 
  334. * @return bool 
  335. */ 
  336. public function is_read_only( $post_type ) { 
  337. if ( 'post' == $post_type 
  338. && ! MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_POST_BY_POST ) 
  339. ) { 
  340. $read_only = true; 
  341. } elseif ( 'attachment' == $post_type ) { 
  342. $read_only = true; 
  343.  
  344. } else { 
  345. $read_only = false; 
  346.  
  347. return apply_filters( 
  348. 'ms_controller_membership_metabox_is_read_only',  
  349. $read_only,  
  350. $post_type,  
  351. $this 
  352. ); 
  353.  
  354. /** 
  355. * Filter returns the default contents of a Membership Page if the URL param 
  356. * &ms-default=1 is set. 
  357. * 
  358. * Effectively this will display the default contents inside the Post-Editor 
  359. * without changing the page itself. Only after the user saves the content 
  360. * it will affect the Membership page 
  361. * 
  362. * @since 1.0.0 
  363. * @param string $content Default page content. 
  364. * @return string Modified page content. 
  365. */ 
  366. public function show_default_content( $content ) { 
  367. static $Message = false; 
  368. global $post, $post_type; 
  369.  
  370. if ( ! isset( $_GET['ms-default'] ) ) { return $content; } 
  371. if ( '1' != $_GET['ms-default'] ) { return $content; } 
  372. if ( 'page' != $post_type ) { return $content; } 
  373.  
  374. $ms_page = MS_Model_Pages::get_page_by( 'id', $post->ID ); 
  375.  
  376. if ( empty( $ms_page ) ) { return $content; } 
  377.  
  378. $type = MS_Model_Pages::get_page_type( $ms_page ); 
  379.  
  380. if ( ! $Message ) { 
  381. $Message = true; 
  382. lib3()->ui->admin_message( 
  383. __( 
  384. '<strong>Tipp</strong>:<br />' . 
  385. 'The page content is reset to the default content but is <em>not saved yet</em>!<br />' . 
  386. 'You can simply close this page to keep your current page contents.',  
  387. 'membership2' 
  388. ); 
  389.  
  390. return MS_Model_Pages::get_default_content( $type ); 
  391.  
  392. /** 
  393. * Load Membership Metabox specific scripts. 
  394. * 
  395. * @since 1.0.0 
  396. */ 
  397. public function admin_enqueue_scripts() { 
  398. global $post_type; 
  399.  
  400. if ( in_array( $post_type, $this->post_types ) 
  401. && ! $this->is_read_only( $post_type ) 
  402. ) { 
  403. lib3()->ui->data( 'ms_data', array( 'ms_init' => array( 'metabox' ) ) ); 
  404. wp_enqueue_script( 'ms-admin' ); 
.