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

  1. <?php 
  2. /** 
  3. * Membership Special Pages 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_Special_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_Special::RULE_ID; 
  22.  
  23. /** 
  24. * Available special pages 
  25. * 
  26. * @since 1.0.0 
  27. * 
  28. * @var array 
  29. */ 
  30. protected $_content = null; 
  31.  
  32. /** 
  33. * Analysis information on which page type was detected. 
  34. * 
  35. * @since 1.0.0 
  36. * 
  37. * @var string 
  38. */ 
  39. public $_matched_type = ''; 
  40.  
  41. /** 
  42. * Cache the result of is_special_page 
  43. * 
  44. * @since 1.0.0 
  45. * 
  46. * @var bool 
  47. */ 
  48. public $_is_special = null; 
  49.  
  50. /** 
  51. * Cache the result of has_rule_for_current_page 
  52. * 
  53. * @since 1.0.0 
  54. * 
  55. * @var bool 
  56. */ 
  57. public $_has_rule = null; 
  58.  
  59. /** 
  60. * Returns the active flag for a specific rule. 
  61. * State depends on Add-on 
  62. * 
  63. * @since 1.0.0 
  64. * @return bool 
  65. */ 
  66. static public function is_active() { 
  67. return MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_SPECIAL_PAGES ); 
  68.  
  69. /** 
  70. * Checks if the current page is a special page that can be handled by this 
  71. * rule 
  72. * 
  73. * @since 1.0.0 
  74. * 
  75. * @return bool 
  76. */ 
  77. static public function is_special_page() { 
  78. if ( null === $this->_is_special ) { 
  79. $this->_is_special = is_home() 
  80. || is_front_page() 
  81. || is_404() 
  82. || is_search() 
  83. || is_archive() 
  84. || is_author() 
  85. || is_date() 
  86. || is_time(); 
  87.  
  88. return $this->_is_special; 
  89.  
  90. /** 
  91. * Verify access to the current page. 
  92. * 
  93. * @since 1.0.0 
  94. * 
  95. * @param int $id The page_id to verify access. 
  96. * @return bool|null True if has access, false otherwise. 
  97. * Null means: Rule not relevant for current page. 
  98. */ 
  99. public function has_access( $id, $admin_has_access = true ) { 
  100. $has_access = null; 
  101.  
  102. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_SPECIAL_PAGES ) ) { 
  103. if ( $this->has_rule_for_current_page() ) { 
  104. $has_access = false; 
  105.  
  106. if ( $this->check_current_page( $this->rule_value ) ) { 
  107. if ( ! $this->get_membership()->is_base() ) { 
  108. $has_access = true; 
  109.  
  110. return apply_filters( 
  111. 'ms_rule_special_model_has_access',  
  112. $has_access,  
  113. $id,  
  114. $this 
  115. ); 
  116.  
  117. /** 
  118. * Checks if the current page is a special page and if the special page is 
  119. * protected by this rule. 
  120. * 
  121. * @since 1.0.0 
  122. * 
  123. * @return bool 
  124. */ 
  125. public function has_rule_for_current_page() { 
  126. if ( null === $this->_has_rule ) { 
  127. if ( ! MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_SPECIAL_PAGES ) ) { 
  128. $this->_has_rule = false; 
  129. } else { 
  130. $base = $this->get_membership()->get_base(); 
  131. $base_rule = $base->get_rule( $this->rule_type ); 
  132. $this->_has_rule = $this->check_current_page( $base_rule->rule_value ); 
  133.  
  134. return $this->_has_rule; 
  135.  
  136. /** 
  137. * Checks if the current page can be accessed by the specified rules 
  138. * 
  139. * @since 1.0.0 
  140. * 
  141. * @param array $rules List of allowed pages. 
  142. * @return bool 
  143. */ 
  144. protected function check_current_page( $rules ) { 
  145. $result = false; 
  146.  
  147. foreach ( $rules as $key => $active ) { 
  148. if ( ! $active ) { continue; } 
  149.  
  150. /** 
  151. * The item order is critical, in case a page has multiple flags 
  152. * like "Front" and "Home" and "Archive". 
  153. * In this example "Archive" might be denied but "Front" allowed,  
  154. * so we have to define a hierarchy which flag is actually used. 
  155. */ 
  156. switch ( $key ) { 
  157. case 'front': $result = is_front_page(); break; 
  158. case 'home': $result = is_home(); break; 
  159. case 'notfound': $result = is_404(); break; 
  160. case 'search': $result = is_search(); break; 
  161. case 'attachment': $result = is_attachment(); break; 
  162. case 'single': $result = is_singular(); break; 
  163. case 'archive': $result = is_archive(); break; 
  164. case 'author': $result = is_author(); break; 
  165. case 'date': $result = is_date(); break; 
  166. case 'year': $result = is_year(); break; 
  167. case 'month': $result = is_month(); break; 
  168. case 'day': $result = is_day(); break; 
  169. case 'time': $result = is_time(); break; 
  170.  
  171. if ( $result ) { 
  172. $this->matched_type = $key; 
  173. break; 
  174.  
  175. return apply_filters( 
  176. 'ms_rule_special_model_check_current_page',  
  177. $result,  
  178. $rules 
  179. ); 
  180.  
  181. /** 
  182. * Returns a list of special pages that can be configured by this rule. 
  183. * 
  184. * @since 1.0.0 
  185. * 
  186. * @return array List of special pages. 
  187. */ 
  188. protected function get_special_pages() { 
  189. if ( ! is_array( $this->_content ) ) { 
  190. $this->_content = array(); 
  191. $front_type = get_option( 'show_on_front' ); 
  192.  
  193. $front_url = MS_Helper_Utility::home_url( '/' ); 
  194. if ( 'page' === $front_type ) { 
  195. $home_url = get_permalink( get_option( 'page_for_posts' ) ); 
  196. } else { 
  197. $home_url = $front_url; 
  198.  
  199. $arch_year = get_year_link( '' ); 
  200. $arch_month = get_month_link( '', '' ); 
  201. $arch_day = get_day_link( '', '', '' ); 
  202. $arch_hour = esc_url_raw( 
  203. add_query_arg( 'hour', '15', $arch_day ) 
  204. ); 
  205.  
  206. // Archive pages 
  207. $this->_content['archive'] = (object) array( 
  208. 'label' => __( 'Any Archive page', 'membership2' ),  
  209. 'url' => '',  
  210. ); 
  211. $this->_content['author'] = (object) array( 
  212. 'label' => __( 'Author Archives', 'membership2' ),  
  213. 'url' => '',  
  214. ); 
  215. $this->_content['date'] = (object) array( 
  216. 'label' => __( 'Any Date or Time Archive', 'membership2' ),  
  217. 'url' => '',  
  218. ); 
  219. $this->_content['year'] = (object) array( 
  220. 'label' => __( 'Archive: Year', 'membership2' ),  
  221. 'url' => $arch_year,  
  222. ); 
  223. $this->_content['month'] = (object) array( 
  224. 'label' => __( 'Archive: Month', 'membership2' ),  
  225. 'url' => $arch_month,  
  226. ); 
  227. $this->_content['day'] = (object) array( 
  228. 'label' => __( 'Archive: Day', 'membership2' ),  
  229. 'url' => $arch_day,  
  230. ); 
  231. $this->_content['time'] = (object) array( 
  232. 'label' => __( 'Archive: Time', 'membership2' ),  
  233. 'url' => $arch_hour,  
  234. ); 
  235.  
  236. // Singular pages 
  237. $this->_content['front'] = (object) array( 
  238. 'label' => __( 'Front Page', 'membership2' ),  
  239. 'url' => $front_url,  
  240. ); 
  241. $this->_content['home'] = (object) array( 
  242. 'label' => __( 'Blog Index', 'membership2' ),  
  243. 'url' => $home_url,  
  244. ); 
  245. $this->_content['notfound'] = (object) array( 
  246. 'label' => __( '404 Not Found', 'membership2' ),  
  247. 'url' => '',  
  248. ); 
  249. $this->_content['search'] = (object) array( 
  250. 'label' => __( 'Search Results', 'membership2' ),  
  251. 'url' => '',  
  252. ); 
  253. $this->_content['single'] = (object) array( 
  254. 'label' => __( 'Any single page or post', 'membership2' ),  
  255. 'url' => '',  
  256. ); 
  257. $this->_content['attachment'] = (object) array( 
  258. 'label' => __( 'Any attachment page', 'membership2' ),  
  259. 'url' => '',  
  260. ); 
  261.  
  262. return $this->_content; 
  263.  
  264. /** 
  265. * Get the total content count. 
  266. * Used in Dashboard to display how many special pages are protected. 
  267. * 
  268. * @since 1.0.0 
  269. * 
  270. * @param $args The query post args 
  271. * @see @link http://codex.wordpress.org/Class_Reference/WP_Query 
  272. * @return int The total content count. 
  273. */ 
  274. public function get_content_count( $args = null ) { 
  275. $args['posts_per_page'] = 0; 
  276. $args['offset'] = false; 
  277. $count = count( $this->get_contents( $args ) ); 
  278.  
  279. return apply_filters( 
  280. 'ms_rule_special_model_get_content_count',  
  281. $count,  
  282. $args 
  283. ); 
  284.  
  285. /** 
  286. * Get content to protect. 
  287. * Used in Dashboard to display a list of special pages. 
  288. * 
  289. * @since 1.0.0 
  290. * 
  291. * @param $args The query post args 
  292. * @see @link http://codex.wordpress.org/Class_Reference/WP_Query 
  293. * @return array The contents array. 
  294. */ 
  295. public function get_contents( $args = null ) { 
  296. $special_pages = $this->get_special_pages(); 
  297. $contents = array(); 
  298.  
  299. $filter = $this->get_exclude_include( $args ); 
  300. if ( is_array( $filter->include ) ) { 
  301. $special_pages = array_intersect_key( $special_pages, array_flip( $filter->include ) ); 
  302. } elseif ( is_array( $filter->exclude ) ) { 
  303. $special_pages = array_diff_key( $special_pages, array_flip( $filter->exclude ) ); 
  304.  
  305. foreach ( $special_pages as $id => $data ) { 
  306. $content = (object) array(); 
  307.  
  308. // Search the special page name... 
  309. if ( ! empty( $args['s'] ) ) { 
  310. if ( false === stripos( $data->label, $args['s'] ) ) { 
  311. continue; 
  312.  
  313. $content->id = $id; 
  314. $content->type = MS_Rule_Special::RULE_ID; 
  315. $content->name = $data->label; 
  316. $content->post_title = $data->label; 
  317. $content->url = $data->url; 
  318. $content->access = $this->get_rule_value( $content->id ); 
  319.  
  320. $contents[ $content->id ] = $content; 
  321.  
  322. // If not visitor membership, just show Membership2 
  323. if ( ! $this->is_base_rule ) { 
  324. $contents = array_intersect_key( $contents, $this->rule_value ); 
  325.  
  326. if ( ! empty( $args['rule_status'] ) ) { 
  327. $contents = $this->filter_content( $args['rule_status'], $contents ); 
  328.  
  329. if ( ! empty( $args['posts_per_page'] ) ) { 
  330. $total = $args['posts_per_page']; 
  331. $offset = ! empty( $args['offset'] ) ? $args['offset'] : 0; 
  332. $contents = array_slice( $contents, $offset, $total ); 
  333.  
  334. return apply_filters( 
  335. 'ms_rule_special_model_get_contents',  
  336. $contents,  
  337. $this 
  338. ); 
  339.  
.