. add_action( 'wp_footer', 'wp_maybe_inline_styles', 1 ); // Run for late-loaded styles in the footer. /* * Block specific actions and filters. */ // Footnotes Block. add_action( 'init', '_wp_footnotes_kses_init' ); add_action( 'set_current_user', '_wp_footnotes_kses_init' ); add_filter( 'force_filtered_html_on_import', '_wp_footnotes_force_filtered_html_on_import_filter', 999 ); /* * Disable "Post Attributes" for wp_navigation post type. The attributes are * also conditionally enabled when a site has custom templates. Block Theme * templates can be available for every post type. */ add_filter( 'theme_wp_navigation_templates', '__return_empty_array' ); // Taxonomy. add_action( 'init', 'create_initial_taxonomies', 0 ); // Highest priority. add_action( 'change_locale', 'create_initial_taxonomies' ); // Canonical. add_action( 'template_redirect', 'redirect_canonical' ); add_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 ); // Media. add_action( 'wp_playlist_scripts', 'wp_playlist_scripts' ); add_action( 'customize_controls_enqueue_scripts', 'wp_plupload_default_settings' ); add_action( 'plugins_loaded', '_wp_add_additional_image_sizes', 0 ); add_filter( 'plupload_default_settings', 'wp_show_heic_upload_error' ); // Nav menu. add_filter( 'nav_menu_item_id', '_nav_menu_item_id_use_once', 10, 2 ); add_filter( 'nav_menu_css_class', 'wp_nav_menu_remove_menu_item_has_children_class', 10, 4 ); // Widgets. add_action( 'after_setup_theme', 'wp_setup_widgets_block_editor', 1 ); add_action( 'init', 'wp_widgets_init', 1 ); add_action( 'change_locale', array( 'WP_Widget_Media', 'reset_default_labels' ) ); add_action( 'widgets_init', '_wp_block_theme_register_classic_sidebars', 1 ); // Admin Bar. // Don't remove. Wrong way to disable. add_action( 'template_redirect', '_wp_admin_bar_init', 0 ); add_action( 'admin_init', '_wp_admin_bar_init' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_admin_bar_bump_styles' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_admin_bar_header_styles' ); add_action( 'admin_enqueue_scripts', 'wp_enqueue_admin_bar_header_styles' ); add_action( 'before_signup_header', '_wp_admin_bar_init' ); add_action( 'activate_header', '_wp_admin_bar_init' ); add_action( 'wp_body_open', 'wp_admin_bar_render', 0 ); add_action( 'wp_footer', 'wp_admin_bar_render', 1000 ); // Back-compat for themes not using `wp_body_open`. add_action( 'in_admin_header', 'wp_admin_bar_render', 0 ); // Former admin filters that can also be hooked on the front end. add_action( 'media_buttons', 'media_buttons' ); add_filter( 'image_send_to_editor', 'image_add_caption', 20, 8 ); add_filter( 'media_send_to_editor', 'image_media_send_to_editor', 10, 3 ); // Embeds. add_action( 'rest_api_init', 'wp_oembed_register_route' ); add_filter( 'rest_pre_serve_request', '_oembed_rest_pre_serve_request', 10, 4 ); add_action( 'wp_head', 'wp_oembed_add_discovery_links' ); add_action( 'wp_head', 'wp_oembed_add_host_js' ); // Back-compat for sites disabling oEmbed host JS by removing action. add_filter( 'embed_oembed_html', 'wp_maybe_enqueue_oembed_host_js' ); add_action( 'embed_head', 'enqueue_embed_scripts', 1 ); add_action( 'embed_head', 'print_emoji_detection_script' ); add_action( 'embed_head', 'wp_enqueue_embed_styles', 9 ); add_action( 'embed_head', 'print_embed_styles' ); // Retained for backwards-compatibility. Unhooked by wp_enqueue_embed_styles(). add_action( 'embed_head', 'wp_print_head_scripts', 20 ); add_action( 'embed_head', 'wp_print_styles', 20 ); add_action( 'embed_head', 'wp_robots' ); add_action( 'embed_head', 'rel_canonical' ); add_action( 'embed_head', 'locale_stylesheet', 30 ); add_action( 'enqueue_embed_scripts', 'wp_enqueue_emoji_styles' ); add_action( 'embed_content_meta', 'print_embed_comments_button' ); add_action( 'embed_content_meta', 'print_embed_sharing_button' ); add_action( 'embed_footer', 'print_embed_sharing_dialog' ); add_action( 'embed_footer', 'print_embed_scripts' ); add_action( 'embed_footer', 'wp_print_footer_scripts', 20 ); add_filter( 'excerpt_more', 'wp_embed_excerpt_more', 20 ); add_filter( 'the_excerpt_embed', 'wptexturize' ); add_filter( 'the_excerpt_embed', 'convert_chars' ); add_filter( 'the_excerpt_embed', 'wpautop' ); add_filter( 'the_excerpt_embed', 'shortcode_unautop' ); add_filter( 'the_excerpt_embed', 'wp_embed_excerpt_attachment' ); add_filter( 'oembed_dataparse', 'wp_filter_oembed_iframe_title_attribute', 5, 3 ); add_filter( 'oembed_dataparse', 'wp_filter_oembed_result', 10, 3 ); add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 ); add_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10, 3 ); // Capabilities. add_filter( 'user_has_cap', 'wp_maybe_grant_install_languages_cap', 1 ); add_filter( 'user_has_cap', 'wp_maybe_grant_resume_extensions_caps', 1 ); add_filter( 'user_has_cap', 'wp_maybe_grant_site_health_caps', 1, 4 ); // Block templates post type and rendering. add_filter( 'render_block_context', '_block_template_render_without_post_block_context' ); add_filter( 'pre_wp_unique_post_slug', 'wp_filter_wp_template_unique_post_slug', 10, 5 ); add_action( 'save_post_wp_template_part', 'wp_set_unique_slug_on_create_template_part' ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_block_template_skip_link' ); add_action( 'wp_footer', 'the_block_template_skip_link' ); // Retained for backwards-compatibility. Unhooked by wp_enqueue_block_template_skip_link(). add_action( 'after_setup_theme', 'wp_enable_block_templates', 1 ); add_action( 'wp_loaded', '_add_template_loader_filters' ); // wp_navigation post type. add_filter( 'rest_wp_navigation_item_schema', array( 'WP_Navigation_Fallback', 'update_wp_navigation_post_schema' ) ); // Fluid typography. add_filter( 'render_block', 'wp_render_typography_support', 10, 2 ); // User preferences. add_action( 'init', 'wp_register_persisted_preferences_meta' ); // CPT wp_block custom postmeta field. add_action( 'init', 'wp_create_initial_post_meta' ); // Include revisioned meta when considering whether a post revision has changed. add_filter( 'wp_save_post_revision_post_has_changed', 'wp_check_revisioned_meta_fields_have_changed', 10, 3 ); // Save revisioned post meta immediately after a revision is saved add_action( '_wp_put_post_revision', 'wp_save_revisioned_meta_fields', 10, 2 ); // Include revisioned meta when creating or updating an autosave revision. add_action( 'wp_creating_autosave', 'wp_autosave_post_revisioned_meta_fields' ); // When restoring revisions, also restore revisioned meta. add_action( 'wp_restore_post_revision', 'wp_restore_post_revision_meta', 10, 2 ); // Font management. add_action( 'wp_head', 'wp_print_font_faces', 50 ); add_action( 'deleted_post', '_wp_after_delete_font_family', 10, 2 ); add_action( 'before_delete_post', '_wp_before_delete_font_face', 10, 2 ); add_action( 'init', '_wp_register_default_font_collections' ); // Add ignoredHookedBlocks metadata attribute to the template and template part post types. add_filter( 'rest_pre_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes' ); add_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' ); // Update ignoredHookedBlocks postmeta for some post types. add_filter( 'rest_pre_insert_page', 'update_ignored_hooked_blocks_postmeta' ); add_filter( 'rest_pre_insert_post', 'update_ignored_hooked */ namespace RankMath\Admin; use RankMath\Helpers\Param; use RankMath\Helper; /** * Page class. */ class Page { /** * Unique ID used for menu_slug. * * @var string */ public $id = null; /** * The text to be displayed in the title tags of the page. * * @var string */ public $title = null; /** * The slug name for the parent menu. * * @var string */ public $parent = null; /** * The The on-screen name text for the menu. * * @var string */ public $menu_title = null; /** * The capability required for this menu to be displayed to the user. * * @var string */ public $capability = 'manage_options'; /** * The icon for this menu. * * @var string */ public $icon = 'dashicons-art'; /** * The position in the menu order this menu should appear. * * @var int */ public $position = -1; /** * The init hook priority. * * @var int */ public $priority = 25; /** * The function/file that displays the page content for the menu page. * * @var string|callable */ public $render = null; /** * The function that run on page POST to save data. * * @var callable */ public $onsave = null; /** * Hold contextual help tabs. * * @var array */ public $help = null; /** * Hold scripts and styles. * * @var array */ public $assets = null; /** * Check if plugin is network active. * * @var array */ public $is_network = false; /** * Hold classes for body tag. * * @var array */ public $classes = null; /** * Hold localized data. * * @var array */ public $json = null; /** * The Constructor. * * @param string $id Admin page unique id. * @param string $title Title of the admin page. * @param array $config Optional. Override page settings. */ public function __construct( $id, $title, $config = [] ) { // Early bail! if ( ! $id ) { wp_die( esc_html__( '$id variable required', 'rank-math' ), esc_html__( 'Variable Required', 'rank-math' ) ); } if ( ! $title ) { wp_die( esc_html__( '$title variable required', 'rank-math' ), esc_html__( 'Variable Required', 'rank-math' ) ); } $this->id = $id; $this->title = $title; foreach ( $config as $key => $value ) { $this->$key = $value; } if ( ! $this->menu_title ) { $this->menu_title = $title; } add_action( 'init', [ $this, 'init' ], $this->priority ?? 25 ); } /** * Init admin page when WordPress Initialises. * * @codeCoverageIgnore */ public function init() { $priority = $this->parent ? intval( $this->position ) : -1; add_action( $this->is_network ? 'network_admin_menu' : 'admin_menu', [ $this, 'register_menu' ], $priority ); // If not the page is not this page stop here. if ( ! $this->is_current_page() ) { return; } $hooks = [ 'admin_init' => [ 'callback' => 'save', 'condition' => ! is_null( $this->onsave ) && is_callable( $this->onsave ), ], 'admin_enqueue_scripts' => [ 'callback' => 'enqueue', 'condition' => ! empty( $this->assets ), ], 'admin_head' => [ 'callback' => 'contextual_help', 'condition' => ! empty( $this->help ), ], 'admin_body_class' => [ 'callback' => 'body_class', 'condition' => ! empty( $this->classes ), ], ]; foreach ( $hooks as $hook => $data ) { if ( true === $data['condition'] ) { add_action( $hook, [ $this, $data['callback'] ] ); } } } /** * Register Admin Menu. * * @codeCoverageIgnore */ public function register_menu() { if ( ! $this->parent ) { add_menu_page( $this->title, $this->menu_title, $this->capability, $this->id, [ $this, 'display' ], $this->icon, $this->position ); return; } add_submenu_page( $this->parent, $this->title, $this->menu_title, $this->capability, $this->id, [ $this, 'display' ] ); } /** * Enqueue styles and scripts. * * @codeCoverageIgnore */ public function enqueue() { $this->enqueue_styles(); $this->enqueue_scripts(); $this->add_localized_data(); } /** * Add classes to of WordPress admin. * * @codeCoverageIgnore * * @param string $classes Space-separated list of CSS classes. * * @return string */ public function body_class( $classes = '' ) { return $classes . ' ' . join( ' ', $this->classes ); } /** * Save anything you want using onsave function. * * @codeCoverageIgnore */ public function save() { call_user_func( $this->onsave, $this ); } /** * Contextual Help. * * @codeCoverageIgnore */ public function contextual_help() { $screen = get_current_screen(); foreach ( $this->help as $tab_id => $tab ) { $tab['id'] = $tab_id; $tab['content'] = $this->get_help_content( $tab ); $screen->add_help_tab( $tab ); } } /** * Render admin page content using render function you passed in config. * * @codeCoverageIgnore */ public function display() { if ( is_null( $this->render ) ) { return; } if ( 'settings' === $this->render ) { return $this->display_settings(); } if ( is_callable( $this->render ) ) { call_user_func( $this->render, $this ); return; } if ( is_string( $this->render ) ) { include_once $this->render; } } /** * Is the page is currrent page. * * @return bool */ public functio