PageRenderTime 26ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/learnpress/inc/admin/class-lp-modal-search-items.php

https://bitbucket.org/lemse/unilemse
PHP | 369 lines | 220 code | 57 blank | 92 comment | 27 complexity | d85d696f6ce09fb8c5d221773d8db9ea MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause
  1. <?php
  2. /**
  3. * Class LP_Modal_Search_Items.
  4. *
  5. * @author ThimPress
  6. * @package LearnPress/Classes
  7. * @version 3.0.0
  8. */
  9. /**
  10. * Prevent loading this file directly
  11. */
  12. defined( 'ABSPATH' ) || exit();
  13. if ( ! class_exists( 'LP_Modal_Search_Items' ) ) {
  14. /**
  15. * Class LP_Modal_Search_Items
  16. */
  17. class LP_Modal_Search_Items {
  18. /**
  19. * @var array
  20. */
  21. protected $_options = array();
  22. /**
  23. * @var array
  24. */
  25. protected $_query_args = array();
  26. /**
  27. * @var array
  28. */
  29. protected $_items = array();
  30. /**
  31. * @var bool
  32. */
  33. protected $_changed = true;
  34. /**
  35. * LP_Modal_Search_Items constructor.
  36. *
  37. * @param string $options
  38. */
  39. public function __construct( $options = '' ) {
  40. add_action( 'admin_print_footer_scripts', array( $this, 'js_template' ) );
  41. $this->_options = wp_parse_args(
  42. $options,
  43. array(
  44. 'type' => '',
  45. 'context' => '',
  46. 'context_id' => '',
  47. 'exclude' => '',
  48. 'term' => '',
  49. 'add_button' => __( 'Add', 'learnpress' ),
  50. 'close_button' => __( 'Close', 'learnpress' ),
  51. 'title' => __( 'Search items', 'learnpress' ),
  52. 'limit' => 10,
  53. 'paged' => 1
  54. )
  55. );
  56. if ( is_string( $this->_options['exclude'] ) ) {
  57. $this->_options['exclude'] = explode( ',', $this->_options['exclude'] );
  58. }
  59. add_filter( 'learn-press/modal-search-items/exclude', array(
  60. $this,
  61. 'exclude_items'
  62. ), 10, 4 );
  63. add_filter( 'learn-press/modal-search-items/args', array(
  64. $this,
  65. 'query_args'
  66. ), 10, 3 );
  67. // add_filter( 'learn-press/modal-search-items/not-found', array(
  68. // $this,
  69. // '_modal_search_items_not_found'
  70. // ), 10, 2 );
  71. }
  72. /**
  73. * Build query args from object options and get posts.
  74. *
  75. * @return array
  76. */
  77. protected function _get_items() {
  78. global $wpdb;
  79. $current_items = array();
  80. $current_items_in_order = learn_press_get_request( 'current_items' );
  81. $user = learn_press_get_current_user();
  82. $term = $this->_options['term'];
  83. $type = $this->_options['type'];
  84. $context = $this->_options['context'];
  85. $context_id = $this->_options['context_id'];
  86. if ( $current_items_in_order ) {
  87. foreach ( $current_items_in_order as $item ) {
  88. $sql = "SELECT meta_value
  89. FROM {$wpdb->prefix}learnpress_order_itemmeta
  90. WHERE meta_key = '_course_id'
  91. AND learnpress_order_item_id = $item";
  92. $id = $wpdb->get_results( $sql, OBJECT );
  93. array_push( $current_items, $id[0]->meta_value );
  94. }
  95. }
  96. // @since 3.0.0
  97. $exclude = array_unique( (array) apply_filters( 'learn-press/modal-search-items/exclude', $this->_options['exclude'], $type, $context, $context_id ) );
  98. // @deprecated
  99. $exclude = array_unique( (array) apply_filters( 'learn_press_modal_search_items_exclude', $exclude, $type, $context, $context_id ) );
  100. if ( is_array( $exclude ) ) {
  101. $exclude = array_map( 'intval', $exclude );
  102. }
  103. $paged = max( 1, $this->_options['paged'] );
  104. $args = array(
  105. 'post_type' => array( $type ),
  106. 'post_status' => 'publish',
  107. 'order' => 'ASC',
  108. 'orderby' => 'parent title',
  109. 'exclude' => $exclude,
  110. 'posts_per_page' => $this->_options['limit'],
  111. 'offset' => ( $paged - 1 ) * $this->_options['limit']
  112. );
  113. if ( $context_id = apply_filters( 'learn-press/modal-search-items/context-id', $context_id, $context ) ) {
  114. $args['author'] = get_post_field( 'post_author', $context_id );
  115. }
  116. if ( $term ) {
  117. $args['s'] = $term;
  118. }
  119. // @since 3.0.0
  120. $this->_query_args = apply_filters( 'learn-press/modal-search-items/args', $args, $context, $context_id );
  121. // @deprecated
  122. $this->_query_args = apply_filters( 'learn_press_filter_admin_ajax_modal_search_items_args', $this->_query_args, $context, $context_id );
  123. if ( $posts = get_posts( $this->_query_args ) ) {
  124. $this->_items = wp_list_pluck( $posts, 'ID' );
  125. }
  126. return $this->_items;
  127. }
  128. /**
  129. * Get the items
  130. *
  131. * @return array
  132. */
  133. public function get_items() {
  134. if ( $this->_changed ) {
  135. $this->_get_items();
  136. }
  137. return $this->_items;
  138. }
  139. /**
  140. * Get pagination in html.
  141. *
  142. * @param bool $html
  143. *
  144. * @return array|string
  145. */
  146. function get_pagination( $html = true ) {
  147. $pagination = '';
  148. if ( $items = $this->get_items() ) {
  149. $args = $this->_query_args;
  150. if ( ! empty( $args['exclude'] ) ) {
  151. $args['post__not_in'] = $args['exclude'];
  152. }
  153. $q = new WP_Query( $args );
  154. if ( $this->_options['paged'] && $q->max_num_pages > 1 ) {
  155. $pagenum_link = html_entity_decode( get_pagenum_link() );
  156. $query_args = array();
  157. $url_parts = explode( '?', $pagenum_link );
  158. if ( isset( $url_parts[1] ) ) {
  159. wp_parse_str( $url_parts[1], $query_args );
  160. }
  161. $pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
  162. $pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
  163. $pagination = array(
  164. 'base' => $pagenum_link,
  165. 'total' => $q->max_num_pages,
  166. 'current' => max( 1, $this->_options['paged'] ),
  167. 'mid_size' => 1,
  168. 'add_args' => array_map( 'urlencode', $query_args ),
  169. 'prev_text' => __( '<', 'learnpress' ),
  170. 'next_text' => __( '>', 'learnpress' ),
  171. 'type' => ''
  172. );
  173. if ( $html ) {
  174. $pagination = paginate_links( $pagination );
  175. }
  176. }
  177. $this->_changed = false;
  178. }
  179. return $pagination;
  180. }
  181. /**
  182. * Return string of list items
  183. *
  184. * @return string
  185. */
  186. public function get_html_items() {
  187. ob_start();
  188. if ( $items = $this->get_items() ) {
  189. foreach ( $items as $id => $item ) {
  190. $type = get_post_type( $item );
  191. $type_object = get_post_type_object( $type );
  192. $type_name = $type_object ? $type_object->labels->singular_name : '';
  193. printf( '
  194. <li class="%s" data-id="%2$d" data-type="%4$s" data-text="%3$s">
  195. <label>
  196. <input type="checkbox" value="%2$d" name="selectedItems[]">
  197. <span class="lp-item-text">%3$s (%5$s - #%6$s)</span>
  198. </label>
  199. </li>
  200. ', 'lp-result-item', $item, esc_attr( get_the_title( $item ) ), $type, $type_name, $item );
  201. }
  202. } else {
  203. // @since 3.0.0
  204. $item_not_found = apply_filters( 'learn-press/modal-search-items/not-found', __( 'No item found', 'learnpress' ), $this->_options['type'] );
  205. // @deprecated
  206. $item_not_found = apply_filters( 'learn_press_modal_search_items_not_found', $item_not_found );
  207. echo '<li>' . $item_not_found . '</li>';
  208. }
  209. return ob_get_clean();
  210. }
  211. /**
  212. * JS Modal template.
  213. */
  214. public function js_template() {
  215. $view = learn_press_get_admin_view( 'modal-search-items' );
  216. include $view;
  217. }
  218. /**
  219. * @param array $args
  220. * @param string $context
  221. * @param string $context_id
  222. *
  223. * @return mixed
  224. */
  225. public static function query_args( $args, $context, $context_id ) {
  226. if ( ( LP_ORDER_CPT === get_post_type( $context_id ) ) && ( LP_COURSE_CPT === $args['post_type'] ) ) {
  227. if ( ! empty( $args['author'] ) ) {
  228. unset( $args['author'] );
  229. }
  230. }
  231. return $args;
  232. }
  233. /**
  234. * Filter to exclude the items has already added to it's parent.
  235. * Each item only use one time
  236. *
  237. * @param $exclude
  238. * @param $type
  239. * @param string $context
  240. * @param null $context_id
  241. *
  242. * @return array
  243. */
  244. public static function exclude_items( $exclude, $type, $context = '', $context_id = null ) {
  245. global $wpdb;
  246. $used_items = array();
  247. switch ( $type ) {
  248. case 'lp_lesson':
  249. case 'lp_quiz':
  250. $query = $wpdb->prepare( "
  251. SELECT item_id
  252. FROM {$wpdb->prefix}learnpress_section_items si
  253. INNER JOIN {$wpdb->prefix}learnpress_sections s ON s.section_id = si.section_id
  254. INNER JOIN {$wpdb->posts} p ON p.ID = s.section_course_id
  255. WHERE %d
  256. AND p.post_type = %s
  257. ", 1, LP_COURSE_CPT );
  258. $used_items = $wpdb->get_col( $query );
  259. break;
  260. case 'lp_question':
  261. $query = $wpdb->prepare( "
  262. SELECT question_id
  263. FROM {$wpdb->prefix}learnpress_quiz_questions AS qq
  264. INNER JOIN {$wpdb->posts} q ON q.ID = qq.quiz_id
  265. WHERE %d
  266. AND q.post_type = %s
  267. ", 1, LP_QUIZ_CPT );
  268. $used_items = $wpdb->get_col( $query );
  269. break;
  270. }
  271. if ( $used_items && $exclude ) {
  272. $exclude = array_merge( $exclude, $used_items );
  273. } else if ( $used_items ) {
  274. $exclude = $used_items;
  275. }
  276. return is_array( $exclude ) ? array_unique( $exclude ) : array();
  277. }
  278. /**
  279. * @param $message
  280. * @param $type
  281. *
  282. * @return string
  283. */
  284. public static function items_not_found( $message, $type ) {
  285. switch ( $type ) {
  286. case LP_LESSON_CPT:
  287. $message = __( 'There are no available lessons for this course, please use ', 'learnpress' );
  288. $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_lesson' ) . '">' . esc_html__( 'Add new item', 'learnpress' ) . '</a>';
  289. break;
  290. case LP_QUIZ_CPT:
  291. $message = __( 'There are no available quizzes for this course, please use ', 'learnpress' );
  292. $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_quiz' ) . '">' . esc_html__( 'Add new item', 'learnpress' ) . '</a>';
  293. break;
  294. case LP_QUESTION_CPT:
  295. $message = __( 'There are no available questions for this quiz, please use ', 'learnpress' );
  296. $message .= '<a target="_blank" href="' . admin_url( 'post-new.php?post_type=lp_question' ) . '">' . esc_html__( 'Add new item', 'learnpress' ) . '</a>';
  297. break;
  298. }
  299. return $message;
  300. }
  301. /**
  302. * @return bool|LP_Modal_Search_Items
  303. */
  304. public static function instance() {
  305. static $instance = false;
  306. if ( ! $instance ) {
  307. $instance = new self();
  308. }
  309. return $instance;
  310. }
  311. }
  312. }