PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.2.3
Kirki – Freeform Page Builder, Website Builder & Customizer v6.2.3
6.2.4 6.2.3 6.2.2 6.2.1 6.2.0 6.1.1 6.1.0 6.0.14 6.0.13 6.0.12 6.0.11 6.0.10 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.19 4.0.20 4.0.21 4.0.22 4.0.23 4.0.24 4.1 4.2.0 5.0.0 5.1.0 5.1.1 5.2.0 5.2.1 5.2.2 5.2.3 6.0.0 trunk 3.0.40 3.0.41 3.0.42 3.0.43 3.0.44 3.0.45 3.1.0 3.1.1 3.1.2
kirki / includes / Frontend / Preview / Utils.php
kirki / includes / Frontend / Preview Last commit date
templates 3 months ago DataHelper.php 1 week ago ExceptionalElements.php 5 days ago Preview.php 5 days ago Utils.php 1 week ago
Utils.php
428 lines
1 <?php
2
3 /**
4 * Preivew scripts data and styles helper
5 *
6 * @package kirki
7 */
8
9 namespace Kirki\Frontend\Preview;
10
11 use Kirki\Ajax\Users;
12 use Kirki\API\ContentManager\ContentManagerHelper;
13 use Kirki\HelperFunctions;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 /**
20 * DataHelper Class
21 */
22 class Utils {
23
24 public static function get_items_data_from_dynamic_contents( $dynamic_content, $options ) {
25 $collection_type = $dynamic_content['collectionType'];
26 if ( $collection_type === 'users' ) {
27 return self::get_users_collection( $dynamic_content, $options );
28 } elseif ( $collection_type === 'posts' ) {
29 return self::get_posts_collection( $dynamic_content, $options );
30 } elseif ( $collection_type === 'terms' ) {
31 return self::get_terms_collection( $dynamic_content, $options );
32 } else {
33 $args = self::get_common_args( $dynamic_content, $options );
34 $collection = apply_filters( 'kirki_collection_' . $dynamic_content['collectionType'], false, $args );
35 $data = $collection ? $collection['data'] : array();
36 $pagination = $collection ? $collection['pagination'] : array();
37 $item_type = $collection && isset( $collection['itemType'] ) ? $collection['itemType'] : 'post';
38 return array(
39 'data' => $data,
40 'pagination' => $pagination,
41 'itemType' => $item_type,
42 );
43 }
44 }
45
46 private static function get_posts_collection( $dynamic_content, $options ) {
47 $args = self::get_common_args( $dynamic_content, $options );
48 $collection = HelperFunctions::get_posts( $args );
49 $data = $collection['data'];
50 $pagination = $collection['pagination'];
51 return array(
52 'data' => $data,
53 'pagination' => $pagination,
54 'itemType' => 'post',
55 );
56 }
57 private static function get_terms_collection( $dynamic_content, $options ) {
58 $args = array(
59 'taxonomy' => $dynamic_content['taxonomy'],
60 'hide_empty' => false,
61 'current_page' => isset( $options['page'] ) ? $options['page'] : 1,
62 'item_per_page' => isset( $dynamic_content['items'] ) ? $dynamic_content['items'] : 3,
63 'offset' => isset( $dynamic_content['offset'] ) ? $dynamic_content['offset'] : 0,
64 );
65
66 if ( isset( $dynamic_content['inherit'] ) && $dynamic_content['inherit'] ) {
67 if ( isset( $options['itemType'] ) && $options['itemType'] === 'post' ) {
68 $post_parent = $options['post']->ID;
69 } else {
70 $post_parent = HelperFunctions::get_post_id_if_possible_from_url();
71 }
72 $args['post_parent'] = $post_parent;
73 $args['inherit'] = true;
74 }
75
76 $terms = HelperFunctions::get_terms( $args );
77
78 $data = $terms['data'];
79 $pagination = $terms['pagination'];
80 return array(
81 'data' => $data,
82 'pagination' => $pagination,
83 'itemType' => 'term',
84 );
85 }
86
87 private static function get_users_collection( $dynamic_content, $options ) {
88 $args = array();
89
90 if ( isset( $dynamic_content['sorting'] ) && is_array( $dynamic_content['sorting'] ) ) {
91 $order = $dynamic_content['sorting']['order'] ?? $dynamic_content['sorting']['type'] ?? 'DESC';
92 $orderby = $dynamic_content['sorting']['orderby'] ?? $dynamic_content['sorting']['value'] ?? 'date';
93 $args['sorting'] = array(
94 'order' => $order,
95 'orderby' => $orderby,
96 );
97 }
98
99 if ( isset( $options['filters'] ) ) {
100 $args['filters'] = $options['filters'];
101 } elseif ( isset( $dynamic_content['filters'] ) ) {
102 $args['filters'] = $dynamic_content['filters'];
103 }
104
105 if ( isset( $dynamic_content['inherit'] ) && $dynamic_content['inherit'] === true ) {
106 $args['inherit'] = true;
107 $args['post_parent'] = $options['post']->ID ?? HelperFunctions::get_post_id_if_possible_from_url();
108 }
109
110 $item_per_page = isset( $dynamic_content['items'] ) ? $dynamic_content['items'] : 3;
111 $offset = isset( $dynamic_content['offset'] ) ? $dynamic_content['offset'] : 0;
112
113 $current_page = 1;
114 if ( isset( $options['page'] ) ) {
115 $current_page = $options['page'];
116 }
117
118 $args['current_page'] = $current_page;
119 $args['item_per_page'] = $item_per_page;
120 $args['offset'] = $offset;
121
122 if ( isset( $options['q'] ) ) {
123 $args['q'] = $options['q'];
124 }
125
126 $users = Users::get_users( $args );
127 $data = $users['data'];
128 $pagination = $users['pagination'];
129
130 return array(
131 'data' => $data,
132 'pagination' => $pagination,
133 'itemType' => 'user',
134 );
135 }
136
137
138 private static function get_common_args( $dynamic_content, $options ) {
139 $args = array();
140 if ( isset( $dynamic_content['sorting'] ) && is_array( $dynamic_content['sorting'] ) ) {
141 $order = $dynamic_content['sorting']['order'] ?? $dynamic_content['sorting']['type'] ?? 'DESC';
142 $orderby = $dynamic_content['sorting']['orderby'] ?? $dynamic_content['sorting']['value'] ?? 'date';
143 $args['sorting'] = array(
144 'order' => $order,
145 'orderby' => $orderby,
146 );
147 }
148
149 if ( isset( $options['filters'] ) ) {
150 $args['filters'] = $options['filters'];
151 } elseif ( isset( $dynamic_content['filters'] ) ) {
152 $args['filters'] = $dynamic_content['filters'];
153 }
154
155 $search_related_collection_ids = isset( $options['search_related_collection_ids'] ) ? $options['search_related_collection_ids'] : array();
156 $is_searchable_collection_element = isset($search_related_collection_ids[$options['element_id']]);
157
158 if ( ! isset( $dynamic_content['relatedCollection'] ) && $is_searchable_collection_element ) {
159
160 // This code is for taxonomy filter START
161 $filters = array();
162 $taxonomies = array();
163 if ( isset( $_GET['taxonomy'] ) && is_array( $_GET['taxonomy'] ) ) {
164 $taxonomies = $_GET['taxonomy'];
165 } elseif ( isset( $options['collection_param_filters'], $options['collection_param_filters']['taxonomy'] ) ) {
166 // This code came from pagination, filter, search api from frontend
167 $taxonomies = $options['collection_param_filters']['taxonomy'];
168 }
169 foreach ( $taxonomies as $name => $value ) {
170 if ( ! empty( $value ) ) {
171 $filters[] = array(
172 'id' => 'taxonomy',
173 'type' => 'taxonomy',
174 'taxonomy' => $name,
175 'terms' => $value,
176 );
177 }
178 }
179
180 $args['filters'] = array_merge( $args['filters'], $filters );
181 // This code is for taxonomy filter END
182
183 // This code is for post/cm filter START
184 $ref_post_ids = array();
185 if ( isset( $_GET['post'], $_GET['post']['cm_post'] ) && is_array( $_GET['post']['cm_post'] ) ) {
186 $ref_post_ids = array_map( 'intval', $_GET['post']['cm_post'] );
187 } elseif ( isset( $options['collection_param_filters'], $options['collection_param_filters']['post'], $options['collection_param_filters']['post']['cm_post'] ) ) {
188 // This code came from pagination, filter, search api from frontend
189 $ref_post_ids = $options['collection_param_filters']['post']['cm_post'];
190 }
191
192 if ( ! empty( $ref_post_ids ) ) {
193
194 $included_post_ids = ContentManagerHelper::get_post_ids_by_ref_post_ids( $ref_post_ids );
195
196 $args['IDs'] = $included_post_ids;
197 // Make sure all post ids are integers
198 }
199 // This code is for post/cm filter END
200 }
201
202 if ( isset( $dynamic_content['type'] ) ) {
203 $args['name'] = $dynamic_content['type'];
204 }
205
206 if ( isset( $dynamic_content['inherit'] ) && $dynamic_content['inherit'] === true ) {
207 $args['inherit'] = true;
208
209 if ( isset( $options['itemType'], $options[ $options['itemType'] ], $options[ $options['itemType'] ]->ID ) ) {
210 // if itemType is set and it has ID property then use it as post_parent
211 $args['post_parent'] = $options[ $options['itemType'] ]->ID;
212 } else {
213 $args['post_parent'] = $options['post']->ID ?? HelperFunctions::get_post_id_if_possible_from_url();
214 }
215
216 if ( isset( $options['user'], $options['user']['ID'] ) ) {
217 // update $filter data with this user author in property
218
219 $args['context'] = array(
220 'id' => $options['user']['ID'],
221 'collectionType' => 'user',
222 );
223 }
224 if ( isset( $options['term'] ) ) {
225 // update $filter data with this term in property
226 $args['context'] = array(
227 'id' => $options['term']['term_id'],
228 'slug' => $options['term']['slug'],
229 'taxonomy' => $options['term']['taxonomy'],
230 'collectionType' => 'term',
231 );
232 }
233
234 if ( isset( $options['comment'] ) ) {
235 $comment = $options['comment'];
236
237 if ( isset( $comment['id'] ) ) {
238
239 $args['context'] = array(
240 'comment_ID' => $comment['id'], // comment_ID
241 );
242 } elseif ( isset( $comment['comment_ID'] ) ) {
243 $args['context'] = array(
244 'comment_ID' => $comment['comment_ID'], // comment_ID
245 );
246 }
247 }
248
249 // for external plugin support
250 if ( isset( $options['itemType'], $options[ $options['itemType'] ] ) ) {
251 $args['parent_item_type'] = $options['itemType'];
252 $args['parent_item'] = $options[ $options['itemType'] ];
253 }
254 }
255 if ( isset( $dynamic_content['related'] ) && $dynamic_content['related'] === true ) {
256 $args['related'] = true;
257 $args['related_post_parent'] = $options['post']->ID ?? HelperFunctions::get_post_id_if_possible_from_url();
258 }
259
260 if ( ! empty( $dynamic_content['type'] ) && false !== strpos( $dynamic_content['type'], KIRKI_CONTENT_MANAGER_PREFIX ) ) {
261 $parent_id = str_replace( KIRKI_CONTENT_MANAGER_PREFIX . '_', '', $dynamic_content['type'] );
262 $args['post_parent'] = $parent_id;
263 }
264
265 $item_per_page = isset( $dynamic_content['items'] ) ? $dynamic_content['items'] : 3;
266 $offset = isset( $dynamic_content['offset'] ) ? $dynamic_content['offset'] : 0;
267
268 $current_page = 1;
269 if ( isset( $options['page'] ) ) {
270 $current_page = $options['page'];
271 }
272
273 $args['current_page'] = $current_page;
274 $args['item_per_page'] = $item_per_page;
275 $args['offset'] = $offset;
276
277 // if options has query value
278 if ( isset( $options['q'] ) ) {
279 $args['q'] = $options['q'];
280 }
281
282 if(empty($args['q'])){
283 $args['q'] = HelperFunctions::sanitize_text(isset($_REQUEST['q']) ?$_REQUEST['q']:'' );
284 }
285
286 if( (isset($options['inside_collection']) && $options['inside_collection'] === true) || !$is_searchable_collection_element ) {
287 // this is for nested collection like: terms, multiref etc
288 $args['current_page'] = 1;
289 $args['pagination'] = false;
290 $args['q'] = '';
291 }
292
293 return $args;
294 }
295
296 /**
297 * Dynamic content types whose values are plain text by nature and must never
298 * be rendered as live markup.
299 *
300 * Comment fields are the important case: their content is supplied by
301 * (potentially unauthenticated) visitors, so anything stored there is
302 * untrusted. Rich types — `post` (post_content), `reference`, `gallery`,
303 * `menu` — are deliberately excluded, because those are authored by users
304 * with editing capabilities and are expected to emit HTML.
305 *
306 * @return string[]
307 */
308 public static function get_plain_text_dynamic_content_types() {
309 return apply_filters( 'kirki_plain_text_dynamic_content_types', array( 'comment' ) );
310 }
311
312 /**
313 * Escape a resolved dynamic value when its type is plain text by nature.
314 *
315 * The value is decoded first and then escaped, so markup that was stored in
316 * entity-encoded form (`&lt;script&gt;`) is normalised to a single, escaped
317 * representation and displays as the literal text the visitor typed instead
318 * of turning back into a live tag further down the render pipeline.
319 *
320 * @param mixed $content The resolved dynamic value.
321 * @param array $dynamic_content The dynamic content definition.
322 * @return mixed The escaped value, or the value untouched when it is not plain text.
323 */
324 public static function esc_dynamic_text_value( $content, $dynamic_content ) {
325 if ( ! is_string( $content ) || '' === $content ) {
326 return $content;
327 }
328
329 $type = isset( $dynamic_content['type'] ) ? $dynamic_content['type'] : '';
330
331 if ( ! in_array( $type, self::get_plain_text_dynamic_content_types(), true ) ) {
332 return $content;
333 }
334
335 return htmlspecialchars(
336 html_entity_decode( $content, ENT_QUOTES | ENT_HTML5, 'UTF-8' ),
337 ENT_QUOTES,
338 'UTF-8'
339 );
340 }
341
342 public static function getDynamicRichTextValue( $dynamic_content, $options ) {
343 $html = '';
344 if ( ! $dynamic_content ) {
345 return $html;
346 }
347 // Post excerpt length for frontend. If post excerpt is used.
348 if (isset($dynamic_content['value']) && $dynamic_content['value'] === 'post_excerpt' && isset( $dynamic_content['postExcerptLength'] ) ) {
349 $post_excerpt_length = $dynamic_content['postExcerptLength'] ?? 55;
350 $GLOBALS['kirki_post_excerpt_length'] = $post_excerpt_length;
351 }
352
353 $contentInfo = array(
354 'dynamicContent' => $dynamic_content,
355 'options' => $options,
356 );
357
358 if ( isset( $options['itemType'], $options[ $options['itemType'] ], $options[ $options['itemType'] ]->ID ) ) {
359 $contentInfo['collectionItem'] = array(
360 'ID' => $options[ $options['itemType'] ]->ID,
361 );
362 }
363 $content = apply_filters( 'kirki_dynamic_content', false, $contentInfo );
364 if ( $content ) {
365 return self::esc_dynamic_text_value( $content, $dynamic_content );
366 }
367
368 // fix warning
369 if(!isset($dynamic_content['value'])){
370 $dynamic_content['value'] = false;
371 }
372
373 if ( $dynamic_content['type'] === 'post' ) {
374 $dynamic_options = array();
375 $cm_field_type = isset( $dynamic_content['cmFieldType'] ) ? $dynamic_content['cmFieldType'] : '';
376 if ( isset( $dynamic_content['format'] ) && 'post_date' === $dynamic_content['value'] ) {
377 $dynamic_options['format'] = $dynamic_content['format'];
378 } elseif ( ( 'post_time' === $dynamic_content['value'] || 'time' === $cm_field_type ) && isset( $dynamic_content['timeFormat'] ) ) {
379 $dynamic_options['timeFormat'] = $dynamic_content['timeFormat'];
380 }
381
382 $content = HelperFunctions::get_post_dynamic_content(
383 $dynamic_content['value'],
384 $options['post'] ?? null,
385 $dynamic_content['meta'] ?? '',
386 $dynamic_options
387 );
388
389 $html .= $content;
390 } elseif ( $dynamic_content['type'] === 'term' && isset( $options['term'] ) && isset( $options['term'][ $dynamic_content['value'] ] ) ) {
391 $html .= $options['term'][ $dynamic_content['value'] ];
392 } elseif ( $dynamic_content['type'] === 'user' ) {
393 // $html .= $options['user'][ $dynamic_content['value'] ];
394 $content = HelperFunctions::get_user_dynamic_content(
395 $dynamic_content['value'],
396 $options['user']['ID'] ?? null,
397 $dynamic_content['meta'] ?? ''
398 );
399
400 // Date may need to format
401 if ( 'registered_date' === $dynamic_content['value'] && isset( $dynamic_content['format'] ) ) {
402 $content = HelperFunctions::format_date( $content, $dynamic_content['format'] );
403 }
404
405 $html .= $content;
406
407 } elseif ( $dynamic_content['type'] === 'menu' && isset( $options['menu'] ) && isset( $options['menu']->{$dynamic_content['value']} ) ) {
408 $html .= $options['menu']->{$dynamic_content['value']};
409 } elseif ( $dynamic_content['type'] === 'others' && isset( $dynamic_content['value'] ) ) {
410 // Post count is used in collection item index.
411 if ( $dynamic_content['value'] === 'item_index' && isset( $options['item_index'] ) ) {
412 $content = $options['item_index'];
413
414 $html .= $content;
415 }
416 } else {
417 $item_type = $dynamic_content['type'];
418 if ( isset( $options[ $item_type ] ) ) {
419 $data = $options[ $item_type ] ?? array();
420 $value = isset( $data[ $dynamic_content['value'] ] ) ? $data[ $dynamic_content['value'] ] : '';
421 $html .= $value;
422 }
423 }
424
425 return $html;
426 }
427 }
428