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