/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. * Do protected shortcode [do_protected_shortcode]. 
  98. * 
  99. * This shortcode is executed to replace a protected shortcode. 
  100. * 
  101. * @since 1.0.0 
  102. */ 
  103. public function do_protected_shortcode() { 
  104. $content = null; 
  105. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  106. $msg = $settings->get_protection_message( 
  107. MS_Model_Settings::PROTECTION_MSG_SHORTCODE,  
  108. $this->membership_id 
  109. ); 
  110.  
  111. if ( $msg ) { 
  112. $content = $msg; 
  113. } else { 
  114. $content = __( 'Shortcode content protected.', 'membership2' ); 
  115.  
  116. return apply_filters( 
  117. 'ms_model_shortcode_do_protected_shortcode_content',  
  118. $content,  
  119. $this 
  120. ); 
  121.  
  122. /** 
  123. * Do membership content protection shortcode. 
  124. * 
  125. * self::PROTECT_CONTENT_SHORTCODE 
  126. * 
  127. * Verify if content is protected comparing to self::$membership_ids. 
  128. * 
  129. * @since 1.0.0 
  130. * 
  131. * @param array $atts The shortcode attributes. 
  132. * @param string $content The content inside the shortcode. 
  133. * @param string $code The shortcode code. 
  134. * @return string The shortcode output 
  135. */ 
  136. static public function protect_content_shortcode( $atts, $content = null, $code = '' ) { 
  137. $atts = apply_filters( 
  138. 'ms_model_shortcode_protect_content_shortcode_atts',  
  139. shortcode_atts( 
  140. array( 
  141. 'id' => '',  
  142. 'access' => true,  
  143. 'silent' => false,  
  144. 'msg' => false,  
  145. ),  
  146. $atts 
  147. ); 
  148. extract( $atts ); 
  149.  
  150. $membership_ids = explode( ', ', $id ); 
  151.  
  152. if ( $silent ) { 
  153. $msg = ''; 
  154. } else { 
  155. if ( ! is_string( $msg ) || ! strlen( $msg ) ) { 
  156. $settings = MS_Factory::load( 'MS_Model_Settings' ); 
  157. $membership_id = apply_filters( 'ms_detect_membership_id', 0 ); 
  158. $msg = $settings->get_protection_message( 
  159. MS_Model_Settings::PROTECTION_MSG_SHORTCODE,  
  160. $membership_id 
  161. ); 
  162.  
  163. $access = lib3()->is_true( $access ); 
  164.  
  165. if ( ! $access ) { 
  166. // No access to member of membership_ids 
  167.  
  168. if ( self::is_member_of( $membership_ids ) ) { 
  169. // User belongs to these memberships and therefore cannot see 
  170. // this content... 
  171.  
  172. if ( $silent ) { 
  173. // Silent protection: Do not show a message, simply hide it 
  174. $content = ''; 
  175. } else { 
  176. $content = '<div class="ms-protection-msg">'; 
  177. if ( ! empty( $msg ) ) { 
  178. $content .= $msg; 
  179. } else { 
  180. $membership_names = MS_Model_Membership::get_membership_names( 
  181. array( 'post__in' => $membership_ids ) 
  182. ); 
  183. $content .= __( 'No access to members of: ', 'membership2' ); 
  184. $content .= implode( ', ', $membership_names ); 
  185. $content .= '</div>'; 
  186. } else { 
  187. // Give access to member of membership_ids 
  188.  
  189. if ( ! self::is_member_of( $membership_ids ) ) { 
  190. // User does not belong to these memberships and therefore 
  191. // cannot see this content... 
  192.  
  193. if ( $silent ) { 
  194. // Silent protection: Do not show a message, simply hide it 
  195. $content = ''; 
  196. } else { 
  197. $content = '<div class="ms-protection-msg">'; 
  198. if ( ! empty( $msg ) ) { 
  199. $content .= $msg; 
  200. } else { 
  201. $membership_names = MS_Model_Membership::get_membership_names( 
  202. array( 'post__in' => $membership_ids ) 
  203. ); 
  204. $content .= __( 'Content protected to members of: ', 'membership2' ); 
  205. $content .= implode( ', ', $membership_names ); 
  206. $content .= '</div>'; 
  207.  
  208. return apply_filters( 
  209. 'ms_rule_shortcode_model_protect_content_shortcode_content',  
  210. do_shortcode( $content ),  
  211. $atts,  
  212. $content,  
  213. $code 
  214. ); 
  215.  
  216. /** 
  217. * For Admin-Users only: 
  218. * The [ms-protected-content] shortcode is replaced with some debug values 
  219. * for better understanding of the page structure. 
  220. * 
  221. * @since 1.0.0 
  222. * @param array $atts The shortcode attributes. 
  223. * @param string $content The content inside the shortcode. 
  224. * @return string The shortcode output 
  225. */ 
  226. public function debug_protect_content_shortcode( $atts, $content = '' ) { 
  227. $do_debug = true; 
  228.  
  229. /** 
  230. * This wp-config setting defines the default state of the shortcode 
  231. * debugging flag. 
  232. */ 
  233. if ( defined( 'MS_NO_SHORTCODE_PREVIEW' ) && MS_NO_SHORTCODE_PREVIEW ) { 
  234. $do_debug = false; 
  235.  
  236. /** 
  237. * Use this filter to disable the protected-content debugging 
  238. * information for admin users. 
  239. * The content will always be displayed for admin users. 
  240. */ 
  241. $do_debug = apply_filters( 
  242. 'ms_model_shortcode_debug_protected_content',  
  243. $do_debug,  
  244. $atts,  
  245. $content 
  246. ); 
  247.  
  248. $content = do_shortcode( $content ); 
  249.  
  250. if ( ! $do_debug ) { 
  251. return $content; 
  252.  
  253. $atts = apply_filters( 
  254. 'ms_model_shortcode_protect_content_shortcode_atts',  
  255. shortcode_atts( 
  256. array( 
  257. 'id' => '',  
  258. 'access' => true,  
  259. 'silent' => false,  
  260. 'msg' => false,  
  261. ),  
  262. $atts 
  263. ); 
  264. extract( $atts ); 
  265.  
  266. if ( lib3()->is_true( $access ) ) { 
  267. $msg_access = __( 'Visible for members of', 'membership2' ); 
  268. $alt_msg1 = __( 'Other users will see', 'membership2' ); 
  269. $alt_msg2 = __( 'Other uses will see nothing', 'membership2' ); 
  270. } else { 
  271. $msg_access = __( 'Hidden from members of', 'membership2' ); 
  272. $alt_msg1 = __( 'Those users will see', 'membership2' ); 
  273. $alt_msg2 = __( 'Those uses will see nothing', 'membership2' ); 
  274.  
  275. if ( $msg ) { 
  276. $msg_alt = sprintf( '%s: %s', $alt_msg1, $msg ); 
  277. } else { 
  278. $msg_alt = $alt_msg2; 
  279.  
  280. $membership_ids = explode( ', ', $id ); 
  281. $memberships = array(); 
  282. foreach ( $membership_ids as $membership_id ) { 
  283. $membership = MS_Factory::load( 'MS_Model_Membership', $membership_id ); 
  284. $memberships[] = $membership->get_name_tag(); 
  285.  
  286. $css = '<style> 
  287. .ms-membership { 
  288. display: inline-block; 
  289. border-radius: 3px; 
  290. color: #FFF; 
  291. background: #888888; 
  292. padding: 1px 5px; 
  293. font-size: 12px; 
  294. height: 20px; 
  295. line-height: 20px; 
  296. .ms-protected-info { 
  297. border: 1px solid rgba(0, 0, 0, 0.07); 
  298. .ms-protected-info:hover { 
  299. border: 1px solid rgba(0, 0, 0, 0.3); 
  300. .ms-protected-info .ms-details,  
  301. .ms-protected-info .ms-alternate-msg { 
  302. background: #EEE; 
  303. padding: 4px; 
  304. font-size: 12px; 
  305. color: #666; 
  306. opacity: 0.25; 
  307. .ms-protected-info:hover .ms-details,  
  308. .ms-protected-info:hover .ms-alternate-msg { 
  309. opacity: 1; 
  310. .ms-protected-info .ms-contents { 
  311. padding: 4px 8px; 
  312. </style>'; 
  313.  
  314. $code = sprintf( 
  315. '<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>',  
  316. $content,  
  317. $msg_alt,  
  318. $msg_access,  
  319. implode( ' ', $memberships ),  
  320. __( 'This information is only displayed for admin users', 'membership2' ) 
  321. ); 
  322.  
  323. return $css . $code; 
  324.  
  325. /** 
  326. * Returns true when the current user is a member of one of the specified 
  327. * memberships. 
  328. * 
  329. * @since 1.0.0 
  330. * 
  331. * @return bool 
  332. */ 
  333. static protected function is_member_of( $ids ) { 
  334. $result = false; 
  335.  
  336. if ( empty( $ids ) ) { 
  337. $result = true; 
  338. } else { 
  339. if ( ! is_array( $ids ) ) { 
  340. $ids = array( $ids ); 
  341.  
  342. foreach ( self::$membership_ids as $the_id ) { 
  343. if ( in_array( $the_id, $ids ) ) { 
  344. $result = true; 
  345. break; 
  346.  
  347. return $result; 
  348.  
  349. /** 
  350. * Get the total content count. 
  351. * 
  352. * @since 1.0.0 
  353. * 
  354. * @param $args The query post args. Not used. 
  355. * @return int The total content count. 
  356. */ 
  357. public function get_content_count( $args = null ) { 
  358. $args['posts_per_page'] = 0; 
  359. $args['offset'] = false; 
  360. $items = $this->get_contents( $args ); 
  361. $count = count( $items ); 
  362.  
  363. return apply_filters( 
  364. 'ms_rule_shortcode_model_get_content_count',  
  365. $count,  
  366. $this 
  367. ); 
  368.  
  369. /** 
  370. * Get content to protect. 
  371. * 
  372. * @since 1.0.0 
  373. * @param $args The filter args 
  374. * 
  375. * @return array The contents array. 
  376. */ 
  377. public function get_contents( $args = null ) { 
  378. global $shortcode_tags; 
  379.  
  380. $exclude = MS_Helper_Shortcode::get_membership_shortcodes(); 
  381. $contents = array(); 
  382.  
  383. foreach ( $shortcode_tags as $key => $function ) { 
  384. if ( in_array( $key, $exclude ) ) { 
  385. continue; 
  386.  
  387. // Search the shortcode-tag... 
  388. if ( ! empty( $args['s'] ) ) { 
  389. if ( false === stripos( $key, $args['s'] ) ) { 
  390. continue; 
  391.  
  392. $contents[ $key ] = new StdClass(); 
  393. $contents[ $key ]->id = $key; 
  394. $contents[ $key ]->name = "[$key]"; 
  395. $contents[ $key ]->type = MS_Rule_Shortcode::RULE_ID; 
  396. $contents[ $key ]->access = $this->get_rule_value( $key ); 
  397.  
  398. $filter = $this->get_exclude_include( $args ); 
  399. if ( is_array( $filter->include ) ) { 
  400. $contents = array_intersect_key( $contents, array_flip( $filter->include ) ); 
  401. } elseif ( is_array( $filter->exclude ) ) { 
  402. $contents = array_diff_key( $contents, array_flip( $filter->exclude ) ); 
  403.  
  404. if ( ! empty( $args['posts_per_page'] ) ) { 
  405. $total = $args['posts_per_page']; 
  406. $offset = ! empty( $args['offset'] ) ? $args['offset'] : 0; 
  407. $contents = array_slice( $contents, $offset, $total ); 
  408.  
  409. return apply_filters( 
  410. 'ms_rule_shortcode_model_get_contents',  
  411. $contents 
  412. ); 
  413.  
.