PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 2.2.1
GenerateBlocks v2.2.1
trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / includes / class-query-loop.php
generateblocks / includes Last commit date
blocks 1 year ago dynamic-tags 3 months ago pattern-library 1 year ago utils 2 years ago class-do-css.php 2 years ago class-dynamic-content.php 6 months ago class-dynamic-tag-security.php 6 months ago class-enqueue-css.php 1 year ago class-legacy-attributes.php 4 years ago class-map-deprecated-attributes.php 2 years ago class-meta-handler.php 3 months ago class-plugin-update.php 1 year ago class-query-loop.php 2 years ago class-query-utils.php 3 months ago class-render-blocks.php 1 year ago class-rest.php 1 year ago class-settings.php 1 year ago dashboard.php 1 year ago defaults.php 1 year ago deprecated.php 1 year ago functions.php 6 months ago general.php 8 months ago
class-query-loop.php
301 lines
1 <?php
2 /**
3 * This file handles the Query Loop functions.
4 *
5 * @package GenerateBlocks
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 /**
13 * Query Loop functions.
14 *
15 * @since 1.5.0
16 */
17 class GenerateBlocks_Query_Loop {
18 /**
19 * Instance.
20 *
21 * @access private
22 * @var object Instance
23 * @since 1.2.0
24 */
25 private static $instance;
26
27 /**
28 * Initiator.
29 *
30 * @since 1.2.0
31 * @return object initialized object of class.
32 */
33 public static function get_instance() {
34 if ( ! isset( self::$instance ) ) {
35 self::$instance = new self();
36 }
37
38 return self::$instance;
39 }
40
41 /**
42 * Constructor.
43 */
44 public function __construct() {
45 add_filter( 'generateblocks_attr_grid-wrapper', array( $this, 'add_grid_wrapper_attributes' ), 10, 2 );
46 add_filter( 'generateblocks_attr_container', array( $this, 'add_container_attributes' ), 10, 2 );
47 add_filter( 'generateblocks_attr_grid-item', array( $this, 'add_grid_item_attributes' ), 10, 2 );
48 add_filter( 'generateblocks_attr_button-container', array( $this, 'add_button_wrapper_attributes' ), 10, 2 );
49 add_filter( 'generateblocks_defaults', array( $this, 'add_block_defaults' ) );
50 add_filter( 'generateblocks_query_loop_args', array( $this, 'set_query_loop_defaults' ) );
51 }
52
53 /**
54 * Helper function that constructs a WP_Query args array from
55 * a `Query` block properties.
56 *
57 * @param WP_Block $block Block instance.
58 * @param int $page Current query's page.
59 *
60 * @todo: https://github.com/WordPress/wordpress-develop/blob/44e308c12e68b5c6b63845fd84369ba36985e193/src/wp-includes/blocks.php#L1126
61 */
62 public static function get_query_args( $block, $page ) {
63 $query_attributes = ( is_array( $block->context ) && isset( $block->context['generateblocks/query'] ) )
64 ? $block->context['generateblocks/query']
65 : array();
66
67 // Set up our pagination.
68 $query_attributes['paged'] = $page;
69
70 $query_args = self::map_post_type_attributes( $query_attributes );
71
72 if ( isset( $query_args['tax_query'] ) ) {
73 $query_args['tax_query'] = self::normalize_tax_query_attributes( $query_args['tax_query'] );
74 }
75
76 if ( isset( $query_args['date_query_after'] ) || isset( $query_args['date_query_before'] ) ) {
77 $query_args['date_query'] = self::normalize_date_query_attributes(
78 isset( $query_args['date_query_after'] ) ? $query_args['date_query_after'] : null,
79 isset( $query_args['date_query_before'] ) ? $query_args['date_query_before'] : null
80 );
81
82 unset( $query_args['date_query_after'] );
83 unset( $query_args['date_query_before'] );
84 }
85
86 if ( isset( $query_args['stickyPosts'] ) && 'ignore' === $query_args['stickyPosts'] ) {
87 $query_args['ignore_sticky_posts'] = true;
88 unset( $query_args['stickyPosts'] );
89 }
90
91 if ( isset( $query_args['stickyPosts'] ) && 'exclude' === $query_args['stickyPosts'] ) {
92 $sticky_posts = get_option( 'sticky_posts' );
93 $post_not_in = isset( $query_args['post__not_in'] ) && is_array( $query_args['post__not_in'] ) ? $query_args['post__not_in'] : array();
94 $query_args['post__not_in'] = array_merge( $sticky_posts, $post_not_in );
95 unset( $query_args['stickyPosts'] );
96 }
97
98 if ( isset( $query_args['stickyPosts'] ) && 'only' === $query_args['stickyPosts'] ) {
99 $sticky_posts = get_option( 'sticky_posts' );
100 $query_args['ignore_sticky_posts'] = true;
101 $query_args['post__in'] = $sticky_posts;
102 unset( $query_args['stickyPosts'] );
103 }
104
105 if ( isset( $query_args['tax_query_exclude'] ) ) {
106 $not_in_tax_query = self::normalize_tax_query_attributes( $query_args['tax_query_exclude'], 'NOT IN' );
107 $query_args['tax_query'] = isset( $query_args['tax_query'] )
108 ? array_merge( $query_args['tax_query'], $not_in_tax_query )
109 : $not_in_tax_query;
110
111 unset( $query_args['tax_query_exclude'] );
112 }
113
114 if (
115 isset( $query_args['posts_per_page'] ) &&
116 is_numeric( $query_args['posts_per_page'] )
117 ) {
118 $per_page = intval( $query_args['posts_per_page'] );
119 $offset = 0;
120
121 if (
122 isset( $query_args['offset'] ) &&
123 is_numeric( $query_args['offset'] )
124 ) {
125 $offset = absint( $query_args['offset'] );
126 }
127
128 $query_args['offset'] = ( $per_page * ( $page - 1 ) ) + $offset;
129 $query_args['posts_per_page'] = $per_page;
130 }
131
132 if (
133 isset( $query_args['post_status'] ) &&
134 'publish' !== $query_args['post_status'] &&
135 ! current_user_can( 'read_private_posts' )
136 ) {
137 // If the user can't read private posts, we'll force the post status to be public.
138 $query_args['post_status'] = 'publish';
139 }
140
141 return $query_args;
142 }
143
144 /**
145 * Map query parameters to their correct query names.
146 *
147 * @param array $attributes Block attributes.
148 */
149 public static function map_post_type_attributes( $attributes ) {
150 $attributes_map = array(
151 'page' => 'paged',
152 'per_page' => 'posts_per_page',
153 'search' => 's',
154 'after' => 'date_query_after',
155 'before' => 'date_query_before',
156 'author' => 'author__in',
157 'exclude' => 'post__not_in',
158 'include' => 'post__in',
159 'order' => 'order',
160 'orderby' => 'orderby',
161 'status' => 'post_status',
162 'parent' => 'post_parent__in',
163 'parent_exclude' => 'post_parent__not_in',
164 'author_exclude' => 'author__not_in',
165 );
166
167 return generateblocks_map_array_keys( $attributes, $attributes_map );
168 }
169
170 /**
171 * Normalize the tax query attributes to be used in the WP_Query
172 *
173 * @param array $raw_tax_query Tax query.
174 * @param string $operator Tax operator.
175 *
176 * @return array|array[]
177 */
178 public static function normalize_tax_query_attributes( $raw_tax_query, $operator = 'IN' ) {
179 return array_map(
180 function( $tax ) use ( $operator ) {
181 return array(
182 'taxonomy' => $tax['taxonomy'],
183 'field' => 'term_id',
184 'terms' => $tax['terms'],
185 'operator' => $operator,
186 'include_children' => isset( $tax['includeChildren'] ) ? $tax['includeChildren'] : true,
187 );
188 },
189 $raw_tax_query
190 );
191 }
192
193 /**
194 * Normalize the date query attributes to be used in the WP_Query
195 *
196 * @param string|null $after The after date.
197 * @param string|null $before The before date.
198 *
199 * @return array
200 */
201 public static function normalize_date_query_attributes( $after = null, $before = null ) {
202 $result = array( 'inclusive' => true );
203
204 if ( generateblocks_is_valid_date( $after ) ) {
205 $result['after'] = $after;
206 }
207
208 if ( generateblocks_is_valid_date( $before ) ) {
209 $result['before'] = $before;
210 }
211
212 return $result;
213 }
214
215 /**
216 * Add defaults for our Query settings.
217 *
218 * @param array $defaults Block defaults.
219 */
220 public function add_block_defaults( $defaults ) {
221 $defaults['container']['isQueryLoopItem'] = false;
222 $defaults['container']['isPagination'] = false;
223 $defaults['gridContainer']['isQueryLoop'] = false;
224 $defaults['buttonContainer']['isPagination'] = false;
225
226 return $defaults;
227 }
228
229 /**
230 * Add HTML attributes to the Query Loop wrapper.
231 *
232 * @param array $attributes Existing HTML attributes.
233 * @param array $settings Block settings.
234 */
235 public function add_grid_wrapper_attributes( $attributes, $settings ) {
236 if ( $settings['isQueryLoop'] ) {
237 $attributes['class'] .= ' gb-query-loop-wrapper';
238 }
239
240 return $attributes;
241 }
242
243 /**
244 * Add HTML attributes to the Query Loop Containers.
245 *
246 * @param array $attributes Existing HTML attributes.
247 * @param array $settings Block settings.
248 */
249 public function add_container_attributes( $attributes, $settings ) {
250 if ( $settings['isPagination'] ) {
251 $attributes['class'] .= ' gb-query-loop-pagination';
252 }
253
254 return $attributes;
255 }
256
257 /**
258 * Add HTML attributes to the Query Loop Item wrapper.
259 *
260 * @param array $attributes Existing HTML attributes.
261 * @param array $settings Block settings.
262 */
263 public function add_grid_item_attributes( $attributes, $settings ) {
264 if ( $settings['isQueryLoopItem'] ) {
265 $attributes['class'] .= ' ' . implode( ' ', get_post_class( 'gb-query-loop-item' ) );
266 }
267
268 return $attributes;
269 }
270
271 /**
272 * Add HTML attributes to the Button wrapper.
273 *
274 * @param array $attributes Existing HTML attributes.
275 * @param array $settings Block settings.
276 */
277 public function add_button_wrapper_attributes( $attributes, $settings ) {
278 if ( $settings['isPagination'] ) {
279 $attributes['class'] .= ' gb-query-loop-pagination';
280 }
281
282 return $attributes;
283 }
284
285 /**
286 * Set the default query loop arguments.
287 *
288 * @param array $query_args The query loop arguments.
289 * @return array The query loop arguments with defaults.
290 */
291 public function set_query_loop_defaults( $query_args ) {
292 if ( ! isset( $query_args['posts_per_page'] ) || '' === $query_args['posts_per_page'] ) {
293 $query_args['posts_per_page'] = 10;
294 }
295
296 return $query_args;
297 }
298 }
299
300 GenerateBlocks_Query_Loop::get_instance();
301