PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.7.3
GenerateBlocks v1.7.3
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 3 years ago class-do-css.php 3 years ago class-dynamic-content.php 3 years ago class-enqueue-css.php 3 years ago class-legacy-attributes.php 4 years ago class-plugin-update.php 5 years ago class-query-loop.php 3 years ago class-render-blocks.php 3 years ago class-rest.php 3 years ago class-settings.php 4 years ago dashboard.php 3 years ago defaults.php 3 years ago functions.php 3 years ago general.php 3 years ago
class-query-loop.php
292 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 return $query_args;
133 }
134
135 /**
136 * Map query parameters to their correct query names.
137 *
138 * @param array $attributes Block attributes.
139 */
140 public static function map_post_type_attributes( $attributes ) {
141 $attributes_map = array(
142 'page' => 'paged',
143 'per_page' => 'posts_per_page',
144 'search' => 's',
145 'after' => 'date_query_after',
146 'before' => 'date_query_before',
147 'author' => 'author__in',
148 'exclude' => 'post__not_in',
149 'include' => 'post__in',
150 'order' => 'order',
151 'orderby' => 'orderby',
152 'status' => 'post_status',
153 'parent' => 'post_parent__in',
154 'parent_exclude' => 'post_parent__not_in',
155 'author_exclude' => 'author__not_in',
156 );
157
158 return generateblocks_map_array_keys( $attributes, $attributes_map );
159 }
160
161 /**
162 * Normalize the tax query attributes to be used in the WP_Query
163 *
164 * @param array $raw_tax_query Tax query.
165 * @param string $operator Tax operator.
166 *
167 * @return array|array[]
168 */
169 public static function normalize_tax_query_attributes( $raw_tax_query, $operator = 'IN' ) {
170 return array_map(
171 function( $tax ) use ( $operator ) {
172 return array(
173 'taxonomy' => $tax['taxonomy'],
174 'field' => 'term_id',
175 'terms' => $tax['terms'],
176 'operator' => $operator,
177 'include_children' => isset( $tax['includeChildren'] ) ? $tax['includeChildren'] : true,
178 );
179 },
180 $raw_tax_query
181 );
182 }
183
184 /**
185 * Normalize the date query attributes to be used in the WP_Query
186 *
187 * @param string|null $after The after date.
188 * @param string|null $before The before date.
189 *
190 * @return array
191 */
192 public static function normalize_date_query_attributes( $after = null, $before = null ) {
193 $result = array( 'inclusive' => true );
194
195 if ( generateblocks_is_valid_date( $after ) ) {
196 $result['after'] = $after;
197 }
198
199 if ( generateblocks_is_valid_date( $before ) ) {
200 $result['before'] = $before;
201 }
202
203 return $result;
204 }
205
206 /**
207 * Add defaults for our Query settings.
208 *
209 * @param array $defaults Block defaults.
210 */
211 public function add_block_defaults( $defaults ) {
212 $defaults['container']['isQueryLoopItem'] = false;
213 $defaults['container']['isPagination'] = false;
214 $defaults['gridContainer']['isQueryLoop'] = false;
215 $defaults['buttonContainer']['isPagination'] = false;
216
217 return $defaults;
218 }
219
220 /**
221 * Add HTML attributes to the Query Loop wrapper.
222 *
223 * @param array $attributes Existing HTML attributes.
224 * @param array $settings Block settings.
225 */
226 public function add_grid_wrapper_attributes( $attributes, $settings ) {
227 if ( $settings['isQueryLoop'] ) {
228 $attributes['class'] .= ' gb-query-loop-wrapper';
229 }
230
231 return $attributes;
232 }
233
234 /**
235 * Add HTML attributes to the Query Loop Containers.
236 *
237 * @param array $attributes Existing HTML attributes.
238 * @param array $settings Block settings.
239 */
240 public function add_container_attributes( $attributes, $settings ) {
241 if ( $settings['isPagination'] ) {
242 $attributes['class'] .= ' gb-query-loop-pagination';
243 }
244
245 return $attributes;
246 }
247
248 /**
249 * Add HTML attributes to the Query Loop Item wrapper.
250 *
251 * @param array $attributes Existing HTML attributes.
252 * @param array $settings Block settings.
253 */
254 public function add_grid_item_attributes( $attributes, $settings ) {
255 if ( $settings['isQueryLoopItem'] ) {
256 $attributes['class'] .= ' ' . implode( ' ', get_post_class( 'gb-query-loop-item' ) );
257 }
258
259 return $attributes;
260 }
261
262 /**
263 * Add HTML attributes to the Button wrapper.
264 *
265 * @param array $attributes Existing HTML attributes.
266 * @param array $settings Block settings.
267 */
268 public function add_button_wrapper_attributes( $attributes, $settings ) {
269 if ( $settings['isPagination'] ) {
270 $attributes['class'] .= ' gb-query-loop-pagination';
271 }
272
273 return $attributes;
274 }
275
276 /**
277 * Set the default query loop arguments.
278 *
279 * @param array $query_args The query loop arguments.
280 * @return array The query loop arguments with defaults.
281 */
282 public function set_query_loop_defaults( $query_args ) {
283 if ( ! isset( $query_args['posts_per_page'] ) || '' === $query_args['posts_per_page'] ) {
284 $query_args['posts_per_page'] = 10;
285 }
286
287 return $query_args;
288 }
289 }
290
291 GenerateBlocks_Query_Loop::get_instance();
292