$group['key'], 'post' => 0, 'previewed' => false)); } catch (\Throwable $ignored) { /* Guidance cannot fail a saved schema. */ } break; } } private static function key($name) { global $wpdb; return $wpdb->get_blog_prefix().$name; } public static function goals() { return array('directory'=>__('A directory or catalog','customfields-com'),'events'=>__('Events or locations','customfields-com'),'profiles'=>__('People or profiles','customfields-com'),'submissions'=>__('Collect content from visitors','customfields-com'),'other'=>__('Something else','customfields-com')); } public static function preferences() { $value=get_user_meta(get_current_user_id(),self::key(self::PREF),true); return is_array($value)?array_merge(array('goal'=>'','group'=>'','post'=>0,'previewed'=>false,'skipped'=>false,'measure'=>false),$value):array('goal'=>'','group'=>'','post'=>0,'previewed'=>false,'skipped'=>false,'measure'=>false); } public static function save_preferences($changes) { if(!current_user_can('manage_options')||!is_array($changes)){return new \WP_Error('cf_outcome_access',__('Administrator access is required.','customfields-com'));} $allowed=array('goal','group','post','previewed','skipped','measure'); if(array_diff(array_keys($changes),$allowed)){return new \WP_Error('cf_outcome_input',__('This preference could not be saved.','customfields-com'));} if(array_key_exists('goal',$changes)&&(!is_string($changes['goal'])||($changes['goal']!==''&&!isset(self::goals()[$changes['goal']])))){return new \WP_Error('cf_outcome_goal',__('Choose a supported goal.','customfields-com'));} if(array_key_exists('group',$changes)&&(!is_string($changes['group'])||strlen($changes['group'])>120)){return new \WP_Error('cf_outcome_group',__('Choose a field group.','customfields-com'));} if(array_key_exists('post',$changes)&&(!is_int($changes['post'])||$changes['post']<0)){return new \WP_Error('cf_outcome_post',__('Choose an existing record.','customfields-com'));} foreach(array('previewed','skipped','measure')as$key){if(array_key_exists($key,$changes)&&!is_bool($changes[$key]))return new \WP_Error('cf_outcome_input',__('This preference could not be saved.','customfields-com'));} $value=array_merge(self::preferences(),$changes);$key=self::key(self::PREF);update_user_meta(get_current_user_id(),$key,$value);wp_cache_delete(get_current_user_id(),'user_meta'); if(get_user_meta(get_current_user_id(),$key,true)!==$value){return new \WP_Error('cf_outcome_storage',__('The local preference was not saved. Please retry.','customfields-com'));}return true; } public static function menu(){add_submenu_page('customfields',__('Use your fields','customfields-com'),__('Use your fields','customfields-com'),'manage_options','customfields-start',array(__CLASS__,'page'));} public static function assets(){if(current_user_can('manage_options')&&in_array($_GET['page']??'',array('customfields','customfields-start'),true)){wp_enqueue_style('customfields-outcomes',CUSTOMFIELDS_URL.'assets/outcomes.css',array('customfields-admin'),CUSTOMFIELDS_VERSION);}} // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only routing, filtering or pagination; no mutation is authorized by this query parameter. Object access remains checked by the renderer. private static function url($page='customfields-start'){return admin_url('admin.php?page='.$page);} private static function form($operation){echo '
'; self::form('skip'); echo ''; if ($selected !== '' || $preferences['skipped']) { echo ''; } echo ''; } public static function page() { if (!current_user_can('manage_options')) { return; } nocache_headers(); $p = self::preferences(); $groups = customfields_get_groups(); $requested = self::query('group'); $selected = $requested !== '' ? self::group($requested) : self::group($p['group']); if (!$selected && $requested === '' && $groups) { $selected = reset($groups); } $search = self::query('content_search'); $choices = $selected ? self::choices($selected, $search) : array(); $record = self::query('record'); $context = null; if ($selected) { if ($record !== '' && ctype_digit($record)) { $context = self::context($selected, (int) $record); } elseif ($record === '') { if ($selected['key'] === $p['group'] && !empty($p['post']) && $search === '') { $context = self::context($selected, (int) $p['post']); } if (!$context && ($selected['target'] ?? '') === 'user' && $search === '') { $context = self::context($selected, get_current_user_id()); } if (!$context && $choices) { $context = reset($choices); } } if ($context) { $choices[$context['id']] = $context; } } echo '' . esc_html__('Save a real value, check the result, then choose how to show it. Nothing is created or published by this guide.', 'customfields-com') . '
' . esc_html__('Your fields are saved and ready to use.', 'customfields-com') . ' ' . esc_html__('Edit fields', 'customfields-com') . '
' . esc_html($first_steps[$p['goal']] ?? __('Start with a field group and choose where it appears.', 'customfields-com')) . '
' . esc_html__('Create your first field group', 'customfields-com') . ''; } if ($selected) { echo '' . esc_html__('Open the editor, fill in your fields and use its Save or Update button. Return here afterwards to check what was saved.', 'customfields-com') . '
'; if (($selected['target'] ?? 'post') === 'post') { echo '' . esc_html__('Fields hidden in the WordPress block editor? Expand Meta Boxes at the bottom of the editor to find your field group.', 'customfields-com') . '
'; } if (($selected['target'] ?? 'post') !== 'options') { self::selection_form($selected); echo ''; } if ($context) { echo '' . esc_html($context['title']) . '
' . esc_html__('Open editor to enter values', 'customfields-com') . ''; } else { echo ''; self::browse_links($selected); } if (($selected['target'] ?? 'post') !== 'options') { echo '' . esc_html__('Shows permitted matches from up to 50 results. You can also return directly from the link below your fields in an editor.', 'customfields-com') . '
' . esc_html__('SAVED VALUES · PRIVATE PREVIEW', 'customfields-com') . '
' . esc_html__('Saved values checked. Your guide progress is up to date.', 'customfields-com') . '
'; } if ($preview['unsupported']) { echo '' . esc_html__('Not shown in this preview:', 'customfields-com') . ' ' . esc_html(implode(', ', $preview['unsupported'])) . '
'; } } echo '' . esc_html__('Refresh saved values', 'customfields-com') . '
' . esc_html__('This preview updates after you save in the editor and refresh here.', 'customfields-com') . '
'; } else { echo '' . esc_html__('Choose a permitted record to preview its saved values.', 'customfields-com') . '
'; } self::display_help($selected, $context); echo '' . esc_html__('Compare an incoming spreadsheet or check existing content before deciding how to update it.', 'customfields-com') . '
' . esc_html__('Compare a CSV', 'customfields-com') . ' ' . esc_html__('Check content', 'customfields-com') . '' . esc_html__('Off by default. Count supported completed workflow events by day for this administrator on this site, retaining up to 90 active days. No field values, files, site URL or licence details are recorded. Nothing is sent. These approximate counts cannot measure Free-to-Pro conversion or verify purchases.', 'customfields-com') . '
'; self::form('measurement'); echo ''; self::form('export'); echo ''; self::form('clear-measurement'); echo '' . esc_html__('Back to field groups', 'customfields-com') . '
'; self::form('skip'); echo '