PluginProbe ʕ •ᴥ•ʔ
Custom Post Type UI / 1.13.4
Custom Post Type UI v1.13.4
1.19.2 1.19.1 1.19.0 trunk 0.7.0.0 0.7.1.0 0.7.2.0 0.8.0.0 0.8.1 0.8.2 0.8.3 0.8.4 0.8.5 0.9.0 0.9.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.1.0 1.1.1 1.1.2 1.1.3 1.10.0 1.10.1 1.10.2 1.11.0 1.11.1 1.11.2 1.12.0 1.12.1 1.13.0 1.13.1 1.13.2 1.13.3 1.13.4 1.13.5 1.13.6 1.13.7 1.14.0 1.15.0 1.15.1 1.16.0 1.17.0 1.17.1 1.17.2 1.17.3 1.18.0 1.18.1 1.18.2 1.18.3 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 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.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.8.0 1.8.1 1.8.2 1.9.0 1.9.1 1.9.2
custom-post-type-ui / inc / utility.php
custom-post-type-ui / inc Last commit date
tools-sections 3 years ago about.php 3 years ago listings.php 3 years ago post-types.php 3 years ago support.php 3 years ago taxonomies.php 3 years ago tools.php 3 years ago utility.php 3 years ago wp-cli.php 3 years ago
utility.php
1005 lines
1 <?php
2 /**
3 * Custom Post Type UI Utility Code.
4 *
5 * @package CPTUI
6 * @subpackage Utility
7 * @author WebDevStudios
8 * @since 1.3.0
9 * @license GPL-2.0+
10 */
11
12 // phpcs:disable WebDevStudios.All.RequireAuthor
13
14 // Exit if accessed directly.
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 /**
20 * Edit links that appear on installed plugins list page, for our plugin.
21 *
22 * @since 1.0.0
23 *
24 * @internal
25 *
26 * @param array $links Array of links to display below our plugin listing.
27 * @return array Amended array of links.
28 */
29 function cptui_edit_plugin_list_links( $links ) {
30
31 if ( is_array( $links ) && isset( $links['edit'] ) ) {
32 // We shouldn't encourage editing our plugin directly.
33 unset( $links['edit'] );
34 }
35
36 // Add our custom links to the returned array value.
37 return array_merge(
38 array(
39 '<a href="' . admin_url( 'admin.php?page=cptui_main_menu' ) . '">' . esc_html__( 'About', 'custom-post-type-ui' ) . '</a>',
40 '<a href="' . admin_url( 'admin.php?page=cptui_support' ) . '">' . esc_html__( 'Help', 'custom-post-type-ui' ) . '</a>',
41 ),
42 $links
43 );
44 }
45 add_filter( 'plugin_action_links_' . plugin_basename( dirname( __DIR__ ) ) . '/custom-post-type-ui.php', 'cptui_edit_plugin_list_links' );
46
47 /**
48 * Returns SVG icon for custom menu icon
49 *
50 * @since 1.2.0
51 *
52 * @return string
53 */
54 function cptui_menu_icon() {
55 return 'dashicons-forms';
56 }
57
58 /**
59 * Return boolean status depending on passed in value.
60 *
61 * @since 0.5.0
62 *
63 * @param mixed $bool_text text to compare to typical boolean values.
64 * @return bool Which bool value the passed in value was.
65 */
66 function get_disp_boolean( $bool_text ) {
67 $bool_text = (string) $bool_text;
68 if ( empty( $bool_text ) || '0' === $bool_text || 'false' === $bool_text ) {
69 return false;
70 }
71
72 return true;
73 }
74
75 /**
76 * Return string versions of boolean values.
77 *
78 * @since 0.1.0
79 *
80 * @param string $bool_text String boolean value.
81 * @return string standardized boolean text.
82 */
83 function disp_boolean( $bool_text ) {
84 $bool_text = (string) $bool_text;
85 if ( empty( $bool_text ) || '0' === $bool_text || 'false' === $bool_text ) {
86 return 'false';
87 }
88
89 return 'true';
90 }
91
92 /**
93 * Display footer links and plugin credits.
94 *
95 * @since 0.3.0
96 *
97 * @internal
98 *
99 * @param string $original Original footer content. Optional. Default empty string.
100 * @return string $value HTML for footer.
101 */
102 function cptui_footer( $original = '' ) {
103
104 $screen = get_current_screen();
105
106 if ( ! is_object( $screen ) || 'cptui_main_menu' !== $screen->parent_base ) {
107 return $original;
108 }
109
110 return sprintf(
111 // translators: Placeholder will hold the name of the plugin, version of the plugin and a link to WebdevStudios.
112 esc_attr__( '%1$s version %2$s by %3$s', 'custom-post-type-ui' ),
113 esc_attr__( 'Custom Post Type UI', 'custom-post-type-ui' ),
114 CPTUI_VERSION,
115 '<a href="https://webdevstudios.com" target="_blank" rel="noopener">WebDevStudios</a>'
116 ) . ' - ' .
117 sprintf(
118 // translators: Placeholders are just for HTML markup that doesn't need translated.
119 '<a href="http://wordpress.org/support/plugin/custom-post-type-ui" target="_blank" rel="noopener">%s</a>',
120 esc_attr__( 'Support forums', 'custom-post-type-ui' )
121 ) . ' - ' .
122 sprintf(
123 // translators: Placeholders are just for HTML markup that doesn't need translated.
124 '<a href="https://wordpress.org/plugins/custom-post-type-ui/reviews/" target="_blank" rel="noopener">%s</a>',
125 sprintf(
126 // translators: Placeholder will hold `<abbr>` tag for CPTUI.
127 esc_attr__( 'Review %s', 'custom-post-type-ui' ),
128 sprintf(
129 // translators: Placeholders are just for HTML markup that doesn't need translated.
130 '<abbr title="%s">%s</abbr>',
131 esc_attr__( 'Custom Post Type UI', 'custom-post-type-ui' ),
132 'CPTUI'
133 )
134 )
135 ) . ' - ' .
136 esc_attr__( 'Follow on Twitter:', 'custom-post-type-ui' ) .
137 sprintf(
138 // translators: Placeholders are just for HTML markup that doesn't need translated.
139 ' %s',
140 '<a href="https://twitter.com/webdevstudios" target="_blank" rel="noopener">WebDevStudios</a>'
141 );
142 }
143 add_filter( 'admin_footer_text', 'cptui_footer' );
144
145 /**
146 * Conditionally flushes rewrite rules if we have reason to.
147 *
148 * @since 1.3.0
149 */
150 function cptui_flush_rewrite_rules() {
151
152 if ( wp_doing_ajax() ) {
153 return;
154 }
155
156 /*
157 * Wise men say that you should not do flush_rewrite_rules on init or admin_init. Due to the nature of our plugin
158 * and how new post types or taxonomies can suddenly be introduced, we need to...potentially. For this,
159 * we rely on a short lived transient. Only 5 minutes life span. If it exists, we do a soft flush before
160 * deleting the transient to prevent subsequent flushes. The only times the transient gets created, is if
161 * post types or taxonomies are created, updated, deleted, or imported. Any other time and this condition
162 * should not be met.
163 */
164 $flush_it = get_transient( 'cptui_flush_rewrite_rules' );
165 if ( 'true' === $flush_it ) {
166 flush_rewrite_rules( false );
167 // So we only run this once.
168 delete_transient( 'cptui_flush_rewrite_rules' );
169 }
170 }
171 add_action( 'admin_init', 'cptui_flush_rewrite_rules' );
172
173 /**
174 * Return the current action being done within CPTUI context.
175 *
176 * @since 1.3.0
177 *
178 * @return string Current action being done by CPTUI
179 */
180 function cptui_get_current_action() {
181 $current_action = '';
182 if ( ! empty( $_GET ) && isset( $_GET['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
183 $current_action .= esc_textarea( wp_unslash( $_GET['action'] ) ); // phpcs:ignore
184 }
185
186 return $current_action;
187 }
188
189 /**
190 * Return an array of all post type slugs from Custom Post Type UI.
191 *
192 * @since 1.3.0
193 *
194 * @return array CPTUI post type slugs.
195 */
196 function cptui_get_post_type_slugs() {
197 $post_types = get_option( 'cptui_post_types' );
198 if ( ! empty( $post_types ) ) {
199 return array_keys( $post_types );
200 }
201 return [];
202 }
203
204 /**
205 * Return an array of all taxonomy slugs from Custom Post Type UI.
206 *
207 * @since 1.3.0
208 *
209 * @return array CPTUI taxonomy slugs.
210 */
211 function cptui_get_taxonomy_slugs() {
212 $taxonomies = get_option( 'cptui_taxonomies' );
213 if ( ! empty( $taxonomies ) ) {
214 return array_keys( $taxonomies );
215 }
216 return [];
217 }
218
219 /**
220 * Return the appropriate admin URL depending on our context.
221 *
222 * @since 1.3.0
223 *
224 * @param string $path URL path.
225 * @return string
226 */
227 function cptui_admin_url( $path ) {
228 if ( is_multisite() && is_network_admin() ) {
229 return network_admin_url( $path );
230 }
231
232 return admin_url( $path );
233 }
234
235 /**
236 * Construct action tag for `<form>` tag.
237 *
238 * @since 1.3.0
239 *
240 * @param object|string $ui CPTUI Admin UI instance. Optional. Default empty string.
241 * @return string
242 */
243 function cptui_get_post_form_action( $ui = '' ) {
244 /**
245 * Filters the string to be used in an `action=""` attribute.
246 *
247 * @since 1.3.0
248 */
249 return apply_filters( 'cptui_post_form_action', '', $ui );
250 }
251
252 /**
253 * Display action tag for `<form>` tag.
254 *
255 * @since 1.3.0
256 *
257 * @param object $ui CPTUI Admin UI instance.
258 */
259 function cptui_post_form_action( $ui ) {
260 echo esc_attr( cptui_get_post_form_action( $ui ) );
261 }
262
263 /**
264 * Fetch our CPTUI post types option.
265 *
266 * @since 1.3.0
267 *
268 * @return mixed
269 */
270 function cptui_get_post_type_data() {
271 return apply_filters( 'cptui_get_post_type_data', get_option( 'cptui_post_types', [] ), get_current_blog_id() );
272 }
273
274 /**
275 * Fetch our CPTUI taxonomies option.
276 *
277 * @since 1.3.0
278 *
279 * @return mixed
280 */
281 function cptui_get_taxonomy_data() {
282 return apply_filters( 'cptui_get_taxonomy_data', get_option( 'cptui_taxonomies', [] ), get_current_blog_id() );
283 }
284
285 /**
286 * Checks if a post type is already registered.
287 *
288 * @since 1.3.0
289 *
290 * @param string $slug Post type slug to check. Optional. Default empty string.
291 * @param array|string $data Post type data being utilized. Optional.
292 * @return mixed
293 */
294 function cptui_get_post_type_exists( $slug = '', $data = [] ) {
295
296 /**
297 * Filters the boolean value for if a post type exists for 3rd parties.
298 *
299 * @since 1.3.0
300 *
301 * @param string $slug Post type slug to check.
302 * @param array|string $data Post type data being utilized.
303 */
304 return apply_filters( 'cptui_get_post_type_exists', post_type_exists( $slug ), $data );
305 }
306
307 /**
308 * Checks if a taxonomy is already registered.
309 *
310 * @since 1.6.0
311 *
312 * @param string $slug Taxonomy slug to check. Optional. Default empty string.
313 * @param array|string $data Taxonomy data being utilized. Optional.
314 *
315 * @return mixed
316 */
317 function cptui_get_taxonomy_exists( $slug = '', $data = [] ) {
318
319 /**
320 * Filters the boolean value for if a taxonomy exists for 3rd parties.
321 *
322 * @since 1.6.0
323 *
324 * @param string $slug Taxonomy slug to check.
325 * @param array|string $data Taxonomy data being utilized.
326 */
327 return apply_filters( 'cptui_get_taxonomy_exists', taxonomy_exists( $slug ), $data );
328 }
329
330 /**
331 * Displays WebDevStudios products in a sidebar on the add/edit screens for post types and taxonomies.
332 *
333 * We hope you don't mind.
334 *
335 * @since 1.3.0
336 *
337 * @internal
338 */
339 function cptui_products_sidebar() {
340
341 echo '<div class="wdspromos">';
342
343 cptui_newsletter_form();
344
345 $ads = cptui_get_ads();
346 if ( ! empty( $ads ) ) {
347 foreach ( $ads as $ad ) {
348 $the_ad = sprintf(
349 '<img src="%s" alt="%s">',
350 esc_attr( $ad['image'] ),
351 esc_attr( $ad['text'] )
352 );
353
354 // Escaping $the_ad breaks the html.
355 printf(
356 '<p><a href="%s">%s</a></p>',
357 esc_url( $ad['url'] ),
358 $the_ad // phpcs:ignore WordPress.Security.EscapeOutput
359 );
360 }
361 printf(
362 '<p><a href="%s">%s</a></p>',
363 'https://pluginize.com/plugins/custom-post-type-ui-extended/ref/pluginizeaff/?campaign=cptui-sidebar-remove',
364 esc_html__( 'Remove these ads?', 'custom-post-type-ui' )
365 );
366 }
367 echo '</div>';
368
369 }
370 add_action( 'cptui_below_post_type_tab_menu', 'cptui_products_sidebar' );
371 add_action( 'cptui_below_taxonomy_tab_menu', 'cptui_products_sidebar' );
372
373 /**
374 * Outputs our newsletter signup form.
375 *
376 * @since 1.3.4
377 * @internal
378 */
379 function cptui_newsletter_form() {
380 ?>
381
382 <div class="email-octopus-form-wrapper">
383 <?php
384 echo sprintf(
385 /* translators: Placeholders are just for HTML markup that doesn't need translated */
386 '<p><strong>%s</strong></p>',
387 esc_html__( 'Get email updates from pluginize.com about Custom Post Type UI', 'custom-post-type-ui' )
388 );
389 ?>
390 <p class="email-octopus-success-message"></p>
391 <p class="email-octopus-error-message"></p>
392
393 <form method="post" action="https://emailoctopus.com/lists/2039e001-4775-11ea-be00-06b4694bee2a/members/embedded/1.3/add" class="email-octopus-form" data-sitekey="6LdYsmsUAAAAAPXVTt-ovRsPIJ_IVhvYBBhGvRV6">
394 <div class="email-octopus-form-row">
395
396 <?php
397 echo sprintf(
398 /* translators: Placeholders are just for HTML markup that doesn't need translated */
399 '<label for="field_0">%s</label>',
400 esc_html__( 'Email address', 'custom-post-type-ui' )
401 );
402 ?>
403 <input id="field_0" name="field_0" type="email" placeholder="email@domain.com" style="max-width:100%;">
404 </div>
405
406 <div class="email-octopus-form-row-hp" aria-hidden="true">
407 <!-- Do not remove this field, otherwise you risk bot sign-ups -->
408 <input type="text" name="hp2039e001-4775-11ea-be00-06b4694bee2a" tabindex="-1" autocomplete="nope">
409 </div>
410
411 <div class="email-octopus-form-row-subscribe">
412 <input type="hidden" name="successRedirectUrl" value="">
413 <?php
414 echo sprintf(
415 /* translators: Placeholders are just for HTML markup that doesn't need translated */
416 '<button type="submit" class="button button-secondary">%s</button>',
417 esc_html__( 'Subscribe', 'custom-post-type-ui' )
418 );
419 ?>
420
421 </div>
422 </form>
423 </div>
424
425 <?php
426 }
427
428 /**
429 * Add our Email Octopus scripts and stylesheet.
430 *
431 * @author Scott Anderson <scott.anderson@webdevstudios.com>
432 * @since NEXT
433 */
434 function enqueue_email_octopus_assets() {
435
436 $current_screen = get_current_screen();
437
438 if ( ! is_object( $current_screen ) ) {
439 return;
440 }
441
442 $screens = [
443 'toplevel_page_cptui_main_menu',
444 'cpt-ui_page_cptui_manage_post_types',
445 'cpt-ui_page_cptui_manage_taxonomies',
446 ];
447
448 if ( ! in_array( $current_screen->base, $screens, true ) ) {
449 return;
450 }
451
452 if ( ! has_action( 'cptui_below_post_type_tab_menu' ) || ! has_action( 'cptui_below_taxonomy_tab_menu' ) ) {
453 return;
454 }
455
456 wp_enqueue_style( 'cptui-emailoctopus', 'https://emailoctopus.com/bundles/emailoctopuslist/css/formEmbed.css' ); // phpcs:ignore
457
458 wp_enqueue_script( 'cptui-emailoctopus-js', 'https://emailoctopus.com/bundles/emailoctopuslist/js/1.4/formEmbed.js', [ 'jquery' ], '', true ); // phpcs:ignore
459
460 }
461 add_action( 'admin_enqueue_scripts', 'enqueue_email_octopus_assets' );
462
463 /**
464 * Fetch all set ads to be displayed.
465 *
466 * @since 1.3.4
467 *
468 * @return array
469 */
470 function cptui_get_ads() {
471
472 /**
473 * Filters the array of ads to iterate over.
474 *
475 * Each index in the ads array should have a url index with the url to link to,
476 * an image index specifying an image location to load from, and a text index used
477 * for alt attribute text.
478 *
479 * @since 1.3.4
480 *
481 * @param array $value Array of ads to iterate over. Default empty.
482 */
483 return (array) apply_filters( 'cptui_ads', [] );
484 }
485
486 /**
487 * Add our default ads to the ads filter.
488 *
489 * @since 1.3.4
490 *
491 * @internal
492 *
493 * @param array $ads Array of ads set so far. Optional.
494 * @return array $ads Array of newly constructed ads.
495 */
496 function cptui_default_ads( $ads = [] ) {
497 $ads[] = [
498 'url' => 'https://pluginize.com/plugins/custom-post-type-ui-extended/?utm_source=cptui-sidebar&utm_medium=text&utm_campaign=cptui',
499 'image' => plugin_dir_url( __DIR__ ) . 'images/wds_ads/cptui-extended.png',
500 'text' => 'Custom Post Type UI Extended product ad',
501 ];
502
503 $ads[] = [
504 'url' => 'https://pluginize.com/plugins/instago/?utm_source=cptui-sidebar&utm_medium=text&utm_campaign=instago',
505 'image' => plugin_dir_url( __DIR__ ) . 'images/wds_ads/instago.png',
506 'text' => 'InstaGo product ad',
507 ];
508
509 $ads[] = [
510 'url' => 'https://pluginize.com/plugins/buddypages/?utm_source=cptui-sidebar&utm_medium=text&utm_campaign=buddypages',
511 'image' => plugin_dir_url( __DIR__ ) . 'images/wds_ads/buddypages.png',
512 'text' => 'BuddyPages product ad',
513 ];
514
515 $ads[] = [
516 'url' => 'https://maintainn.com/?utm_source=Pluginize-v2&utm_medium=Plugin-Sidebar&utm_campaign=CPTUI',
517 'image' => plugin_dir_url( __DIR__ ) . 'images/wds_ads/maintainn.png',
518 'text' => 'Maintainn product ad',
519 ];
520
521 return $ads;
522 }
523 add_filter( 'cptui_ads', 'cptui_default_ads' );
524
525 /**
526 * Randomize our array order.
527 * Preserves CPTUI-Extended as the first index. Self promotion, yo.
528 *
529 * @since 1.3.0
530 *
531 * @param array $ads Array of ads to show.
532 * @return array
533 */
534 function cptui_randomize_ads( $ads = [] ) {
535 $new_order = [];
536 foreach ( $ads as $key => $ad ) {
537 if ( false !== strpos( $ad['url'], 'custom-post-type-ui-extended' ) ) {
538 $new_order[] = $ad;
539 unset( $ads[ $key ] );
540 }
541 }
542 shuffle( $ads );
543
544 return array_merge( $new_order, $ads );
545 }
546 add_filter( 'cptui_ads', 'cptui_randomize_ads', 11 );
547
548 /**
549 * Secondary admin notices function for use with admin_notices hook.
550 *
551 * Constructs admin notice HTML.
552 *
553 * @since 1.4.0
554 *
555 * @param string $message Message to use in admin notice. Optional. Default empty string.
556 * @param bool $success Whether or not a success. Optional. Default true.
557 * @return mixed
558 */
559 function cptui_admin_notices_helper( $message = '', $success = true ) {
560
561 $class = [];
562 $class[] = $success ? 'updated' : 'error';
563 $class[] = 'notice is-dismissible';
564
565 $messagewrapstart = '<div id="message" class="' . implode( ' ', $class ) . '"><p>';
566
567 $messagewrapend = '</p></div>';
568
569 $action = '';
570
571 /**
572 * Filters the custom admin notice for CPTUI.
573 *
574 * @since 1.0.0
575 *
576 * @param string $value Complete HTML output for notice.
577 * @param string $action Action whose message is being generated.
578 * @param string $message The message to be displayed.
579 * @param string $messagewrapstart Beginning wrap HTML.
580 * @param string $messagewrapend Ending wrap HTML.
581 */
582 return apply_filters( 'cptui_admin_notice', $messagewrapstart . $message . $messagewrapend, $action, $message, $messagewrapstart, $messagewrapend );
583 }
584
585 /**
586 * Grab post type or taxonomy slug from $_POST global, if available.
587 *
588 * @since 1.4.0
589 *
590 * @internal
591 *
592 * @return string
593 */
594 function cptui_get_object_from_post_global() {
595 if ( isset( $_POST['cpt_custom_post_type']['name'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
596 $type_item = filter_input( INPUT_POST, 'cpt_custom_post_type', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_REQUIRE_ARRAY );
597 if ( $type_item ) {
598 return sanitize_text_field( $type_item['name'] );
599 }
600 }
601
602 if ( isset( $_POST['cpt_custom_tax']['name'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
603 $tax_item = filter_input( INPUT_POST, 'cpt_custom_tax', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_REQUIRE_ARRAY );
604 if ( $tax_item ) {
605 return sanitize_text_field( $tax_item['name'] );
606 }
607 }
608
609 return esc_html__( 'Object', 'custom-post-type-ui' );
610 }
611
612 /**
613 * Successful add callback.
614 *
615 * @since 1.4.0
616 */
617 function cptui_add_success_admin_notice() {
618 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
619 sprintf(
620 /* translators: Placeholders are just for HTML markup that doesn't need translated */
621 esc_html__( '%s has been successfully added', 'custom-post-type-ui' ),
622 cptui_get_object_from_post_global()
623 )
624 );
625 }
626
627 /**
628 * Fail to add callback.
629 *
630 * @since 1.4.0
631 */
632 function cptui_add_fail_admin_notice() {
633 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
634 sprintf(
635 /* translators: Placeholders are just for HTML markup that doesn't need translated */
636 esc_html__( '%s has failed to be added', 'custom-post-type-ui' ),
637 cptui_get_object_from_post_global()
638 ),
639 false
640 );
641 }
642
643 /**
644 * Successful update callback.
645 *
646 * @since 1.4.0
647 */
648 function cptui_update_success_admin_notice() {
649 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
650 sprintf(
651 /* translators: Placeholders are just for HTML markup that doesn't need translated */
652 esc_html__( '%s has been successfully updated', 'custom-post-type-ui' ),
653 cptui_get_object_from_post_global()
654 )
655 );
656 }
657
658 /**
659 * Fail to update callback.
660 *
661 * @since 1.4.0
662 */
663 function cptui_update_fail_admin_notice() {
664 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
665 sprintf(
666 /* translators: Placeholders are just for HTML markup that doesn't need translated */
667 esc_html__( '%s has failed to be updated', 'custom-post-type-ui' ),
668 cptui_get_object_from_post_global()
669 ),
670 false
671 );
672 }
673
674 /**
675 * Successful delete callback.
676 *
677 * @since 1.4.0
678 */
679 function cptui_delete_success_admin_notice() {
680 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
681 sprintf(
682 /* translators: Placeholders are just for HTML markup that doesn't need translated */
683 esc_html__( '%s has been successfully deleted', 'custom-post-type-ui' ),
684 cptui_get_object_from_post_global()
685 )
686 );
687 }
688
689 /**
690 * Fail to delete callback.
691 *
692 * @since 1.4.0
693 */
694 function cptui_delete_fail_admin_notice() {
695 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
696 sprintf(
697 /* translators: Placeholders are just for HTML markup that doesn't need translated */
698 esc_html__( '%s has failed to be deleted', 'custom-post-type-ui' ),
699 cptui_get_object_from_post_global()
700 ),
701 false
702 );
703 }
704
705 /**
706 * Success to import callback.
707 *
708 * @since 1.5.0
709 */
710 function cptui_import_success_admin_notice() {
711 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
712 esc_html__( 'Successfully imported data.', 'custom-post-type-ui' )
713 );
714 }
715
716 /**
717 * Failure to import callback.
718 *
719 * @since 1.5.0
720 */
721 function cptui_import_fail_admin_notice() {
722 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
723 esc_html__( 'Invalid data provided', 'custom-post-type-ui' ),
724 false
725 );
726 }
727
728 /**
729 * Failure to verify nonce, callback
730 *
731 * @since 1.7.4
732 */
733 function cptui_nonce_fail_admin_notice() {
734 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
735 esc_html__( 'Nonce failed verification', 'custom-post-type-ui' ),
736 false
737 );
738 }
739
740 /**
741 * Returns error message for if trying to register existing post type.
742 *
743 * @since 1.4.0
744 *
745 * @return string
746 */
747 function cptui_slug_matches_post_type() {
748 return sprintf(
749 /* translators: Placeholders are just for HTML markup that doesn't need translated */
750 esc_html__( 'Please choose a different post type name. %s is already registered.', 'custom-post-type-ui' ),
751 cptui_get_object_from_post_global()
752 );
753 }
754
755 /**
756 * Returns error message for if trying to register existing taxonomy.
757 *
758 * @since 1.4.0
759 *
760 * @return string
761 */
762 function cptui_slug_matches_taxonomy() {
763 return sprintf(
764 /* translators: Placeholders are just for HTML markup that doesn't need translated */
765 esc_html__( 'Please choose a different taxonomy name. %s is already registered.', 'custom-post-type-ui' ),
766 cptui_get_object_from_post_global()
767 );
768 }
769
770 /**
771 * Returns error message for if not providing a post type to associate taxonomy to.
772 *
773 * @since 1.6.0
774 *
775 * @return string
776 */
777 function cptui_empty_cpt_on_taxonomy() {
778 return esc_html__( 'Please provide a post type to attach to.', 'custom-post-type-ui' );
779 }
780
781 /**
782 * Returns error message for if trying to register post type with matching page slug.
783 *
784 * @since 1.4.0
785 *
786 * @return string
787 */
788 function cptui_slug_matches_page() {
789 $slug = cptui_get_object_from_post_global();
790 $matched_slug = get_page_by_path(
791 cptui_get_object_from_post_global()
792 );
793 if ( $matched_slug instanceof WP_Post ) {
794 $slug = sprintf(
795 /* translators: Placeholders are just for HTML markup that doesn't need translated */
796 '<a href="%s">%s</a>',
797 get_edit_post_link( $matched_slug->ID ),
798 cptui_get_object_from_post_global()
799 );
800 }
801
802 return sprintf(
803 /* translators: Placeholders are just for HTML markup that doesn't need translated */
804 esc_html__( 'Please choose a different post type name. %s matches an existing page slug, which can cause conflicts.', 'custom-post-type-ui' ),
805 $slug
806 );
807 }
808
809 /**
810 * Returns error message for if trying to use quotes in slugs or rewrite slugs.
811 *
812 * @since 1.4.0
813 *
814 * @return string
815 */
816 function cptui_slug_has_quotes() {
817 return sprintf(
818 esc_html__( 'Please do not use quotes in post type/taxonomy names or rewrite slugs', 'custom-post-type-ui' ),
819 cptui_get_object_from_post_global()
820 );
821 }
822
823 /**
824 * Error admin notice.
825 *
826 * @since 1.4.0
827 */
828 function cptui_error_admin_notice() {
829 echo cptui_admin_notices_helper( // phpcs:ignore WordPress.Security.EscapeOutput
830 apply_filters( 'cptui_custom_error_message', '' ),
831 false
832 );
833 }
834
835 /**
836 * Mark site as not a new CPTUI install upon update to 1.5.0
837 *
838 * @since 1.5.0
839 *
840 * @param object $wp_upgrader WP_Upgrader instance.
841 * @param array $extras Extra information about performed upgrade.
842 */
843 function cptui_not_new_install( $wp_upgrader, $extras ) {
844
845 if ( $wp_upgrader instanceof \Plugin_Upgrader ) {
846 return;
847 }
848
849 if ( ! array_key_exists( 'plugins', $extras ) || ! is_array( $extras['plugins'] ) ) {
850 return;
851 }
852
853 // Was CPTUI updated?
854 if ( ! in_array( 'custom-post-type-ui/custom-post-type-ui.php', $extras['plugins'], true ) ) {
855 return;
856 }
857
858 // If we are already known as not new, return.
859 if ( cptui_is_new_install() ) {
860 return;
861 }
862
863 // We need to mark ourselves as not new.
864 cptui_set_not_new_install();
865 }
866 add_action( 'upgrader_process_complete', 'cptui_not_new_install', 10, 2 );
867
868 /**
869 * Check whether or not we're on a new install.
870 *
871 * @since 1.5.0
872 *
873 * @return bool
874 */
875 function cptui_is_new_install() {
876 $new_or_not = true;
877 $saved = get_option( 'cptui_new_install', '' );
878
879 if ( 'false' === $saved ) {
880 $new_or_not = false;
881 }
882
883 /**
884 * Filters the new install status.
885 *
886 * Offers third parties the ability to override if they choose to.
887 *
888 * @since 1.5.0
889 *
890 * @param bool $new_or_not Whether or not site is a new install.
891 */
892 return (bool) apply_filters( 'cptui_is_new_install', $new_or_not );
893 }
894
895 /**
896 * Set our activation status to not new.
897 *
898 * @since 1.5.0
899 */
900 function cptui_set_not_new_install() {
901 update_option( 'cptui_new_install', 'false' );
902 }
903
904 /**
905 * Returns saved values for single post type from CPTUI settings.
906 *
907 * @since 1.5.0
908 *
909 * @param string $post_type Post type to retrieve CPTUI object for.
910 * @return string
911 */
912 function cptui_get_cptui_post_type_object( $post_type = '' ) {
913 $post_types = get_option( 'cptui_post_types', [] );
914
915 if ( is_array( $post_types ) && array_key_exists( $post_type, $post_types ) ) {
916 return $post_types[ $post_type ];
917 }
918 return [];
919 }
920
921 /**
922 * Returns saved values for single taxonomy from CPTUI settings.
923 *
924 * @since 1.5.0
925 *
926 * @param string $taxonomy Taxonomy to retrieve CPTUI object for.
927 * @return string
928 */
929 function cptui_get_cptui_taxonomy_object( $taxonomy = '' ) {
930 $taxonomies = get_option( 'cptui_taxonomies', [] );
931
932 if ( is_array( $taxonomies ) && array_key_exists( $taxonomy, $taxonomies ) ) {
933 return $taxonomies[ $taxonomy ];
934 }
935 return [];
936 }
937
938 /**
939 * Checks if a requested post type has a custom CPTUI feature supported.
940 *
941 * @since 1.5.0
942 *
943 * @param string $post_type Post type slug.
944 * @param string $feature Feature to check for.
945 * @return bool
946 */
947 function cptui_post_type_supports( $post_type, $feature ) {
948
949 $object = cptui_get_cptui_post_type_object( $post_type );
950
951 if ( ! empty( $object ) ) {
952 if ( array_key_exists( $feature, $object ) && ! empty( $object[ $feature ] ) ) {
953 return true;
954 }
955
956 return false;
957 }
958
959 return false;
960 }
961
962 /**
963 * Add missing post_format taxonomy support for CPTUI post types.
964 *
965 * Addresses bug wih previewing changes for published posts with post types that
966 * have post-formats support.
967 *
968 * @since 1.5.8
969 *
970 * @param array $post_types Array of CPTUI post types.
971 */
972 function cptui_published_post_format_fix( $post_types ) {
973 if ( empty( $post_types ) || ! is_array( $post_types ) ) {
974 return;
975 }
976
977 foreach ( $post_types as $type ) {
978 if ( ! is_array( $type['supports'] ) ) {
979 continue;
980 }
981
982 if ( in_array( 'post-formats', $type['supports'], true ) ) {
983 add_post_type_support( $type['name'], 'post-formats' );
984 register_taxonomy_for_object_type( 'post_format', $type['name'] );
985 }
986 }
987 }
988 add_action( 'cptui_post_register_post_types', 'cptui_published_post_format_fix' );
989
990 /**
991 * Return a ready-to-use admin url for adding a new content type.
992 *
993 * @since 1.7.0
994 *
995 * @param string $content_type Content type to link to.
996 * @return string
997 */
998 function cptui_get_add_new_link( $content_type = '' ) {
999 if ( ! in_array( $content_type, [ 'post_types', 'taxonomies' ], true ) ) {
1000 return cptui_admin_url( 'admin.php?page=cptui_manage_post_types' );
1001 }
1002
1003 return cptui_admin_url( 'admin.php?page=cptui_manage_' . $content_type );
1004 }
1005