settings_key = 'ata_settings'; self::$prefix = 'ata'; $this->menu_slug = 'ata_options_page'; Hook_Registry::add_action( 'admin_menu', array( $this, 'initialise_settings' ) ); Hook_Registry::add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 11, 2 ); Hook_Registry::add_filter( 'plugin_action_links_' . plugin_basename( WZ_SNIPPETZ_FILE ), array( $this, 'plugin_actions_links' ) ); Hook_Registry::add_filter( 'ata_settings_sanitize', array( $this, 'change_settings_on_save' ), 99 ); Hook_Registry::add_action( 'admin_menu', array( $this, 'redirect_on_save' ) ); Hook_Registry::add_action( 'wp_ajax_' . self::$prefix . '_taxonomy_search_tom_select', array( __CLASS__, 'taxonomy_search_tom_select' ) ); } /** * Initialise the settings API. * * @since 3.3.0 */ public function initialise_settings() { $props = array( 'default_tab' => 'general', 'help_sidebar' => $this->get_help_sidebar(), 'help_tabs' => $this->get_help_tabs(), 'admin_footer_text' => $this->get_admin_footer_text(), 'menus' => $this->get_menus(), ); $args = array( 'translation_strings' => $this->get_translation_strings(), 'props' => $props, 'settings_sections' => $this->get_settings_sections(), 'registered_settings' => $this->get_registered_settings(), 'upgraded_settings' => array(), ); $this->settings_api = new Settings\Settings_API( $this->settings_key, self::$prefix, $args ); } /** * Array containing the settings' sections. * * @since 1.8.0 * * @return array Settings array */ public function get_translation_strings() { $strings = array( 'page_header' => esc_html__( 'WebberZone Snippetz Settings', 'add-to-all' ), 'reset_message' => esc_html__( 'Settings have been reset to their default values. Reload this page to view the updated settings.', 'add-to-all' ), 'success_message' => esc_html__( 'Settings updated.', 'add-to-all' ), 'save_changes' => esc_html__( 'Save Changes', 'add-to-all' ), 'reset_settings' => esc_html__( 'Reset all settings', 'add-to-all' ), 'reset_button_confirm' => esc_html__( 'Do you really want to reset all these settings to their default values?', 'add-to-all' ), 'modified_field' => esc_html__( 'Modified from default setting', 'add-to-all' ), 'modified_legend' => esc_html__( 'Setting modified from its default value', 'add-to-all' ), 'default_label' => esc_html__( 'Default', 'add-to-all' ), 'default_none' => esc_html__( 'None', 'add-to-all' ), 'repeater_move_up' => esc_html__( 'Move item up', 'add-to-all' ), 'repeater_move_down' => esc_html__( 'Move item down', 'add-to-all' ), 'repeater_remove_item' => esc_html__( 'Remove item', 'add-to-all' ), ); /** * Filter the array containing the settings' sections. * * @since 1.8.0 * * @param array $strings Translation strings. */ return apply_filters( self::$prefix . '_translation_strings', $strings ); } /** * Get the admin menus. * * @return array Admin menus. */ public function get_menus() { $menus = array(); if ( \WebberZone\Snippetz\Util\Helpers::is_snippets_enabled() ) { $menus[] = array( 'settings_page' => true, 'type' => 'submenu', 'parent_slug' => 'edit.php?post_type=ata_snippets', 'page_title' => esc_html__( 'WebberZone Snippetz Settings', 'add-to-all' ), 'menu_title' => esc_html__( 'Settings', 'add-to-all' ), 'menu_slug' => $this->menu_slug, ); } else { $menus[] = array( 'settings_page' => true, 'type' => 'submenu', 'parent_slug' => 'options-general.php', 'page_title' => esc_html__( 'WebberZone Snippetz Settings', 'add-to-all' ), 'menu_title' => esc_html__( 'Snippetz', 'add-to-all' ), 'menu_slug' => $this->menu_slug, ); } return $menus; } /** * Array containing the settings' sections. * * @since 1.7.0 * * @return array Settings array */ public static function get_settings_sections() { $settings_sections = array( 'general' => esc_html__( 'General', 'add-to-all' ), 'third_party' => esc_html__( 'Third Party', 'add-to-all' ), 'head' => esc_html__( 'Header', 'add-to-all' ), 'body' => esc_html__( 'Body', 'add-to-all' ), 'footer' => esc_html__( 'Footer', 'add-to-all' ), 'feed' => esc_html__( 'Feed', 'add-to-all' ), ); /** * Filter the array containing the settings' sections. * * @since 1.2.0 * * @param array $settings_sections Settings array */ return apply_filters( self::$prefix . '_settings_sections', $settings_sections ); } /** * Retrieve the array of plugin settings * * @since 1.7.0 * * @return array Settings array */ public static function get_registered_settings() { $settings = array(); $sections = self::get_settings_sections(); foreach ( $sections as $section => $value ) { $method_name = 'settings_' . $section; if ( method_exists( __CLASS__, $method_name ) ) { $settings[ $section ] = self::$method_name(); } } /** * Filters the settings array * * @since 1.2.0 * * @param array $settings Settings array */ return apply_filters( self::$prefix . '_registered_settings', $settings ); } /** * Sanitize a raw settings array against all registered field callbacks. * * Does not depend on $_POST or a Settings_API instance, so it is safe to * call during admin-post.php requests (e.g. settings import). * * @param array $input Raw settings array (e.g. decoded from imported JSON). * @return array Sanitized array containing only known setting keys. */ public static function sanitize_all( array $input ): array { $registered_settings = self::get_registered_settings(); $non_setting_types = array( 'header', 'descriptive_text' ); $settings_sanitize = new Settings\Settings_Sanitize( array( 'settings_key' => 'ata_settings', 'prefix' => self::$prefix ? self::$prefix : 'ata', ) ); $output = array(); foreach ( $registered_settings as $tab_settings ) { foreach ( $tab_settings as $setting ) { $key = $setting['id']; $type = $setting['type']; if ( in_array( $type, $non_setting_types, true ) || ! array_key_exists( $key, $input ) ) { continue; } if ( isset( $setting['sanitize_callback'] ) && is_callable( $setting['sanitize_callback'] ) ) { $output[ $key ] = call_user_func( $setting['sanitize_callback'], $input[ $key ] ); continue; } $method = 'sanitize_' . $type . '_field'; // Field types with no callback of their own must still not store raw input. if ( ! is_callable( array( $settings_sanitize, $method ) ) ) { $method = 'sanitize_missing'; } // Every callback receives the field configuration so choice fields can validate against their own options. $output[ $key ] = $settings_sanitize->$method( $input[ $key ], $setting ); } } return $output; } /** * Raw default values for every setting, keyed by option ID. * * Deliberately contains no translation calls, so it is safe to invoke before `init` * (e.g. from `ata_get_option()` on the frontend). Values are pre-normalised (checkboxes * as 1/0) and the array is intentionally unfiltered — consumers apply the * `ata_settings_defaults` filter themselves. `feed_copyrightnotice` is the one entry * that isn't the field's own default: its real value is computed by * `get_copyright_text()` in the field definition (which needs to run on every install, * not just here), so the raw default is left empty, matching what both consumers * already pass as their fallback. * * @since 2.4.2 * * @return array Raw default values keyed by option ID. */ public static function get_defaults() { return array( // General. 'enable_snippets' => 1, 'enable_external_css_js' => 0, 'enable_combination' => 0, 'snippet_priority' => 999, // Third party. 'sc_project' => '', 'sc_security' => '', 'ga_uacct' => '', 'google_verification' => '', 'bing_verification' => '', 'facebook_domain_verification' => '', 'pinterest_verification' => '', // Header. 'head_css' => '', 'head_other_html' => '', // Body. 'wp_body_open' => '', 'content_filter_priority' => 999, 'exclude_on_post_ids' => '', 'content_process_shortcode' => 0, 'content_add_html_before' => 0, 'content_html_before' => '', 'content_add_html_after' => 0, 'content_html_after' => '', 'content_add_html_before_single' => 0, 'content_html_before_single' => '', 'content_add_html_after_single' => 0, 'content_html_after_single' => '', 'content_add_html_before_post' => 0, 'content_html_before_post' => '', 'content_add_html_after_post' => 0, 'content_html_after_post' => '', 'content_add_html_before_page' => 0, 'content_html_before_page' => '', 'content_add_html_after_page' => 0, 'content_html_after_page' => '', // Footer. 'footer_process_shortcode' => 0, 'footer_other_html' => '', 'add_credit' => 0, // Feed. 'feed_add_copyright' => 1, 'feed_copyrightnotice' => '', 'feed_add_title' => 1, 'feed_title_text' => '%title% was first posted on %date% at %time%.', 'feed_process_shortcode' => 0, 'feed_add_html_before' => 0, 'feed_html_before' => '', 'feed_add_html_after' => 0, 'feed_html_after' => '', ); } /** * Returns the Header settings. * * @since 1.7.0 * * @return array Header settings. */ public static function settings_general() { $defaults = self::get_defaults(); $settings = array( 'enable_snippets' => array( 'id' => 'enable_snippets', 'name' => esc_html__( 'Enable Snippets Manager', 'add-to-all' ), 'desc' => esc_html__( 'Disabling this will turn off the Snippets manager and any of the associated functionality. This will not delete any snippets data that was created before this was turned off.', 'add-to-all' ), 'type' => 'checkbox', 'default' => $defaults['enable_snippets'], ), 'enable_external_css_js' => array( 'id' => 'enable_external_css_js', 'name' => esc_html__( 'Enable external CSS/JS files', 'add-to-all' ), 'desc' => esc_html__( 'Save CSS and JS snippets as external minified files instead of inline output. Improves page load performance.', 'add-to-all' ), 'type' => 'checkbox', 'default' => $defaults['enable_external_css_js'], ), 'enable_combination' => array( 'id' => 'enable_combination', 'name' => esc_html__( 'Enable file combination', 'add-to-all' ), 'desc' => esc_html__( 'Combine all CSS/JS snippets into single files. Note: Conditions are ignored for combined files.', 'add-to-all' ), 'type' => 'checkbox', 'default' => $defaults['enable_combination'], ), 'snippet_priority' => array( 'id' => 'snippet_priority', 'name' => esc_html__( 'Snippet content priority', 'add-to-all' ), 'desc' => esc_html__( 'Priority of the snippet content. Lower number means all snippets are added earlier relative to other content. Number below 10 is not recommended. At the next level, priority of each snippet is independently set from the Edit Snippets screen.', 'add-to-all' ), 'type' => 'text', 'default' => $defaults['snippet_priority'], ), ); /** * Filters the Header settings array * * @since 1.7.0 * * @param array $settings Header Settings array */ return apply_filters( self::$prefix . '_settings_general', $settings ); } /** * Returns the Third party settings. * * @since 1.5.0 * * @return array Third party settings. */ public static function settings_third_party() { $defaults = self::get_defaults(); $settings = array( 'statcounter_header' => array( 'id' => 'statcounter_header', 'name' => '
wp_head()' ),
'type' => 'html',
'default' => $defaults['head_other_html'],
'field_class' => 'codemirror_html',
),
);
/**
* Filters the Header settings array
*
* @since 1.5.0
*
* @param array $settings Header Settings array
*/
return apply_filters( self::$prefix . '_settings_head', $settings );
}
/**
* Returns the Content settings.
*
* @since 1.5.0
*
* @return array Content settings.
*/
public static function settings_body() {
$defaults = self::get_defaults();
$settings = array(
'wp_body_open_header' => array(
'id' => 'wp_body_open_header',
'name' => 'wp_footer()' ),
'type' => 'html',
'default' => $defaults['footer_other_html'],
'field_class' => 'codemirror_html',
),
);
/**
* Filters the Footer settings array
*
* @since 1.5.0
*
* @param array $settings Footer Settings array
*/
return apply_filters( self::$prefix . '_settings_footer', $settings );
}
/**
* Returns the Feed settings.
*
* @since 1.5.0
*
* @return array Feed settings.
*/
public static function settings_feed() {
$defaults = self::get_defaults();
$settings = array(
'feed_add_copyright' => array(
'id' => 'feed_add_copyright',
'name' => esc_html__( 'Add copyright notice?', 'add-to-all' ),
'desc' => esc_html__( 'Check this to add the below copyright notice to your feed.', 'add-to-all' ),
'type' => 'checkbox',
'default' => $defaults['feed_add_copyright'],
),
'feed_copyrightnotice' => array(
'id' => 'feed_copyrightnotice',
'name' => esc_html__( 'Coyright text', 'add-to-all' ),
/* translators: No strings here. */
'desc' => esc_html__( 'Enter valid HTML only. This copyright notice is added as the last item of your feed. You can also use %year% for the year or %first_year% for the year of the first post,', 'add-to-all' ),
'type' => 'html',
'default' => self::get_copyright_text(),
'field_class' => 'codemirror_html',
),
'feed_add_title' => array(
'id' => 'feed_add_title',
'name' => esc_html__( 'Add post title?', 'add-to-all' ),
'desc' => esc_html__( 'Add a link to the title of the post in the feed.', 'add-to-all' ),
'type' => 'checkbox',
'default' => $defaults['feed_add_title'],
),
'feed_title_text' => array(
'id' => 'feed_title_text',
'name' => esc_html__( 'Title text', 'add-to-all' ),
/* translators: No strings here. */
'desc' => esc_html__( 'The above text will be added to the feed. You can use %title% to add a link to the post, %date% and %time% to display the date and time of the post respectively.', 'add-to-all' ),
'type' => 'textarea',
/* translators: No strings here. */
'default' => $defaults['feed_title_text'],
),
'feed_process_shortcode' => array(
'id' => 'feed_process_shortcode',
'name' => esc_html__( 'Process shortcodes in feed', 'add-to-all' ),
'desc' => esc_html__( 'Check this box to execute any shortcodes that you enter in the options below.', 'add-to-all' ),
'type' => 'checkbox',
'default' => $defaults['feed_process_shortcode'],
),
'feed_add_html_before' => array(
'id' => 'feed_add_html_before',
'name' => esc_html__( 'Add HTML before content?', 'add-to-all' ),
'desc' => esc_html__( 'Check this to add the HTML below before the content of your post.', 'add-to-all' ),
'type' => 'checkbox',
'default' => $defaults['feed_add_html_before'],
),
'feed_html_before' => array(
'id' => 'feed_html_before',
'name' => esc_html__( 'HTML to add before the content', 'add-to-all' ),
'desc' => esc_html__( 'Enter valid HTML or JavaScript (wrapped in script tags). No PHP allowed.', 'add-to-all' ),
'type' => 'html',
'default' => $defaults['feed_html_before'],
'field_class' => 'codemirror_html',
),
'feed_add_html_after' => array(
'id' => 'feed_add_html_after',
'name' => esc_html__( 'Add HTML after content?', 'add-to-all' ),
'desc' => esc_html__( 'Check this to add the HTML below before the content of your post.', 'add-to-all' ),
'type' => 'checkbox',
'default' => $defaults['feed_add_html_after'],
),
'feed_html_after' => array(
'id' => 'feed_html_after',
'name' => esc_html__( 'HTML to add after the content', 'add-to-all' ),
'desc' => esc_html__( 'Enter valid HTML or JavaScript (wrapped in script tags). No PHP allowed.', 'add-to-all' ),
'type' => 'html',
'default' => $defaults['feed_html_after'],
'field_class' => 'codemirror_html',
),
'add_credit' => array(
'id' => 'add_credit',
'name' => esc_html__( 'Add a link to "WebberZone Snippetz" plugin page', 'add-to-all' ),
'desc' => '',
'type' => 'checkbox',
'default' => $defaults['add_credit'],
),
);
/**
* Filters the Feed settings array
*
* @since 1.5.0
*
* @param array $settings Feed Settings array
*/
return apply_filters( self::$prefix . '_settings_feed', $settings );
}
/**
* Copyright notice text.
*
* @since 1.7.0
* @return string Copyright notice
*/
public static function get_copyright_text() {
$copyrightnotice = '©' . gmdate( 'Y' ) . ' "' . get_option( 'blogname' ) . '". ';
$copyrightnotice .= esc_html__( 'Use of this feed is for personal non-commercial use only. If you are not reading this article in your feed reader, then the site is guilty of copyright infringement. Please contact me at ', 'add-to-all' );
$copyrightnotice .= '' . get_option( 'admin_email' ) . '';
/**
* Copyright notice text.
*
* @since 1.2.0
* @param string $copyrightnotice Copyright notice
*/
return apply_filters( self::$prefix . '_copyright_text', $copyrightnotice );
}
/**
* Upgrade v1.1.0 settings to v1.2.0.
*
* @since 1.7.0
* @return array Settings array
*/
public function get_upgrade_settings() {
$old_settings = get_option( 'ald_ata_settings' );
if ( empty( $old_settings ) ) {
return array();
} else {
$map = array(
'add_credit' => 'addcredit',
// Content options.
'content_html_before' => 'content_htmlbefore',
'content_html_after' => 'content_htmlafter',
'content_add_html_before' => 'content_addhtmlbefore',
'content_add_html_after' => 'content_addhtmlafter',
'content_html_before_single' => 'content_htmlbeforeS',
'content_html_after_single' => 'content_htmlafterS',
'content_add_html_before_single' => 'content_addhtmlbeforeS',
'content_add_html_after_single' => 'content_addhtmlafterS',
'content_filter_priority' => 'content_filter_priority',
// Feed options.
'feed_html_before' => 'feed_htmlbefore',
'feed_html_after' => 'feed_htmlafter',
'feed_add_html_before' => 'feed_addhtmlbefore',
'feed_add_html_after' => 'feed_addhtmlafter',
'feed_copyrightnotice' => 'feed_copyrightnotice',
'feed_add_title' => 'feed_addtitle',
'feed_title_text' => 'feed_titletext',
'feed_add_copyright' => 'feed_addcopyright',
// 3rd party options.
'sc_project' => 'tp_sc_project',
'sc_security' => 'tp_sc_security',
'ga_uacct' => 'tp_ga_uacct',
'tynt_id' => 'tp_tynt_id',
// Footer options.
'footer_other_html' => 'ft_other',
// Header options.
'head_css' => 'head_CSS',
'head_other_html' => 'head_other',
);
foreach ( $map as $key => $value ) {
$settings[ $key ] = strval( $old_settings[ $value ] );
}
delete_option( 'ald_ata_settings' );
return $settings;
}
}
/**
* Adding WordPress plugin action links.
*
* @since 1.7.0
*
* @param array $links Array of links.
* @return array
*/
public function plugin_actions_links( $links ) {
$location = $this->get_settings_location();
return array_merge(
array(
'settings' => '' . esc_html__( 'Settings', 'add-to-all' ) . '',
),
$links
);
}
/**
* Add meta links on Plugins page.
*
* @since 1.7.0
*
* @param array $links Array of Links.
* @param string $file Current file.
* @return array
*/
public function plugin_row_meta( $links, $file ) {
if ( false !== strpos( $file, 'add-to-all.php' ) ) {
$new_links = array(
'support' => '' . esc_html__( 'Support', 'add-to-all' ) . '',
'donate' => '' . esc_html__( 'Donate', 'add-to-all' ) . '',
'contribute' => '' . esc_html__( 'Contribute', 'add-to-all' ) . '',
);
$links = array_merge( $links, $new_links );
}
return $links;
}
/**
* Get the help sidebar content to display on the plugin settings page.
*
* @since 1.8.0
*/
public function get_help_sidebar() {
$help_sidebar =
/* translators: 1: Plugin support site link. */
'' . sprintf( __( 'For more information or how to get support visit the support site.', 'add-to-all' ), esc_url( 'https://webberzone.com/support/' ) ) . '
' . /* translators: 1: WordPress.org support forums link. */ '' . sprintf( __( 'Support queries should be posted in the WordPress.org support forums.', 'add-to-all' ), esc_url( 'https://wordpress.org/support/plugin/add-to-all' ) ) . '
' . '' . sprintf( /* translators: 1: Github issues link, 2: Github plugin page link. */ __( 'Post an issue on GitHub (bug reports only).', 'add-to-all' ), esc_url( 'https://github.com/ajaydsouza/add-to-all/issues' ), esc_url( 'https://github.com/ajaydsouza/add-to-all' ) ) . '
'; /** * Filter to modify the help sidebar content. * * @since 1.8.0 * * @param string $help_sidebar Help sidebar content. */ return apply_filters( self::$prefix . '_settings_help', $help_sidebar ); } /** * Get the help tabs to display on the plugin settings page. * * @since 1.8.0 */ public function get_help_tabs() { $help_tabs = array( array( 'id' => 'ata-settings-general-help', 'title' => esc_html__( 'General', 'add-to-all' ), 'content' => '' . esc_html__( 'This screen provides general settings. Enable/disable the Snippets Manager and set the global priority of snippets.', 'add-to-all' ) . '
' . '' . esc_html__( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.', 'add-to-all' ) . '
', ), array( 'id' => 'ata-settings-third-party-help', 'title' => esc_html__( 'Third Party', 'add-to-all' ), 'content' => '' . esc_html__( 'This screen provides the settings for configuring the integration with third party scripts.', 'add-to-all' ) . '
' . '' . sprintf( /* translators: 1: Google Analystics help article. */ esc_html__( 'Google Analytics tracking can be found by visiting this %s', 'add-to-all' ), '' . esc_html__( 'article', 'add-to-all' ) . '.' ) . '
' . '' . esc_html__( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.', 'add-to-all' ) . '
', ), array( 'id' => 'ata-settings-header-help', 'title' => esc_html__( 'Header', 'add-to-all' ), 'content' => '' . esc_html__( 'This screen allows you to control what content is added to the header of your site.', 'add-to-all' ) . '
' . '' . esc_html__( 'You can add custom CSS or HTML code. Useful for adding meta tags for site verification, etc.', 'add-to-all' ) . '
' . '' . esc_html__( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.', 'add-to-all' ) . '
', ), array( 'id' => 'ata-settings-body-help', 'title' => esc_html__( 'Body', 'add-to-all' ), 'content' => '' . esc_html__( 'This screen allows you to control what content is added to the content of posts, pages and custom post types.', 'add-to-all' ) . '
' . '' . esc_html__( 'You can set the priority of the filter and choose if you want this to be displayed on either all content (including archives) or just single posts/pages.', 'add-to-all' ) . '
' . '' . esc_html__( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.', 'add-to-all' ) . '
', ), array( 'id' => 'ata-settings-footer-help', 'title' => esc_html__( 'Footer', 'add-to-all' ), 'content' => '' . esc_html__( 'This screen allows you to control what content is added to the footer of your site.', 'add-to-all' ) . '
' . '' . esc_html__( 'You can add custom HTML code. Useful for adding tracking code for analytics, etc.', 'add-to-all' ) . '
' . '' . esc_html__( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.', 'add-to-all' ) . '
', ), array( 'id' => 'ata-settings-feed-help', 'title' => esc_html__( 'Feed', 'add-to-all' ), 'content' => '' . esc_html__( 'This screen allows you to control what content is added to the feed of your site.', 'add-to-all' ) . '
' . '' . esc_html__( 'You can add copyright text, a link to the title and date of the post, and HTML before and after the content', 'add-to-all' ) . '
' . '' . esc_html__( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.', 'add-to-all' ) . '
', ), ); /** * Filter to add more help tabs. */ return apply_filters( self::$prefix . '_help_tabs', $help_tabs ); } /** * Get admin footer text. * * @return string */ public function get_admin_footer_text() { return sprintf( /* translators: 1: Opening anchor tag with Plugin page link, 2: Closing anchor tag, 3: Opening anchor tag with review link. */ __( 'Thank you for using %1$sWebberZone Snippetz%2$s! Please %3$srate us%2$s on %3$sWordPress.org%2$s', 'add-to-all' ), '', '', '' ); } /** * Modify settings when they are being saved. * * @since 2.0.0 * * @param array $settings Settings array. * @return array Sanitized settings array. */ public function change_settings_on_save( $settings ) { return $settings; } /** * Redirect to the correct settings page on save. * * @since 2.0.0 */ public function redirect_on_save() { if ( isset( $_GET['page'] ) && $_GET['page'] === $this->menu_slug && isset( $_GET['settings-updated'] ) && true === (bool) $_GET['settings-updated'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $location = $this->get_settings_location(); wp_safe_redirect( $location ); exit; } } /** * Get link of the Settings page. * * @since 2.0.1 */ public function get_settings_location() { if ( \WebberZone\Snippetz\Util\Helpers::is_snippets_enabled() ) { $location = admin_url( "/edit.php?post_type=ata_snippets&page={$this->menu_slug}" ); } else { $location = admin_url( "/options-general.php?page={$this->menu_slug}" ); } return $location; } /** * Default settings. * * @since 2.2.0 * * @return array Default settings. */ public static function settings_defaults() { $options = array(); $default_types = array( 'color', 'css', 'csv', 'file', 'html', 'multicheck', 'number', 'numbercsv', 'password', 'postids', 'posttypes', 'radio', 'radiodesc', 'repeater', 'select', 'sensitive', 'taxonomies', 'text', 'textarea', 'thumbsizes', 'url', 'wysiwyg', ); // Populate some default values. foreach ( self::get_registered_settings() as $tab => $settings ) { foreach ( $settings as $option ) { if ( ! isset( $option['id'] ) ) { continue; } $setting_id = $option['id']; $setting_type = $option['type'] ?? ''; $default_value = ''; // When checkbox is set to true, set this to 1. if ( 'checkbox' === $setting_type ) { $default_value = isset( $option['default'] ) ? (int) (bool) $option['default'] : 0; } elseif ( isset( $option['default'] ) && in_array( $setting_type, $default_types, true ) ) { $default_value = $option['default']; } $options[ $setting_id ] = $default_value; } } /** * Filters the default settings array. * * @since 2.2.0 * * @param array $options Default settings. */ return apply_filters( self::$prefix . '_settings_defaults', $options ); } /** * AJAX handler for Tom Select taxonomy search. * * @since 2.3.0 * * @return void */ public static function taxonomy_search_tom_select() { // Verify nonce. if ( ! isset( $_REQUEST['nonce'] ) ) { wp_send_json_error( array( 'message' => 'Missing nonce' ) ); } $nonce_valid = wp_verify_nonce( sanitize_key( $_REQUEST['nonce'] ), self::$prefix . '_taxonomy_search_tom_select' ); if ( ! $nonce_valid ) { wp_send_json_error( array( 'message' => 'Invalid nonce', 'received_nonce' => sanitize_key( $_REQUEST['nonce'] ), 'expected_action' => self::$prefix . '_taxonomy_search_tom_select', ) ); } if ( ! isset( $_REQUEST['endpoint'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended wp_send_json_error( 'Missing endpoint' ); } $endpoint = sanitize_key( $_REQUEST['endpoint'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $search_term = isset( $_REQUEST['q'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['q'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $comma = _x( ',', 'tag delimiter', 'add-to-all' ); if ( ',' !== $comma ) { $search_term = str_replace( $comma, ',', $search_term ); } if ( false !== strpos( $search_term, ',' ) ) { $search_term = explode( ',', $search_term ); $search_term = $search_term[ count( $search_term ) - 1 ]; } $search_term = trim( $search_term, " \t\n\r\0\x0B" ); if ( 'meta_keys' === $endpoint ) { if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'Insufficient permissions' ); } if ( strlen( $search_term ) < 2 ) { wp_send_json_success( array() ); } global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $keys = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE %s ORDER BY meta_key ASC LIMIT 20", '%' . $wpdb->esc_like( $search_term ) . '%' ) ); $results = array(); foreach ( (array) $keys as $meta_key ) { if ( is_string( $meta_key ) && '' !== $meta_key ) { $results[] = array( 'value' => $meta_key, 'text' => $meta_key, ); } } wp_send_json_success( $results ); } if ( 'public_taxonomies' === $endpoint ) { $taxonomies = (array) get_taxonomies( array( 'public' => true ), 'objects' ); $taxonomy = array(); $tax = null; foreach ( $taxonomies as $taxonomy_object ) { if ( empty( $taxonomy_object->cap->assign_terms ) ) { continue; } if ( ! current_user_can( $taxonomy_object->cap->assign_terms ) ) { continue; } $taxonomy[] = $taxonomy_object->name; } if ( empty( $taxonomy ) ) { wp_send_json_success( array() ); } $tax = get_taxonomy( $taxonomy[0] ); } else { $taxonomy = $endpoint; $tax = get_taxonomy( $taxonomy ); if ( ! $tax ) { wp_send_json_error( 'Invalid taxonomy' ); } if ( ! current_user_can( $tax->cap->assign_terms ) ) { wp_send_json_error( 'Insufficient permissions' ); } } /** This filter has been defined in /wp-admin/includes/ajax-actions.php */ $term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $search_term ); /* * Require $term_search_min_chars chars for matching (default: 2) * ensure it's a non-negative, non-zero integer. */ if ( ( 0 === $term_search_min_chars ) || ( strlen( $search_term ) < $term_search_min_chars ) ) { wp_send_json_success( array() ); } $terms = get_terms( array( 'taxonomy' => $taxonomy, 'name__like' => $search_term, 'orderby' => 'name', 'order' => 'ASC', 'number' => 20, 'hide_empty' => false, ) ); $results = array(); foreach ( (array) $terms as $term ) { $formatted_string = "{$term->name} ({$term->taxonomy}:{$term->term_taxonomy_id})"; $results[] = array( 'value' => $formatted_string, 'text' => $term->name, ); } wp_send_json_success( $results ); } }