PluginProbe ʕ •ᴥ•ʔ
Shortcodes and extra features for Phlox theme / trunk
Shortcodes and extra features for Phlox theme vtrunk
2.17.21 2.17.20 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.6 1.0.9 1.1.0 1.3.0 1.3.1 1.3.10 1.3.14 1.3.2 1.3.3 1.3.6 1.4.0 1.4.1 1.4.2 1.5.0 1.5.2 1.6.0 1.6.2 1.6.4 1.7.0 1.7.2 2.10.0 2.10.1 2.10.3 2.10.5 2.10.7 2.10.8 2.10.9 2.11.0 2.11.1 2.11.2 2.12.0 2.14.0 2.15.0 2.15.2 2.15.4 2.15.5 2.15.6 2.15.7 2.15.8 2.15.9 2.16.0 2.16.1 2.16.2 2.16.3 2.16.4 2.17.0 2.17.1 2.17.12 2.17.13 2.17.14 2.17.15 2.17.16 2.17.2 2.17.3 2.17.4 2.17.5 2.17.6 2.17.8 2.17.9 2.4.12 2.4.13 2.4.14 2.4.16 2.4.18 2.4.19 2.4.9 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.14 2.5.15 2.5.16 2.5.17 2.5.19 2.5.2 2.5.20 2.5.3 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.10 2.6.12 2.6.13 2.6.14 2.6.15 2.6.16 2.6.17 2.6.19 2.6.2 2.6.20 2.6.4 2.6.5 2.6.7 2.7.0 2.7.1 2.7.10 2.7.11 2.7.12 2.7.13 2.7.14 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.9 2.9.0 2.9.12 2.9.14 2.9.15 2.9.16 2.9.17 2.9.18 2.9.19 2.9.2 2.9.20 2.9.21 2.9.22 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8
auxin-elements / includes / elementor / modules / query-control / classes / elementor-post-query.php
auxin-elements / includes / elementor / modules / query-control / classes Last commit date
elementor-post-query.php 4 years ago elementor-related-query.php 6 years ago
elementor-post-query.php
372 lines
1 <?php
2 namespace Auxin\Plugin\CoreElements\Elementor\Modules\QueryControl\Classes;
3
4 use Elementor\Widget_Base;
5 use Auxin\Plugin\CoreElements\Elementor\Modules\QueryControl\Module;
6
7 class Elementor_Post_Query {
8 protected $widget;
9 protected $query_args;
10 protected $prefix;
11 protected $widget_settings;
12
13 /**
14 * Elementor_Post_Query constructor.
15 *
16 * @param Widget_Base $widget
17 * @param string $group_query_name
18 * @param array $query_args
19 */
20 public function __construct( $widget, $group_query_name, $query_args = [] ) {
21 $this->widget = $widget;
22 $this->prefix = $group_query_name . '_';
23 $this->query_args = $query_args;
24
25 $settings = $this->widget->get_settings();
26 $defaults = $this->get_query_defaults();
27
28 $this->widget_settings = wp_parse_args( $settings, $defaults );
29 }
30
31 /**
32 * 1) build query args
33 * 2) invoke callback to fine-tune query-args
34 * 3) generate WP_Query object
35 * 4) if no results & fallback is set, generate a new WP_Query with fallback args
36 * 5) return WP_Query
37 *
38 * @return \WP_Query
39 */
40 public function get_query() {
41 $this->get_query_args();
42
43 $offset_control = $this->get_widget_settings( 'offset' );
44
45 $query_id = $this->get_widget_settings( 'query_id' );
46 if ( ! empty( $query_id ) ) {
47 add_action( 'pre_get_posts', [ $this, 'pre_get_posts_query_filter' ] );
48 }
49
50 if ( 0 < $offset_control ) {
51 add_action( 'pre_get_posts', [ $this, 'fix_query_offset' ], 1 );
52 add_filter( 'found_posts', [ $this, 'fix_query_found_posts' ], 1, 2 );
53 }
54
55 $query = new \WP_Query( $this->query_args );
56
57 remove_action( 'pre_get_posts', [ $this, 'pre_get_posts_query_filter' ] );
58 remove_action( 'pre_get_posts', [ $this, 'fix_query_offset' ], 1 );
59 remove_filter( 'found_posts', [ $this, 'fix_query_found_posts' ], 1 );
60
61 Module::add_to_avoid_list( wp_list_pluck( $query->posts, 'ID' ) );
62
63 return $query;
64 }
65
66 protected function get_query_defaults() {
67 $defaults = [
68 $this->prefix . 'post_type' => 'post',
69 $this->prefix . 'posts_ids' => [],
70 $this->prefix . 'orderby' => 'date',
71 $this->prefix . 'order' => 'desc',
72 $this->prefix . 'offset' => 0,
73 $this->prefix . 'posts_per_page' => 3,
74 ];
75
76 return $defaults;
77 }
78
79 public function get_query_args() {
80 global $wp_query;
81 $post_type = $this->get_widget_settings( 'post_type' );
82
83 if ( 'current_query' === $post_type ) {
84 $current_query_vars = $wp_query->query_vars;
85
86 $current_query_vars = apply_filters( 'elementor/query/get_query_args/current_query', $current_query_vars );
87 $this->query_args = $current_query_vars;
88 return $current_query_vars;
89 }
90
91 $this->set_common_args();
92 $this->set_order_args();
93 $this->set_pagination_args();
94 $this->set_post_include_args();
95
96 if ( 'by_id' !== $post_type ) {
97
98 $this->set_post_exclude_args();
99 $this->set_avoid_duplicates();
100 $this->set_terms_args();
101 $this->set_author_args();
102 $this->set_date_args();
103 }
104
105 $this->query_args = apply_filters( 'elementor/query/query_args', $this->query_args, $this->widget );
106
107 return $this->query_args;
108 }
109
110 protected function set_pagination_args() {
111 $this->set_query_arg( 'posts_per_page', $this->get_widget_settings( 'posts_per_page' ) );
112 $sticky_post = $this->get_widget_settings( 'ignore_sticky_posts' ) ? true : false;
113 $this->set_query_arg( 'ignore_sticky_posts', $sticky_post );
114 }
115
116 protected function set_common_args() {
117 $this->query_args['post_status'] = 'publish'; // Hide drafts/private posts for admins
118
119 $post_type = $this->get_widget_settings( 'post_type' );
120 if ( 'by_id' === $post_type ) {
121 $post_types = auxin_get_public_post_types();
122 $this->query_args['post_type'] = array_keys( $post_types );
123 } else {
124 $this->query_args['post_type'] = $post_type;
125 }
126 }
127
128 protected function set_post_include_args() {
129
130 if ( 'by_id' === $this->get_widget_settings( 'post_type' ) ) {
131
132 $this->set_query_arg( 'post__in', $this->get_widget_settings( 'posts_ids' ) );
133
134 if ( empty( $this->query_args['post__in'] ) ) {
135 // If no selection - return an empty query
136 $this->query_args['post__in'] = [ 0 ];
137 }
138 }
139 }
140
141 protected function set_post_exclude_args() {
142
143 $exclude = $this->get_widget_settings( 'exclude' );
144
145 if ( empty( $exclude ) ) {
146 return;
147 }
148
149 $post__not_in = [];
150
151 if ( $this->maybe_in_array( 'current_post', $exclude ) ) {
152 if ( is_singular() ) {
153 $post__not_in[] = get_queried_object_id();
154 }
155 }
156
157 $exclude_ids = $this->get_widget_settings( 'exclude_ids' );
158 if ( $this->maybe_in_array( 'manual_selection', $exclude ) && ! empty( $exclude_ids ) ) {
159 $post__not_in = array_merge( $post__not_in, $exclude_ids );
160 }
161
162 $this->set_query_arg( 'post__not_in', $post__not_in );
163 }
164
165 protected function set_avoid_duplicates() {
166 if ( 'yes' === $this->get_widget_settings( 'avoid_duplicates' ) ) {
167 $post__not_in = isset( $this->query_args['post__not_in'] ) ? $this->query_args['post__not_in'] : [];
168 $post__not_in = array_merge( $post__not_in, Module::$displayed_ids );
169 $this->set_query_arg( 'post__not_in', $post__not_in );
170 }
171 }
172
173 protected function set_terms_args() {
174
175 $post_type = $this->get_widget_settings( 'post_type' );
176
177 if ( 'by_id' === $post_type ) {
178 return;
179 }
180 $this->build_terms_query_include( 'include_term_ids' );
181 $this->build_terms_query_exclude( 'exclude_term_ids' );
182 }
183
184 protected function build_terms_query_include( $control_id ) {
185 $this->build_terms_query( 'include', $control_id );
186 }
187
188 protected function build_terms_query_exclude( $control_id ) {
189 $this->build_terms_query( 'exclude', $control_id, true );
190 }
191
192 protected function build_terms_query( $tab_id, $control_id, $exclude = false ) {
193 $tab_id = $this->get_widget_settings( $tab_id );
194 $settings_terms = $this->get_widget_settings( $control_id );
195 if ( empty( $tab_id ) || empty( $settings_terms ) || ! $this->maybe_in_array( 'terms', $tab_id ) ) {
196 return;
197 }
198
199 $terms = [];
200
201 // Switch to term_id in order to get all term children (sub-categories):
202 foreach ( $settings_terms as $id ) {
203 $term_data = get_term_by( 'term_taxonomy_id', $id );
204 if ( false !== $term_data ) {
205 $taxonomy = $term_data->taxonomy;
206 $terms[ $taxonomy ][] = $id;
207 }
208 }
209 $this->insert_tax_query( $terms, $exclude );
210 }
211
212 protected function insert_tax_query( $terms, $exclude ) {
213 $tax_query = [];
214 foreach ( $terms as $taxonomy => $ids ) {
215 $query = [
216 'taxonomy' => $taxonomy,
217 'field' => 'term_taxonomy_id',
218 'terms' => $ids,
219 ];
220
221 if ( $exclude ) {
222 $query['operator'] = 'NOT IN';
223 }
224
225 $tax_query[] = $query;
226 }
227
228 if ( empty( $tax_query ) ) {
229 return;
230 }
231
232 if ( empty( $this->query_args['tax_query'] ) ) {
233 $this->query_args['tax_query'] = $tax_query;
234 } else {
235 $this->query_args['tax_query']['relation'] = 'AND';
236 $this->query_args['tax_query'][] = $tax_query;
237 }
238 }
239
240 protected function set_author_args() {
241
242 $include_authors = $this->get_widget_settings( 'include_authors' );
243 if ( ! empty( $include_authors ) && $this->maybe_in_array( 'authors', $this->get_widget_settings( 'include' ) ) ) {
244 $this->set_query_arg( 'author__in', $include_authors );
245 }
246
247 $exclude_authors = $this->get_widget_settings( 'exclude_authors' );
248 if ( ! empty( $exclude_authors ) && $this->maybe_in_array( 'authors', $this->get_widget_settings( 'exclude' ) ) ) {
249 //exclude only if not explicitly included
250 if ( empty( $this->query_args['author__in'] ) ) {
251 $this->set_query_arg( 'author__not_in', $exclude_authors );
252 }
253 }
254 }
255
256 protected function set_order_args() {
257 $order = $this->get_widget_settings( 'order' );
258 if ( ! empty( $order ) ) {
259 $this->set_query_arg( 'orderby', $this->get_widget_settings( 'orderby' ) );
260 $this->set_query_arg( 'order', $this->get_widget_settings( 'order' ) );
261 }
262 }
263
264 protected function set_date_args() {
265
266 $select_date = $this->get_widget_settings( 'select_date' );
267 if ( ! empty( $select_date ) ) {
268 $date_query = [];
269 switch ( $select_date ) {
270 case 'today':
271 $date_query['after'] = '-1 day';
272 break;
273 case 'week':
274 $date_query['after'] = '-1 week';
275 break;
276 case 'month':
277 $date_query['after'] = '-1 month';
278 break;
279 case 'quarter':
280 $date_query['after'] = '-3 month';
281 break;
282 case 'year':
283 $date_query['after'] = '-1 year';
284 break;
285 case 'exact':
286 $after_date = $this->get_widget_settings( 'date_after' );
287 if ( ! empty( $after_date ) ) {
288 $date_query['after'] = $after_date;
289 }
290 $before_date = $this->get_widget_settings( 'date_before' );
291 if ( ! empty( $before_date ) ) {
292 $date_query['before'] = $before_date;
293 }
294 $date_query['inclusive'] = true;
295 break;
296 }
297
298 $this->set_query_arg( 'date_query', $date_query );
299 }
300 }
301
302 /**\
303 * @param string $control_name
304 *
305 * @return mixed|null
306 */
307 protected function get_widget_settings( $control_name ) {
308 $control_name = $this->prefix . $control_name;
309 return isset( $this->widget_settings[ $control_name ] ) ? $this->widget_settings[ $control_name ] : null;
310 }
311
312 /**
313 * @param string $key
314 * @param mixed $value
315 */
316 protected function set_query_arg( $key, $value ) {
317 if ( ! isset( $this->query_args[ $key ] ) ) {
318 $this->query_args[ $key ] = $value;
319 }
320 }
321
322 /**
323 * @param string $value
324 * @param mixed $maybe_array
325 *
326 * @return bool
327 */
328 protected function maybe_in_array( $value, $maybe_array ) {
329 return is_array( $maybe_array ) ? in_array( $value, $maybe_array, true ) : $value === $maybe_array;
330 }
331
332 /**
333 * @param \WP_Query $wp_query
334 */
335 public function pre_get_posts_query_filter( $wp_query ) {
336 if ( $this->widget ) {
337 $query_id = $this->get_widget_settings( 'query_id' );
338 $widget_name = $this->widget->get_name();
339 do_action( "elementor/query/{$query_id}", $wp_query, $this->widget );
340 }
341 }
342
343 /**
344 * @param \WP_Query $query
345 */
346 public function fix_query_offset( &$query ) {
347 $offset = $this->get_widget_settings( 'offset' );
348
349 if ( $offset && $query->is_paged ) {
350 $query->query_vars['offset'] = $offset + ( ( $query->query_vars['paged'] - 1 ) * $query->query_vars['posts_per_page'] );
351 } else {
352 $query->query_vars['offset'] = $offset;
353 }
354 }
355
356 /**
357 * @param int $found_posts
358 * @param \WP_Query $query
359 *
360 * @return int
361 */
362 public function fix_query_found_posts( $found_posts, $query ) {
363 $offset = $this->get_widget_settings( 'offset' );
364
365 if ( $offset ) {
366 $found_posts -= $offset;
367 }
368
369 return $found_posts;
370 }
371 }
372