' . esc_html__( 'No display rule. The template never shows.', 'headfoot' ) . ''; } else { echo esc_html( implode( ', ', array_map( [ Rules::class, 'get_label' ], $include ) ) ); } if ( ! empty( $exclude ) ) { /* translators: %s: Comma separated rule labels. */ echo '
' . esc_html( sprintf( __( 'Except: %s', 'headfoot' ), implode( ', ', array_map( [ Rules::class, 'get_label' ], $exclude ) ) ) ) . ''; } if ( ! empty( $roles ) && ! in_array( 'all', $roles, true ) ) { $options = Rules::get_role_options(); $labels = []; foreach ( $roles as $role ) { $labels[] = isset( $options[ $role ] ) ? $options[ $role ] : $role; } /* translators: %s: Comma separated role labels. */ echo '
' . esc_html( sprintf( __( 'Users: %s', 'headfoot' ), implode( ', ', $labels ) ) ) . ''; } break; case 'headfoot_shortcode': printf( '', esc_attr( '[' . Shortcode::TAG . ' id="' . (int) $post_id . '"]' ) ); break; } } /** * Prints the type dropdown above the list table. * * @param string $post_type Post type of the list table. * @return void */ public function type_filter( $post_type ) { if ( Post_Type::POST_TYPE !== $post_type ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read only filter of the list table. $current = isset( $_GET['headfoot_type'] ) ? sanitize_key( wp_unslash( $_GET['headfoot_type'] ) ) : ''; ?> is_main_query() || Post_Type::POST_TYPE !== $query->get( 'post_type' ) ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read only filter of the list table. $type = isset( $_GET['headfoot_type'] ) ? sanitize_key( wp_unslash( $_GET['headfoot_type'] ) ) : ''; if ( ! isset( Post_Type::get_types()[ $type ] ) ) { return; } $meta_query = (array) $query->get( 'meta_query' ); $meta_query[] = [ 'key' => Post_Type::META_TYPE, 'value' => $type, ]; $query->set( 'meta_query', $meta_query ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query } /** * Tells whether the current screen belongs to the plugin. * * @return bool */ private function is_plugin_screen() { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; return $screen && Post_Type::POST_TYPE === $screen->post_type; } /** * Registers the meta box. * * @param string $post_type Post type of the edit screen. * @return void */ public function add_meta_box( $post_type ) { if ( Post_Type::POST_TYPE !== $post_type ) { return; } add_meta_box( 'headfoot-template-settings', esc_html__( 'Template Settings', 'headfoot' ), [ $this, 'render_meta_box' ], Post_Type::POST_TYPE, 'normal', 'high' ); } /** * Changes the title placeholder on the edit screen. * * @param string $placeholder Placeholder text. * @param \WP_Post $post Post object. * @return string */ public function title_placeholder( $placeholder, $post ) { if ( $post && Post_Type::POST_TYPE === $post->post_type ) { return esc_html__( 'Template name, for example Main Header', 'headfoot' ); } return $placeholder; } /** * Loads the meta box assets on the edit screen. * * @param string $hook Current admin page. * @return void */ public function enqueue( $hook ) { if ( ! $this->is_plugin_screen() ) { return; } if ( 'edit.php' === $hook ) { wp_enqueue_style( 'headfoot-list-table', HEADFOOT_URL . 'assets/admin/list-table.css', [], HEADFOOT_VERSION ); return; } if ( ! in_array( $hook, [ 'post.php', 'post-new.php' ], true ) ) { return; } wp_enqueue_style( 'headfoot-meta-box', HEADFOOT_URL . 'assets/admin/meta-box.css', [], HEADFOOT_VERSION ); wp_enqueue_script( 'headfoot-meta-box', HEADFOOT_URL . 'assets/admin/meta-box.js', [ 'jquery', 'jquery-ui-autocomplete' ], HEADFOOT_VERSION, true ); wp_localize_script( 'headfoot-meta-box', 'headfootMetaBox', [ 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( self::SEARCH_NONCE ), 'action' => self::SEARCH_NONCE, 'specific' => Rules::SPECIFIC, 'noResults' => esc_html__( 'No results.', 'headfoot' ), ] ); } /** * Prints the meta box. * * @param \WP_Post $post Current post. * @return void */ public function render_meta_box( $post ) { wp_nonce_field( self::NONCE_ACTION, self::NONCE_FIELD ); $type = Post_Type::sanitize_type( get_post_meta( $post->ID, Post_Type::META_TYPE, true ) ); $include = get_post_meta( $post->ID, Post_Type::META_INCLUDE, true ); $exclude = get_post_meta( $post->ID, Post_Type::META_EXCLUDE, true ); $roles = get_post_meta( $post->ID, Post_Type::META_ROLES, true ); $canvas = get_post_meta( $post->ID, Post_Type::META_CANVAS, true ); $include = is_array( $include ) ? $include : []; $exclude = is_array( $exclude ) ? $exclude : []; $roles = is_array( $roles ) ? $roles : []; // A new template starts with the rule Entire Website. if ( 'auto-draft' === $post->post_status && empty( $include ) ) { $include = [ 'global' ]; } ?>
render_rule_row( $name . '[]', $rule ); ?>
> value="">
read_list( 'headfoot_include_rules' ) ) ); update_post_meta( $post_id, Post_Type::META_EXCLUDE, Rules::sanitize_list( $this->read_list( 'headfoot_exclude_rules' ) ) ); update_post_meta( $post_id, Post_Type::META_ROLES, Rules::sanitize_roles( $this->read_list( 'headfoot_user_roles' ) ) ); update_post_meta( $post_id, Post_Type::META_CANVAS, empty( $_POST['headfoot_show_on_canvas'] ) ? '0' : '1' ); Elementor\Panel_Controls::sync_page_settings( $post_id ); } /** * Reads a list field from the request. * * The nonce test in save() runs before this method. * * @param string $field Field name. * @return array */ private function read_list( $field ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified in save(). if ( ! isset( $_POST[ $field ] ) || ! is_array( $_POST[ $field ] ) ) { return []; } // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified in save(). return array_map( 'sanitize_text_field', wp_unslash( $_POST[ $field ] ) ); } /** * Answers the AJAX search for specific targets. * * Returns at most 20 posts and terms that the current user can read. * * @return void */ public function search_targets() { check_ajax_referer( self::SEARCH_NONCE, 'nonce' ); if ( ! current_user_can( 'edit_pages' ) ) { wp_send_json_error( esc_html__( 'You are not allowed to search targets.', 'headfoot' ), 403 ); } $term = isset( $_GET['term'] ) ? sanitize_text_field( wp_unslash( $_GET['term'] ) ) : ''; $term = trim( $term ); if ( '' === $term ) { wp_send_json( [] ); } $results = []; $post_types = array_diff( get_post_types( [ 'public' => true ] ), [ Post_Type::POST_TYPE, 'attachment', 'elementor_library', 'e-landing-page', 'e-floating-buttons' ] ); if ( is_numeric( $term ) ) { $post = get_post( (int) $term ); if ( $post && in_array( $post->post_type, $post_types, true ) && current_user_can( 'read_post', $post->ID ) ) { $results[] = $this->post_result( $post ); } } $posts = get_posts( [ 's' => $term, 'post_type' => array_values( $post_types ), 'post_status' => [ 'publish', 'private', 'draft', 'pending', 'future' ], 'posts_per_page' => self::SEARCH_LIMIT, 'no_found_rows' => true, 'suppress_filters' => false, 'lang' => '', // Polylang: search every language. ] ); foreach ( $posts as $post ) { if ( ! current_user_can( 'read_post', $post->ID ) ) { continue; } $results[ 'post:' . $post->ID ] = $this->post_result( $post ); } $results = array_values( array_unique( $results, SORT_REGULAR ) ); if ( count( $results ) < self::SEARCH_LIMIT ) { $taxonomies = array_diff( get_taxonomies( [ 'public' => true ] ), [ 'post_format' ] ); $terms = get_terms( [ 'taxonomy' => array_values( $taxonomies ), 'name__like' => $term, 'number' => self::SEARCH_LIMIT - count( $results ), 'hide_empty' => false, 'lang' => '', // Polylang: search every language. ] ); if ( ! is_wp_error( $terms ) ) { foreach ( $terms as $found ) { $results[] = [ 'value' => 'term:' . $found->term_id, 'label' => Rules::get_label( 'term:' . $found->term_id ), ]; } } } wp_send_json( array_slice( $results, 0, self::SEARCH_LIMIT ) ); } /** * Builds one search result for a post. * * @param \WP_Post $post Post object. * @return array */ private function post_result( $post ) { return [ 'value' => 'post:' . $post->ID, 'label' => Rules::get_label( 'post:' . $post->ID ), ]; } /** * Prints the admin notices. * * @return void */ public function notices() { if ( ! current_user_can( 'edit_theme_options' ) ) { return; } $screen = get_current_screen(); $screen_id = $screen ? $screen->id : ''; $on_plugin = $this->is_plugin_screen(); if ( Plugin::instance()->is_uae_active() && ( $on_plugin || 'plugins' === $screen_id ) ) { printf( '

%s

', esc_html__( 'HeadFoot renders nothing while Elementor Header & Footer Builder (Ultimate Addons for Elementor) is active. Deactivate one of the two plugins.', 'headfoot' ) ); return; } if ( $on_plugin && ! Settings::is_settings_screen() && 'generic' === Compat\Theme_Loader::get_method() && ! Compat\Theme_Loader::get_known_theme() ) { printf( '

%s

', sprintf( /* translators: 1: Theme name, 2: Link to the configuration page. */ esc_html__( 'The theme %1$s has no dedicated integration. The plugin replaces the header.php and footer.php files of the theme with a generic fallback. If the page layout breaks, change the theme integration in the %2$s.', 'headfoot' ), '' . esc_html( wp_get_theme()->get( 'Name' ) ) . '', '' . esc_html__( 'Header & Footer Settings', 'headfoot' ) . '' ) ); } } }