features = $features;
}
public function register(): void
{
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue' ) );
add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ), 10, 2 );
}
/**
* User-requested placement: the panel renders BELOW the block editor's
* content area, not in the right-hand sidebar. WordPress still supports
* classic (non-block) meta boxes on block-editor screens — registering
* one with context "normal" places it under the content exactly like on
* the Classic Editor (ClassicMetaBox); sidebar.js then mounts the same
* React panel into this box's empty container instead of a PluginSidebar.
*/
public function add_meta_box( string $post_type, \WP_Post $post ): void
{
if ( ! in_array( $post_type, PostTypes::supported(), true ) || ! use_block_editor_for_post( $post ) )
{
return;
}
add_meta_box(
'acez_seo_sidebar_box',
__( 'Acez SEO AI', 'acez-seo' ),
array( $this, 'render_mount_point' ),
$post_type,
'normal',
'high'
);
}
public function render_mount_point(): void
{
echo '
';
}
public function enqueue(): void
{
$screen = get_current_screen();
if ( null === $screen || ! in_array( $screen->post_type, PostTypes::supported(), true ) )
{
return;
}
wp_enqueue_script(
'acez-seo-sidebar',
ACEZ_SEO_URL . 'assets/js/sidebar.js',
array( 'wp-dom-ready', 'wp-element', 'wp-components', 'wp-data', 'wp-i18n', 'wp-api-fetch', 'acez-seo-article-generator' ),
ACEZ_SEO_VERSION,
true
);
wp_set_script_translations( 'acez-seo-sidebar', 'acez-seo', ACEZ_SEO_DIR . 'languages' );
wp_enqueue_style(
'acez-seo-sidebar',
ACEZ_SEO_URL . 'assets/css/sidebar.css',
array(),
ACEZ_SEO_VERSION
);
// M66 (option d) — shared with the Classic meta box (ClassicMetaBox).
wp_enqueue_style(
'acez-seo-pro-teaser',
ACEZ_SEO_URL . 'assets/css/pro-teaser.css',
array(),
ACEZ_SEO_VERSION
);
wp_localize_script( 'acez-seo-sidebar', 'AcezSeoHelp', HelpContent::all() );
wp_localize_script( 'acez-seo-sidebar', 'AcezSeoHelpStrings', array( 'watchVideo' => __( 'Watch video ↗', 'acez-seo' ) ) );
// M64 — single label source shared with ClassicMetaBox's PHP .
wp_localize_script( 'acez-seo-sidebar', 'AcezSeoSearchIntentLabels', \AcezSeo\Data\MetaFields::search_intent_labels() );
// M66 — same single-label-source convention for the forced-schema-type dropdown.
wp_localize_script( 'acez-seo-sidebar', 'AcezSeoSchemaTypeOverrideLabels', \AcezSeo\Data\MetaFields::schema_type_override_labels() );
// M62 — full-article generation, shared modal/converter with the
// Classic meta box (see ClassicMetaBox). sidebar.js calls
// window.AcezSeoArticleGenerator.open() directly from its own button.
wp_enqueue_style(
'acez-seo-article-generator',
ACEZ_SEO_URL . 'assets/css/article-generator.css',
array(),
ACEZ_SEO_VERSION
);
wp_enqueue_script(
'acez-seo-markdown-article',
ACEZ_SEO_URL . 'assets/js/markdown-article.js',
array(),
ACEZ_SEO_VERSION,
true
);
wp_enqueue_script(
'acez-seo-article-generator',
ACEZ_SEO_URL . 'assets/js/article-generator.js',
array( 'acez-seo-markdown-article', 'wp-data', 'wp-blocks' ),
ACEZ_SEO_VERSION,
true
);
wp_localize_script( 'acez-seo-article-generator', 'AcezSeoArticleCfg', \AcezSeo\Ai\ArticleGeneratorL10n::config() );
// M51 — same lights/teaser styles as the Classic meta box; the JS
// panel itself is gated by AcezSeoSidebarCfg.liteAnalysisEnabled below.
if ( \AcezSeo\Analysis\LiteAnalyzer::enabled() )
{
wp_enqueue_style( 'acez-seo-lite-analysis', ACEZ_SEO_URL . 'assets/css/lite-analysis.css', array(), ACEZ_SEO_VERSION );
}
wp_localize_script(
'acez-seo-sidebar',
'AcezSeoSidebarCfg',
array(
'aiEnabled' => null === $this->features || $this->features->enabled( 'ai' ),
// M51 — Lite analysis panel; hidden when Pro's full analysis
// (with the same keyphrase field) is active, to avoid duplicate lights.
'liteAnalysisEnabled' => \AcezSeo\Analysis\LiteAnalyzer::enabled(),
// M66 (option d) — locked-teaser CTA target, shared with the
// Classic meta box's own license_tab_url(). The former
// 'proActive' flag is gone: since M69 Etapy 3-4 both Pro
// sections are decided by whether the addon filled its slot in
// window.AcezSeoSidebarSlots, never by a licence the base
// plugin has no business reading.
'licenseUrl' => add_query_arg(
array(
'page' => \AcezSeo\Admin\Ui\FormControls::PAGE_SLUG,
'tab' => 'license',
),
admin_url( 'admin.php' )
),
)
);
}
}