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