/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 ( ! $this->has_rule_for_current_url() ) { return null; } 
  56.  
  57. if ( ! empty( $id ) ) { 
  58. $url = get_permalink( $id ); 
  59. } else { 
  60. $url = MS_Helper_Utility::get_current_url(); 
  61.  
  62. $exclude = apply_filters( 
  63. 'ms_rule_url_model_excluded_urls',  
  64. array() 
  65. ); 
  66.  
  67. // Check for exclude list. 
  68. if ( $this->check_url_expression_match( $url, $exclude ) ) { 
  69. $has_access = true; 
  70. } else { 
  71. // The URL is protected and has no exception. Deny it by default. 
  72. $has_access = false; 
  73.  
  74. // Check for URL group. 
  75. $accessible = $this->get_accessible_urls(); 
  76. if ( $this->check_url_expression_match( $url, $accessible ) ) { 
  77. if ( $this->get_membership()->is_base() ) { 
  78. // For guests all defined URL groups are denied. 
  79. $has_access = false; 
  80. } else { 
  81. $has_access = true; 
  82.  
  83. return apply_filters( 
  84. 'ms_rule_url_model_has_access',  
  85. $has_access,  
  86. $id,  
  87. $this 
  88. ); 
  89.  
  90. /** 
  91. * Verify if current url has protection rules. 
  92. * 
  93. * @since 1.0.0 
  94. * 
  95. * @return boolean True if has access, false otherwise. 
  96. */ 
  97. protected function has_rule_for_current_url() { 
  98. $has_rules = false; 
  99.  
  100. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_URL_GROUPS ) ) { 
  101. $url = MS_Helper_Utility::get_current_url(); 
  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. // Straight match. 
  150. $check_list = array_merge( 
  151. $check_list,  
  152. array_map( 'untrailingslashit', $check_list ) 
  153. ); 
  154.  
  155. $url = strtolower( $url ); 
  156. foreach ( $check_list as $check ) { 
  157. if ( $match ) { break; } 
  158.  
  159. if ( false !== strpos( $url, $check ) ) { 
  160. $match = true; 
  161.  
  162. return apply_filters( 
  163. 'ms_rule_url_model_check_url_expression_match',  
  164. $match,  
  165. $url,  
  166. $check_list,  
  167. $this 
  168. ); 
  169.  
  170. /** 
  171. * Count protection rules quantity. 
  172. * 
  173. * @since 1.0.0 
  174. * 
  175. * @param bool $has_access_only Optional. Count rules for has_access status only. 
  176. * @return int $count The rule count result. 
  177. */ 
  178. public function count_rules( $has_access_only = true ) { 
  179. $count = count( $this->rule_value ); 
  180.  
  181. return apply_filters( 
  182. 'ms_rule_url_model_count_rules',  
  183. $count,  
  184. $this 
  185. ); 
  186.  
  187. /** 
  188. * Get the total content count. 
  189. * Used in Dashboard to display how many special pages are protected. 
  190. * 
  191. * @since 1.0.0 
  192. * 
  193. * @param $args Ignored 
  194. * @return int The total content count. 
  195. */ 
  196. public function get_content_count( $args = null ) { 
  197. $count = count( $this->get_protected_urls() ); 
  198.  
  199. return apply_filters( 
  200. 'ms_rule_url_model_get_content_count',  
  201. $count,  
  202. $args 
  203. ); 
  204.  
  205. /** 
  206. * Get content to protect. 
  207. * 
  208. * @since 1.0.0 
  209. * @param $args The filter args 
  210. * 
  211. * @return array The contents array. 
  212. */ 
  213. public function get_contents( $args = null ) { 
  214. $protected_urls = $this->get_protected_urls(); 
  215. $membership_urls = $this->rule_value; 
  216.  
  217. $contents = array(); 
  218. foreach ( $membership_urls as $hash => $value ) { 
  219. if ( ! isset( $protected_urls[$hash] ) ) { 
  220. continue; 
  221.  
  222. $content = new StdClass(); 
  223. $content->id = $hash; 
  224. $content->type = MS_Rule_Url::RULE_ID; 
  225. $content->name = $protected_urls[$hash]; 
  226. $content->url = $protected_urls[$hash]; 
  227. $content->access = $this->get_rule_value( $content->id ); 
  228. $contents[] = $content; 
  229.  
  230. return apply_filters( 
  231. 'ms_rule_url_model_get_contents',  
  232. $contents 
  233. ); 
  234.  
  235. /** 
  236. * Set access status to content. 
  237. * 
  238. * @since 1.0.0 
  239. * @param string $id The content id to set access to. 
  240. * @param int $access The access status to set. 
  241. */ 
  242. public function set_access( $hash, $access ) { 
  243. if ( $this->is_base_rule ) { 
  244. /** 
  245. * Base rule cannot modify URL access via this function! 
  246. * Values of the base-rule are modified via a special Ajax handler 
  247. * that directly calls `add_url()` 
  248. * 
  249. * @see MS_Rule_Url::process_form() 
  250. */ 
  251. return; 
  252.  
  253. if ( empty( $access ) ) { 
  254. $this->delete_url( $hash ); 
  255. } else { 
  256. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  257. $url = $base_rule->get_url_from_hash( $hash ); 
  258. $this->add_url( $url ); 
  259.  
  260. do_action( 'ms_rule_url_set_access', $hash, $access, $this ); 
  261.  
  262. /** 
  263. * Serializes this rule in a single array. 
  264. * We don't use the PHP `serialize()` function to serialize the whole object 
  265. * because a lot of unrequired and duplicate data will be serialized 
  266. * 
  267. * @since 1.0.0 
  268. * @return array The serialized values of the Rule. 
  269. */ 
  270. public function serialize() { 
  271. $result = $this->rule_value; 
  272. return $result; 
  273.  
  274. /** 
  275. * Populates the rule_value array with the specified value list. 
  276. * This function is used when de-serializing a membership to re-create the 
  277. * rules associated with the membership. 
  278. * 
  279. * @since 1.0.0 
  280. * @param array $values A list of allowed IDs. 
  281. */ 
  282. public function populate( $values ) { 
  283. foreach ( $values as $hash => $url ) { 
  284. $this->add_url( $url ); 
  285.  
  286. /** 
  287. * Adds a new URL to the rule 
  288. * 
  289. * @since 1.0.0 
  290. * @param string $url 
  291. */ 
  292. public function add_url( $url ) { 
  293. $url = trim( $url ); 
  294.  
  295. // Index is a hash to prevent duplicate URLs in the list. 
  296. $hash = md5( $url ); 
  297. $this->rule_value[ $hash ] = $url; 
  298.  
  299. /** 
  300. * Removes an URL from the rule. 
  301. * 
  302. * An URL can be deleted either by specifying an Hash (prefered) or the 
  303. * plain-text URL. If a Hash value is specified the URL is always ignored. 
  304. * 
  305. * @since 1.0.0 
  306. * @param string $hash The URL-hash. 
  307. * @param string $url Optional. The plain-text URL. 
  308. */ 
  309. public function delete_url( $hash, $url = null ) { 
  310. if ( ! empty( $hash ) ) { 
  311. unset( $this->rule_value[ $hash ] ); 
  312. } elseif ( ! empty( $url ) ) { 
  313. $url = trim( $url ); 
  314. $hash = md5( $url ); 
  315. unset( $this->rule_value[ $hash ] ); 
  316.  
  317. /** 
  318. * Returns the URL from a specific hash value. 
  319. * 
  320. * @since 1.0.0 
  321. * @param string $hash The URL-hash. 
  322. */ 
  323. public function get_url_from_hash( $hash ) { 
  324. $url = ''; 
  325.  
  326. $urls = $this->get_protected_urls(); 
  327. if ( isset( $urls[ $hash ] ) ) { 
  328. $url = $urls[ $hash ]; 
  329.  
  330. return $url; 
  331.  
  332. /** 
  333. * Returns a list with all protected URLs. 
  334. * 
  335. * @since 1.0.0 
  336. * @param string $hash The URL-hash. 
  337. */ 
  338. public function get_protected_urls() { 
  339. static $Protected_Urls = null; 
  340.  
  341. if ( null === $Protected_Urls ) { 
  342. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type ); 
  343. $Protected_Urls = $base_rule->rule_value; 
  344.  
  345. return $Protected_Urls; 
  346.  
  347. /** 
  348. * Returns a list with all accessible URLs. 
  349. * 
  350. * @since 1.0.0 
  351. * @param string $hash The URL-hash. 
  352. */ 
  353. public function get_accessible_urls() { 
  354. $accessible_Urls = $this->get_protected_urls(); 
  355. foreach ( $accessible_Urls as $key => $access ) { 
  356. if ( empty( $this->rule_value[$key] ) ) { 
  357. unset( $accessible_Urls[$key] ); 
  358.  
  359. return $accessible_Urls; 
.