/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. * Replace specific menus for certain members. 
  71. * 
  72. * Relevant Action Hooks: 
  73. * - theme_mod_nav_menu_locations 
  74. * 
  75. * @since 1.0.0 
  76. * 
  77. * @param array $default The default menu assignment array. 
  78. */ 
  79. public function replace_menus( $defaults ) { 
  80. // We ignore the base membership for this rule-type. 
  81. if ( $this->is_base_rule ) { return $defaults; } 
  82.  
  83. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  84.  
  85. foreach ( $defaults as $key => $menu ) { 
  86. $replace = $this->get_rule_value( $key ); 
  87. if ( ! $replace ) { continue; } 
  88.  
  89. $replacement = $base_rule->get_rule_value( $key ); 
  90.  
  91. if ( is_numeric( $replacement ) && $replacement > 0 ) { 
  92. $defaults[ $key ] = intval( $replacement ); 
  93.  
  94. return apply_filters( 
  95. 'ms_rule_replacelocation_model_replace_menus',  
  96. $defaults,  
  97. $this 
  98. ); 
  99.  
  100. /** 
  101. * Get content to protect. 
  102. * 
  103. * @since 1.0.0 
  104. * @param $args The query post args 
  105. * @return array The contents array. 
  106. */ 
  107. public function get_contents( $args = null ) { 
  108. $contents = array(); 
  109.  
  110. $areas = $this->get_nav_array(); 
  111. $menus = $this->get_menu_array(); 
  112.  
  113. if ( is_array( $areas ) ) { 
  114. foreach ( $areas as $key => $description ) { 
  115. $val = 0; 
  116. $saved = $this->get_rule_value( $key ); 
  117. $post_title = ''; 
  118. $access = false; 
  119.  
  120. if ( is_numeric( $saved ) && isset( $menus[ $saved ] ) ) { 
  121. $val = absint( $saved ); 
  122. $access = true; 
  123. $post_title = sprintf( 
  124. '%s → %s',  
  125. strip_tags( $description ),  
  126. $menus[$saved] 
  127. ); 
  128.  
  129. $contents[ $key ] = (object) array( 
  130. 'access' => $access,  
  131. 'title' => $description,  
  132. 'value' => $val,  
  133. 'post_title' => $post_title,  
  134. 'id' => $key,  
  135. 'type' => $this->rule_type,  
  136. ); 
  137.  
  138. if ( ! empty( $args['rule_status'] ) ) { 
  139. $contents = $this->filter_content( $args['rule_status'], $contents ); 
  140.  
  141. return apply_filters( 
  142. 'ms_rule_replacelocation_model_get_contents',  
  143. $contents,  
  144. $args,  
  145. $this 
  146. ); 
  147.  
  148. /** 
  149. * Returns an array of matching options that are displayed in a select 
  150. * list for each item. 
  151. * 
  152. * @since 1.0.0 
  153. * @return array 
  154. */ 
  155. public function get_matching_options( $args = null ) { 
  156. $options = array( 
  157. 0 => __( '( Default Menu )', 'membership2' ),  
  158. ); 
  159.  
  160. $options += $this->get_menu_array(); 
  161.  
  162. return apply_filters( 
  163. 'ms_rule_replacelocation_model_get_matching_options',  
  164. $options,  
  165. $args,  
  166. $this 
  167. ); 
  168.  
  169. /** 
  170. * Get menu array. 
  171. * 
  172. * @since 1.0.0 
  173. * 
  174. * @return array { 
  175. * @type string $menu_id The menu id. 
  176. * @type string $name The menu name. 
  177. * } 
  178. */ 
  179. public function get_menu_array() { 
  180. if ( empty( $this->menus ) ) { 
  181. $this->menus = array( 
  182. __( 'No menus found.', 'membership2' ),  
  183. ); 
  184.  
  185. $navs = wp_get_nav_menus( array( 'orderby' => 'name' ) ); 
  186.  
  187. if ( ! empty( $navs ) ) { 
  188. $this->menus = array(); 
  189.  
  190. foreach ( $navs as $nav ) { 
  191. $this->menus[ $nav->term_id ] = $nav->name; 
  192.  
  193. $this->menus = apply_filters( 
  194. 'ms_rule_replacelocation_model_get_menu_array',  
  195. $this->menus,  
  196. $this 
  197. ); 
  198.  
  199. return $this->menus; 
  200.  
  201. /** 
  202. * Get navigational areas. 
  203. * 
  204. * @since 1.0.0 
  205. * 
  206. * @return array { 
  207. * @type string $menu_id The menu id. 
  208. * @type string $name The menu name. 
  209. * } 
  210. */ 
  211. public function get_nav_array() { 
  212. $contents = array( 
  213. __( 'No menus found.', 'membership2' ),  
  214. ); 
  215.  
  216. $areas = get_registered_nav_menus(); 
  217.  
  218. if ( ! empty( $areas ) ) { 
  219. $contents = $areas; 
  220.  
  221. return apply_filters( 
  222. 'ms_rule_replacelocation_model_get_nav_array',  
  223. $contents,  
  224. $this 
  225. ); 
  226.  
  227. /** 
  228. * Get rule value for a specific content. 
  229. * 
  230. * @since 1.0.0 
  231. * 
  232. * @param string $id The content id to get rule value for. 
  233. * @return boolean The rule value for the requested content. Default $rule_value_default. 
  234. */ 
  235. public function get_rule_value( $id ) { 
  236. if ( is_scalar( $id ) && isset( $this->rule_value[ $id ] ) ) { 
  237. if ( $this->is_base_rule ) { 
  238. // The base-rule actually saves a menu_id as rule value. 
  239. $value = intval( $this->rule_value[ $id ] ); 
  240. } else { 
  241. // Non-Base rules only save a boolean flag 
  242. $value = (bool) $this->rule_value[ $id ]; 
  243. } else { 
  244. // Default response is NULL: "Not-Denied" 
  245. $value = MS_Model_Rule::RULE_VALUE_UNDEFINED; 
  246.  
  247. return apply_filters( 
  248. 'ms_get_rule_value',  
  249. $value,  
  250. $id,  
  251. $this->rule_type,  
  252. $this 
  253. ); 
  254.  
  255. /** 
  256. * Set access status to content. 
  257. * 
  258. * @since 1.0.0 
  259. * @param string $id The content id to set access to. 
  260. * @param int $access The access status to set. 
  261. */ 
  262. public function set_access( $id, $replace ) { 
  263. $delete = false; 
  264.  
  265. if ( ! $this->is_base_rule ) { 
  266. if ( MS_Model_Rule::RULE_VALUE_NO_ACCESS == $replace ) { 
  267. $delete = true; 
  268. } else { 
  269. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  270. $replace = true; 
  271.  
  272. if ( $delete ) { 
  273. unset( $this->rule_value[ $id ] ); 
  274. } else { 
  275. $this->rule_value[ $id ] = $replace; 
  276.  
  277. do_action( 'ms_rule_replacemenu_set_access', $id, $replace, $this ); 
  278.  
  279. /** 
  280. * Give access to content. 
  281. * 
  282. * @since 1.0.0 
  283. * @param string $id The content id to give access. 
  284. */ 
  285. public function give_access( $id ) { 
  286. if ( $this->is_base_rule ) { 
  287. // The base rule can only be updated via Ajax! 
  288. $cur_val = $this->get_rule_value( $id ); 
  289. if ( empty( $cur_val ) ) { 
  290. $this->set_access( $id, true ); 
  291. return; 
  292. } else { 
  293. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  294. $value = $base_rule->get_rule_value( $id ); 
  295.  
  296. $this->set_access( $id, $value ); 
  297.  
  298. do_action( 'ms_rule_replacemenu_give_access', $id, $this ); 
  299.  
  300. /** 
  301. * Serializes this rule in a single array. 
  302. * We don't use the PHP `serialize()` function to serialize the whole object 
  303. * because a lot of unrequired and duplicate data will be serialized 
  304. * 
  305. * @since 1.0.0 
  306. * @return array The serialized values of the Rule. 
  307. */ 
  308. public function serialize() { 
  309. $result = $this->rule_value; 
  310. return $result; 
  311.  
  312. /** 
  313. * Populates the rule_value array with the specified value list. 
  314. * This function is used when de-serializing a membership to re-create the 
  315. * rules associated with the membership. 
  316. * 
  317. * @since 1.0.0 
  318. * @param array $values A list of allowed IDs. 
  319. */ 
  320. public function populate( $values ) { 
  321. $this->rule_value = array(); 
  322. foreach ( $values as $menu_id => $replacement ) { 
  323. $this->rule_value[$menu_id] = $replacement; 
  324.  
.