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

  1. <?php 
  2. /** 
  3. * Membership Shortcode 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_Shortcode_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_Shortcode::RULE_ID; 
  22.  
  23. /** 
  24. * Holds the membership-IDs of all memberships of the user. 
  25. * 
  26. * @since 1.0.0 
  27. * 
  28. * @var array 
  29. */ 
  30. static protected $membership_ids = array(); 
  31.  
  32. /** 
  33. * Protect content shortcode. 
  34. * 
  35. * @since 1.0.0 
  36. * 
  37. * @var string 
  38. */ 
  39. const PROTECT_CONTENT_SHORTCODE = 'ms-protect-content'; 
  40.  
  41. /** 
  42. * Returns the active flag for a specific rule. 
  43. * State depends on Add-on 
  44. * 
  45. * @since 1.0.0 
  46. * @return bool 
  47. */ 
  48. static public function is_active() { 
  49. return MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_SHORTCODE ); 
  50.  
  51. /** 
  52. * Verify access to the current content. 
  53. * 
  54. * This rule will return NULL (not relevant), because shortcodes are 
  55. * replaced inside the page content instead of protecting the whole page. 
  56. * 
  57. * @since 1.0.0 
  58. * 
  59. * @param string $id The content id to verify access. 
  60. * @return bool|null True if has access, false otherwise. 
  61. * Null means: Rule not relevant for current page. 
  62. */ 
  63. public function has_access( $id, $admin_has_access = true ) { 
  64. return null; 
  65.  
  66. /** 
  67. * Set initial protection. 
  68. * 
  69. * Add [ms-protect-content] shortcode to protect membership content inside post. 
  70. * 
  71. * @since 1.0.0 
  72. */ 
  73. public function protect_content() { 
  74. parent::protect_content(); 
  75.  
  76. self::$membership_ids[] = $this->membership_id; 
  77.  
  78. add_shortcode( 
  79. self::PROTECT_CONTENT_SHORTCODE,  
  80. array( __CLASS__, 'protect_content_shortcode' ) 
  81. ); 
  82.  
  83. if ( MS_Model_Addon::is_enabled( MS_Model_Addon::ADDON_SHORTCODE ) ) { 
  84. global $shortcode_tags; 
  85. $exclude = MS_Helper_Shortcode::get_membership_shortcodes(); 
  86.  
  87. foreach ( $shortcode_tags as $shortcode => $callback_funciton ) { 
  88. if ( in_array( $shortcode, $exclude ) ) { 
  89. continue; 
  90. if ( ! parent::has_access( $shortcode ) ) { 
  91. $shortcode_tags[ $shortcode ] = array( 
  92. &$this,  
  93. 'do_protected_shortcode',  
  94. ); 
  95.  
  96. /** 
  97. * Allow using the [ms-protect-content] shortcode on admin-side. 
  98. * 
  99. * @since 1.0.2.4 
  100. */ 
  101. public function protect_admin_content() { 
  102. $this->protect_content(); 
  103.  
  104. /** 
  105. * Do protected shortcode [do_protected_shortcode]. 
  106. * 
  107. * This shortcode is executed to replace a protected shortcode. 
  108. * 
  109. * @since 1.0.0 
  110. */ 
  111. public function do_protected_shortcode() { 
  112. $content = null; 
  113. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  114. $msg = $settings->get_protection_message( 
  115. MS_Model_Settings::PROTECTION_MSG_SHORTCODE,  
  116. $this->membership_id 
  117. ); 
  118.  
  119. if ( $msg ) { 
  120. $content = $msg; 
  121. } else { 
  122. $content = __( 'Shortcode content protected.', 'membership2' ); 
  123.  
  124. return apply_filters( 
  125. 'ms_model_shortcode_do_protected_shortcode_content',  
  126. $content,  
  127. $this 
  128. ); 
  129.  
  130. /** 
  131. * Do membership content protection shortcode. 
  132. * 
  133. * self::PROTECT_CONTENT_SHORTCODE 
  134. * 
  135. * Verify if content is protected comparing to self::$membership_ids. 
  136. * 
  137. * @since 1.0.0 
  138. * 
  139. * @param array $atts The shortcode attributes. 
  140. * @param string $content The content inside the shortcode. 
  141. * @param string $code The shortcode code. 
  142. * @return string The shortcode output 
  143. */ 
  144. static public function protect_content_shortcode( $atts, $content = null, $code = '' ) { 
  145. $atts = apply_filters( 
  146. 'ms_model_shortcode_protect_content_shortcode_atts',  
  147. shortcode_atts( 
  148. array( 
  149. 'id' => '',  
  150. 'access' => true,  
  151. 'silent' => false,  
  152. 'msg' => false,  
  153. ),  
  154. $atts 
  155. ); 
  156. extract( $atts ); 
  157.  
  158. $membership_ids = explode( ', ', $id ); 
  159.  
  160. if ( $silent ) { 
  161. $msg = ''; 
  162. } else { 
  163. if ( ! is_string( $msg ) || ! strlen( $msg ) ) { 
  164. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  165. // TO-DO: Need to think about logic here. Tracking ID: 70522969408012/53509795076060 
  166. if( defined( 'MS_PROTECTED_MESSAGE_REVERSE_RULE' ) && MS_PROTECTED_MESSAGE_REVERSE_RULE ) { 
  167. $membership_id = $atts['id']; 
  168. }else{ 
  169. $membership_id = apply_filters( 'ms_detect_membership_id', 0 ); 
  170.  
  171. $msg = $settings->get_protection_message( 
  172. MS_Model_Settings::PROTECTION_MSG_SHORTCODE,  
  173. $membership_id 
  174. ); 
  175.  
  176. $access = lib3()->is_true( $access ); 
  177.  
  178. if ( ! $access ) { 
  179. // No access to member of membership_ids 
  180.  
  181. if ( self::is_member_of( $membership_ids ) ) { 
  182. // User belongs to these memberships and therefore cannot see 
  183. // this content... 
  184.  
  185. if ( $silent ) { 
  186. // Silent protection: Do not show a message, simply hide it 
  187. $content = ''; 
  188. } else { 
  189. $content = '<div class="ms-protection-msg">'; 
  190. if ( ! empty( $msg ) ) { 
  191. $content .= $msg; 
  192. } else { 
  193. $membership_names = MS_Model_Membership::get_membership_names( 
  194. array( 'post__in' => $membership_ids ) 
  195. ); 
  196. $content .= __( 'No access to members of: ', 'membership2' ); 
  197. $content .= implode( ', ', $membership_names ); 
  198. $content .= '</div>'; 
  199. } else { 
  200. // Give access to member of membership_ids 
  201.  
  202. if ( ! self::is_member_of( $membership_ids ) ) { 
  203. // User does not belong to these memberships and therefore 
  204. // cannot see this content... 
  205.  
  206. if ( $silent ) { 
  207. // Silent protection: Do not show a message, simply hide it 
  208. $content = ''; 
  209. } else { 
  210. $content = '<div class="ms-protection-msg">'; 
  211. if ( ! empty( $msg ) ) { 
  212. $content .= $msg; 
  213. } else { 
  214. $membership_names = MS_Model_Membership::get_membership_names( 
  215. array( 'post__in' => $membership_ids ) 
  216. ); 
  217. $content .= __( 'Content protected to members of: ', 'membership2' ); 
  218. $content .= implode( ', ', $membership_names ); 
  219. $content .= '</div>'; 
  220.  
  221. return apply_filters( 
  222. 'ms_rule_shortcode_model_protect_content_shortcode_content',  
  223. do_shortcode( $content ),  
  224. $atts,  
  225. $content,  
  226. $code 
  227. ); 
  228.  
  229. /** 
  230. * For Admin-Users only: 
  231. * The [ms-protected-content] shortcode is replaced with some debug values 
  232. * for better understanding of the page structure. 
  233. * 
  234. * @since 1.0.0 
  235. * @param array $atts The shortcode attributes. 
  236. * @param string $content The content inside the shortcode. 
  237. * @return string The shortcode output 
  238. */ 
  239. public function debug_protect_content_shortcode( $atts, $content = '' ) { 
  240. $do_debug = true; 
  241.  
  242. /** 
  243. * This wp-config setting defines the default state of the shortcode 
  244. * debugging flag. 
  245. */ 
  246. if ( defined( 'MS_NO_SHORTCODE_PREVIEW' ) && MS_NO_SHORTCODE_PREVIEW ) { 
  247. $do_debug = false; 
  248.  
  249. /** 
  250. * Use this filter to disable the protected-content debugging 
  251. * information for admin users. 
  252. * The content will always be displayed for admin users. 
  253. */ 
  254. $do_debug = apply_filters( 
  255. 'ms_model_shortcode_debug_protected_content',  
  256. $do_debug,  
  257. $atts,  
  258. $content 
  259. ); 
  260.  
  261. $content = do_shortcode( $content ); 
  262.  
  263. if ( ! $do_debug ) { 
  264. return $content; 
  265.  
  266. $atts = apply_filters( 
  267. 'ms_model_shortcode_protect_content_shortcode_atts',  
  268. shortcode_atts( 
  269. array( 
  270. 'id' => '',  
  271. 'access' => true,  
  272. 'silent' => false,  
  273. 'msg' => false,  
  274. ),  
  275. $atts 
  276. ); 
  277. extract( $atts ); 
  278.  
  279. if ( lib3()->is_true( $access ) ) { 
  280. $msg_access = __( 'Visible for members of', 'membership2' ); 
  281. $alt_msg1 = __( 'Other users will see', 'membership2' ); 
  282. $alt_msg2 = __( 'Other uses will see nothing', 'membership2' ); 
  283. } else { 
  284. $msg_access = __( 'Hidden from members of', 'membership2' ); 
  285. $alt_msg1 = __( 'Those users will see', 'membership2' ); 
  286. $alt_msg2 = __( 'Those uses will see nothing', 'membership2' ); 
  287.  
  288. if ( $msg ) { 
  289. $msg_alt = sprintf( '%s: %s', $alt_msg1, $msg ); 
  290. } else { 
  291. $msg_alt = $alt_msg2; 
  292.  
  293. $membership_ids = explode( ', ', $id ); 
  294. $memberships = array(); 
  295. foreach ( $membership_ids as $membership_id ) { 
  296. $membership = MS_Factory::load( 'MS_Model_Membership', $membership_id ); 
  297. $memberships[] = $membership->get_name_tag(); 
  298.  
  299. $css = '<style> 
  300. .ms-membership { 
  301. display: inline-block; 
  302. border-radius: 3px; 
  303. color: #FFF; 
  304. background: #888888; 
  305. padding: 1px 5px; 
  306. font-size: 12px; 
  307. height: 20px; 
  308. line-height: 20px; 
  309. .ms-protected-info { 
  310. border: 1px solid rgba(0, 0, 0, 0.07); 
  311. .ms-protected-info:hover { 
  312. border: 1px solid rgba(0, 0, 0, 0.3); 
  313. .ms-protected-info .ms-details,  
  314. .ms-protected-info .ms-alternate-msg { 
  315. background: #EEE; 
  316. padding: 4px; 
  317. font-size: 12px; 
  318. color: #666; 
  319. opacity: 0.25; 
  320. .ms-protected-info:hover .ms-details,  
  321. .ms-protected-info:hover .ms-alternate-msg { 
  322. opacity: 1; 
  323. .ms-protected-info .ms-contents { 
  324. padding: 4px 8px; 
  325. </style>'; 
  326.  
  327. $code = sprintf( 
  328. '<div class="ms-protected-info" title="%5$s"><div class="ms-details">%3$s: %4$s</div><div class="ms-contents">%1$s</div><div class="ms-alternate-msg">%2$s</div></div>',  
  329. $content,  
  330. $msg_alt,  
  331. $msg_access,  
  332. implode( ' ', $memberships ),  
  333. __( 'This information is only displayed for admin users', 'membership2' ) 
  334. ); 
  335.  
  336. return $css . $code; 
  337.  
  338. /** 
  339. * Returns true when the current user is a member of one of the specified 
  340. * memberships. 
  341. * 
  342. * @since 1.0.0 
  343. * 
  344. * @return bool 
  345. */ 
  346. static protected function is_member_of( $ids ) { 
  347. $result = false; 
  348.  
  349. if ( empty( $ids ) ) { 
  350. $result = true; 
  351. } else { 
  352. if ( ! is_array( $ids ) ) { 
  353. $ids = array( $ids ); 
  354.  
  355. foreach ( self::$membership_ids as $the_id ) { 
  356. if ( in_array( $the_id, $ids ) ) { 
  357. $result = true; 
  358. break; 
  359.  
  360. return $result; 
  361.  
  362. /** 
  363. * Get the total content count. 
  364. * 
  365. * @since 1.0.0 
  366. * 
  367. * @param $args The query post args. Not used. 
  368. * @return int The total content count. 
  369. */ 
  370. public function get_content_count( $args = null ) { 
  371. $args['posts_per_page'] = 0; 
  372. $args['offset'] = false; 
  373. $items = $this->get_contents( $args ); 
  374. $count = count( $items ); 
  375.  
  376. return apply_filters( 
  377. 'ms_rule_shortcode_model_get_content_count',  
  378. $count,  
  379. $this 
  380. ); 
  381.  
  382. /** 
  383. * Get content to protect. 
  384. * 
  385. * @since 1.0.0 
  386. * @param $args The filter args 
  387. * 
  388. * @return array The contents array. 
  389. */ 
  390. public function get_contents( $args = null ) { 
  391. global $shortcode_tags; 
  392.  
  393. $exclude = MS_Helper_Shortcode::get_membership_shortcodes(); 
  394. $contents = array(); 
  395.  
  396. foreach ( $shortcode_tags as $key => $function ) { 
  397. if ( in_array( $key, $exclude ) ) { 
  398. continue; 
  399.  
  400. // Search the shortcode-tag... 
  401. if ( ! empty( $args['s'] ) ) { 
  402. if ( false === stripos( $key, $args['s'] ) ) { 
  403. continue; 
  404.  
  405. $contents[ $key ] = new StdClass(); 
  406. $contents[ $key ]->id = $key; 
  407. $contents[ $key ]->name = "[$key]"; 
  408. $contents[ $key ]->type = MS_Rule_Shortcode::RULE_ID; 
  409. $contents[ $key ]->access = $this->get_rule_value( $key ); 
  410.  
  411. $filter = $this->get_exclude_include( $args ); 
  412. if ( is_array( $filter->include ) ) { 
  413. $contents = array_intersect_key( $contents, array_flip( $filter->include ) ); 
  414. } elseif ( is_array( $filter->exclude ) ) { 
  415. $contents = array_diff_key( $contents, array_flip( $filter->exclude ) ); 
  416.  
  417. if ( ! empty( $args['posts_per_page'] ) ) { 
  418. $total = $args['posts_per_page']; 
  419. $offset = ! empty( $args['offset'] ) ? $args['offset'] : 0; 
  420. $contents = array_slice( $contents, $offset, $total ); 
  421.  
  422. return apply_filters( 
  423. 'ms_rule_shortcode_model_get_contents',  
  424. $contents 
  425. ); 
  426.  
.