/wp-content/plugins/membership/app/rule/replacelocation/class-ms-rule-replacelocation-model.php

https://gitlab.com/najomie/fit-hippie · PHP · 365 lines · 180 code · 45 blank · 140 comment · 26 complexity · 7de6323e39f7c0feb051a4f629aea122 MD5 · raw file

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