/app/rule/replacemenu/class-ms-rule-replacemenu-model.php

  1. <?php 
  2. /** 
  3. * Membership Replace-Menu Rule class. 
  4. * 
  5. * @since 1.0.0 
  6. * 
  7. * @package Membership2 
  8. * @subpackage Model 
  9. */ 
  10. class MS_Rule_ReplaceMenu_Model extends MS_Rule { 
  11.  
  12. /** 
  13. * Rule type. 
  14. * 
  15. * @since 1.0.0 
  16. * 
  17. * @var string $rule_type 
  18. */ 
  19. protected $rule_type = MS_Rule_ReplaceMenu::RULE_ID; 
  20.  
  21. /** 
  22. * An array of all available menu items. 
  23. * @var array 
  24. */ 
  25. protected $menus = array(); 
  26.  
  27. /** 
  28. * Mapping of menu_ids that should be replaced. 
  29. * @var array 
  30. */ 
  31. protected $replacements; 
  32.  
  33. /** 
  34. * Returns the active flag for a specific rule. 
  35. * State depends on Add-on 
  36. * 
  37. * @since 1.0.0 
  38. * @return bool 
  39. */ 
  40. static public function is_active() { 
  41. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  42. return 'menu' == $settings->menu_protection; 
  43.  
  44. /** 
  45. * Verify access to the current content. 
  46. * 
  47. * This rule will return NULL (not relevant), because the menus are 
  48. * protected via a wordpress hook instead of protecting the current page. 
  49. * 
  50. * @since 1.0.0 
  51. * 
  52. * @param string $id The content id to verify access. 
  53. * @return bool|null True if has access, false otherwise. 
  54. * Null means: Rule not relevant for current page. 
  55. */ 
  56. public function has_access( $id, $admin_has_access = true ) { 
  57. return null; 
  58.  
  59. /** 
  60. * Set initial protection. 
  61. * 
  62. * @since 1.0.0 
  63. */ 
  64. public function protect_content() { 
  65. parent::protect_content(); 
  66.  
  67. /** 
  68. * Replace the "menu" attribute of the wp_nav_menu() call 
  69. */ 
  70. $this->add_filter( 'wp_nav_menu_args', 'replace_menus' ); 
  71.  
  72. /** 
  73. * Replace specific menus for certain members. 
  74. * 
  75. * Relevant Action Hooks: 
  76. * - wp_nav_menu_args 
  77. * 
  78. * @since 1.0.0 
  79. * 
  80. * @param mixed $args Attributes of the call to wp_nav_menu(). 
  81. * @return mixed The updated attributes. 
  82. */ 
  83. public function replace_menus( $args ) { 
  84. // We ignore the base membership for this rule-type. 
  85. if ( $this->is_base_rule ) { return $args; } 
  86.  
  87. $id = $args['menu']; 
  88.  
  89. if ( ! is_numeric( $id ) ) { 
  90. // Get the nav menu based on the theme_location 
  91. $locations = get_nav_menu_locations(); 
  92. if ( $args['theme_location'] && isset( $locations[ $args['theme_location'] ] ) ) { 
  93. $id = $locations[ $args['theme_location'] ]; 
  94.  
  95. if ( is_numeric( $id ) ) { 
  96. $replacements = $this->get_replacements(); 
  97.  
  98. if ( isset( $replacements[ $id ] ) ) { 
  99. $args['menu'] = $replacements[ $id ]; 
  100. $args['theme_location'] = ''; 
  101.  
  102. return apply_filters( 
  103. 'ms_rule_replacemenu_model_replace_menus',  
  104. $args,  
  105. $this 
  106. ); 
  107.  
  108. /** 
  109. * Get menu array. 
  110. * 
  111. * @since 1.0.0 
  112. * 
  113. * @return array { 
  114. * @type string $menu_id The menu id. 
  115. * @type string $name The menu name. 
  116. * } 
  117. */ 
  118. public function get_menus() { 
  119. if ( empty( $this->menus ) ) { 
  120. $navs = wp_get_nav_menus( array( 'orderby' => 'name' ) ); 
  121.  
  122. if ( ! empty( $navs ) ) { 
  123. $this->menus = array(); 
  124.  
  125. foreach ( $navs as $nav ) { 
  126. $this->menus[ $nav->term_id ] = $nav->name; 
  127.  
  128. $this->menus = apply_filters( 
  129. 'ms_rule_replacemenu_model_get_menus',  
  130. $this->menus,  
  131. $this 
  132. ); 
  133.  
  134. if ( empty( $this->menus ) ) { 
  135. $this->menus = array( 
  136. __( 'No menus found.', 'membership2' ),  
  137. ); 
  138.  
  139. return $this->menus; 
  140.  
  141. /** 
  142. * Get content to protect. 
  143. * 
  144. * @since 1.0.0 
  145. * @param $args The query post args 
  146. * @return array The contents array. 
  147. */ 
  148. public function get_contents( $args = null ) { 
  149. $contents = array(); 
  150.  
  151. $menus = $this->get_menus(); 
  152.  
  153. if ( is_array( $menus ) ) { 
  154. foreach ( $menus as $key => $name ) { 
  155. $val = 0; 
  156. $saved = $this->get_rule_value( $key ); 
  157. $post_title = ''; 
  158. $access = false; 
  159.  
  160. if ( is_numeric( $saved ) && isset( $menus[ $saved ] ) ) { 
  161. $val = absint( $saved ); 
  162. $access = true; 
  163. $post_title = sprintf( 
  164. '%s → %s',  
  165. strip_tags( $name ),  
  166. $menus[$saved] 
  167. ); 
  168.  
  169. $contents[ $key ] = (object) array( 
  170. 'access' => $access,  
  171. 'title' => $name,  
  172. 'value' => $val,  
  173. 'post_title' => $post_title,  
  174. 'id' => $key,  
  175. 'type' => $this->rule_type,  
  176. ); 
  177.  
  178. if ( ! empty( $args['rule_status'] ) ) { 
  179. $contents = $this->filter_content( $args['rule_status'], $contents ); 
  180.  
  181. return apply_filters( 
  182. 'ms_rule_replacemenu_model_get_contents',  
  183. $contents,  
  184. $args,  
  185. $this 
  186. ); 
  187.  
  188. /** 
  189. * Returns an array that contains menu_ids that should be replaced. 
  190. * 
  191. * @since 1.0.0 
  192. * @return array { 
  193. * $original => $replacement 
  194. * } 
  195. */ 
  196. protected function get_replacements() { 
  197. if ( ! is_array( $this->replacements ) ) { 
  198. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  199. $this->replacements = array(); 
  200. $menus = $this->get_menus(); 
  201.  
  202. foreach ( $menus as $menu_id => $name ) { 
  203. $replace = $this->get_rule_value( $menu_id ); 
  204. if ( ! $replace ) { continue; } 
  205.  
  206. $replacement = $base_rule->get_rule_value( $menu_id ); 
  207.  
  208. if ( is_numeric( $replacement ) && $replacement > 0 ) { 
  209. $this->replacements[ $menu_id ] = intval( $replacement ); 
  210.  
  211. return $this->replacements; 
  212.  
  213. /** 
  214. * Returns an array of matching options that are displayed in a select 
  215. * list for each item. 
  216. * 
  217. * @since 1.0.0 
  218. * @return array 
  219. */ 
  220. public function get_matching_options( $args = null ) { 
  221. $options = array( 
  222. 0 => __( '( No replacement )', 'membership2' ),  
  223. ); 
  224.  
  225. $options += $this->get_menus(); 
  226.  
  227. return apply_filters( 
  228. 'ms_rule_replacemenu_model_get_matching_options',  
  229. $options,  
  230. $args,  
  231. $this 
  232. ); 
  233.  
  234. /** 
  235. * Get rule value for a specific content. 
  236. * 
  237. * @since 1.0.0 
  238. * 
  239. * @param string $id The content id to get rule value for. 
  240. * @return boolean The rule value for the requested content. Default $rule_value_default. 
  241. */ 
  242. public function get_rule_value( $id ) { 
  243. if ( is_scalar( $id ) && isset( $this->rule_value[ $id ] ) ) { 
  244. if ( $this->is_base_rule ) { 
  245. // The base-rule actually saves a menu_id as rule value. 
  246. $value = intval( $this->rule_value[ $id ] ); 
  247. } else { 
  248. // Non-Base rules only save a boolean flag 
  249. $value = (bool) $this->rule_value[ $id ]; 
  250. } else { 
  251. // Default response is NULL: "Not-Denied" 
  252. $value = MS_Model_Rule::RULE_VALUE_UNDEFINED; 
  253.  
  254. return apply_filters( 
  255. 'ms_get_rule_value',  
  256. $value,  
  257. $id,  
  258. $this->rule_type,  
  259. $this 
  260. ); 
  261.  
  262. /** 
  263. * Set access status to content. 
  264. * 
  265. * @since 1.0.0 
  266. * @param string $id The content id to set access to. 
  267. * @param int $access The access status to set. 
  268. */ 
  269. public function set_access( $id, $replace ) { 
  270. $delete = false; 
  271.  
  272. if ( ! $this->is_base_rule ) { 
  273. if ( MS_Model_Rule::RULE_VALUE_NO_ACCESS == $replace ) { 
  274. $delete = true; 
  275. } else { 
  276. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  277. $replace = true; 
  278.  
  279. if ( $delete ) { 
  280. unset( $this->rule_value[ $id ] ); 
  281. } else { 
  282. $this->rule_value[ $id ] = $replace; 
  283.  
  284. do_action( 'ms_rule_replacemenu_set_access', $id, $replace, $this ); 
  285.  
  286. /** 
  287. * Give access to content. 
  288. * 
  289. * @since 1.0.0 
  290. * @param string $id The content id to give access. 
  291. */ 
  292. public function give_access( $id ) { 
  293. if ( $this->is_base_rule ) { 
  294. // The base rule can only be updated via Ajax! 
  295. $cur_val = $this->get_rule_value( $id ); 
  296. if ( empty( $cur_val ) ) { 
  297. $this->set_access( $id, true ); 
  298. return; 
  299. } else { 
  300. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  301. $value = $base_rule->get_rule_value( $id ); 
  302.  
  303. $this->set_access( $id, $value ); 
  304.  
  305. do_action( 'ms_rule_replacemenu_give_access', $id, $this ); 
  306.  
  307. /** 
  308. * Serializes this rule in a single array. 
  309. * We don't use the PHP `serialize()` function to serialize the whole object 
  310. * because a lot of unrequired and duplicate data will be serialized 
  311. * 
  312. * @since 1.0.0 
  313. * @return array The serialized values of the Rule. 
  314. */ 
  315. public function serialize() { 
  316. $result = $this->rule_value; 
  317. return $result; 
  318.  
  319. /** 
  320. * Populates the rule_value array with the specified value list. 
  321. * This function is used when de-serializing a membership to re-create the 
  322. * rules associated with the membership. 
  323. * 
  324. * @since 1.0.0 
  325. * @param array $values A list of allowed IDs. 
  326. */ 
  327. public function populate( $values ) { 
  328. $this->rule_value = array(); 
  329. foreach ( $values as $menu_id => $replacement ) { 
  330. $this->rule_value[$menu_id] = $replacement; 
  331.  
.