PageRenderTime 26ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/meta-box-include-exclude/class-mb-include-exclude.php

https://gitlab.com/code26/selah
PHP | 379 lines | 166 code | 52 blank | 161 comment | 40 complexity | 8b45d91014c55529c1bcf5211a455f1e MD5 | raw file
  1. <?php
  2. /**
  3. * Control the include, exclude condition for meta boxes
  4. *
  5. * @link https://metabox.io/plugins/meta-box-include-exclude/
  6. * @package Meta Box
  7. * @subpackage Meta Box Include Exclude
  8. */
  9. /**
  10. * Control the include, exclude condition for meta boxes
  11. *
  12. * @link https://metabox.io/plugins/meta-box-include-exclude/
  13. * @package Meta Box
  14. * @subpackage Meta Box Include Exclude
  15. */
  16. /**
  17. * Class MB_Include_Exclude
  18. */
  19. class MB_Include_Exclude {
  20. /**
  21. * Store the current post ID.
  22. *
  23. * @var string
  24. */
  25. protected static $post_id;
  26. /**
  27. * Check if meta box is displayed or not.
  28. *
  29. * @param bool $show Show or hide meta box.
  30. * @param array $meta_box Meta Box parameters.
  31. *
  32. * @return bool
  33. */
  34. public static function check( $show, $meta_box ) {
  35. if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
  36. return $show;
  37. }
  38. self::$post_id = self::get_current_post_id();
  39. if ( isset( $meta_box['include'] ) ) {
  40. $show = self::maybe_exclude_include( 'include', $meta_box );
  41. }
  42. if ( isset( $meta_box['exclude'] ) ) {
  43. $show = ! self::maybe_exclude_include( 'exclude', $meta_box );
  44. }
  45. return $show;
  46. }
  47. /**
  48. * Check if meta box is excluded for current post.
  49. *
  50. * @param string $type Accept 'include' or 'exclude'.
  51. * @param array $meta_box Meta box data.
  52. *
  53. * @return bool
  54. */
  55. protected static function maybe_exclude_include( $type, $meta_box ) {
  56. $conditions = $meta_box[ $type ];
  57. $relation = isset( $conditions['relation'] ) && in_array( strtoupper( $conditions['relation'] ), array( 'AND', 'OR' ), true ) ? strtoupper( $conditions['relation'] ) : 'OR';
  58. // Initial value.
  59. $value = 'OR' === $relation ? false : true;
  60. // For better loop of checking terms.
  61. unset( $conditions['relation'] );
  62. $check_by = array( 'ID', 'parent', 'slug', 'template', 'user_role', 'user_id', 'custom', 'is_child', 'edited_user_role', 'edited_user_id' );
  63. foreach ( $check_by as $by ) {
  64. $func = "check_{$by}";
  65. if ( ! isset( $conditions[ $by ] ) || ! method_exists( __CLASS__, $func ) ) {
  66. continue;
  67. }
  68. $condition = self::$func( $conditions[ $by ], $meta_box );
  69. if ( self::combine( $value, $condition, $relation ) ) {
  70. return $value;
  71. }
  72. // For better loop of checking terms.
  73. unset( $conditions[ $by ] );
  74. }
  75. // By parent taxonomy, including category and post_tag.
  76. // Note that we unset all other parameters, so we can safely loop in the condition array.
  77. if ( empty( $conditions ) ) {
  78. return $value;
  79. }
  80. // Change 'tag' to correct name 'post_tag'.
  81. if ( isset( $conditions['parent_tag'] ) ) {
  82. $conditions['parent_post_tag'] = $conditions['parent_tag'];
  83. unset( $conditions['parent_tag'] );
  84. }
  85. foreach ( $conditions as $key => $terms ) {
  86. if ( 0 !== strpos( $key, 'parent_' ) ) {
  87. continue;
  88. }
  89. $taxonomy = substr( $key, 7 );
  90. $condition = self::check_parent_terms( $taxonomy, $terms );
  91. if ( self::combine( $value, $condition, $relation ) ) {
  92. return $value;
  93. }
  94. unset( $condition[ $key ] );
  95. }
  96. // By taxonomy, including category and post_tag.
  97. // Note that we unset all other parameters, so we can safely loop in the condition array.
  98. if ( empty( $conditions ) ) {
  99. return $value;
  100. }
  101. // Change 'tag' to correct name 'post_tag'.
  102. if ( isset( $conditions['tag'] ) ) {
  103. $conditions['post_tag'] = $conditions['tag'];
  104. unset( $conditions['tag'] );
  105. }
  106. foreach ( $conditions as $key => $terms ) {
  107. $condition = self::check_terms( $key, $terms );
  108. if ( self::combine( $value, $condition, $relation ) ) {
  109. return $value;
  110. }
  111. }
  112. return $value;
  113. }
  114. /**
  115. * Check if current post has specific ID
  116. *
  117. * @param array $ids List of post IDs. Can be array or CSV.
  118. *
  119. * @return bool
  120. */
  121. protected static function check_ID( $ids ) {
  122. return in_array( self::$post_id, self::csv_to_array( $ids ) );
  123. }
  124. /**
  125. * Check if current post has specific parent.
  126. *
  127. * @param array $ids List post ids.
  128. *
  129. * @return bool
  130. */
  131. protected static function check_parent( $ids ) {
  132. $post = get_post( self::$post_id );
  133. return $post && in_array( $post->post_parent, self::csv_to_array( $ids ) );
  134. }
  135. /**
  136. * Check if current post has specific slug.
  137. *
  138. * @param array $slugs List post slugs.
  139. *
  140. * @return bool
  141. */
  142. protected static function check_slug( $slugs ) {
  143. $post = get_post( self::$post_id );
  144. return $post && in_array( $post->post_name, self::csv_to_array( $slugs ) );
  145. }
  146. /**
  147. * Check if current post has specific template
  148. *
  149. * @param array $templates List page templates.
  150. *
  151. * @return bool
  152. */
  153. protected static function check_template( $templates ) {
  154. $template = get_post_meta( self::$post_id, '_wp_page_template', true );
  155. return in_array( $template, self::csv_to_array( $templates ) );
  156. }
  157. /**
  158. * Check if current post has specific term
  159. *
  160. * @param string $taxonomy Taxonomy name.
  161. * @param array $terms Terms.
  162. *
  163. * @return bool
  164. */
  165. protected static function check_terms( $taxonomy, $terms ) {
  166. $terms = self::csv_to_array( $terms );
  167. $post_terms = wp_get_post_terms( self::$post_id, $taxonomy );
  168. if ( is_wp_error( $post_terms ) || ! is_array( $post_terms ) || empty( $post_terms ) ) {
  169. return false;
  170. }
  171. foreach ( $post_terms as $post_term ) {
  172. if ( in_array( $post_term->term_id, $terms ) || in_array( $post_term->name, $terms ) || in_array( $post_term->slug, $terms ) ) {
  173. return true;
  174. }
  175. }
  176. return false;
  177. }
  178. /**
  179. * Check if current post has specific term
  180. *
  181. * @param string $taxonomy Taxonomy name.
  182. * @param array $terms Terms.
  183. *
  184. * @return bool
  185. */
  186. protected static function check_parent_terms( $taxonomy, $terms ) {
  187. $terms = self::csv_to_array( $terms );
  188. $post_terms = wp_get_post_terms( self::$post_id, $taxonomy );
  189. if ( is_wp_error( $post_terms ) || ! is_array( $post_terms ) || empty( $post_terms ) ) {
  190. return false;
  191. }
  192. foreach ( $post_terms as $post_term ) {
  193. if ( empty( $post_term->parent ) ) {
  194. continue;
  195. }
  196. $parent = get_term( $post_term->parent, $taxonomy );
  197. if ( in_array( $parent->term_id, $terms ) || in_array( $parent->name, $terms ) || in_array( $parent->slug, $terms ) ) {
  198. return true;
  199. }
  200. }
  201. return false;
  202. }
  203. /**
  204. * Check by current user role.
  205. *
  206. * @param array|string $roles List of user roles. Array or CSV.
  207. *
  208. * @return bool
  209. */
  210. protected static function check_user_role( $roles ) {
  211. $user = wp_get_current_user();
  212. $roles = array_map( 'strtolower', self::csv_to_array( $roles ) );
  213. $roles = array_intersect( $user->roles, $roles );
  214. return ! empty( $roles );
  215. }
  216. /**
  217. * Check by current user ID.
  218. *
  219. * @param array|string $user_ids List of user IDs. Array or CSV.
  220. *
  221. * @return bool
  222. */
  223. protected static function check_user_id( $user_ids ) {
  224. $user_id = get_current_user_id();
  225. return in_array( $user_id, self::csv_to_array( $user_ids ) );
  226. }
  227. /**
  228. * Check by edit user role.
  229. *
  230. * @param array|string $roles List of user roles. Array of CSV.
  231. * @return boolean
  232. */
  233. protected static function check_edited_user_role( $roles ) {
  234. /*
  235. * If edit another user's profile, get the edited user instead.
  236. * This is required for MB User Meta extension.
  237. */
  238. if ( isset( $GLOBALS['pagenow'] ) && 'user-edit.php' === $GLOBALS['pagenow'] ) {
  239. // If edit other's profile, check edited user.
  240. $user_id = intval( $_REQUEST['user_id'] );
  241. $user = get_userdata( $user_id );
  242. $roles = array_map( 'strtolower', self::csv_to_array( $roles ) );
  243. $roles = array_intersect( $user->roles, $roles );
  244. return ! empty( $roles );
  245. } elseif ( isset( $GLOBALS['pagenow'] ) && 'profile.php' === $GLOBALS['pagenow'] ) {
  246. // If edit profile, check current user.
  247. return self::check_user_role( $roles );
  248. }
  249. return true;
  250. }
  251. /**
  252. * Check by edited user id.
  253. *
  254. * @param array|string $user_ids List of user ids. Array of CSV.
  255. * @return boolean
  256. */
  257. protected static function check_edited_user_id( $user_ids ) {
  258. if ( isset( $GLOBALS['pagenow'] ) && 'user-edit.php' === $GLOBALS['pagenow'] ) {
  259. // If edit other's profile, check edited user.
  260. $user_id = intval( $_REQUEST['user_id'] );
  261. return in_array( $user_id, self::csv_to_array( $user_ids ) );
  262. } elseif ( isset( $GLOBALS['pagenow'] ) && 'profile.php' === $GLOBALS['pagenow'] ) {
  263. // If edit profile, check current user.
  264. return self::check_user_id( $user_ids );
  265. }
  266. return true;
  267. }
  268. /**
  269. * Check by custom function
  270. *
  271. * @param array $func Callable.
  272. * @param array $meta_box Meta box data.
  273. *
  274. * @return bool
  275. */
  276. protected static function check_custom( $func, $meta_box ) {
  277. return is_callable( $func ) ? call_user_func( $func, $meta_box ) : false;
  278. }
  279. /**
  280. * Check the page is child or not
  281. *
  282. * @param bool $value Boolean value.
  283. *
  284. * @return bool
  285. */
  286. protected static function check_is_child( $value ) {
  287. $post = get_post( self::$post_id );
  288. $is_child = $post && $post->post_parent ? true : false;
  289. return $is_child === $value;
  290. }
  291. /**
  292. * Get current post ID.
  293. *
  294. * @return int|false Post ID if successful. False on failure.
  295. */
  296. protected static function get_current_post_id() {
  297. $post_id = isset( $_GET['post'] ) ? $_GET['post'] : ( isset( $_POST['post_ID'] ) ? $_POST['post_ID'] : false );
  298. return is_numeric( $post_id ) ? absint( $post_id ) : false;
  299. }
  300. /**
  301. * Convert a comma separated string to array.
  302. *
  303. * @param string $string Comma separated string.
  304. *
  305. * @return array
  306. */
  307. protected static function csv_to_array( $string ) {
  308. return is_array( $string ) ? $string : array_filter( array_map( 'trim', explode( ',', $string . ',' ) ) );
  309. }
  310. /**
  311. * Combine 2 logical value.
  312. *
  313. * @param bool $value1 First value.
  314. * @param bool $value2 Second value.
  315. * @param string $relation 'OR' or 'AND'.
  316. *
  317. * @return bool Indicator for quick break the check.
  318. */
  319. protected static function combine( &$value1, $value2, $relation ) {
  320. if ( 'OR' === $relation ) {
  321. $value1 = $value1 || $value2;
  322. return $value1;
  323. }
  324. $value1 = $value1 && $value2;
  325. return ! $value1;
  326. }
  327. }