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

  1. <?php 
  2. /** 
  3. * Membership URL Group Rule class. 
  4. * 
  5. * Persisted by Membership class. 
  6. * 
  7. * @since 1.0.0 
  8. * 
  9. * @package Membership2 
  10. * @subpackage Model 
  11. */ 
  12. class MS_Rule_Url_Model extends MS_Rule { 
  13.  
  14. /** 
  15. * Rule type. 
  16. * 
  17. * @since 1.0.0 
  18. * 
  19. * @var string $rule_type 
  20. */ 
  21. protected $rule_type = MS_Rule_Url::RULE_ID; 
  22.  
  23. /** 
  24. * A list of all URLs that are allowed by the current membership. 
  25. * 
  26. * @since 1.0.0 
  27. * 
  28. * @var array 
  29. */ 
  30. protected $_allowed_urls = null; 
  31.  
  32. /** 
  33. * Returns the active flag for a specific rule. 
  34. * State depends on Add-on 
  35. * 
  36. * @since 1.0.0 
  37. * @return bool 
  38. */ 
  39. static public function is_active() { 
  40. return MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_URL_GROUPS ); 
  41.  
  42. /** 
  43. * Verify access to the current content. 
  44. * 
  45. * @since 1.0.0 
  46. * 
  47. * @param int $id The post/CPT ID to verify access. Defaults to current URL. 
  48. * @return bool|null True if has access, false otherwise. 
  49. * Null means: Rule not relevant for current page. 
  50. */ 
  51. public function has_access( $id, $admin_has_access = true ) { 
  52. $has_access = null; 
  53.  
  54. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_URL_GROUPS ) ) { 
  55. if ( ! empty( $id ) ) { 
  56. $url = get_permalink( $id ); 
  57. } else { 
  58. $url = MS_Helper_Utility::get_current_url(); 
  59. $url = apply_filters( 'ms_rule_url_model_exception_rule', $url ); 
  60.  
  61. if ( ! $this->has_rule_for_url( $url ) ) { return null; } 
  62.  
  63. $exclude = apply_filters( 
  64. 'ms_rule_url_model_excluded_urls',  
  65. array() 
  66. ); 
  67.  
  68. // Check for exclude list. 
  69. if ( $this->check_url_expression_match( $url, $exclude ) ) { 
  70. $has_access = true; 
  71. } else { 
  72. // The URL is protected and has no exception. Deny it by default. 
  73. $has_access = false; 
  74.  
  75. // Check for URL group. 
  76. $accessible = $this->get_accessible_urls(); 
  77. if ( $this->check_url_expression_match( $url, $accessible ) ) { 
  78. if ( $this->get_membership()->is_base() ) { 
  79. // For guests all defined URL groups are denied. 
  80. $has_access = false; 
  81. } else { 
  82. $has_access = true; 
  83.  
  84. return apply_filters( 
  85. 'ms_rule_url_model_has_access',  
  86. $has_access,  
  87. $id,  
  88. $this 
  89. ); 
  90.  
  91. /** 
  92. * Verify if current url has protection rules. 
  93. * 
  94. * @since 1.0.0 
  95. * 
  96. * @return boolean True if has access, false otherwise. 
  97. */ 
  98. protected function has_rule_for_url( $url ) { 
  99. $has_rules = false; 
  100.  
  101. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_URL_GROUPS ) ) { 
  102. if ( $this->check_url_expression_match( $url, $this->get_protected_urls() ) ) { 
  103. $has_rules = true; 
  104.  
  105. return apply_filters( 
  106. 'ms_rule_url_model_has_access',  
  107. $has_rules,  
  108. $this 
  109. ); 
  110.  
  111. /** 
  112. * Verify if a post/custom post type has protection rules. 
  113. * 
  114. * @since 1.0.0 
  115. * 
  116. * @return boolean True if has access, false otherwise. 
  117. */ 
  118. public function has_rule_for_post( $post_id ) { 
  119. $has_rules = false; 
  120.  
  121. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_URL_GROUPS ) ) { 
  122. $url = get_permalink( $post_id ); 
  123. if ( $this->check_url_expression_match( $url, $this->get_protected_urls() ) ) { 
  124. $has_rules = true; 
  125.  
  126. return apply_filters( 
  127. 'ms_rule_url_model_has_rule_for_post',  
  128. $has_rules,  
  129. $this 
  130. ); 
  131.  
  132. /** 
  133. * Check url expression match. 
  134. * 
  135. * @since 1.0.0 
  136. * 
  137. * @param string $url The url to match. 
  138. * @param string[] $check_list The url list to verify match. 
  139. * @return boolean True if matches. 
  140. */ 
  141. public function check_url_expression_match( $url, $check_list ) { 
  142. $match = false; 
  143.  
  144. $check_list = lib3()->array->get( $check_list ); 
  145. if ( count( $check_list ) ) { 
  146. $check_list = array_map( 'strtolower', $check_list ); 
  147. $check_list = array_map( 'trim', $check_list ); 
  148.  
  149. $url = strtolower( $url ); 
  150. foreach ( $check_list as $check ) { 
  151. if (false === empty($check) && 1 === preg_match( '@' . trim($check) . '@', $url) ) { 
  152. $match = true; 
  153. break; 
  154.  
  155. return apply_filters( 
  156. 'ms_rule_url_model_check_url_expression_match',  
  157. $match,  
  158. $url,  
  159. $check_list,  
  160. $this 
  161. ); 
  162.  
  163. /** 
  164. * Count protection rules quantity. 
  165. * 
  166. * @since 1.0.0 
  167. * 
  168. * @param bool $has_access_only Optional. Count rules for has_access status only. 
  169. * @return int $count The rule count result. 
  170. */ 
  171. public function count_rules( $has_access_only = true ) { 
  172. $count = count( $this->rule_value ); 
  173.  
  174. return apply_filters( 
  175. 'ms_rule_url_model_count_rules',  
  176. $count,  
  177. $this 
  178. ); 
  179.  
  180. /** 
  181. * Get the total content count. 
  182. * Used in Dashboard to display how many special pages are protected. 
  183. * 
  184. * @since 1.0.0 
  185. * 
  186. * @param $args Ignored 
  187. * @return int The total content count. 
  188. */ 
  189. public function get_content_count( $args = null ) { 
  190. $count = count( $this->get_protected_urls() ); 
  191.  
  192. return apply_filters( 
  193. 'ms_rule_url_model_get_content_count',  
  194. $count,  
  195. $args 
  196. ); 
  197.  
  198. /** 
  199. * Get content to protect. 
  200. * 
  201. * @since 1.0.0 
  202. * @param $args The filter args 
  203. * 
  204. * @return array The contents array. 
  205. */ 
  206. public function get_contents( $args = null ) { 
  207. $protected_urls = $this->get_protected_urls(); 
  208. $membership_urls = $this->rule_value; 
  209.  
  210. $contents = array(); 
  211. foreach ( $membership_urls as $hash => $value ) { 
  212. if ( ! isset( $protected_urls[$hash] ) ) { 
  213. continue; 
  214.  
  215. $content = new StdClass(); 
  216. $content->id = $hash; 
  217. $content->type = MS_Rule_Url::RULE_ID; 
  218. $content->name = $protected_urls[$hash]; 
  219. $content->url = $protected_urls[$hash]; 
  220. $content->access = $this->get_rule_value( $content->id ); 
  221. $contents[] = $content; 
  222.  
  223. return apply_filters( 
  224. 'ms_rule_url_model_get_contents',  
  225. $contents 
  226. ); 
  227.  
  228. /** 
  229. * Set access status to content. 
  230. * 
  231. * @since 1.0.0 
  232. * @param string $id The content id to set access to. 
  233. * @param int $access The access status to set. 
  234. */ 
  235. public function set_access( $hash, $access ) { 
  236. if ( $this->is_base_rule ) { 
  237. /** 
  238. * Base rule cannot modify URL access via this function! 
  239. * Values of the base-rule are modified via a special Ajax handler 
  240. * that directly calls `add_url()` 
  241. * 
  242. * @see MS_Rule_Url::process_form() 
  243. */ 
  244. return; 
  245.  
  246. if ( empty( $access ) ) { 
  247. $this->delete_url( $hash ); 
  248. } else { 
  249. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  250. $url = $base_rule->get_url_from_hash( $hash ); 
  251. $this->add_url( $url ); 
  252.  
  253. do_action( 'ms_rule_url_set_access', $hash, $access, $this ); 
  254.  
  255. /** 
  256. * Serializes this rule in a single array. 
  257. * We don't use the PHP `serialize()` function to serialize the whole object 
  258. * because a lot of unrequired and duplicate data will be serialized 
  259. * 
  260. * @since 1.0.0 
  261. * @return array The serialized values of the Rule. 
  262. */ 
  263. public function serialize() { 
  264. $result = $this->rule_value; 
  265. return $result; 
  266.  
  267. /** 
  268. * Populates the rule_value array with the specified value list. 
  269. * This function is used when de-serializing a membership to re-create the 
  270. * rules associated with the membership. 
  271. * 
  272. * @since 1.0.0 
  273. * @param array $values A list of allowed IDs. 
  274. */ 
  275. public function populate( $values ) { 
  276. foreach ( $values as $hash => $url ) { 
  277. $this->add_url( $url ); 
  278.  
  279. /** 
  280. * Adds a new URL to the rule 
  281. * 
  282. * @since 1.0.0 
  283. * @param string $url 
  284. */ 
  285. public function add_url( $url ) { 
  286. $url = trim( $url ); 
  287.  
  288. // Index is a hash to prevent duplicate URLs in the list. 
  289. $hash = md5( $url ); 
  290. $this->rule_value[ $hash ] = $url; 
  291.  
  292. /** 
  293. * Removes an URL from the rule. 
  294. * 
  295. * An URL can be deleted either by specifying an Hash (prefered) or the 
  296. * plain-text URL. If a Hash value is specified the URL is always ignored. 
  297. * 
  298. * @since 1.0.0 
  299. * @param string $hash The URL-hash. 
  300. * @param string $url Optional. The plain-text URL. 
  301. */ 
  302. public function delete_url( $hash, $url = null ) { 
  303. if ( ! empty( $hash ) ) { 
  304. unset( $this->rule_value[ $hash ] ); 
  305. } elseif ( ! empty( $url ) ) { 
  306. $url = trim( $url ); 
  307. $hash = md5( $url ); 
  308. unset( $this->rule_value[ $hash ] ); 
  309.  
  310. /** 
  311. * Returns the URL from a specific hash value. 
  312. * 
  313. * @since 1.0.0 
  314. * @param string $hash The URL-hash. 
  315. */ 
  316. public function get_url_from_hash( $hash ) { 
  317. $url = ''; 
  318.  
  319. $urls = $this->get_protected_urls(); 
  320. if ( isset( $urls[ $hash ] ) ) { 
  321. $url = $urls[ $hash ]; 
  322.  
  323. return $url; 
  324.  
  325. /** 
  326. * Returns a list with all protected URLs. 
  327. * 
  328. * @since 1.0.0 
  329. * @param string $hash The URL-hash. 
  330. */ 
  331. public function get_protected_urls() { 
  332. static $Protected_Urls = null; 
  333.  
  334. if ( null === $Protected_Urls ) { 
  335. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  336. $Protected_Urls = $base_rule->rule_value; 
  337.  
  338. return $Protected_Urls; 
  339.  
  340. /** 
  341. * Returns a list with all accessible URLs. 
  342. * 
  343. * @since 1.0.0 
  344. * @param string $hash The URL-hash. 
  345. */ 
  346. public function get_accessible_urls() { 
  347. $accessible_Urls = $this->get_protected_urls(); 
  348. foreach ( $accessible_Urls as $key => $access ) { 
  349. if ( empty( $this->rule_value[$key] ) ) { 
  350. unset( $accessible_Urls[$key] ); 
  351.  
  352. return $accessible_Urls; 
.