PluginProbe ʕ •ᴥ•ʔ
Kirki – Freeform Page Builder, Website Builder & Customizer / 6.1.0
Kirki – Freeform Page Builder, Website Builder & Customizer v6.1.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 / customizer / packages / utils / src / Helper.php
kirki / customizer / packages / utils / src Last commit date
Setting 5 months ago Helper.php 5 months ago MaterialColors.php 5 months ago Util.php 3 weeks ago
Helper.php
413 lines
1 <?php
2 /**
3 * Helper methods
4 *
5 * @package Kirki
6 * @category Core
7 * @author Themeum
8 * @copyright Copyright (c) 2023, Themeum
9 * @license https://opensource.org/licenses/MIT
10 * @since 1.0
11 */
12
13 namespace Kirki\Util;
14
15 // Exit if accessed directly.
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit;
18 }
19
20 /**
21 * A simple object containing static methods.
22 */
23 class Helper {
24
25 /**
26 * Recursive replace in arrays.
27 *
28 * @static
29 * @access public
30 * @param array $array The first array.
31 * @param array $array1 The second array.
32 * @return mixed
33 */
34 public static function array_replace_recursive( $array, $array1 ) {
35 if ( function_exists( 'array_replace_recursive' ) ) {
36 return array_replace_recursive( $array, $array1 );
37 }
38
39 /**
40 * Handle the arguments, merge one by one.
41 *
42 * In PHP 7 func_get_args() changed the way it behaves but this doesn't mean anything in this case
43 * since this method is only used when the array_replace_recursive() function doesn't exist
44 * and that was introduced in PHP v5.3.
45 *
46 * Once WordPress-Core raises its minimum requirements we'll be able to remove this fallback completely.
47 */
48 $args = func_get_args(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue
49 $array = $args[0];
50 if ( ! is_array( $array ) ) {
51 return $array;
52 }
53 $count = count( $args );
54 for ( $i = 1; $i < $count; $i++ ) {
55 if ( is_array( $args[ $i ] ) ) {
56 $array = self::recurse( $array, $args[ $i ] );
57 }
58 }
59 return $array;
60 }
61
62 /**
63 * Helper method to be used from the array_replace_recursive method.
64 *
65 * @static
66 * @access public
67 * @param array $array The first array.
68 * @param array $array1 The second array.
69 * @return array
70 */
71 public static function recurse( $array, $array1 ) {
72 foreach ( $array1 as $key => $value ) {
73
74 // Create new key in $array, if it is empty or not an array.
75 if ( ! isset( $array[ $key ] ) || ( isset( $array[ $key ] ) && ! is_array( $array[ $key ] ) ) ) {
76 $array[ $key ] = [];
77 }
78
79 // Overwrite the value in the base array.
80 if ( is_array( $value ) ) {
81 $value = self::recurse( $array[ $key ], $value );
82 }
83 $array[ $key ] = $value;
84 }
85 return $array;
86 }
87
88 /**
89 * Initialize the WP_Filesystem.
90 *
91 * @static
92 * @access public
93 * @return object WP_Filesystem
94 */
95 public static function init_filesystem() {
96 $credentials = [];
97
98 if ( ! defined( 'FS_METHOD' ) ) {
99 define( 'FS_METHOD', 'direct' );
100 }
101
102 $method = defined( 'FS_METHOD' ) ? FS_METHOD : false;
103
104 if ( 'ftpext' === $method ) {
105 // If defined, set it to that, Else, set to NULL.
106 $credentials['hostname'] = defined( 'FTP_HOST' ) ? preg_replace( '|\w+://|', '', FTP_HOST ) : null;
107 $credentials['username'] = defined( 'FTP_USER' ) ? FTP_USER : null;
108 $credentials['password'] = defined( 'FTP_PASS' ) ? FTP_PASS : null;
109
110 // Set FTP port.
111 if ( strpos( $credentials['hostname'], ':' ) && null !== $credentials['hostname'] ) {
112 list( $credentials['hostname'], $credentials['port'] ) = explode( ':', $credentials['hostname'], 2 );
113 if ( ! is_numeric( $credentials['port'] ) ) {
114 unset( $credentials['port'] );
115 }
116 } else {
117 unset( $credentials['port'] );
118 }
119
120 // Set connection type.
121 if ( ( defined( 'FTP_SSL' ) && FTP_SSL ) && 'ftpext' === $method ) {
122 $credentials['connection_type'] = 'ftps';
123 } elseif ( ! array_filter( $credentials ) ) {
124 $credentials['connection_type'] = null;
125 } else {
126 $credentials['connection_type'] = 'ftp';
127 }
128 }
129
130 // The WordPress filesystem.
131 global $wp_filesystem;
132
133 if ( empty( $wp_filesystem ) ) {
134 require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' ); // phpcs:ignore WPThemeReview.CoreFunctionality.FileInclude
135 WP_Filesystem( $credentials );
136 }
137
138 return $wp_filesystem;
139 }
140
141 /**
142 * Returns the attachment object.
143 *
144 * @static
145 * @access public
146 * @see https://pippinsplugins.com/retrieve-attachment-id-from-image-url/
147 * @param string $url URL to the image.
148 * @return int|string Numeric ID of the attachment.
149 */
150 public static function get_image_id( $url ) {
151 global $wpdb;
152 if ( empty( $url ) ) {
153 return 0;
154 }
155
156 $attachment = wp_cache_get( 'kirki_image_id_' . md5( $url ), null );
157 if ( false === $attachment ) {
158 $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid = %s;", $url ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
159 wp_cache_add( 'kirki_image_id_' . md5( $url ), $attachment, null );
160 }
161
162 if ( ! empty( $attachment ) ) {
163 return $attachment[0];
164 }
165 return 0;
166 }
167
168 /**
169 * Returns an array of the attachment's properties.
170 *
171 * @param string $url URL to the image.
172 * @return array
173 */
174 public static function get_image_from_url( $url ) {
175 $image_id = self::get_image_id( $url );
176 $image = wp_get_attachment_image_src( $image_id, 'full' );
177
178 return [
179 'url' => $image[0],
180 'width' => $image[1],
181 'height' => $image[2],
182 'thumbnail' => $image[3],
183 ];
184 }
185
186 /**
187 * Get an array of posts.
188 *
189 * @static
190 * @access public
191 * @param array $args Define arguments for the get_posts function.
192 * @return array
193 */
194 public static function get_posts( $args ) {
195 if ( is_string( $args ) ) {
196 $args = add_query_arg(
197 [
198 'suppress_filters' => false,
199 ]
200 );
201 } elseif ( is_array( $args ) && ! isset( $args['suppress_filters'] ) ) {
202 $args['suppress_filters'] = false;
203 }
204
205 // Get the posts.
206 // TODO: WordPress.VIP.RestrictedFunctions.get_posts_get_posts.
207 $posts = get_posts( $args );
208
209 // Properly format the array.
210 $items = [];
211 foreach ( $posts as $post ) {
212 $items[ $post->ID ] = $post->post_title;
213 }
214 wp_reset_postdata();
215
216 return $items;
217 }
218
219 /**
220 * Get an array of publicly-querable taxonomies.
221 *
222 * @static
223 * @access public
224 * @return array
225 */
226 public static function get_taxonomies() {
227 $items = [];
228
229 // Get the taxonomies.
230 $taxonomies = get_taxonomies(
231 [
232 'public' => true,
233 ]
234 );
235
236 // Build the array.
237 foreach ( $taxonomies as $taxonomy ) {
238 $id = $taxonomy;
239 $taxonomy = get_taxonomy( $taxonomy );
240 $items[ $id ] = $taxonomy->labels->name;
241 }
242
243 return $items;
244 }
245
246 /**
247 * Get an array of publicly-querable post-types.
248 *
249 * @static
250 * @access public
251 * @return array
252 */
253 public static function get_post_types() {
254 $items = [];
255
256 // Get the post types.
257 $post_types = get_post_types(
258 [
259 'public' => true,
260 ],
261 'objects'
262 );
263
264 // Build the array.
265 foreach ( $post_types as $post_type ) {
266 $items[ $post_type->name ] = $post_type->labels->name;
267 }
268
269 return $items;
270 }
271
272 /**
273 * Get an array of terms from a taxonomy.
274 *
275 * @static
276 * @access public
277 * @param string|array $taxonomies See https://developer.wordpress.org/reference/functions/get_terms/ for details.
278 * @return array
279 */
280 public static function get_terms( $taxonomies ) {
281 $items = [];
282
283 // Get the post types.
284 $terms = get_terms( $taxonomies );
285
286 // Build the array.
287 foreach ( $terms as $term ) {
288 $items[ $term->term_id ] = $term->name;
289 }
290
291 return $items;
292 }
293
294 /**
295 * Returns an array of navigation menus.
296 *
297 * @access public
298 * @param string $value_field The value to be stored in options. Accepted values: id|slug.
299 * @return array
300 */
301 public static function get_nav_menus( $value_field = 'id' ) {
302 $choices = [];
303 $nav_menus = wp_get_nav_menus();
304
305 foreach ( $nav_menus as $term ) {
306 $choices[ 'slug' === $value_field ? $term->slug : $term->term_id ] = $term->name;
307 }
308
309 return $choices;
310 }
311
312 /**
313 * Gets an array of material-design colors.
314 *
315 * @static
316 * @access public
317 * @param string $context Allows us to get subsets of the palette.
318 * @return array
319 */
320 public static function get_material_design_colors( $context = 'primary' ) {
321 return \Kirki\Util\MaterialColors::get_colors( $context );
322 }
323
324 /**
325 * Get an array of all available dashicons.
326 *
327 * @static
328 * @access public
329 * @return array
330 */
331 public static function get_dashicons() {
332 if ( class_exists( '\Kirki\Util\Dashicons' ) ) {
333 return \Kirki\Util\Dashicons::get_icons();
334 }
335 return [];
336 }
337
338 /**
339 * Compares the 2 values given the condition
340 *
341 * @param mixed $value1 The 1st value in the comparison.
342 * @param mixed $value2 The 2nd value in the comparison.
343 * @param string $operator The operator we'll use for the comparison.
344 * @return boolean whether The comparison has succeeded (true) or failed (false).
345 */
346 public static function compare_values( $value1, $value2, $operator ) {
347 if ( '===' === $operator ) {
348 return $value1 === $value2;
349 }
350 if ( '!==' === $operator ) {
351 return $value1 !== $value2;
352 }
353 if ( ( '!=' === $operator || 'not equal' === $operator ) ) {
354 return $value1 != $value2; // phpcs:ignore WordPress.PHP.StrictComparisons
355 }
356 if ( ( '>=' === $operator || 'greater or equal' === $operator || 'equal or greater' === $operator ) ) {
357 return $value2 >= $value1;
358 }
359 if ( ( '<=' === $operator || 'smaller or equal' === $operator || 'equal or smaller' === $operator ) ) {
360 return $value2 <= $value1;
361 }
362 if ( ( '>' === $operator || 'greater' === $operator ) ) {
363 return $value2 > $value1;
364 }
365 if ( ( '<' === $operator || 'smaller' === $operator ) ) {
366 return $value2 < $value1;
367 }
368 if ( 'contains' === $operator || 'in' === $operator ) {
369 if ( is_array( $value1 ) && is_array( $value2 ) ) {
370 foreach ( $value2 as $val ) {
371 if ( in_array( $val, $value1 ) ) { // phpcs:ignore WordPress.PHP.StrictInArray
372 return true;
373 }
374 }
375 return false;
376 }
377 if ( is_array( $value1 ) && ! is_array( $value2 ) ) {
378 return in_array( $value2, $value1 ); // phpcs:ignore WordPress.PHP.StrictInArray
379 }
380 if ( is_array( $value2 ) && ! is_array( $value1 ) ) {
381 return in_array( $value1, $value2 ); // phpcs:ignore WordPress.PHP.StrictInArray
382 }
383 return ( false !== strrpos( $value1, $value2 ) || false !== strpos( $value2, $value1 ) );
384 }
385 if ( 'does not contain' === $operator || 'not in' === $operator ) {
386 return ! self::compare_values( $value1, $value2, $operator );
387 }
388 return $value1 == $value2; // phpcs:ignore WordPress.PHP.StrictComparisons
389 }
390
391 /**
392 * Prepare PHP array to be used as JS object.
393 *
394 * @see See https://developer.wordpress.org/reference/classes/wp_scripts/localize/
395 *
396 * @param array $values The data which can be either a single or multi-dimensional array.
397 * @return array
398 */
399 public static function prepare_php_array_for_js( $values ) {
400
401 foreach ( $values as $key => $value ) {
402 if ( ! is_scalar( $value ) ) {
403 continue;
404 }
405
406 $values[ $key ] = html_entity_decode( (string) $value, ENT_QUOTES, 'UTF-8' );
407 }
408
409 return $values;
410
411 }
412 }
413