SEO field. */ private const CONTROLS = array( 'wpiseo_title' => 'title', 'wpiseo_description' => 'description', 'wpiseo_focus_keyword' => 'focus_keywords', 'wpiseo_noindex' => 'noindex', ); /** * Registers hooks (only does work when Elementor is active). */ public function register(): void { add_action( 'elementor/documents/register_controls', array( $this, 'controls' ) ); add_filter( 'elementor/document/save/data', array( $this, 'save' ), 10, 2 ); } /** * Adds the SEO section. * * @param \Elementor\Core\Base\Document $document Elementor document. */ public function controls( $document ): void { $post = $this->post( $document ); if ( null === $post || ! class_exists( '\Elementor\Controls_Manager' ) ) { return; } $template = MetaModule::post_type( Plugin::instance()->options(), $post->post_type ); $keywords = (array) Meta::post( $post->ID, 'focus_keywords' ); $document->start_controls_section( 'wpiseo_section', array( 'label' => __( 'SEO', 'wpinterface-seo' ), 'tab' => \Elementor\Controls_Manager::TAB_SETTINGS, ) ); $document->add_control( 'wpiseo_title', array( 'label' => __( 'SEO title', 'wpinterface-seo' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => (string) Meta::post( $post->ID, 'title' ), 'placeholder' => $template['title'], 'label_block' => true, ) ); $document->add_control( 'wpiseo_description', array( 'label' => __( 'Meta description', 'wpinterface-seo' ), 'type' => \Elementor\Controls_Manager::TEXTAREA, 'default' => (string) Meta::post( $post->ID, 'description' ), 'placeholder' => $template['description'], 'rows' => 3, ) ); $document->add_control( 'wpiseo_focus_keyword', array( 'label' => __( 'Focus keyword', 'wpinterface-seo' ), 'type' => \Elementor\Controls_Manager::TEXT, 'default' => (string) ( $keywords[0] ?? '' ), 'label_block' => true, ) ); $document->add_control( 'wpiseo_noindex', array( 'label' => __( 'Search engines', 'wpinterface-seo' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => (string) Meta::post( $post->ID, 'noindex' ), 'options' => array( '' => __( 'Default for this type', 'wpinterface-seo' ), 'index' => __( 'Index', 'wpinterface-seo' ), 'noindex' => __( 'Noindex', 'wpinterface-seo' ), ), ) ); $document->add_control( 'wpiseo_more', array( 'type' => \Elementor\Controls_Manager::RAW_HTML, 'raw' => sprintf( '%s', esc_url( admin_url( 'post.php?post=' . $post->ID . '&action=edit' ) ), esc_html__( 'Content analysis, social and schema settings are in the WordPress editor.', 'wpinterface-seo' ) ), ) ); $document->end_controls_section(); } /** * Stores the SEO fields in post meta and keeps them out of Elementor's * page settings. * * @param array $data Data being saved. * @param \Elementor\Core\Base\Document $document Elementor document. * @return array */ public function save( $data, $document ): array { $data = is_array( $data ) ? $data : array(); $post = $this->post( $document ); if ( null === $post || ! isset( $data['settings'] ) || ! is_array( $data['settings'] ) ) { return $data; } foreach ( self::CONTROLS as $control => $field ) { if ( ! array_key_exists( $control, $data['settings'] ) ) { continue; } $value = $data['settings'][ $control ]; unset( $data['settings'][ $control ] ); if ( 'focus_keywords' === $field ) { $current = array_values( (array) Meta::post( $post->ID, 'focus_keywords' ) ); $current[0] = (string) $value; $value = array_values( array_filter( array_map( 'strval', $current ) ) ); } Meta::write( 'post', $post->ID, $field, $value ); } return $data; } /** * The post behind a document, when the user may edit its SEO. * * @param mixed $document Elementor document. */ private function post( $document ): ?WP_Post { if ( ! is_object( $document ) || ! is_callable( array( $document, 'get_main_id' ) ) ) { return null; } $post = get_post( (int) $document->get_main_id() ); if ( ! $post instanceof WP_Post || ! in_array( $post->post_type, Editor::post_types(), true ) || ! current_user_can( Capabilities::EDIT_SEO ) || ! current_user_can( 'edit_post', $post->ID ) ) { return null; } return $post; } }