PluginProbe
Cooked – Recipe Management / 1.11.4
Cooked – Recipe Management v1.11.4
1.16.1 1.16.0 1.15.0 trunk 1.10.0 1.11.0 1.11.1 1.11.2 1.11.3 1.11.4 1.12.0 1.13.0 1.14.0 1.7.10 1.7.11 1.7.12 1.7.13 1.7.15.1 1.7.15.3 1.7.15.4 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 All 37 releases
cooked / includes / class.cooked-settings.php

class.cooked-settings.php in Cooked – Recipe Management 1.11.4, at includes/class.cooked-settings.php

729 lines 35.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Register Settings
4 *
5 * @package Cooked
6 * @subpackage Settings
7 * @since 1.0.0
8 */
9
10 // Exit if accessed directly
11 if ( !defined( 'ABSPATH' ) ) exit;
12
13 /**
14 * Cooked_Settings Class
15 *
16 * This class handles the settings creation and contains functions for retreiving those settings.
17 *
18 * @since 1.0.0
19 */
20 class Cooked_Settings {
21
22 public function __construct() {
23 add_filter( 'admin_init', [&$this, 'init'] );
24 add_filter( 'init', [&$this, 'init'] );
25 add_action( 'save_post', [&$this, 'browse_page_saved'], 10, 1 );
26 add_action( 'admin_notices', [ &$this, 'cooked_settings_saved_admin_notice' ] );
27 add_action( 'admin_notices', [ &$this, 'browse_page_missing_notice' ] );
28 }
29
30 public function browse_page_saved( $post_id ) {
31 // Just a revision, don't do anything
32 if ( wp_is_post_revision( $post_id ) ) return;
33
34 $_cooked_settings = Cooked_Settings::get();
35 if ( isset($_cooked_settings['browse_page']) && $_cooked_settings['browse_page'] == $post_id ) {
36 flush_rewrite_rules(false);
37 }
38 }
39
40 public static function init() {
41 global $_cooked_settings, $list_id_counter;
42
43 $list_id_counter = 0;
44 $_cooked_settings = Cooked_Settings::get();
45 register_setting( 'cooked_settings_group', 'cooked_settings', ['sanitize_callback' => [__CLASS__, 'sanitize_settings']] );
46 register_setting( 'cooked_settings_group', 'cooked_settings_saved' );
47 }
48
49 // Add this new method to handle settings sanitization.
50 public static function sanitize_settings($settings) {
51 $cooked_tabs_fields = self::tabs_fields();
52
53 // Process each field
54 foreach ($cooked_tabs_fields as $tab) {
55 if (isset($tab['fields']) && !empty($tab['fields'])) {
56 foreach ($tab['fields'] as $field_name => $field) {
57 // Handle checkbox fields specifically
58 if ($field['type'] === 'checkboxes') {
59 // If the field is missing from submission, set it as an empty array
60 if (!isset($settings[$field_name])) {
61 $settings[$field_name] = [];
62 } else {
63 // Remove any empty string values from checkbox arrays
64 if (!isset($settings[$field_name]) || !is_array($settings[$field_name])) {
65 $settings[$field_name] = [];
66 } else {
67 $settings[$field_name] = array_filter($settings[$field_name], function($value) {
68 return $value !== '';
69 });
70 }
71 }
72 }
73 }
74 }
75 }
76
77 return $settings;
78 }
79
80 function cooked_settings_saved_admin_notice() {
81 if (isset($_GET['settings-updated']) && $_GET['settings-updated'] && isset($_GET['page']) && $_GET['page'] === 'cooked_settings') {
82 add_settings_error(
83 'cooked_settings_group',
84 'cooked_settings_updated',
85 __( 'Cooked settings has been updated!', 'cooked' ),
86 'updated'
87 );
88 }
89 }
90
91 function browse_page_missing_notice() {
92 // Only show on admin pages, not on the Cooked settings page itself
93 if ( isset($_GET['page']) && $_GET['page'] === 'cooked_settings' ) {
94 return;
95 }
96
97 // Get Cooked settings
98 $_cooked_settings = self::get();
99
100 // Check if browse page is set
101 if ( empty($_cooked_settings['browse_page']) || !$_cooked_settings['browse_page'] ) {
102 $class = 'notice notice-warning is-dismissible';
103 $message = sprintf(
104 '<strong>' . __( 'Cooked Plugin Setup', 'cooked' ) . '</strong> ' .
105 __( 'To display your recipes properly, please set up your %s.', 'cooked' ),
106 '<a href="' . trailingslashit( admin_url() ) . 'admin.php?page=cooked_settings#recipe_settings">' . __( 'Browse/Search Recipes Page', 'cooked' ) . '</a>'
107 );
108 printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), $message );
109 }
110 }
111
112 public static function reset() {
113 global $_cooked_settings;
114 $_cooked_settings = Cooked_Settings::get();
115 }
116
117 public static function get() {
118 $_cooked_settings = get_option( 'cooked_settings', [] );
119
120 // Get defaults for fields that are not set yet.
121 $cooked_tabs_fields = self::tabs_fields();
122
123 if ( isset($cooked_tabs_fields) && !empty($cooked_tabs_fields) ) {
124 foreach ( $cooked_tabs_fields as $tab ) {
125 if ( isset($tab['fields']) && !empty($tab['fields']) ) {
126 foreach ( $tab['fields'] as $name => $field ) {
127 if ( $field['type'] == 'nonce' || $field['type'] == 'misc_button' ) continue;
128
129 if ( $field['type'] === 'checkboxes' ) {
130 $_cooked_settings[$name] = isset($_cooked_settings[$name]) ? $_cooked_settings[$name] : ( isset( $field['default'] ) ? $field['default'] : [] );
131 } else {
132 $_cooked_settings[$name] = isset($_cooked_settings[$name]) ? $_cooked_settings[$name] : ( isset( $field['default'] ) ? $field['default'] : false );
133 }
134 }
135 }
136 }
137 }
138
139 return apply_filters( 'cooked_get_settings', $_cooked_settings );
140 }
141
142 public static function tabs_fields() {
143 $pages_array = self::pages_array( __('Choose a page...','cooked'), __('No pages','cooked') );
144 $categories_array = self::terms_array( 'cp_recipe_category', __('No default', 'cooked'), __('No categories', 'cooked') );
145 $recipes_per_page_array = self::per_page_array();
146
147 // Dynamically load roles.
148 $role_options = [];
149 if (is_user_logged_in()) {
150 global $wp_roles;
151 $roles = $wp_roles->roles;
152
153 if (!empty($roles)) {
154 foreach ( $roles as $role => $data ) {
155 $role_options[$role] = [
156 'label' => $data['name']
157 ];
158 }
159 }
160 }
161
162 return apply_filters('cooked_settings_tabs_fields', [
163 'recipe_settings' => [
164 'name' => __('General', 'cooked'),
165 'icon' => 'gear',
166 'fields' => [
167 'browse_page' => [
168 'title' => __('Browse/Search Recipes Page', 'cooked'),
169 /* translators: a description on how to add the [cooked-browse] shortcode to a page */
170 'desc' => sprintf(__('Create a page with the %s shortcode on it, then choose it from this dropdown.', 'cooked'), '<code>[cooked-browse]</code>') . '<br><em>' . __('<b>Note:</b> This setting is required for the plugin to function properly.', 'cooked') . '</em>',
171 'type' => 'select',
172 'default' => 0,
173 'options' => $pages_array
174 ],
175 'recipes_per_page' => [
176 'title' => __('Recipes Per Page', 'cooked'),
177 /* translators: a description on how to choose the default number of recipes per page. */
178 'desc' => sprintf(__('Choose the default (set via the %s panel) or choose a different number here.', 'cooked'), '<a href="' . trailingslashit(get_admin_url()) . 'options-reading.php">' . __('Settings > Reading', 'cooked') . '</a>'),
179 'type' => 'select',
180 'default' => 9,
181 'options' => $recipes_per_page_array
182 ],
183 'recipe_taxonomies' => [
184 'title' => __('Recipe Taxonomies', 'cooked'),
185 'desc' => __('Choose which taxonomies you want to enable for your recipes.', 'cooked'),
186 'type' => 'checkboxes',
187 'default' => ['cp_recipe_category'],
188 'options' => apply_filters(
189 'cooked_taxonomy_options',
190 [
191 'cp_recipe_category' => __('Categories', 'cooked')
192 ]
193 )
194 ],
195 'recipe_info_display_options' => [
196 'title' => __('Global Recipe Toggles', 'cooked'),
197 'desc' => __('You can quickly hide or show different recipe elements (site-wide) with these checkboxes.', 'cooked'),
198 'type' => 'checkboxes',
199 'default' => apply_filters(
200 'cooked_recipe_info_display_options_defaults',
201 [
202 'author',
203 'taxonomies',
204 'difficulty_level',
205 'excerpt',
206 'timing_prep',
207 'timing_cook',
208 'timing_total',
209 'servings'
210 ]
211 ),
212 'options' => apply_filters(
213 'cooked_recipe_info_display_options',
214 [
215 'author' => __('Author', 'cooked'),
216 'taxonomies' => __('Category', 'cooked'),
217 'difficulty_level' => __('Difficulty Level', 'cooked'),
218 'excerpt' => __('Excerpt', 'cooked'),
219 'notes' => __('Notes', 'cooked'),
220 'timing_prep' => __('Prep Time', 'cooked'),
221 'timing_cook' => __('Cook Time', 'cooked'),
222 'timing_total' => __('Total Time', 'cooked'),
223 'servings' => __('Servings', 'cooked')
224 ]
225 )
226 ],
227 'carb_format' => [
228 'title' => __('Carbs Format', 'cooked'),
229 'desc' => __('You can display carbs as "Total" or "Net".', 'cooked'),
230 'type' => 'select',
231 'default' => 'total',
232 'options' => apply_filters(
233 'cooked_settings_carb_formats',
234 [
235 'total' => __('Total Carbs', 'cooked'),
236 'net' => __('Net Carbs', 'cooked')
237 ]
238 )
239 ],
240 'author_name_format' => [
241 'title' => __('Author Name Format', 'cooked'),
242 'desc' => __('You can show the full author\'s name or just a part of it.', 'cooked'),
243 'type' => 'select',
244 'default' => 'full',
245 'options' => apply_filters(
246 'cooked_settings_author_formats',
247 [
248 'full' => __('Full name', 'cooked'),
249 'first_last_initial' => __('Full first name w/last name initial', 'cooked'),
250 'first_initial_last' => __('First name initial w/full last name', 'cooked'),
251 'first_only' => __('First name only', 'cooked')
252 ]
253 )
254 ],
255 'disable_author_links' => [
256 'title' => __('Author Links', 'cooked'),
257 'desc' => __('If you do not want the author names to link to the author recipe listings, you can disable them here.', 'cooked') . '<br><em>' . __('<b>Note:</b> Author links require the Browse/Search Recipes Page to be set up correctly to function properly.', 'cooked') . '</em>',
258 'type' => 'checkboxes',
259 'color' => 'red',
260 'default' => [],
261 'options' => apply_filters(
262 'cooked_author_link_options',
263 [
264 'disabled' => __('Disable Author Links', 'cooked'),
265 ]
266 )
267 ],
268 'browse_default_cp_recipe_category' => [
269 'title' => __('Default Category', 'cooked'),
270 /* translators: a description on how to set the default recipe category for the [cooked-browse] shortcode. */
271 'desc' => sprintf(__('Optionally set the default recipe category for your %s shortcode display.', 'cooked'), '<code>[cooked-browse]</code>'),
272 'type' => 'select',
273 'default' => 0,
274 'options' => $categories_array
275 ],
276 'browse_default_sort' => [
277 'title' => __('Default Sort Order', 'cooked'),
278 /* translators: a description on how to set the default sort order for the [cooked-browse] shortcode. */
279 'desc' => sprintf(__('Set the default sort order for your %s shortcode display.', 'cooked'), '<code>[cooked-browse]</code>'),
280 'type' => 'select',
281 'default' => 'date_desc',
282 'options' => apply_filters(
283 'cooked_settings_sort_options',
284 [
285 'date_desc' => __('Newest First', 'cooked'),
286 'date_asc' => __('Oldest First', 'cooked'),
287 'title_asc' => __('Alphabetical', 'cooked'),
288 'title_desc' => __('Alphabetical (reversed)', 'cooked'),
289 ]
290 )
291 ],
292 'section_heading_default_html_tag' => [
293 'title' => __('Section Heading Default HTML Tag', 'cooked'),
294 /* translators: a description on how to set the default sort order for the [cooked-browse] shortcode. */
295 'desc' => __('Set the default HTML tag for your section headings.', 'cooked'),
296 'type' => 'select',
297 'default' => 'div',
298 'options' => apply_filters(
299 'cooked_settings_section_heading_default_html_tag_options',
300 [
301 'div' => __('div', 'cooked'),
302 'h2' => __('h2', 'cooked'),
303 'h3' => __('h3', 'cooked'),
304 'h4' => __('h4', 'cooked'),
305 'h5' => __('h5', 'cooked'),
306 'h6' => __('h6', 'cooked'),
307 ]
308 )
309 ],
310 'recipe_wp_editor_roles' => [
311 'title' => __('WP Editor Roles', 'cooked'),
312 'desc' => __('Choose which user roles can use the WP Editor for the Excerpt, Directions & Notes fields.', 'cooked'),
313 'type' => 'checkboxes',
314 'default' => apply_filters('cooked_recipe_wp_editor_roles_defaults', ['administrator', 'editor', 'cooked_recipe_editor']),
315 'options' => $role_options
316 ],
317 'advanced' => [
318 'title' => __('Advanced Settings', 'cooked'),
319 'desc' => '',
320 'type' => 'checkboxes',
321 'color' => 'red',
322 'class' => 'cooked-danger',
323 'default' => [],
324 'options' => apply_filters(
325 'cooked_advanced_options',
326 [
327 /* translators: an option to only show recipes with the [cooked-recipe] shortcode. */
328 'disable_public_recipes' => '<strong>' . __('Disable Public Recipes', 'cooked') . '</strong> &mdash; ' . sprintf(__('Only show recipes using the %s shortcode.', 'cooked'), '<code>[cooked-recipe]</code>'),
329 /* translators: an option to disable "meta" tags. */
330 'disable_meta_tags' => '<strong>' . sprintf(__('Disable %s Tags', 'cooked'), 'Cooked <code>&lt;meta&gt;</code>') . '</strong> &mdash; ' . __('Prevents duplicates when tags already exist.', 'cooked'),
331 'disable_servings_switcher' => '<strong>' . __('Disable "Servings Switcher"', 'cooked') . '</strong> &mdash; ' . __('Removes the servings dropdown on recipes.', 'cooked'),
332 'disable_schema_output' => '<strong>' . __('Disable Recipe Schema Output', 'cooked') . '</strong> &mdash; ' . __('You should only do this if you\'re using something else to output schema information.', 'cooked'),
333 'disable_cp_recipe_archive' => '<strong>' . __('Disable Recipe Archive Page', 'cooked') . '</strong> &mdash; ' . __('Prevents the recipe archive from being displayed.', 'cooked')
334 ]
335 )
336 ],
337 ]
338 ],
339 'design' => [
340 'name' => __('Design', 'cooked'),
341 'icon' => 'pencil',
342 'fields' => [
343 'dark_mode' => [
344 'title' => __('Dark Mode', 'cooked'),
345 'desc' => __('If your site has a dark background, you should enable "Dark Mode" so that Cooked can match this style.', 'cooked'),
346 'type' => 'checkboxes',
347 'default' => [],
348 'options' => apply_filters(
349 'cooked_dark_mode_options',
350 [
351 'enabled' => __('Enable "Dark Mode"', 'cooked'),
352 ]
353 )
354 ],
355 'hide_author_avatars' => [
356 'title' => __('Author Images', 'cooked'),
357 'desc' => __('If you do not want to display the author images (avatars), you can disable them here.', 'cooked'),
358 'type' => 'checkboxes',
359 'color' => 'red',
360 'default' => [],
361 'options' => apply_filters(
362 'cooked_author_image_options',
363 [
364 'hidden' => __('Hide Author Images', 'cooked'),
365 ]
366 )
367 ],
368 'main_color' => [
369 'title' => __('Main Color', 'cooked'),
370 'desc' => __('Used on buttons, cooking timer, etc.', 'cooked'),
371 'type' => 'color_field',
372 'default' => '#16a780',
373 'options' => '#16a780'
374 ],
375 'main_color_hover' => [
376 'title' => __('Main Color (on hover)', 'cooked'),
377 'desc' => __('Used when hovering over buttons.', 'cooked'),
378 'type' => 'color_field',
379 'default' => '#1b9371',
380 'options' => '#1b9371'
381 ],
382 'responsive_breakpoint_1' => [
383 'title' => __('First Responsive Breakpoint', 'cooked'),
384 'desc' => __('Set the first responsive breakpoint. Best for large tablets.', 'cooked'),
385 'type' => 'number_field',
386 'default' => '1000',
387 'options' => ''
388 ],
389 'responsive_breakpoint_2' => [
390 'title' => __('Second Responsive Breakpoint', 'cooked'),
391 'desc' => __('Set the second responsive breakpoint. Best for small tablets.', 'cooked'),
392 'type' => 'number_field',
393 'default' => '750',
394 'options' => ''
395 ],
396 'responsive_breakpoint_3' => [
397 'title' => __('Third Responsive Breakpoint', 'cooked'),
398 'desc' => __('Set the third responsive breakpoint. Best for phones and other small devices.', 'cooked'),
399 'type' => 'number_field',
400 'default' => '520',
401 'options' => ''
402 ]
403 ]
404 ],
405 'permalinks' => [
406 'name' => __('Permalinks', 'cooked'),
407 'icon' => 'link-lt',
408 'fields' => [
409 'recipe_permalink' => [
410 'title' => __('Recipe Permalink', 'cooked'),
411 'desc' => '',
412 'type' => 'permalink_field',
413 'options' => __('recipe-name', 'cooked'),
414 'default' => 'recipes'
415 ],
416 'recipe_author_permalink' => [
417 'title' => __('Recipe Author Permalink', 'cooked'),
418 'desc' => '',
419 'type' => 'permalink_field',
420 'options' => __('author-name', 'cooked'),
421 'default' => 'recipe-author'
422 ],
423 'recipe_category_permalink' => [
424 'title' => __('Recipe Category Permalink', 'cooked'),
425 'desc' => '',
426 'type' => 'permalink_field',
427 'options' => __('recipe-category-name', 'cooked'),
428 'default' => 'recipe-category'
429 ]
430 ]
431 ]
432 ], $pages_array, $categories_array);
433 }
434
435 public static function per_page_array() {
436 $counter = 0;
437 /* translators: posts_per_page default */
438 $per_page_array[] = sprintf( __('WordPress Default %s','cooked'), '(' . get_option( 'posts_per_page' ) . ')' );
439 do {
440 $counter++;
441 $per_page_array[$counter] = $counter;
442 } while ( $counter < 50 );
443 $per_page_array['-1'] = __('Show All (no pagination)','cooked');
444
445 return apply_filters( 'cooked_per_page_options', $per_page_array );
446 }
447
448 public static function pages_array( $choose_text, $none_text = false ) {
449 $page_array = [];
450 $pages = get_posts([
451 'post_type' => 'page',
452 'posts_per_page' => -1
453 ]);
454
455 if( !empty($pages) ) {
456 $page_array[0] = $choose_text;
457 foreach ($pages as $_page) {
458 $page_array[$_page->ID] = $_page->post_title . ' (ID:' . $_page->ID . ')';
459 }
460 } elseif ( $none_text ) {
461 $page_array[0] = $none_text;
462 }
463
464 return apply_filters( 'cooked_settings_pages_array', $page_array );
465 }
466
467 public static function terms_array( $term, $choose_text, $none_text = false, $hide_empty = false, $parents_only = false, $child_of = false ) {
468 $terms_array = [];
469
470 $args = [
471 'taxonomy' => $term,
472 'hide_empty' => $hide_empty
473 ];
474
475 if ( $parents_only ) {
476 $args['parent'] = '0';
477 } elseif ( $child_of ) {
478 $_term = is_numeric($child_of) ? $child_of : get_term_by( 'slug', $child_of, $term );
479 $term_id = is_object( $_term ) ? $_term->term_id : $_term;
480 $args['parent'] = $term_id;
481 }
482
483 $terms = get_terms( $args );
484
485 if ( !empty($terms) ) {
486 if ($choose_text) {
487 $terms_array[0] = $choose_text;
488 }
489
490 foreach ($terms as $_term) {
491 if ( !is_array($_term) ) {
492 $terms_array[$_term->term_id] = $_term->name;
493 }
494 }
495 } elseif ( $none_text ) {
496 $terms_array[0] = $none_text;
497 }
498
499 return apply_filters( 'cooked_settings_' . $term . '_array', $terms_array );
500 }
501
502 public static function field_radio( $field_name, $options ) {
503 global $_cooked_settings, $conditions;
504
505 $counter = 1;
506
507 echo '<p class="cooked-padded">';
508 foreach ( $options as $value => $name) {
509 $is_disabled = '';
510 $conditional_value = '';
511 $conditional_requirement = '';
512
513 if ( is_array($name) ):
514 if ( isset($name['read_only']) && $name['read_only'] ):
515 $is_disabled = ' disabled';
516 endif;
517
518 if ( isset($name['conditional_value']) && $name['conditional_value'] ):
519 $conditional_value = ' v-model="' . esc_attr($name['conditional_value']) . '"';
520 if ( !in_array( $name['conditional_value'], $conditions ) ):
521 $conditions[$value] = esc_attr($name['conditional_requirement']);
522 endif;
523 endif;
524
525 if ( isset($name['conditional_requirement']) && $name['conditional_requirement'] ):
526 if ( is_array($name['conditional_requirement']) ):
527 $conditional_requirement = ' v-show="' . implode( ' && ', $name['conditional_requirement'] ) . '"';
528 else:
529 $conditional_requirement = ' v-show="' . esc_attr($name['conditional_requirement']) . '"';
530 endif;
531 endif;
532
533 $name = $name['label'];
534 endif;
535
536 $combined_extras = $is_disabled . $conditional_value;
537
538 if ( $conditional_requirement ): echo '<transition name="fade"><span class="conditional-requirement"' . esc_attr( $conditional_requirement ) . '>'; endif;
539 echo '<input' . $combined_extras . ' type="radio" id="radio-group-' . esc_attr( $field_name ) . '-' . esc_attr( $value ) . '" name="cooked_settings[' . esc_attr( $field_name ) . ']" value="' . esc_attr( $value ) . '"' . ( isset( $_cooked_settings[$field_name] ) && $_cooked_settings[$field_name] == $value || isset( $_cooked_settings[$field_name][0] ) && $_cooked_settings[$field_name][0] == $value ? ' checked' : '' ) . '/>';
540 echo '&nbsp;<label for="radio-group-' . esc_attr( $field_name ) . '-' . esc_attr( $value ) . '">' . wp_kses_post( $name ) . '</label>';
541 echo '<br>';
542 if ( $conditional_requirement ): echo '</span></transition>'; endif;
543
544 $counter++;
545 }
546 echo '</p>';
547 }
548
549 public static function field_select( $field_name, $options, $color = false, $field = []) {
550 global $_cooked_settings;
551
552 $is_disabled = '';
553
554 if ( isset($field['read_only']) && $field['read_only'] ) {
555 $is_disabled = ' disabled';
556 }
557
558 echo '<p>';
559 echo '<select' . $is_disabled . ' name="cooked_settings[' . esc_attr( $field_name ) . ']">';
560 foreach ( $options as $value => $name) {
561 echo '<option value="' . esc_attr( $value ) . '"' . ( isset( $_cooked_settings[$field_name] ) && $_cooked_settings[$field_name] == $value ? ' selected' : '' ) . '>' . esc_attr( $name ) . '</option>';
562 }
563 echo '</select>';
564 echo '</p>';
565 }
566
567 public static function field_nonce( $field_name, $options ) {
568 wp_nonce_field( $field_name, $field_name );
569 }
570
571 // Kept here for backwards compatibility only. Removed used in Cooked Pro 1.0.1
572 public static function field_misc_button( $field_name, $title ) {
573 echo '<p>';
574 echo '<input type="submit" class="button-secondary" name="' . esc_attr( $field_name ) . '" value="' . esc_attr( $title ) . '">';
575 echo '</p>';
576 }
577 // END
578
579 public static function field_migrate_button( $field_name, $title ) {
580 $old_recipes = get_transient('cooked_classic_recipes');
581
582 if ($old_recipes != 'complete') {
583 $total = count($old_recipes);
584
585 if ($total > 0) {
586 echo '<p>';
587 echo '<input id="cooked-migration-button" type="button" class="button-secondary" name="begin_cooked_migration" value="' . __( 'Begin Migration', 'cooked' ) . '">';
588 echo '</p>';
589 echo '<p>';
590 echo '<span id="cooked-migration-progress" class="cooked-progress"><span class="cooked-progress-bar"></span></span><span id="cooked-migration-progress-text" class="cooked-progress-text">0 / ' . esc_html( $total ) . '</span>';
591 echo '</p>';
592 echo '<p id="cooked-migration-completed"><strong>Migration Complete!</strong> You can now <a href="' . esc_url( add_query_arg(['page' => 'cooked_settings'], admin_url( 'admin.php' ) ) ) . '">' . __( 'reload', 'cooked' ) . '</a> the settings screen.</p>';
593 }
594 }
595 }
596
597 public static function field_text($field_name, $placeholder) {
598 global $_cooked_settings;
599
600 echo '<p>';
601 echo '<input id="cooked_field--' . esc_attr( $field_name ) . '" type="text"' . ( $placeholder ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '' ) . ' name="cooked_settings[' . esc_attr( $field_name ) . ']" value="' . ( isset( $_cooked_settings[$field_name] ) && $_cooked_settings[$field_name] ? esc_attr( $_cooked_settings[$field_name] ) : '' ) . '">';
602 echo '</p>';
603 }
604
605 public static function field_password($field_name, $placeholder) {
606 global $_cooked_settings;
607
608 echo '<p>';
609 echo '<input type="password"' . ( $placeholder ? ' placeholder="' . esc_attr( $placeholder ) . '"' : '' ) . ' name="cooked_settings[' . esc_attr( $field_name ) . ']" value="' . ( isset( $_cooked_settings[$field_name] ) && $_cooked_settings[$field_name] ? esc_attr( $_cooked_settings[$field_name] ) : '' ) . '">';
610 echo '</p>';
611 }
612
613 public static function field_html($field_name, $html) {
614 echo wp_kses_post($html);
615 }
616
617 public static function field_permalink_field($field_name, $end_of_url) {
618 global $_cooked_settings;
619
620 $browse_page_id = $_cooked_settings['browse_page'];
621 $browse_page_url = '';
622
623 if (!empty($browse_page_id) && $field_name !== 'recipe_permalink') {
624 $browse_page_url = get_permalink( $browse_page_id );
625 }
626
627 if (empty($browse_page_url)) {
628 $browse_page_url = get_home_url();
629 }
630
631 if (substr($browse_page_url, -1) !== '/') {
632 $browse_page_url .= '/';
633 }
634
635 echo '<p class="cooked-permalink-field-wrapper">';
636 echo '<span>' . $browse_page_url . '</span><input type="text" class="cooked-permalink-field" name="cooked_settings[' . esc_attr( $field_name ) . ']" value="' . ( isset( $_cooked_settings[$field_name] ) && $_cooked_settings[$field_name] ? esc_attr( $_cooked_settings[$field_name] ) : '' ) . '"><span>/' . esc_html( $end_of_url ) . '/</span>';
637 echo '</p>';
638 }
639
640 public static function field_number_field( $field_name, $options ) {
641 global $_cooked_settings;
642
643 echo '<p>';
644 echo '<input type="number" step="any" name="cooked_settings[' . esc_attr( $field_name ) . ']" value="' . ( isset( $_cooked_settings[$field_name] ) && $_cooked_settings[$field_name] ? esc_attr( $_cooked_settings[$field_name] ) : '' ) . '">';
645 echo '</p>';
646 }
647
648 public static function field_color_field( $field_name, $default ) {
649 global $_cooked_settings;
650
651 echo '<p>';
652 echo '<input class="cooked-color-field" type="text"' . ( $default ? ' data-default-color="' . esc_attr( $default ) . '"' : '' ) . ' name="cooked_settings[' . esc_attr( $field_name ) . ']" value="' . ( isset( $_cooked_settings[$field_name] ) && $_cooked_settings[$field_name] ? esc_attr( $_cooked_settings[$field_name] ) : '' ) . '">';
653 echo '</p>';
654 }
655
656 public static function field_checkboxes($field_name, $options, $color = false, $field = []) {
657 global $_cooked_settings, $conditions;
658
659 echo '<p class="cooked-padded">';
660 foreach ($options as $value => $name) {
661 $is_disabled = '';
662 $conditional_value = '';
663 $conditional_requirement = '';
664
665 if (is_array($name)) {
666 if (isset($name['read_only']) && $name['read_only']):
667 $is_disabled = ' disabled';
668 endif;
669
670 if (isset($name['conditional_value']) && $name['conditional_value']):
671 $conditional_value = ' v-model="' . esc_attr($name['conditional_value']) . '"';
672 if ( !in_array( $name['conditional_value'], $conditions ) ):
673 $conditions[$field_name][$name['conditional_value']] = $value;
674 endif;
675 endif;
676
677 if (isset($name['conditional_requirement']) && $name['conditional_requirement']):
678 if (is_array($name['conditional_requirement'])):
679 $conditional_requirement = ' v-show="' . implode( ' && ', $name['conditional_requirement'] ) . '"';
680 else:
681 $conditional_requirement = ' v-show="' . esc_attr($name['conditional_requirement']) . '"';
682 endif;
683 endif;
684
685 $name = $name['label'];
686 }
687
688 $combined_extras = $is_disabled . $conditional_value;
689
690 if ($conditional_requirement) {
691 echo '<transition name="fade"><span class="conditional-requirement"' . esc_attr($conditional_requirement) . '>';
692 }
693
694 // Check if the setting exists at all
695 $setting_exists = isset($_cooked_settings[$field_name]) && is_array($_cooked_settings[$field_name]);
696
697 // Only use default if setting doesn't exist
698 $use_default = !$setting_exists && isset($field['default']);
699
700 // Determine if checkbox should be checked
701 $is_checked = ($setting_exists && in_array($value, $_cooked_settings[$field_name])) ||
702 ($use_default && in_array($value, (array)$field['default'])) ||
703 $is_disabled;
704
705 if ($is_disabled) {
706 echo '<input type="hidden" name="cooked_settings[' . esc_attr($field_name) . '][]" value="' . esc_attr($value) . '">';
707 echo '<input' . $combined_extras . ' class="cooked-switch' . ($color ? '-' . esc_attr($color) : '') .
708 '" type="checkbox" id="checkbox-group-' . esc_attr($field_name) . '-' . esc_attr($value) .
709 '"' . ($is_checked ? ' checked' : '') . '/>';
710 } else {
711 echo '<input' . $combined_extras . ' class="cooked-switch' . ($color ? '-' . esc_attr($color) : '') .
712 '" type="checkbox" id="checkbox-group-' . esc_attr($field_name) . '-' . esc_attr($value) .
713 '" name="cooked_settings[' . esc_attr($field_name) . '][]" value="' . esc_attr($value) .
714 '"' . ($is_checked ? ' checked' : '') . '/>';
715 }
716
717 echo '&nbsp;<label for="checkbox-group-' . esc_attr($field_name) . '-' . esc_attr($value) . '">' .
718 wp_kses_post($name) . '</label>';
719 echo '<br>';
720
721 if ($conditional_requirement) {
722 echo '</span></transition>';
723 }
724 }
725 echo '</p>';
726 }
727
728 }
729