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