PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.0
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.0
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / admin / class-lp-modal-search-items.php

class-lp-modal-search-items.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.0, at inc/admin/class-lp-modal-search-items.php

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