PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://gitlab.com/najomie/fit-hippie
PHP | 403 lines | 179 code | 53 blank | 171 comment | 18 complexity | 170c0687e0a7c8bd59b3982873d511ff MD5 | raw file
  1. <?php
  2. /**
  3. * Membership Comment Rule class.
  4. *
  5. * Persisted by Membership class.
  6. *
  7. * @since 1.0.0
  8. * @package Membership2
  9. * @subpackage Model
  10. */
  11. class MS_Rule_Content_Model extends MS_Rule {
  12. /**
  13. * Rule type.
  14. *
  15. * @since 1.0.0
  16. *
  17. * @var string $rule_type
  18. */
  19. protected $rule_type = MS_Rule_Content::RULE_ID;
  20. /**
  21. * Available special pages
  22. *
  23. * @since 1.0.0
  24. *
  25. * @var array
  26. */
  27. protected $_content = null;
  28. /**
  29. * Comment content ID.
  30. *
  31. * @since 1.0.0
  32. *
  33. * @var string $content_id
  34. */
  35. const CONTENT_ID = 'content';
  36. /**
  37. * Rule value constants.
  38. *
  39. * @since 1.0.0
  40. *
  41. * @var int
  42. */
  43. const COMMENT_NO_ACCESS = 'cmt_none';
  44. const COMMENT_READ = 'cmt_read';
  45. const COMMENT_WRITE = 'cmt_full';
  46. const MORE_LIMIT = 'no_more';
  47. /**
  48. * Flag of the final comment access level.
  49. * When an user is member of multiple memberships with different
  50. * comment-access-restrictions then the MOST GENEROUS access will be granted.
  51. *
  52. * @since 1.0.0
  53. *
  54. * @var string
  55. */
  56. protected static $comment_access = self::COMMENT_NO_ACCESS;
  57. /**
  58. * Set to true, if the user did not specify any comment protection.
  59. * This means that the default logic should be used...
  60. *
  61. * @since 1.0.0
  62. *
  63. * @var bool
  64. */
  65. protected static $comment_public = null;
  66. /**
  67. * The message displayed below the "read more" mark.
  68. *
  69. * @since 1.0.0
  70. *
  71. * @var string
  72. */
  73. protected $protection_message = '';
  74. /**
  75. * Verify access to the current content.
  76. *
  77. * This rule will return NULL (not relevant), because the comments are
  78. * protected via WordPress hooks instead of protecting the whole page.
  79. *
  80. * @since 1.0.0
  81. *
  82. * @param string $id The content id to verify access.
  83. * @return bool|null True if has access, false otherwise.
  84. * Null means: Rule not relevant for current page.
  85. */
  86. public function has_access( $id, $admin_has_access = true ) {
  87. return null;
  88. }
  89. /**
  90. * Set initial protection.
  91. *
  92. * @since 1.0.0
  93. */
  94. public function protect_content() {
  95. parent::protect_content();
  96. // ********* COMMENTS **********
  97. // No comments on special pages (signup, account, ...)
  98. $this->add_filter( 'the_content', 'check_special_page' );
  99. /*
  100. * We find the public comment access once.
  101. * This is the access ganted to guests or memberships that do not define
  102. * an explicit comment access rule.
  103. */
  104. if ( null === self::$comment_public ) {
  105. $base_rule = MS_Model_Membership::get_base()->get_rule( $this->rule_type );
  106. if ( null === $base_rule->get_rule_value( self::COMMENT_WRITE ) ) {
  107. self::$comment_public = self::COMMENT_WRITE;
  108. } elseif ( null === $base_rule->get_rule_value( self::COMMENT_READ ) ) {
  109. self::$comment_public = self::COMMENT_READ;
  110. } else {
  111. self::$comment_public = self::COMMENT_NO_ACCESS;
  112. }
  113. }
  114. // Find the most generous comment access rule.
  115. $has_full = $this->get_rule_value( self::COMMENT_WRITE );
  116. $has_read = $this->get_rule_value( self::COMMENT_READ );
  117. $has_none = $this->get_rule_value( self::COMMENT_NO_ACCESS );
  118. if ( true === $has_full ) {
  119. // Membership allows full comment access.
  120. self::$comment_access = self::COMMENT_WRITE;
  121. } elseif ( true === $has_read ) {
  122. // Membership allows read-only access.
  123. if ( self::$comment_access == self::COMMENT_NO_ACCESS ) {
  124. self::$comment_access = self::COMMENT_READ;
  125. }
  126. } elseif ( true === $has_none ) {
  127. // Membership does not allow any comment access.
  128. // (no change, this is the default access level)
  129. } else {
  130. // This membership does not define a comment access: Use public access!
  131. self::$comment_access = self::$comment_public;
  132. }
  133. $this->add_action(
  134. 'ms_setup_protection_done',
  135. 'protect_comments'
  136. );
  137. // ********** READ MORE **********
  138. if( defined( 'MS_PROTECTED_MESSAGE_REVERSE_RULE' ) && MS_PROTECTED_MESSAGE_REVERSE_RULE ) {
  139. $rule = MS_Factory::load( 'MS_Rule_Content_Model' );
  140. $allowed_memberships = $rule->get_memberships( self::MORE_LIMIT );
  141. if( ! is_array( $allowed_memberships ) ) $allowed_memberships = array();
  142. $sorted_membership = array();
  143. foreach( $allowed_memberships as $allowed_membership_id => $allowed_membership_name ) {
  144. $m_obj = MS_Factory::load( 'MS_Model_Membership', $allowed_membership_id );
  145. $key = $m_obj->priority;
  146. while( array_key_exists( $key, $sorted_membership ) ) {
  147. $key++;
  148. }
  149. $sorted_membership[$key] = $allowed_membership_id;
  150. }
  151. $protected_membership_id = reset( $sorted_membership );
  152. }else{
  153. $protected_membership_id = $this->membership_id;
  154. }
  155. $this->protection_message = MS_Plugin::instance()->settings->get_protection_message(
  156. MS_Model_Settings::PROTECTION_MSG_MORE_TAG,
  157. //$this->membership_id
  158. $protected_membership_id
  159. );
  160. if ( ! parent::has_access( self::MORE_LIMIT ) ) {
  161. $this->add_filter( 'the_content_more_link', 'show_moretag_protection', 99, 2 );
  162. $this->add_filter( 'the_content', 'replace_more_tag_content', 1 );
  163. $this->add_filter( 'the_content_feed', 'replace_more_tag_content', 1 );
  164. }
  165. }
  166. // ********* COMMENTS **********
  167. /**
  168. * Setup the comment permissions after all membership rules were parsed.
  169. *
  170. * @since 1.0.0
  171. */
  172. public function protect_comments() {
  173. static $Done = false;
  174. if ( $Done ) { return; }
  175. $Done = true;
  176. switch ( self::$comment_access ) {
  177. case self::COMMENT_WRITE:
  178. // Don't change the inherent comment status.
  179. break;
  180. case self::COMMENT_READ:
  181. $this->add_filter( 'comment_form_before', 'hide_form_start', 1 );
  182. $this->add_filter( 'comment_form_after', 'hide_form_end', 99 );
  183. add_filter( 'comment_reply_link', '__return_null', 99 );
  184. break;
  185. case self::COMMENT_NO_ACCESS:
  186. add_filter( 'comments_open', '__return_false', 99 );
  187. add_filter( 'get_comments_number', '__return_zero', 99 );
  188. break;
  189. }
  190. }
  191. /**
  192. * Before the comment form is output we start buffering.
  193. *
  194. * @since 1.0.0
  195. */
  196. public function hide_form_start() {
  197. ob_start();
  198. }
  199. /**
  200. * At the end of the comment form we clear the buffer: The form is gone!
  201. *
  202. * @since 1.0.0
  203. */
  204. public function hide_form_end() {
  205. ob_end_clean();
  206. }
  207. /**
  208. * Close comments for membership special pages.
  209. *
  210. * Related Action Hooks:
  211. * - the_content
  212. *
  213. * @since 1.0.0
  214. *
  215. * @param string $content The content to filter.
  216. */
  217. public function check_special_page( $content ) {
  218. if ( MS_Model_Pages::is_membership_page() ) {
  219. add_filter( 'comments_open', '__return_false', 100 );
  220. }
  221. return apply_filters(
  222. 'ms_rule_content_model_check_special_page',
  223. $content,
  224. $this
  225. );
  226. }
  227. // ********** READ MORE **********
  228. /**
  229. * Show more tag protection message.
  230. *
  231. * Related Action Hooks:
  232. * - the_content_more_link
  233. *
  234. * @since 1.0.0
  235. *
  236. * @param string $more_tag_link the more tag link before filter.
  237. * @param string $more_tag The more tag content before filter.
  238. * @return string The protection message.
  239. */
  240. public function show_moretag_protection( $more_tag_link, $more_tag ) {
  241. $msg = stripslashes( $this->protection_message );
  242. return apply_filters(
  243. 'ms_rule_more_model_show_moretag_protection',
  244. $msg,
  245. $more_tag_link,
  246. $more_tag,
  247. $this
  248. );
  249. }
  250. /**
  251. * Replace more tag
  252. *
  253. * Related Action Hooks:
  254. * - the_content
  255. * - the_content_feed
  256. *
  257. * @since 1.0.0
  258. *
  259. * @param string $the_content The post content before filter.
  260. * @return string The content replaced by more tag content.
  261. */
  262. public function replace_more_tag_content( $the_content ) {
  263. $more_starts_at = strpos( $the_content, '<span id="more-' );
  264. if ( false !== $more_starts_at ) {
  265. $the_content = substr( $the_content, 0, $more_starts_at );
  266. $the_content .= stripslashes( $this->protection_message );
  267. }
  268. return apply_filters(
  269. 'ms_rule_more_model_replace_more_tag_content',
  270. $the_content,
  271. $this
  272. );
  273. }
  274. // ********** ADMIN FUNCTIONS **********
  275. /**
  276. * Returns a list of special pages that can be configured by this rule.
  277. *
  278. * @since 1.0.0
  279. *
  280. * @param bool $flat If set to true then all pages are in the same
  281. * hierarchy (no sub-arrays).
  282. * @return array List of special pages.
  283. */
  284. protected function get_rule_items() {
  285. if ( ! is_array( $this->_content ) ) {
  286. $this->_content = array();
  287. $this->_content[self::COMMENT_NO_ACCESS] = (object) array(
  288. 'label' => __( 'Comments: No Access', 'membership2' ),
  289. );
  290. $this->_content[self::COMMENT_READ] = (object) array(
  291. 'label' => __( 'Comments: Read Only Access', 'membership2' ),
  292. );
  293. $this->_content[self::COMMENT_WRITE] = (object) array(
  294. 'label' => __( 'Comments: Read and Write Access', 'membership2' ),
  295. );
  296. $this->_content[self::MORE_LIMIT] = (object) array(
  297. 'label' => __( 'Hide "read more" content', 'membership2' ),
  298. );
  299. }
  300. return $this->_content;
  301. }
  302. /**
  303. * Count protection rules quantity.
  304. *
  305. * @since 1.0.0
  306. *
  307. * @return int $count The rule count result.
  308. */
  309. public function count_rules( $args = null ) {
  310. $count = count( $this->get_contents( $args ) );
  311. return apply_filters(
  312. 'ms_rule_content_model_count_rules',
  313. $count,
  314. $this
  315. );
  316. }
  317. /**
  318. * Get content to protect.
  319. *
  320. * @since 1.0.0
  321. *
  322. * @param $args Optional. Not used.
  323. * @return array The content.
  324. */
  325. public function get_contents( $args = null ) {
  326. $items = $this->get_rule_items();
  327. $contents = array();
  328. foreach ( $items as $key => $data ) {
  329. $content = (object) array();
  330. // Search the special page name...
  331. if ( ! empty( $args['s'] ) ) {
  332. if ( false === stripos( $data->label, $args['s'] ) ) {
  333. continue;
  334. }
  335. }
  336. $content->id = $key;
  337. $content->type = MS_Rule_Content::RULE_ID;
  338. $content->name = $data->label;
  339. $content->post_title = $data->label;
  340. $content->access = $this->get_rule_value( $content->id );
  341. $contents[ $content->id ] = $content;
  342. }
  343. return apply_filters(
  344. 'ms_rule_content_model_get_content',
  345. $contents,
  346. $args,
  347. $this
  348. );
  349. }
  350. }