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