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

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