PluginProbe ʕ •ᴥ•ʔ
Hustle – Email Marketing, Lead Generation, Optins, Popups / 7.2.1
Hustle – Email Marketing, Lead Generation, Optins, Popups v7.2.1
7.8.14.2 7.8.14 7.8.14.1 7.8.13 7.8.13.1 trunk 3.0 3.1 3.1.1 3.1.2 3.1.3 3.1.4 4.3.2 4.4.4 4.4.5 4.4.5.1 4.4.5.4 4.6 4.6.1.1 4.6.1.4 4.7.0.2 4.7.0.3 4.7.0.7 4.7.0.9 4.7.1.0 4.7.1.1 4.8.0.0 5.0.0 5.0.1 5.0.1.1 5.0.1.2 5.1 5.1.1 5.1.2 5.1.3 5.1.3.1 5.1.3.2 5.1.4 5.1.5 6.0 6.0.1 6.0.2 6.0.3 6.0.4.2 6.0.5 6.0.6.1 6.0.7 6.0.8.1 6.0.9 7.0.0.1 7.0.2 7.0.3 7.0.4 7.1.0 7.1.1 7.2.0 7.2.1 7.3.0 7.3.1 7.3.3 7.3.5 7.3.6 7.3.7 7.4.0 7.4.1 7.4.11 7.4.13 7.4.13.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.5.1 7.4.5.2 7.4.6 7.4.7 7.5.0 7.6.0 7.6.1 7.6.3 7.6.4 7.6.6 7.7.0 7.7.1 7.8.0 7.8.1 7.8.10 7.8.10.1 7.8.10.2 7.8.11 7.8.12 7.8.12.1 7.8.2 7.8.3 7.8.4 7.8.5 7.8.6 7.8.7 7.8.8 7.8.9 7.8.9.1 7.8.9.2 7.8.9.3
wordpress-popup / inc / opt-in-utils.php
wordpress-popup / inc Last commit date
display-conditions 6 years ago helpers 6 years ago metas 6 years ago provider 6 years ago providers 6 years ago update 6 years ago class-hustle-admin-page-abstract.php 6 years ago class-hustle-condition-factory.php 6 years ago class-hustle-dashboard-admin.php 6 years ago class-hustle-data.php 6 years ago class-hustle-db.php 6 years ago class-hustle-module-collection.php 6 years ago class-hustle-module-page-abstract.php 6 years ago class-hustle-notifications.php 6 years ago class-hustle-wp-dashboard-page.php 6 years ago hustle-admin-common.php 6 years ago hustle-collection.php 6 years ago hustle-deletion.php 6 years ago hustle-embedded-admin.php 6 years ago hustle-entries-admin.php 6 years ago hustle-entry-model.php 6 years ago hustle-general-data-protection.php 6 years ago hustle-init.php 6 years ago hustle-mail.php 6 years ago hustle-meta.php 6 years ago hustle-migration.php 6 years ago hustle-model.php 6 years ago hustle-module-admin.php 6 years ago hustle-module-decorator.php 6 years ago hustle-module-front-ajax.php 6 years ago hustle-module-front.php 6 years ago hustle-module-model.php 6 years ago hustle-module-renderer.php 6 years ago hustle-module-widget-legacy.php 6 years ago hustle-module-widget.php 6 years ago hustle-modules-common-admin-ajax.php 6 years ago hustle-modules-common-admin.php 6 years ago hustle-popup-admin.php 6 years ago hustle-providers-admin.php 6 years ago hustle-providers.php 6 years ago hustle-renderer-abstract.php 6 years ago hustle-renderer-sshare.php 6 years ago hustle-settings-admin-ajax.php 6 years ago hustle-settings-admin.php 6 years ago hustle-settings-page.php 6 years ago hustle-slidein-admin.php 6 years ago hustle-sshare-admin.php 6 years ago hustle-sshare-model.php 6 years ago hustle-tracking-model.php 6 years ago opt-in-geo.php 6 years ago opt-in-utils.php 6 years ago opt-in-wpmudev-api.php 6 years ago
opt-in-utils.php
1663 lines
1 <?php
2
3 /**
4 * Conditions utils
5 *
6 * Most of the methods are courtesy Philipp Stracker
7 *
8 * Class Opt_In_Utils
9 */
10 class Opt_In_Utils {
11
12 /**
13 * Instance of Opt_In_Geo
14 *
15 * @var Opt_In_Geo
16 */
17 private $geo;
18
19 /**
20 * CPT
21 *
22 * @var array
23 */
24 private static $post_types;
25
26 /**
27 * Array of administrator roles
28 *
29 * @var array
30 */
31 private static $admin_roles;
32
33 public static $comment;
34
35 public function __construct( Opt_In_Geo $geo ) {
36 $this->geo = $geo;
37 }
38
39 /**
40 * Checks if user has already commented
41 *
42 * @return bool|int
43 */
44 public function has_user_commented() {
45 if ( null === self::$comment ) {
46 // Guests (and maybe logged in users) are tracked via a cookie.
47 self::$comment = isset( $_COOKIE[ 'comment_author_' . COOKIEHASH ] ) ? 1 : 0;
48
49 if ( ! self::$comment && is_user_logged_in() ) {
50 // For logged-in users we can also check the database.
51 $count = get_comments(
52 array(
53 'count' => true,
54 'user_id' => get_current_user_id(),
55 )
56 );
57 self::$comment = $count > 0;
58 }
59 }
60 return self::$comment;
61 }
62
63 /**
64 * Returns the referrer.
65 *
66 * @return string
67 */
68 public function get_referrer() {
69 $referrer = '';
70
71 $is_ajax = ( defined( 'DOING_AJAX' ) && DOING_AJAX )
72 || ( ! empty( $_POST['_po_method_'] ) && 'raw' === $_POST['_po_method_'] ); // WPCS: CSRF ok.
73
74 if ( isset( $_REQUEST['thereferrer'] ) ) { // WPCS: CSRF ok.
75 $referrer = $_REQUEST['thereferrer']; // WPCS: CSRF ok.
76 } elseif ( ! $is_ajax && isset( $_SERVER['HTTP_REFERER'] ) ) {
77 // When doing Ajax request we NEVER use the HTTP_REFERER!
78 $referrer = $_SERVER['HTTP_REFERER'];
79 }
80
81 return $referrer;
82 }
83
84 /**
85 * Tests if the current referrer is one of the referers of the list.
86 * Current referrer has to be specified in the URL param "thereferer".
87 *
88 * @param array $list List of referers to check.
89 * @return bool
90 */
91 public function test_referrer( $list ) {
92 $response = false;
93 if ( is_string( $list ) ) {
94 $list = preg_split( '/\r\n|\r|\n/', $list );
95 }
96 if ( ! is_array( $list ) ) {
97 return true;
98 }
99
100 $referrer = $this->get_referrer();
101
102 if ( ! empty( $referrer ) ) {
103 foreach ( $list as $item ) {
104 $item = trim( $item );
105 $res = stripos( $referrer, $item );
106 if ( false !== $res ) {
107 $response = true;
108 break;
109 }
110 }
111 }
112
113 return $response;
114 }
115
116 /**
117 * Tests if the $test_url matches any pattern defined in the $list.
118 *
119 * @since 4.6
120 * @param string $test_url The URL to test.
121 * @param array $list List of URL-patterns to test against.
122 * @return bool
123 */
124 public function check_url( $list ) {
125 $response = false;
126
127 $list = array_map( 'trim', (array) $list );
128 if ( empty( $list ) ) {
129 $response = true;
130
131 } else {
132
133 $test_url = strtok( $this->get_current_actual_url( true ), '#' );
134 $test_url_no_protocol = strtok( $this->get_current_actual_url(), '#' );
135
136 foreach ( $list as $match ) {
137 $match = strtok( $match, '#' );
138
139 // We're using '%' at the beggining of the string in visibility conditions to differentiate
140 // regular urls from regex. If it's not regex, use regular url check.
141 if ( 0 !== strpos( $match, '%' ) ) {
142
143 // Check if we're using a wildcard.
144 if ( false === strpos( $match, '*' ) ) {
145 $match = preg_quote( $match, null );
146 if ( false === strpos( $match, '://' ) ) {
147 $match = '\w+://' . $match;
148 }
149 if ( '/' !== substr( $match, -1 ) ) {
150 $match .= '/?';
151 } else {
152 $match .= '?';
153 }
154 $exp = '#^' . $match . '$#i';
155
156 $res = preg_match( $exp, $test_url );
157
158 } else {
159 // Check wildcards.
160 $res = fnmatch( $match, $test_url_no_protocol );
161 }
162 } else {
163 // Check for regex urls.
164 $match = ltrim( $match, '%' );
165 $exp = $match;
166
167 $res = preg_match( $exp, $test_url );
168 }
169
170 if ( $res ) {
171 $response = true;
172 break;
173 }
174 }
175 }
176
177 return $response;
178 }
179
180 /**
181 * Returns current url
182 * should only be called after plugins_loaded hook is fired
183 *
184 * @return string
185 */
186 public static function get_current_url() {
187 if ( ! did_action( 'plugins_loaded' ) ) {
188 new Exception( 'This method should only be called after plugins_loaded hook is fired' ); }
189
190 global $wp;
191 return add_query_arg( $wp->query_string, '', home_url( $wp->request ) );
192 }
193
194 /**
195 * Returns current actual url, the one seen on browser
196 *
197 * @return string
198 */
199 public function get_current_actual_url( $with_protocol = false ) {
200 if ( ! did_action( 'plugins_loaded' ) ) {
201 new Exception( 'This method should only be called after plugins_loaded hook is fired' ); }
202
203 if ( ! $with_protocol ) {
204 return "$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
205 }
206 return 'http' . ( isset( $_SERVER['HTTPS'] ) ? 's' : '' ) . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
207 }
208
209 /**
210 * Checks if the current user IP belongs to one of the countries defined in
211 * country_codes list.
212 *
213 * @param array $country_codes List of country codes.
214 * @return bool
215 */
216 public function test_country( $country_codes ) {
217 $response = true;
218 $country = $this->geo->get_user_country();
219
220 if ( 'XX' === $country ) {
221 return $response;
222 }
223
224 return in_array( $country, (array) $country_codes, true );
225 }
226
227 /**
228 * Checks if user is allowed to perform the ajax actions
229 *
230 * @since 4.0
231 * @param array $capability Hustle capability
232 * @param int $module_id Optional. Module id
233 */
234 public static function is_user_allowed_ajax( $capability, $module_id = null ) {
235 if ( is_null( $module_id ) ) {
236 $allowed = current_user_can( $capability );
237 } else {
238 $allowed = self::is_user_allowed( $capability, $module_id );
239 }
240
241 if ( ! $allowed ) {
242 wp_send_json_error( __( 'Invalid request, you are not allowed to make this request', 'hustle' ) );
243 }
244 }
245
246 /**
247 * Check is it admin role or not
248 *
249 * @param string|array $role
250 * @return bool
251 */
252 public static function is_admin_role( $role ) {
253 $admin_roles = array_keys( self::get_admin_roles() );
254
255 if ( ! is_array( $role ) ) {
256 return in_array( $role, $admin_roles, true );
257 }
258
259 return (bool) array_intersect( $role, $admin_roles );
260 }
261
262 /**
263 * Get admin role array
264 *
265 * @since 4.1.0
266 * @return array
267 */
268 public static function get_admin_roles() {
269
270 if ( is_null( self::$admin_roles ) ) {
271 $admins = array();
272 $all_roles = wp_roles();
273
274 if ( $all_roles->is_role( 'administrator' ) ) {
275 $admins['administrator'] = ucfirst( translate_user_role( 'administrator', 'hustle' ) );
276
277 } else {
278 foreach ( $all_roles->roles as $name => $data ) {
279 if ( ! empty( $data['capabilities']['manage_options'] ) && true === $data['capabilities']['manage_options'] ) {
280 $admins[ $name ] = $data['name'];
281 }
282 }
283 }
284
285 self::$admin_roles = apply_filters( 'hustle_get_admin_roles', $admins );
286 }
287
288 return self::$admin_roles;
289 }
290
291 /**
292 * Get short days names html escaped and translated
293 *
294 * @since 4.0
295 * @return array
296 */
297 public static function get_short_days_names() {
298 return array(
299 esc_html__( 'Su', 'hustle' ),
300 esc_html__( 'Mo', 'hustle' ),
301 esc_html__( 'Tu', 'hustle' ),
302 esc_html__( 'We', 'hustle' ),
303 esc_html__( 'Th', 'hustle' ),
304 esc_html__( 'Fr', 'hustle' ),
305 esc_html__( 'Sa', 'hustle' ),
306 );
307 }
308
309 /**
310 * Checks if user has the capability
311 *
312 * @since 4.0
313 * @param array $capability Hustle capability
314 * @param int $module_id Optional. Module id
315 * @return bool
316 */
317 public static function is_user_allowed( $capability, $module_id = null ) {
318
319 // Super admins can do everything.
320 if ( current_user_can( 'setup_network' ) ) {
321 return true;
322 }
323
324 $user = wp_get_current_user();
325 $current_user_caps = (array) $user->allcaps;
326 $current_user_roles = (array) $user->roles;
327
328 if ( self::is_admin_role( $current_user_roles ) ) {
329 // If editing a module and the user is godish, allow.
330 return true;
331
332 } elseif ( 'hustle_edit_module' === $capability && ! empty( $current_user_caps['hustle_create'] ) ) {
333 // If the user can create, it also can edit. Allow.
334 return true;
335
336 } elseif ( is_null( $module_id ) ) {
337 // If we're not editing a module, check for the requested capability.
338 return ! empty( $current_user_caps[ $capability ] );
339
340 } else {
341
342 // If editing a module and the user isn't godish...
343 $module = Hustle_Module_Model::instance()->get( $module_id );
344
345 // If the module isn't valid, abort.
346 if ( is_wp_error( $module ) ) {
347 return false;
348 }
349
350 // Check for the specific allowed roles.
351 $allowed_roles = $module->get_edit_roles();
352 return (bool) array_intersect( $allowed_roles, $current_user_roles );
353 }
354
355 return false;
356 }
357
358 /**
359 * Checks if the ajax
360 *
361 * @since 1.0
362 * @param $action string ajax call action name
363 */
364 public static function validate_ajax_call( $action ) {
365 if ( ! check_ajax_referer( $action, false, false ) ) {
366 wp_send_json_error( __( 'Invalid request, you are not allowed to make this request', 'hustle' ) ); }
367 }
368
369 /**
370 * Verify if current version is FREE
371 **/
372 public static function _is_free() {
373 $is_free = ! file_exists( Opt_In::$plugin_path . 'lib/wpmudev-dashboard/wpmudev-dash-notification.php' );
374
375 return $is_free;
376 }
377
378 /**
379 * Remove "-pro" that came from the menu which causes template not to work
380 **/
381 public static function clean_current_screen( $screen ) {
382 return str_replace( 'hustle-pro', 'hustle', $screen );
383 }
384
385 /**
386 * Get the user roles options.
387 *
388 * @since 4.0
389 *
390 * @return array
391 */
392 public static function get_user_roles() {
393
394 global $wp_roles;
395 $roles = $wp_roles->get_names();
396
397 return apply_filters( 'hustle_get_module_permissions_roles', $roles );
398 }
399
400 // ====================================
401 // INTEGRATIONS
402 // ====================================
403
404 /**
405 * Used for sanitizing form submissions.
406 * This method will do a simple sanitation of $post_data. It applies sanitize_text_field() to the keys and values of the first level array.
407 * The keys from second level arrays are converted to numbers, and their values are sanitized with sanitize_text_field() as well.
408 * This method doesn’t do an exhaustive sanitation, so you should handled special cases if your integration requires something different.
409 * The names passed on $required_fields are searched into $post_data array keys. If the key is not set, an array with the key “errors” is returned.
410 *
411 * @since 3.0.5
412 * @param array $post_data The data to be sanitized and validated.
413 * @param array $required_fields Fields that must exist on $post_data so the validation doesn't fail.
414 * @return array
415 */
416 public static function validate_and_sanitize_fields( $post_data, $required_fields = array() ) {
417 // for serialized data or form
418 if ( ! is_array( $post_data ) && is_string( $post_data ) ) {
419 $post_string = $post_data;
420 $post_data = array();
421 wp_parse_str( $post_string, $post_data );
422 }
423
424 $errors = array();
425 foreach ( $required_fields as $key => $required_field ) {
426 if ( ! isset( $post_data[ $required_field ] ) || ( empty( trim( $post_data[ $required_field ] ) ) && '0' !== $post_data[ $required_field ] ) ) {
427 /* translators: ... */
428 $errors[ $required_field ] = sprintf( __( 'Field %s is required.', 'hustle' ), $required_field );
429 continue;
430 }
431 }
432
433 if ( ! empty( $errors ) ) {
434 return array( 'errors' => $errors );
435 }
436
437 $sanitized_data = array();
438 foreach ( $post_data as $key => $post_datum ) {
439 /**
440 * Sanitize here every request so we dont need to sanitize it again on other methods,
441 * unless special treatment is required.
442 */
443 $sanitized_data[ sanitize_text_field( $key ) ] = self::sanitize_text_input_deep( $post_datum );
444 }
445
446 return $sanitized_data;
447 }
448
449 /**
450 * Sanitizes the values of a multi-dimensional array.
451 * The keys of the sub-arrays are converted to numerical arrays.
452 * Sub-arrays are expected to have numerical indexes.
453 *
454 * @since 3.0.5
455 * @param array|string $value
456 * @return string
457 */
458 public static function sanitize_text_input_deep( $value, $key = null ) {
459 $value = is_array( $value ) ?
460 array_map( array( 'Opt_In_Utils', 'sanitize_text_input_deep' ), $value, array_keys( $value ) ) :
461 sanitize_text_field( $value );
462
463 return $value;
464 }
465
466 /**
467 * Adds an entry to debug log
468 *
469 * By default it will check `WP_DEBUG` and HUSTLE_DEBUG to decide whether to add the log,
470 * then will check `filters`.
471 *
472 * @since 3.0.5
473 * @since 4.0 also checks HUSTLE_DEBUG
474 */
475 public static function maybe_log() {
476
477 $wp_debug_enabled = ( defined( 'WP_DEBUG' ) && WP_DEBUG );
478
479 $enabled = ( defined( 'HUSTLE_DEBUG' ) && HUSTLE_DEBUG );
480
481 $stored_settings = Hustle_Settings_Admin::get_general_settings();
482 $debug_setting_enabled = '1' === $stored_settings['debug_enabled'];
483
484 $enabled = ( $wp_debug_enabled && ( $debug_setting_enabled || $enabled ) );
485
486 /**
487 * Filter to enable or disable log for Hustle
488 *
489 * By default it will check `WP_DEBUG`
490 *
491 * @since 3.0.5
492 *
493 * @param bool $enabled current enabled status
494 */
495 $enabled = apply_filters( 'hustle_enable_log', $enabled );
496
497 if ( $enabled ) {
498 $args = func_get_args();
499 $message = wp_json_encode( $args );
500 if ( false !== $message ) {
501 error_log( '[Hustle] ' . $message ); // phpcs:ignore
502 }
503 }
504 }
505
506
507 // ====================================
508 // MARKUPS
509 // ====================================
510
511 /**
512 * Image function
513 *
514 * Return image element with 2x and 1x support.
515 *
516 * @since 4.0.0
517 */
518 public static function hustle_image( $image_path, $image_suffix, $image_class, $support ) {
519 $image = '';
520 /**
521 * White labeling based on Dash Plugin Settings
522 */
523 $hide_branding = apply_filters( 'wpmudev_branding_hide_branding', false );
524 if ( $hide_branding ) {
525 return $image;
526 }
527 $image_name = esc_html__( 'Hustle image', 'hustle' );
528 if ( ( true === $support ) || ( '2x' === $support ) ) {
529 if ( '' !== $image_class ) {
530 $image = '<img src="' . $image_path . '.' . $image_suffix . '" srcset="' . $image_path . '.' . $image_suffix . ' 1x, ' . $image_path . '@2x' . '.' . $image_suffix . ' 2x" alt="' . $image_name . '" class="' . $image_class . '" aria-hidden="true">';
531 } else {
532 $image = '<img src="' . $image_path . '.' . $image_suffix . '" srcset="' . $image_path . '.' . $image_suffix . ' 1x, ' . $image_path . '@2x' . '.' . $image_suffix . ' 2x" alt="' . $image_name . '" aria-hidden="true">';
533 }
534 } else {
535 if ( '' !== $image_class ) {
536 $image = '<img src="' . $image_path . '.' . $image_suffix . '" alt="' . $image_name . '" class="' . $image_class . '" aria-hidden="true">';
537 } else {
538 $image = '<img src="' . $image_path . '.' . $image_suffix . '" alt="' . $image_name . '" aria-hidden="true">';
539 }
540 }
541 echo $image; // phpcs:ignore
542 }
543
544 /**
545 * Color Picker
546 *
547 * Return the correct color picker markup that's compatible with Shared UI 2.0
548 *
549 * @since 4.0.0
550 * @since 4.1.1 Params $is_js_template and $value added.
551 *
552 * @param string $id "id" attribute of the input.
553 * @param string $name "name" attribute of the input.
554 * @param string $alpha "false"/"true". Enables or disables the alpha selector in the colorpicker.
555 * @param bool $is_js_template whether this colorpicker will be filled via js templating.
556 * @param string $value Value to be used when js templating isn't used.
557 */
558 public static function sui_colorpicker( $id, $name, $alpha = 'false', $is_js_template = true, $value = false ) {
559
560 $value = ( ! $is_js_template && $value ) ? esc_attr( $value ) : '{{ ' . esc_attr( $name ) . ' }}';
561
562 echo '<div class="sui-colorpicker-wrap">
563
564 <div class="sui-colorpicker" aria-hidden="true">
565 <div class="sui-colorpicker-value">
566 <span role="button">
567 <span style="background-color: ' . $value . '"></span>
568 </span>
569 <input class="hustle-colorpicker-input" type="text" value="' . $value . '"/>
570 <button><span class="sui-icon-close" aria-hidden="true"></span></button>
571 </div>
572 <button class="sui-button">' . esc_html__( 'Select', 'hustle' ) . '</button>
573 </div>
574
575 <input type="text"
576 name="' . esc_attr( $name ) . '"
577 value="' . $value . '"
578 id="' . esc_attr( $id ) . '"
579 class="sui-colorpicker-input"
580 data-alpha="' . esc_attr( $alpha ) . '"
581 data-attribute="' . esc_attr( $name ) . '" />
582
583 </div>';
584
585 }
586
587 /**
588 * Return the image markup for retina and no retina images
589 *
590 * @since 4.0
591 *
592 * @param string $image_path
593 * @param string $class
594 * @param string $retina_image_path
595 * @return string
596 */
597 public static function render_image_markup( $image_path, $image_retina_path = '', $image_class = '', $image_width = '', $image_height = '' ) {
598
599 $image = '';
600
601 $image_path = esc_url( $image_path );
602 $image_srcset = '';
603 $image_styles = '';
604
605 if ( ! empty( $image_retina_path ) || '' !== $image_retina_path ) {
606 $image_srcset = $image_path . ' 1x, ' . esc_url( $image_retina_path ) . ' 2x';
607 }
608
609 if ( '' !== $image_width || '' !== $image_height ) {
610
611 $image_styles .= ' styles="';
612
613 if ( '' !== $image_width ) {
614 $image_styles = 'max-width: ' . $image_width . 'px';
615
616 if ( '' !== $image_height ) {
617 $image_styles = ' ';
618 }
619 }
620
621 if ( '' !== $image_height ) {
622 $image_styles = 'max-height: ' . $image_height . 'px';
623 }
624
625 $image_styles .= '"';
626
627 }
628
629 $image .= '<img';
630
631 $image .= ' src="' . $image_path . '"';
632
633 if ( '' !== $image_srcset ) {
634 $image .= ' srcset="' . $image_srcset . '"';
635 }
636
637 $image .= ' title="Hustle image"';
638 $image .= ' alt="Hustle image commonly Hustle-Man doing something fun"';
639
640 if ( ! empty( $image_class ) || '' !== $image_class ) {
641 $image .= ' class="' . $image_class . '"';
642 }
643
644 $image .= ' aria-hidden="true"';
645
646 $image .= '/>';
647
648 return $image;
649 }
650
651
652 // ====================================
653 // MISC?
654 // ====================================
655
656 /**
657 * Returns list of optin providers based on their declared classes that implement Opt_In_Provider_Interface
658 *
659 * @return array
660 */
661 public static function get_post_types() {
662 if ( empty( self::$post_types ) ) {
663 /**
664 * Add all custom post types
665 */
666 $post_types = array();
667 $cpts = get_post_types(
668 array(
669 'public' => true,
670 '_builtin' => false,
671 ),
672 'objects'
673 );
674 foreach ( $cpts as $cpt ) {
675
676 // skip ms_invoice
677 if ( 'ms_invoice' === $cpt->name ) {
678 continue;
679 }
680
681 $cpt_array['name'] = $cpt->name;
682 $cpt_array['label'] = $cpt->label;
683 $cpt_array['data'] = self::get_select2_data( $cpt->name );
684
685 $post_types[ $cpt->name ] = $cpt_array;
686 }
687 self::$post_types = $post_types;
688 }
689 return self::$post_types;
690 }
691
692
693 /**
694 * Get usable object for select2
695 *
696 * @param $post_type post type
697 * @return array
698 */
699 public static function get_select2_data( $post_type, $include_ids = null ) {
700 $data = array();
701
702 // We only make query if include_ids are set becuase in other cases the posts
703 // the data is gathered with AJAX.
704 if ( ! empty( $include_ids ) ) {
705 $args = array(
706 'numberposts' => -1,
707 'post_type' => $post_type,
708 'post_status' => 'publish',
709 'order' => 'ASC',
710 'post__in' => $include_ids,
711 );
712
713 $posts = get_posts( $args );
714 foreach ( $posts as $post ) {
715 $data[] = (object) array(
716 'id' => $post->ID,
717 'text' => $post->post_title,
718 );
719 }
720 }
721
722 return $data;
723 }
724
725
726 /**
727 * Return time periods (AM,PM)
728 *
729 * @since 4.0
730 * @return array
731 */
732 public static function get_time_periods() {
733 $periods = array(
734 'am' => __( 'AM', 'hustle' ),
735 'pm' => __( 'PM', 'hustle' ),
736 );
737
738 return $periods;
739 }
740
741
742 /**
743 * Return date formats
744 *
745 * @since 4.0
746 * @return array
747 */
748 public static function get_date_formats() {
749 $formats = array(
750 'yy/mm/dd' => __( '2012/07/31', 'hustle' ),
751 'mm/dd/yy' => __( '07/31/2012', 'hustle' ),
752 'dd/mm/yy' => __( '31/07/2012', 'hustle' ),
753 'yy, MM d' => __( '2012, July 31', 'hustle' ),
754 'd MM, yy' => __( '31 July, 2012', 'hustle' ),
755 'MM d, yy' => __( 'July 31, 2012', 'hustle' ),
756 'dd-mm-yy' => __( '31-07-2012', 'hustle' ),
757 'mm-dd-yy' => __( '07-31-2012', 'hustle' ),
758 'yy-mm-dd' => __( '2012-07-31', 'hustle' ),
759 'dd.mm.yy' => __( '31.07.2012', 'hustle' ),
760 'mm.dd.yy' => __( '07.31.2012', 'hustle' ),
761 'yy.mm.dd' => __( '2012.07.31', 'hustle' ),
762 );
763
764 $formats = apply_filters( 'hustle_date_formats', $formats );
765
766 return $formats;
767 }
768
769 /**
770 * Get the months as translatable strings.
771 *
772 * @since 4.0.4
773 * @param string $version full|short
774 * @return array
775 */
776 public static function get_months( $version = 'full' ) {
777
778 if ( 'full' === $version ) {
779 $months = array(
780 esc_html__( 'January', 'hustle' ),
781 esc_html__( 'February', 'hustle' ),
782 esc_html__( 'March', 'hustle' ),
783 esc_html__( 'April', 'hustle' ),
784 esc_html__( 'May', 'hustle' ),
785 esc_html__( 'June', 'hustle' ),
786 esc_html__( 'July', 'hustle' ),
787 esc_html__( 'August', 'hustle' ),
788 esc_html__( 'September', 'hustle' ),
789 esc_html__( 'October', 'hustle' ),
790 esc_html__( 'November', 'hustle' ),
791 esc_html__( 'December', 'hustle' ),
792 );
793
794 } else {
795 $months = array(
796 esc_html__( 'Jan', 'hustle' ),
797 esc_html__( 'Feb', 'hustle' ),
798 esc_html__( 'Mar', 'hustle' ),
799 esc_html__( 'Apr', 'hustle' ),
800 esc_html__( 'May', 'hustle' ),
801 esc_html__( 'Jun', 'hustle' ),
802 esc_html__( 'Jul', 'hustle' ),
803 esc_html__( 'Aug', 'hustle' ),
804 esc_html__( 'Sep', 'hustle' ),
805 esc_html__( 'Oct', 'hustle' ),
806 esc_html__( 'Nov', 'hustle' ),
807 esc_html__( 'Dec', 'hustle' ),
808 );
809 }
810
811 return apply_filters( 'hustle_get_months', $months, $version );
812 }
813
814 /**
815 * Get the week days as translatable strings.
816 *
817 * @since 4.0.4
818 * @param string $version full|short|min
819 * @return array
820 */
821 public static function get_week_days( $version = 'full' ) {
822
823 if ( 'full' === $version ) {
824 $days = array(
825 esc_html__( 'Sunday', 'hustle' ),
826 esc_html__( 'Monday', 'hustle' ),
827 esc_html__( 'Tuesday', 'hustle' ),
828 esc_html__( 'Wednesday', 'hustle' ),
829 esc_html__( 'Thursday', 'hustle' ),
830 esc_html__( 'Friday', 'hustle' ),
831 esc_html__( 'Saturday', 'hustle' ),
832 );
833
834 } elseif ( 'short' === $version ) {
835 $days = array(
836 esc_html__( 'Sun', 'hustle' ),
837 esc_html__( 'Mon', 'hustle' ),
838 esc_html__( 'Tue', 'hustle' ),
839 esc_html__( 'Wed', 'hustle' ),
840 esc_html__( 'Thu', 'hustle' ),
841 esc_html__( 'Fri', 'hustle' ),
842 esc_html__( 'Sat', 'hustle' ),
843 );
844
845 } else {
846 $days = array(
847 esc_html__( 'Su', 'hustle' ),
848 esc_html__( 'Mo', 'hustle' ),
849 esc_html__( 'Tu', 'hustle' ),
850 esc_html__( 'We', 'hustle' ),
851 esc_html__( 'Th', 'hustle' ),
852 esc_html__( 'Fr', 'hustle' ),
853 esc_html__( 'Sa', 'hustle' ),
854 );
855 }
856
857 return apply_filters( 'hustle_get_months', $days, $version );
858 }
859
860 /**
861 * Convert some unit of time to microseconds.
862 *
863 * @since 4.0
864 *
865 * @param int $value
866 * @param string $unit
867 * @return int
868 */
869 public static function to_microseconds( $value, $unit ) {
870
871 if ( 'seconds' === $unit ) {
872 return intval( $value, 10 ) * 1000;
873
874 } elseif ( 'minutes' === $unit ) {
875 return intval( $value, 10 ) * 60 * 1000;
876
877 } else {
878 return intval( $value, 10 ) * 60 * 60 * 1000;
879 }
880 }
881
882 /**
883 * Get social patform names
884 *
885 * @return array
886 */
887 public static function get_social_platform_names() {
888 $social_platform_names = array(
889 'facebook' => esc_html__( 'Facebook', 'hustle' ),
890 'twitter' => esc_html__( 'Twitter', 'hustle' ),
891 'pinterest' => esc_html__( 'Pinterest', 'hustle' ),
892 'reddit' => esc_html__( 'Reddit', 'hustle' ),
893 'linkedin' => esc_html__( 'LinkedIn', 'hustle' ),
894 'vkontakte' => esc_html__( 'Vkontakte', 'hustle' ),
895 'fivehundredpx' => esc_html__( '500px', 'hustle' ),
896 'houzz' => esc_html__( 'Houzz', 'hustle' ),
897 'instagram' => esc_html__( 'Instagram', 'hustle' ),
898 'twitch' => esc_html__( 'Twitch', 'hustle' ),
899 'youtube' => esc_html__( 'YouTube', 'hustle' ),
900 'telegram' => esc_html__( 'Telegram', 'hustle' ),
901 'whatsapp' => esc_html__( 'WhatsApp', 'hustle' ),
902 'email' => esc_html__( 'Email', 'hustle' ),
903 );
904
905 /**
906 * Social networks list
907 *
908 * @since 4.0.4
909 *
910 * @param array $social_platform_names {slug} => {name}
911 */
912 return apply_filters( 'hustle_social_platform_names', $social_platform_names );
913 }
914
915 /**
916 * Return reCAPTCHA languages
917 *
918 * @since 4.0
919 * @return array
920 */
921 public static function get_captcha_languages() {
922 return apply_filters(
923 'hustle_captcha_languages',
924 array(
925 'ar' => esc_html__( 'Arabic', 'hustle' ),
926 'af' => esc_html__( 'Afrikaans', 'hustle' ),
927 'am' => esc_html__( 'Amharic', 'hustle' ),
928 'hy' => esc_html__( 'Armenian', 'hustle' ),
929 'az' => esc_html__( 'Azerbaijani', 'hustle' ),
930 'eu' => esc_html__( 'Basque', 'hustle' ),
931 'bn' => esc_html__( 'Bengali', 'hustle' ),
932 'bg' => esc_html__( 'Bulgarian', 'hustle' ),
933 'ca' => esc_html__( 'Catalan', 'hustle' ),
934 'zh-HK' => esc_html__( 'Chinese (Hong Kong)', 'hustle' ),
935 'zh-CN' => esc_html__( 'Chinese (Simplified)', 'hustle' ),
936 'zh-TW' => esc_html__( 'Chinese (Traditional)', 'hustle' ),
937 'hr' => esc_html__( 'Croatian', 'hustle' ),
938 'cs' => esc_html__( 'Czech', 'hustle' ),
939 'da' => esc_html__( 'Danish', 'hustle' ),
940 'nl' => esc_html__( 'Dutch', 'hustle' ),
941 'en-GB' => esc_html__( 'English (UK)', 'hustle' ),
942 'en' => esc_html__( 'English (US)', 'hustle' ),
943 'et' => esc_html__( 'Estonian', 'hustle' ),
944 'fil' => esc_html__( 'Filipino', 'hustle' ),
945 'fi' => esc_html__( 'Finnish', 'hustle' ),
946 'fr' => esc_html__( 'French', 'hustle' ),
947 'fr-CA' => esc_html__( 'French (Canadian)', 'hustle' ),
948 'gl' => esc_html__( 'Galician', 'hustle' ),
949 'ka' => esc_html__( 'Georgian', 'hustle' ),
950 'de' => esc_html__( 'German', 'hustle' ),
951 'de-AT' => esc_html__( 'German (Austria)', 'hustle' ),
952 'de-CH' => esc_html__( 'German (Switzerland)', 'hustle' ),
953 'el' => esc_html__( 'Greek', 'hustle' ),
954 'gu' => esc_html__( 'Gujarati', 'hustle' ),
955 'iw' => esc_html__( 'Hebrew', 'hustle' ),
956 'hi' => esc_html__( 'Hindi', 'hustle' ),
957 'hu' => esc_html__( 'Hungarain', 'hustle' ),
958 'is' => esc_html__( 'Icelandic', 'hustle' ),
959 'id' => esc_html__( 'Indonesian', 'hustle' ),
960 'it' => esc_html__( 'Italian', 'hustle' ),
961 'ja' => esc_html__( 'Japanese', 'hustle' ),
962 'kn' => esc_html__( 'Kannada', 'hustle' ),
963 'ko' => esc_html__( 'Korean', 'hustle' ),
964 'lo' => esc_html__( 'Laothian', 'hustle' ),
965 'lv' => esc_html__( 'Latvian', 'hustle' ),
966 'lt' => esc_html__( 'Lithuanian', 'hustle' ),
967 'ms' => esc_html__( 'Malay', 'hustle' ),
968 'ml' => esc_html__( 'Malayalam', 'hustle' ),
969 'mr' => esc_html__( 'Marathi', 'hustle' ),
970 'mn' => esc_html__( 'Mongolian', 'hustle' ),
971 'no' => esc_html__( 'Norwegian', 'hustle' ),
972 'fa' => esc_html__( 'Persian', 'hustle' ),
973 'pl' => esc_html__( 'Polish', 'hustle' ),
974 'pt' => esc_html__( 'Portuguese', 'hustle' ),
975 'pt-BR' => esc_html__( 'Portuguese (Brazil)', 'hustle' ),
976 'pt-PT' => esc_html__( 'Portuguese (Portugal)', 'hustle' ),
977 'ro' => esc_html__( 'Romanian', 'hustle' ),
978 'ru' => esc_html__( 'Russian', 'hustle' ),
979 'sr' => esc_html__( 'Serbian', 'hustle' ),
980 'si' => esc_html__( 'Sinhalese', 'hustle' ),
981 'sk' => esc_html__( 'Slovak', 'hustle' ),
982 'sl' => esc_html__( 'Slovenian', 'hustle' ),
983 'es' => esc_html__( 'Spanish', 'hustle' ),
984 'es-419' => esc_html__( 'Spanish (Latin America)', 'hustle' ),
985 'sw' => esc_html__( 'Swahili', 'hustle' ),
986 'sv' => esc_html__( 'Swedish', 'hustle' ),
987 'ta' => esc_html__( 'Tamil', 'hustle' ),
988 'te' => esc_html__( 'Telugu', 'hustle' ),
989 'th' => esc_html__( 'Thai', 'hustle' ),
990 'tr' => esc_html__( 'Turkish', 'hustle' ),
991 'uk' => esc_html__( 'Ukrainian', 'hustle' ),
992 'ur' => esc_html__( 'Urdu', 'hustle' ),
993 'vi' => esc_html__( 'Vietnamese', 'hustle' ),
994 'zu' => esc_html__( 'Zulu', 'hustle' ),
995 )
996 );
997 }
998
999 /**
1000 * Gets post property
1001 *
1002 * @since 4.0.4
1003 * @param string $property Requested post property.
1004 * @param string $default Fallback value.
1005 * @return string
1006 */
1007 public static function get_post_data( $property, $default = '' ) {
1008 global $post;
1009
1010 if ( ! $post ) {
1011 // fallback on wp_ajax, `global $post` not available.
1012 $wp_referer = wp_get_referer();
1013 if ( $wp_referer ) {
1014 $post_id = ! function_exists( 'wpcom_vip_url_to_postid' ) ? url_to_postid( $wp_referer ) : wpcom_vip_url_to_postid( $wp_referer );
1015 if ( $post_id ) {
1016 $post_object = get_post( $post_id );
1017 // make sure it's wp_post.
1018 if ( $post_object instanceof WP_Post ) {
1019 // set global $post as $post_object retrieved from `get_post` for next usage.
1020 $post = $post_object; // phpcs:ignore
1021 }
1022 }
1023 }
1024 }
1025
1026 $post_data = (array) $post;
1027 if ( isset( $post_data[ $property ] ) ) {
1028 return $post_data[ $property ];
1029 } else {
1030 return $default;
1031 }
1032 }
1033
1034 /**
1035 * Return local timestamp
1036 *
1037 * @since 4.0.4
1038 * @param int $timestamp
1039 * @return mixed
1040 */
1041 public static function get_local_timestamp( $timestamp = null ) {
1042 // If no timestamp, get it current.
1043 if ( is_null( $timestamp ) ) {
1044 $timestamp = time();
1045 }
1046
1047 return $timestamp + ( get_option( 'gmt_offset' ) * 3600 );
1048 }
1049
1050 // ====================================
1051 // MODULES HELPERS
1052 // ====================================
1053
1054
1055 /**
1056 * Get Time of latest tracked conversion based on $module_id
1057 *
1058 * @since 4.0
1059 *
1060 * @param $module_id
1061 * @param string $subtype
1062 * @param string $cta_or_optin Optional. cta_conversion|optin_conversion|all_conversion CTA or Opt-in conversion
1063 * @return string
1064 */
1065 public static function get_latest_conversion_time_by_module_id( $module_id, $subtype = '', $cta_or_optin = 'all_conversion' ) {
1066 $tracking_model = Hustle_Tracking_Model::get_instance();
1067 $latest_entry = $tracking_model->get_latest_conversion_date_by_module_id( $module_id, $subtype, $cta_or_optin );
1068 if ( $latest_entry ) {
1069 $entry_date = date_i18n( 'j M Y @ H:i A', strtotime( $latest_entry ) );
1070 return $entry_date;
1071 } else {
1072 return esc_html__( 'Never', 'hustle' );
1073 }
1074 }
1075
1076 /**
1077 * Get the time of the latest tracked conversion based on $entry_type
1078 * [popup,slide-in,embedded]
1079 *
1080 * @since 4.0
1081 *
1082 * @param $entry_type
1083 * @return string
1084 */
1085 public static function get_latest_conversion_time( $entry_type ) {
1086 $tracking_model = Hustle_Tracking_Model::get_instance();
1087 $date = $tracking_model->get_latest_conversion_date( $entry_type );
1088
1089 if ( $date ) {
1090 $last_entry_time = mysql2date( 'U', $date );
1091 $time_diff = human_time_diff( current_time( 'timestamp' ), $last_entry_time );
1092 $last_entry_time = sprintf( __( '%s ago', 'hustle' ), $time_diff );
1093
1094 return $last_entry_time;
1095 } else {
1096 return __( 'Never', 'hustle' );
1097 }
1098 }
1099
1100 /**
1101 * Get Time of latest entry created based on $module_id
1102 *
1103 * @since 4.0
1104 *
1105 * @param $module_id
1106 * @return string
1107 */
1108 public static function get_latest_entry_time_by_module_id( $module_id ) {
1109 $latest_entry = Hustle_Entry_Model::get_latest_entry_by_module_id( $module_id );
1110 if ( $latest_entry instanceof Hustle_Entry_Model ) {
1111 return $latest_entry->time_created;
1112 } else {
1113 return esc_html__( 'Never', 'hustle' );
1114 }
1115 }
1116
1117 /**
1118 * Get Time of latest entry created based on $entry_type
1119 * [popup,slide-in,embedded]
1120 *
1121 * @since 4.0
1122 *
1123 * @param $entry_type
1124 * @return string
1125 */
1126 public static function get_latest_entry_time( $entry_type ) {
1127 $latest_entry = Hustle_Entry_Model::get_latest_entry( $entry_type );
1128 if ( $latest_entry instanceof Hustle_Entry_Model ) {
1129 $last_entry_time = mysql2date( 'U', $latest_entry->date_created_sql );
1130 $time_diff = human_time_diff( current_time( 'timestamp' ), $last_entry_time );
1131 $last_entry_time = sprintf( __( '%s ago', 'hustle' ), $time_diff );
1132
1133 return $last_entry_time;
1134 } else {
1135 return __( 'Never', 'hustle' );
1136 }
1137 }
1138
1139 /**
1140 * Get current post id
1141 *
1142 * @since 4.0
1143 *
1144 * @return int|string
1145 */
1146 public static function get_post_id() {
1147 return get_post() ? get_the_ID() : '0';
1148 }
1149
1150 /**
1151 * get formated date
1152 *
1153 * @since 4.0.0
1154 *
1155 * return string $date Current date, formated bu i18n.
1156 */
1157 public static function get_current_date() {
1158 $date = date_i18n( 'Y-m-d H:i:s' );
1159 return $date;
1160 }
1161
1162 /**
1163 * Gets the a current user's property.
1164 *
1165 * @since 4.0.4
1166 * @param string $property The user's property to be retrieved.
1167 * @return string
1168 */
1169 public static function get_user_data( $property ) {
1170 $current_user = wp_get_current_user();
1171
1172 if ( $current_user && $current_user->exists() ) {
1173 return $current_user->get( $property );
1174 }
1175 return '';
1176 }
1177
1178 /**
1179 * Replace a key in an array without changing its order.
1180 *
1181 * @since 4.0
1182 *
1183 * @param string $old_key
1184 * @param string $new_key
1185 * @param array $array
1186 * @return array
1187 */
1188 public static function replace_array_key( $old_key, $new_key, $array ) {
1189
1190 // Replace the name without changing the array's order.
1191 $keys_array = array_keys( $array );
1192 $index = array_search( $old_key, $keys_array, true );
1193
1194 if ( false === $index ) {
1195 return $array;
1196 }
1197
1198 $keys_array[ $index ] = $new_key;
1199
1200 $new_array = array_combine( $keys_array, array_values( $array ) );
1201
1202 return $new_array;
1203 }
1204
1205 /*
1206 * Get the display name of a module type.
1207 *
1208 * @since 4.0
1209 *
1210 * @param string $module_type
1211 * @param boolean $plural
1212 * @param boolean $capitalized
1213 * @return string
1214 */
1215 public static function get_module_type_display_name( $module_type, $plural = false, $capitalized = false ) {
1216
1217 $display_name = '';
1218
1219 if ( Hustle_Module_Model::POPUP_MODULE === $module_type ) {
1220 if ( ! $plural ) {
1221 $display_name = __( 'pop-up', 'hustle' );
1222 } else {
1223 $display_name = __( 'pop-ups', 'hustle' );
1224 }
1225 } elseif ( Hustle_Module_Model::SLIDEIN_MODULE === $module_type ) {
1226 if ( ! $plural ) {
1227 $display_name = __( 'slide-in', 'hustle' );
1228 } else {
1229 $display_name = __( 'slide-ins', 'hustle' );
1230 }
1231 } elseif ( Hustle_Module_Model::EMBEDDED_MODULE === $module_type ) {
1232 if ( ! $plural ) {
1233 $display_name = __( 'embed', 'hustle' );
1234 } else {
1235 $display_name = __( 'embeds', 'hustle' );
1236 }
1237 } elseif ( Hustle_Module_Model::SOCIAL_SHARING_MODULE === $module_type ) {
1238 if ( ! $plural ) {
1239 $display_name = __( 'social sharing', 'hustle' );
1240 } else {
1241 $display_name = __( 'social shares', 'hustle' );
1242 }
1243 }
1244
1245 if ( $capitalized ) {
1246 $display_name = ucwords( $display_name );
1247 }
1248
1249 return $display_name;
1250 }
1251
1252 /**
1253 * Get page templates
1254 *
1255 * @since 4.0.3
1256 */
1257 public static function hustle_get_page_templates() {
1258 $templates = get_page_templates();
1259 $page_templates = array();
1260 foreach ( $templates as $template_name => $template_filename ) {
1261 $page_templates[ $template_filename ] = $template_name;
1262 }
1263 return $page_templates;
1264 }
1265
1266 /**
1267 * Check if WooCommerce is active or not
1268 *
1269 * @return bool
1270 */
1271 public static function is_woocommerce_active() {
1272 return is_plugin_active( 'woocommerce/woocommerce.php' );
1273 }
1274
1275 /**
1276 * Gets the first key of an array.
1277 *
1278 * @since 4.0.0
1279 *
1280 * @param array $array
1281 * @return mixed
1282 */
1283 public static function array_key_first( array $array ) {
1284 return $array ? array_keys( $array )[0] : null;
1285 }
1286
1287 /**
1288 * Get the global placeholders for display.
1289 * The array's key has the placeholder value, that's what's inserted between
1290 * brackets and then replaced by self::replace_global_placeholders().
1291 * The array's value has the display name for the placeholder.
1292 *
1293 * @since 4.0.3
1294 * @see Opt_In_Utils::replace_global_placeholders()
1295 * @return array
1296 */
1297 public static function get_global_placeholders() {
1298
1299 $placeholders = array(
1300 'site_url' => __( 'Site URL', 'hustle' ),
1301 'site_name' => __( 'Site name', 'hustle' ),
1302 'post_url' => __( 'Post/page URL', 'hustle' ),
1303 'post_title' => __( 'Post/page title', 'hustle' ),
1304 );
1305
1306 /**
1307 * Filter the available global placeholders.
1308 * These are used in some text fields, to be replaced by
1309 * self::replace_global_placeholders().
1310 *
1311 * @since 4.0.3
1312 * @see Opt_In_Utils::replace_global_placeholders()
1313 * @return array
1314 */
1315 return apply_filters( 'hustle_get_global_placeholders', $placeholders );
1316 }
1317
1318 /**
1319 * Replace the global placeholders from a string.
1320 * These are added to some text fields by the admin.
1321 * The available ones are returned by self::get_global_placeholders().
1322 *
1323 * @since 4.0.3
1324 * @see Opt_In_Utils::replace_global_placeholders()
1325 * @param string $string String with placeholders to be replaced.
1326 * @return string
1327 */
1328 public static function replace_global_placeholders( $string ) {
1329
1330 preg_match_all( '/\{[^}]*\}/', $string, $matches );
1331
1332 if ( ! empty( $matches[0] ) && is_array( $matches[0] ) ) {
1333
1334 $defined_placeholders = array(
1335 '{site_url}' => site_url(),
1336 '{site_name}' => get_bloginfo( 'name' ),
1337 '{post_url}' => get_permalink(),
1338 '{post_title}' => esc_html( get_the_title() ),
1339 );
1340
1341 /**
1342 * Filter the placeholders and their values.
1343 * The keys of the array belong to the placeholder to be replaced.
1344 * The values of the array belong to the value to use as replacement.
1345 * Eg: [ '{post_url}' => get_permalink() ]
1346 *
1347 * @since 4.0.3
1348 * @return array
1349 */
1350 $defined_placeholders = apply_filters( 'hustle_global_placeholders_to_replace', $defined_placeholders );
1351
1352 foreach ( $matches[0] as $placeholder ) {
1353
1354 if ( key_exists( $placeholder, $defined_placeholders ) ) {
1355 $replacement = $defined_placeholders[ $placeholder ];
1356
1357 if ( $replacement !== $placeholder ) {
1358 // Replace if we found something.
1359 $string = str_replace( $placeholder, $replacement, $string );
1360 }
1361 }
1362 }
1363 }
1364
1365 return $string;
1366 }
1367
1368 // Static stuff below.
1369
1370 /**
1371 * Returns array of browsers
1372 *
1373 * @since 4.1
1374 * @return array|mixed|null|void
1375 */
1376 public static function get_browsers() {
1377
1378 $browsers = array(
1379 'chrome' => __( 'Chrome', 'hustle' ),
1380 'firefox' => __( 'Firefox', 'hustle' ),
1381 'safari' => __( 'Safari', 'hustle' ),
1382 'edge' => __( 'Edge', 'hustle' ),
1383 'MSIE' => __( 'Internet Explorer', 'hustle' ),
1384 'opera' => __( 'Opera', 'hustle' ),
1385 );
1386
1387 /**
1388 * Filter the list of browsers
1389 * Must return an associative array where the key is the browser's slug
1390 * and the value is its display name.
1391 *
1392 * @since 4.1
1393 */
1394 return apply_filters( 'hustle_get_browsers_list', $browsers );
1395 }
1396
1397 /**
1398 * Returns array of countries
1399 *
1400 * @return array|mixed|null|void
1401 */
1402 public static function get_countries() {
1403
1404 $countries = array(
1405 'AU' => __( 'Australia', 'hustle' ),
1406 'AF' => __( 'Afghanistan', 'hustle' ),
1407 'AL' => __( 'Albania', 'hustle' ),
1408 'DZ' => __( 'Algeria', 'hustle' ),
1409 'AS' => __( 'American Samoa', 'hustle' ),
1410 'AD' => __( 'Andorra', 'hustle' ),
1411 'AO' => __( 'Angola', 'hustle' ),
1412 'AI' => __( 'Anguilla', 'hustle' ),
1413 'AQ' => __( 'Antarctica', 'hustle' ),
1414 'AG' => __( 'Antigua and Barbuda', 'hustle' ),
1415 'AR' => __( 'Argentina', 'hustle' ),
1416 'AM' => __( 'Armenia', 'hustle' ),
1417 'AW' => __( 'Aruba', 'hustle' ),
1418 'AT' => __( 'Austria', 'hustle' ),
1419 'AZ' => __( 'Azerbaijan', 'hustle' ),
1420 'BS' => __( 'Bahamas', 'hustle' ),
1421 'BH' => __( 'Bahrain', 'hustle' ),
1422 'BD' => __( 'Bangladesh', 'hustle' ),
1423 'BB' => __( 'Barbados', 'hustle' ),
1424 'BY' => __( 'Belarus', 'hustle' ),
1425 'BE' => __( 'Belgium', 'hustle' ),
1426 'BZ' => __( 'Belize', 'hustle' ),
1427 'BJ' => __( 'Benin', 'hustle' ),
1428 'BM' => __( 'Bermuda', 'hustle' ),
1429 'BT' => __( 'Bhutan', 'hustle' ),
1430 'BO' => __( 'Bolivia', 'hustle' ),
1431 'BA' => __( 'Bosnia and Herzegovina', 'hustle' ),
1432 'BW' => __( 'Botswana', 'hustle' ),
1433 'BV' => __( 'Bouvet Island', 'hustle' ),
1434 'BR' => __( 'Brazil', 'hustle' ),
1435 'IO' => __( 'British Indian Ocean Territory', 'hustle' ),
1436 'BN' => __( 'Brunei', 'hustle' ),
1437 'BG' => __( 'Bulgaria', 'hustle' ),
1438 'BF' => __( 'Burkina Faso', 'hustle' ),
1439 'BI' => __( 'Burundi', 'hustle' ),
1440 'KH' => __( 'Cambodia', 'hustle' ),
1441 'CM' => __( 'Cameroon', 'hustle' ),
1442 'CA' => __( 'Canada', 'hustle' ),
1443 'CV' => __( 'Cape Verde', 'hustle' ),
1444 'KY' => __( 'Cayman Islands', 'hustle' ),
1445 'CF' => __( 'Central African Republic', 'hustle' ),
1446 'TD' => __( 'Chad', 'hustle' ),
1447 'CL' => __( 'Chile', 'hustle' ),
1448 'CN' => __( 'China, People\'s Republic of', 'hustle' ),
1449 'CX' => __( 'Christmas Island', 'hustle' ),
1450 'CC' => __( 'Cocos Islands', 'hustle' ),
1451 'CO' => __( 'Colombia', 'hustle' ),
1452 'KM' => __( 'Comoros', 'hustle' ),
1453 'CD' => __( 'Congo, Democratic Republic of the', 'hustle' ),
1454 'CG' => __( 'Congo, Republic of the', 'hustle' ),
1455 'CK' => __( 'Cook Islands', 'hustle' ),
1456 'CR' => __( 'Costa Rica', 'hustle' ),
1457 'CI' => __( 'Côte d\'Ivoire', 'hustle' ),
1458 'HR' => __( 'Croatia', 'hustle' ),
1459 'CU' => __( 'Cuba', 'hustle' ),
1460 'CW' => __( 'Curaçao', 'hustle' ),
1461 'CY' => __( 'Cyprus', 'hustle' ),
1462 'CZ' => __( 'Czech Republic', 'hustle' ),
1463 'DK' => __( 'Denmark', 'hustle' ),
1464 'DJ' => __( 'Djibouti', 'hustle' ),
1465 'DM' => __( 'Dominica', 'hustle' ),
1466 'DO' => __( 'Dominican Republic', 'hustle' ),
1467 'TL' => __( 'East Timor', 'hustle' ),
1468 'EC' => __( 'Ecuador', 'hustle' ),
1469 'EG' => __( 'Egypt', 'hustle' ),
1470 'SV' => __( 'El Salvador', 'hustle' ),
1471 'GQ' => __( 'Equatorial Guinea', 'hustle' ),
1472 'ER' => __( 'Eritrea', 'hustle' ),
1473 'EE' => __( 'Estonia', 'hustle' ),
1474 'ET' => __( 'Ethiopia', 'hustle' ),
1475 'FK' => __( 'Falkland Islands', 'hustle' ),
1476 'FO' => __( 'Faroe Islands', 'hustle' ),
1477 'FJ' => __( 'Fiji', 'hustle' ),
1478 'FI' => __( 'Finland', 'hustle' ),
1479 'FR' => __( 'France', 'hustle' ),
1480 'FX' => __( 'France, Metropolitan', 'hustle' ),
1481 'GF' => __( 'French Guiana', 'hustle' ),
1482 'PF' => __( 'French Polynesia', 'hustle' ),
1483 'TF' => __( 'French South Territories', 'hustle' ),
1484 'GA' => __( 'Gabon', 'hustle' ),
1485 'GM' => __( 'Gambia', 'hustle' ),
1486 'GE' => __( 'Georgia', 'hustle' ),
1487 'DE' => __( 'Germany', 'hustle' ),
1488 'GH' => __( 'Ghana', 'hustle' ),
1489 'GI' => __( 'Gibraltar', 'hustle' ),
1490 'GR' => __( 'Greece', 'hustle' ),
1491 'GL' => __( 'Greenland', 'hustle' ),
1492 'GD' => __( 'Grenada', 'hustle' ),
1493 'GP' => __( 'Guadeloupe', 'hustle' ),
1494 'GU' => __( 'Guam', 'hustle' ),
1495 'GT' => __( 'Guatemala', 'hustle' ),
1496 'GN' => __( 'Guinea', 'hustle' ),
1497 'GW' => __( 'Guinea-Bissau', 'hustle' ),
1498 'GY' => __( 'Guyana', 'hustle' ),
1499 'HT' => __( 'Haiti', 'hustle' ),
1500 'HM' => __( 'Heard Island And Mcdonald Island', 'hustle' ),
1501 'HN' => __( 'Honduras', 'hustle' ),
1502 'HK' => __( 'Hong Kong', 'hustle' ),
1503 'HU' => __( 'Hungary', 'hustle' ),
1504 'IS' => __( 'Iceland', 'hustle' ),
1505 'IN' => __( 'India', 'hustle' ),
1506 'ID' => __( 'Indonesia', 'hustle' ),
1507 'IR' => __( 'Iran', 'hustle' ),
1508 'IQ' => __( 'Iraq', 'hustle' ),
1509 'IE' => __( 'Ireland', 'hustle' ),
1510 'IL' => __( 'Israel', 'hustle' ),
1511 'IT' => __( 'Italy', 'hustle' ),
1512 'JM' => __( 'Jamaica', 'hustle' ),
1513 'JP' => __( 'Japan', 'hustle' ),
1514 'JT' => __( 'Johnston Island', 'hustle' ),
1515 'JO' => __( 'Jordan', 'hustle' ),
1516 'KZ' => __( 'Kazakhstan', 'hustle' ),
1517 'KE' => __( 'Kenya', 'hustle' ),
1518 'XK' => __( 'Kosovo', 'hustle' ),
1519 'KI' => __( 'Kiribati', 'hustle' ),
1520 'KP' => __( 'Korea, Democratic People\'s Republic of', 'hustle' ),
1521 'KR' => __( 'Korea, Republic of', 'hustle' ),
1522 'KW' => __( 'Kuwait', 'hustle' ),
1523 'KG' => __( 'Kyrgyzstan', 'hustle' ),
1524 'LA' => __( 'Lao People\'s Democratic Republic', 'hustle' ),
1525 'LV' => __( 'Latvia', 'hustle' ),
1526 'LB' => __( 'Lebanon', 'hustle' ),
1527 'LS' => __( 'Lesotho', 'hustle' ),
1528 'LR' => __( 'Liberia', 'hustle' ),
1529 'LY' => __( 'Libya', 'hustle' ),
1530 'LI' => __( 'Liechtenstein', 'hustle' ),
1531 'LT' => __( 'Lithuania', 'hustle' ),
1532 'LU' => __( 'Luxembourg', 'hustle' ),
1533 'MO' => __( 'Macau', 'hustle' ),
1534 'MK' => __( 'Macedonia', 'hustle' ),
1535 'MG' => __( 'Madagascar', 'hustle' ),
1536 'MW' => __( 'Malawi', 'hustle' ),
1537 'MY' => __( 'Malaysia', 'hustle' ),
1538 'MV' => __( 'Maldives', 'hustle' ),
1539 'ML' => __( 'Mali', 'hustle' ),
1540 'MT' => __( 'Malta', 'hustle' ),
1541 'MH' => __( 'Marshall Islands', 'hustle' ),
1542 'MQ' => __( 'Martinique', 'hustle' ),
1543 'MR' => __( 'Mauritania', 'hustle' ),
1544 'MU' => __( 'Mauritius', 'hustle' ),
1545 'YT' => __( 'Mayotte', 'hustle' ),
1546 'MX' => __( 'Mexico', 'hustle' ),
1547 'FM' => __( 'Micronesia', 'hustle' ),
1548 'MD' => __( 'Moldova', 'hustle' ),
1549 'MC' => __( 'Monaco', 'hustle' ),
1550 'MN' => __( 'Mongolia', 'hustle' ),
1551 'ME' => __( 'Montenegro', 'hustle' ),
1552 'MS' => __( 'Montserrat', 'hustle' ),
1553 'MA' => __( 'Morocco', 'hustle' ),
1554 'MZ' => __( 'Mozambique', 'hustle' ),
1555 'MM' => __( 'Myanmar', 'hustle' ),
1556 'NA' => __( 'Namibia', 'hustle' ),
1557 'NR' => __( 'Nauru', 'hustle' ),
1558 'NP' => __( 'Nepal', 'hustle' ),
1559 'NL' => __( 'Netherlands', 'hustle' ),
1560 'AN' => __( 'Netherlands Antilles', 'hustle' ),
1561 'NC' => __( 'New Caledonia', 'hustle' ),
1562 'NZ' => __( 'New Zealand', 'hustle' ),
1563 'NI' => __( 'Nicaragua', 'hustle' ),
1564 'NE' => __( 'Niger', 'hustle' ),
1565 'NG' => __( 'Nigeria', 'hustle' ),
1566 'NU' => __( 'Niue', 'hustle' ),
1567 'NF' => __( 'Norfolk Island', 'hustle' ),
1568 'MP' => __( 'Northern Mariana Islands', 'hustle' ),
1569 'MP' => __( 'Mariana Islands, Northern', 'hustle' ),
1570 'NO' => __( 'Norway', 'hustle' ),
1571 'OM' => __( 'Oman', 'hustle' ),
1572 'PK' => __( 'Pakistan', 'hustle' ),
1573 'PW' => __( 'Palau', 'hustle' ),
1574 'PS' => __( 'Palestine, State of', 'hustle' ),
1575 'PA' => __( 'Panama', 'hustle' ),
1576 'PG' => __( 'Papua New Guinea', 'hustle' ),
1577 'PY' => __( 'Paraguay', 'hustle' ),
1578 'PE' => __( 'Peru', 'hustle' ),
1579 'PH' => __( 'Philippines', 'hustle' ),
1580 'PN' => __( 'Pitcairn Islands', 'hustle' ),
1581 'PL' => __( 'Poland', 'hustle' ),
1582 'PT' => __( 'Portugal', 'hustle' ),
1583 'PR' => __( 'Puerto Rico', 'hustle' ),
1584 'QA' => __( 'Qatar', 'hustle' ),
1585 'RE' => __( 'Réunion', 'hustle' ),
1586 'RO' => __( 'Romania', 'hustle' ),
1587 'RU' => __( 'Russia', 'hustle' ),
1588 'RW' => __( 'Rwanda', 'hustle' ),
1589 'SH' => __( 'Saint Helena', 'hustle' ),
1590 'KN' => __( 'Saint Kitts and Nevis', 'hustle' ),
1591 'LC' => __( 'Saint Lucia', 'hustle' ),
1592 'PM' => __( 'Saint Pierre and Miquelon', 'hustle' ),
1593 'VC' => __( 'Saint Vincent and the Grenadines', 'hustle' ),
1594 'WS' => __( 'Samoa', 'hustle' ),
1595 'SM' => __( 'San Marino', 'hustle' ),
1596 'ST' => __( 'Sao Tome and Principe', 'hustle' ),
1597 'SA' => __( 'Saudi Arabia', 'hustle' ),
1598 'SN' => __( 'Senegal', 'hustle' ),
1599 'CS' => __( 'Serbia', 'hustle' ),
1600 'SC' => __( 'Seychelles', 'hustle' ),
1601 'SL' => __( 'Sierra Leone', 'hustle' ),
1602 'SG' => __( 'Singapore', 'hustle' ),
1603 'MF' => __( 'Sint Maarten', 'hustle' ),
1604 'SK' => __( 'Slovakia', 'hustle' ),
1605 'SI' => __( 'Slovenia', 'hustle' ),
1606 'SB' => __( 'Solomon Islands', 'hustle' ),
1607 'SO' => __( 'Somalia', 'hustle' ),
1608 'ZA' => __( 'South Africa', 'hustle' ),
1609 'GS' => __( 'South Georgia and the South Sandwich Islands', 'hustle' ),
1610 'ES' => __( 'Spain', 'hustle' ),
1611 'LK' => __( 'Sri Lanka', 'hustle' ),
1612 'XX' => __( 'Stateless Persons', 'hustle' ),
1613 'SD' => __( 'Sudan', 'hustle' ),
1614 'SD' => __( 'Sudan, South', 'hustle' ),
1615 'SR' => __( 'Suriname', 'hustle' ),
1616 'SJ' => __( 'Svalbard and Jan Mayen', 'hustle' ),
1617 'SZ' => __( 'Swaziland', 'hustle' ),
1618 'SE' => __( 'Sweden', 'hustle' ),
1619 'CH' => __( 'Switzerland', 'hustle' ),
1620 'SY' => __( 'Syria', 'hustle' ),
1621 'TW' => __( 'Taiwan, Republic of China', 'hustle' ),
1622 'TJ' => __( 'Tajikistan', 'hustle' ),
1623 'TZ' => __( 'Tanzania', 'hustle' ),
1624 'TH' => __( 'Thailand', 'hustle' ),
1625 'TG' => __( 'Togo', 'hustle' ),
1626 'TK' => __( 'Tokelau', 'hustle' ),
1627 'TO' => __( 'Tonga', 'hustle' ),
1628 'TT' => __( 'Trinidad and Tobago', 'hustle' ),
1629 'TN' => __( 'Tunisia', 'hustle' ),
1630 'TR' => __( 'Turkey', 'hustle' ),
1631 'TM' => __( 'Turkmenistan', 'hustle' ),
1632 'TC' => __( 'Turks and Caicos Islands', 'hustle' ),
1633 'TV' => __( 'Tuvalu', 'hustle' ),
1634 'UG' => __( 'Uganda', 'hustle' ),
1635 'UA' => __( 'Ukraine', 'hustle' ),
1636 'AE' => __( 'United Arab Emirates', 'hustle' ),
1637 'GB' => __( 'United Kingdom', 'hustle' ),
1638 'US' => __( 'United States of America (USA)', 'hustle' ),
1639 'UM' => __( 'US Minor Outlying Islands', 'hustle' ),
1640 'UY' => __( 'Uruguay', 'hustle' ),
1641 'UZ' => __( 'Uzbekistan', 'hustle' ),
1642 'VU' => __( 'Vanuatu', 'hustle' ),
1643 'VA' => __( 'Vatican City', 'hustle' ),
1644 'VE' => __( 'Venezuela', 'hustle' ),
1645 'VN' => __( 'Vietnam', 'hustle' ),
1646 'VG' => __( 'Virgin Islands, British', 'hustle' ),
1647 'VI' => __( 'Virgin Islands, U.S.', 'hustle' ),
1648 'WF' => __( 'Wallis And Futuna', 'hustle' ),
1649 'EH' => __( 'Western Sahara', 'hustle' ),
1650 'YE' => __( 'Yemen', 'hustle' ),
1651 'ZM' => __( 'Zambia', 'hustle' ),
1652 'ZW' => __( 'Zimbabwe', 'hustle' ),
1653 );
1654
1655 /**
1656 * Returns a list with countries
1657 * Must be an associative array where the key is the country code
1658 * and its value is its display name.
1659 */
1660 return apply_filters( 'opt_in-country-list', $countries );
1661 }
1662 }
1663