PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.6.0
GenerateBlocks v1.6.0
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 4 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 4 years ago class-settings.php 4 years ago dashboard.php 4 years ago defaults.php 3 years ago functions.php 3 years ago general.php 4 years ago
class-query-loop.php
276 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_grid-item', array( $this, 'add_grid_item_attributes' ), 10, 2 );
47 add_filter( 'generateblocks_attr_button-container', array( $this, 'add_button_wrapper_attributes' ), 10, 2 );
48 add_filter( 'generateblocks_defaults', array( $this, 'add_block_defaults' ) );
49 add_filter( 'generateblocks_query_loop_args', array( $this, 'set_query_loop_defaults' ) );
50 }
51
52 /**
53 * Helper function that constructs a WP_Query args array from
54 * a `Query` block properties.
55 *
56 * @param WP_Block $block Block instance.
57 * @param int $page Current query's page.
58 *
59 * @todo: https://github.com/WordPress/wordpress-develop/blob/44e308c12e68b5c6b63845fd84369ba36985e193/src/wp-includes/blocks.php#L1126
60 */
61 public static function get_query_args( $block, $page ) {
62 $query_attributes = ( is_array( $block->context ) && isset( $block->context['generateblocks/query'] ) )
63 ? $block->context['generateblocks/query']
64 : array();
65
66 // Set up our pagination.
67 $query_attributes['paged'] = $page;
68
69 $query_args = self::map_post_type_attributes( $query_attributes );
70
71 if ( isset( $query_args['tax_query'] ) ) {
72 $query_args['tax_query'] = self::normalize_tax_query_attributes( $query_args['tax_query'] );
73 }
74
75 if ( isset( $query_args['date_query_after'] ) || isset( $query_args['date_query_before'] ) ) {
76 $query_args['date_query'] = self::normalize_date_query_attributes(
77 isset( $query_args['date_query_after'] ) ? $query_args['date_query_after'] : null,
78 isset( $query_args['date_query_before'] ) ? $query_args['date_query_before'] : null
79 );
80
81 unset( $query_args['date_query_after'] );
82 unset( $query_args['date_query_before'] );
83 }
84
85 if ( isset( $query_args['stickyPosts'] ) && 'ignore' === $query_args['stickyPosts'] ) {
86 $query_args['ignore_sticky_posts'] = true;
87 unset( $query_args['stickyPosts'] );
88 }
89
90 if ( isset( $query_args['stickyPosts'] ) && 'exclude' === $query_args['stickyPosts'] ) {
91 $sticky_posts = get_option( 'sticky_posts' );
92 $post_not_in = isset( $query_args['post__not_in'] ) && is_array( $query_args['post__not_in'] ) ? $query_args['post__not_in'] : array();
93 $query_args['post__not_in'] = array_merge( $sticky_posts, $post_not_in );
94 unset( $query_args['stickyPosts'] );
95 }
96
97 if ( isset( $query_args['stickyPosts'] ) && 'only' === $query_args['stickyPosts'] ) {
98 $sticky_posts = get_option( 'sticky_posts' );
99 $query_args['ignore_sticky_posts'] = true;
100 $query_args['post__in'] = $sticky_posts;
101 unset( $query_args['stickyPosts'] );
102 }
103
104 if ( isset( $query_args['tax_query_exclude'] ) ) {
105 $not_in_tax_query = self::normalize_tax_query_attributes( $query_args['tax_query_exclude'], 'NOT IN' );
106 $query_args['tax_query'] = isset( $query_args['tax_query'] )
107 ? array_merge( $query_args['tax_query'], $not_in_tax_query )
108 : $not_in_tax_query;
109
110 unset( $query_args['tax_query_exclude'] );
111 }
112
113 if (
114 isset( $query_args['posts_per_page'] ) &&
115 is_numeric( $query_args['posts_per_page'] )
116 ) {
117 $per_page = intval( $query_args['posts_per_page'] );
118 $offset = 0;
119
120 if (
121 isset( $query_args['offset'] ) &&
122 is_numeric( $query_args['offset'] )
123 ) {
124 $offset = absint( $query_args['offset'] );
125 }
126
127 $query_args['offset'] = ( $per_page * ( $page - 1 ) ) + $offset;
128 $query_args['posts_per_page'] = $per_page;
129 }
130
131 return $query_args;
132 }
133
134 /**
135 * Map query parameters to their correct query names.
136 *
137 * @param array $attributes Block attributes.
138 */
139 public static function map_post_type_attributes( $attributes ) {
140 $attributes_map = array(
141 'page' => 'paged',
142 'per_page' => 'posts_per_page',
143 'search' => 's',
144 'after' => 'date_query_after',
145 'before' => 'date_query_before',
146 'author' => 'author__in',
147 'exclude' => 'post__not_in',
148 'include' => 'post__in',
149 'order' => 'order',
150 'orderby' => 'orderby',
151 'status' => 'post_status',
152 'parent' => 'post_parent__in',
153 'parent_exclude' => 'post_parent__not_in',
154 'author_exclude' => 'author__not_in',
155 );
156
157 return generateblocks_map_array_keys( $attributes, $attributes_map );
158 }
159
160 /**
161 * Normalize the tax query attributes to be used in the WP_Query
162 *
163 * @param array $raw_tax_query Tax query.
164 * @param string $operator Tax operator.
165 *
166 * @return array|array[]
167 */
168 public static function normalize_tax_query_attributes( $raw_tax_query, $operator = 'IN' ) {
169 return array_map(
170 function( $tax ) use ( $operator ) {
171 return array(
172 'taxonomy' => $tax['taxonomy'],
173 'field' => 'term_id',
174 'terms' => $tax['terms'],
175 'operator' => $operator,
176 'include_children' => isset( $tax['includeChildren'] ) ? $tax['includeChildren'] : true,
177 );
178 },
179 $raw_tax_query
180 );
181 }
182
183 /**
184 * Normalize the date query attributes to be used in the WP_Query
185 *
186 * @param string|null $after The after date.
187 * @param string|null $before The before date.
188 *
189 * @return array
190 */
191 public static function normalize_date_query_attributes( $after = null, $before = null ) {
192 $result = array( 'inclusive' => true );
193
194 if ( generateblocks_is_valid_date( $after ) ) {
195 $result['after'] = $after;
196 }
197
198 if ( generateblocks_is_valid_date( $before ) ) {
199 $result['before'] = $before;
200 }
201
202 return $result;
203 }
204
205 /**
206 * Add defaults for our Query settings.
207 *
208 * @param array $defaults Block defaults.
209 */
210 public function add_block_defaults( $defaults ) {
211 $defaults['container']['isQueryLoopItem'] = false;
212 $defaults['gridContainer']['isQueryLoop'] = false;
213 $defaults['buttonContainer']['isPagination'] = false;
214
215 return $defaults;
216 }
217
218 /**
219 * Add HTML attributes to the Query Loop wrapper.
220 *
221 * @param array $attributes Existing HTML attributes.
222 * @param array $settings Block settings.
223 */
224 public function add_grid_wrapper_attributes( $attributes, $settings ) {
225 if ( $settings['isQueryLoop'] ) {
226 $attributes['class'] .= ' gb-query-loop-wrapper';
227 }
228
229 return $attributes;
230 }
231
232 /**
233 * Add HTML attributes to the Query Loop Item wrapper.
234 *
235 * @param array $attributes Existing HTML attributes.
236 * @param array $settings Block settings.
237 */
238 public function add_grid_item_attributes( $attributes, $settings ) {
239 if ( $settings['isQueryLoopItem'] ) {
240 $attributes['class'] .= ' ' . implode( ' ', get_post_class( 'gb-query-loop-item' ) );
241 }
242
243 return $attributes;
244 }
245
246 /**
247 * Add HTML attributes to the Button wrapper.
248 *
249 * @param array $attributes Existing HTML attributes.
250 * @param array $settings Block settings.
251 */
252 public function add_button_wrapper_attributes( $attributes, $settings ) {
253 if ( $settings['isPagination'] ) {
254 $attributes['class'] .= ' gb-query-loop-pagination';
255 }
256
257 return $attributes;
258 }
259
260 /**
261 * Set the default query loop arguments.
262 *
263 * @param array $query_args The query loop arguments.
264 * @return array The query loop arguments with defaults.
265 */
266 public function set_query_loop_defaults( $query_args ) {
267 if ( ! isset( $query_args['posts_per_page'] ) || '' === $query_args['posts_per_page'] ) {
268 $query_args['posts_per_page'] = 10;
269 }
270
271 return $query_args;
272 }
273 }
274
275 GenerateBlocks_Query_Loop::get_instance();
276