admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'aije_insert_link' ) ) ) . ';', 'before' );
}
}
/* ===== Welcome-Banner (einmalig nach Aktivierung) ===== */
public function maybe_show_welcome_banner() {
// Nur für Admins, nur einmal, nicht auf dem WP Rankify Tab selbst
if ( ! current_user_can( 'manage_options' ) ) { return; }
if ( get_option( 'aije_welcome_dismissed' ) ) { return; }
$screen = get_current_screen();
if ( $screen && strpos( $screen->id, 'aije' ) !== false && isset( $_GET['tab'] ) && $_GET['tab'] === 'dashboard' ) { return; }
$profile_url = admin_url( 'profile.php#aije-expert-profile' );
$posts_url = admin_url( 'edit.php' );
$gsc_url = admin_url( 'tools.php?page=aije-lite&tab=gsc' );
$dismiss_url = wp_nonce_url( admin_url( 'admin-post.php?action=aije_dismiss_welcome' ), 'aije_dismiss_welcome' );
$nonce = wp_create_nonce( 'aije_welcome_dismiss_nonce' );
?>
🎯
Willkommen bei WP Rankify!
3 Schritte, damit dein erster Score stimmt
esc_html__( 'Dashboard', 'ai-json-extractor-auto-embed-lite' ),
'settings' => esc_html__( 'Einstellungen', 'ai-json-extractor-auto-embed-lite' ),
'tracking' => esc_html__( 'Tracking & Analytics', 'ai-json-extractor-auto-embed-lite' ),
'gsc' => esc_html__( 'Google Suche', 'ai-json-extractor-auto-embed-lite' ),
'llms' => esc_html__( 'llms.txt', 'ai-json-extractor-auto-embed-lite' ),
'license' => esc_html__( 'Lizenz', 'ai-json-extractor-auto-embed-lite' ),
);
$tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'dashboard';
echo '';
echo '
' . esc_html__( 'WP Rankify', 'ai-json-extractor-auto-embed-lite' ) . ' (AI Auto Embed)
';
echo '
';
foreach ( $tabs as $k => $label ) {
$class = ( $tab === $k ) ? ' nav-tab nav-tab-active' : ' nav-tab';
$url = add_query_arg( array( 'page' => 'aije-lite', 'tab' => $k ), admin_url( 'tools.php' ) );
echo '' . esc_html( $label ) . '';
}
echo '
';
echo '
⭐ WP Rankify bewerten
';
if ( $licensed ) {
echo '
' . esc_html__( 'Lizenz aktiv.', 'ai-json-extractor-auto-embed-lite' ) . '
';
}
$admin_dir = plugin_dir_path( AIJE_PLUGIN_FILE ) . 'admin/';
// Tabs 'export', 'automation' und 'pinghub' bleiben hier absichtlich erreichbar
// (Funktionalität unverändert), auch wenn sie oben nicht mehr gelistet werden.
switch ( $tab ) {
case 'dashboard': require $admin_dir . 'tab-dashboard.php'; break;
case 'export': require $admin_dir . 'tab-export.php'; break;
case 'automation': require $admin_dir . 'tab-automation.php'; break;
case 'pinghub': require $admin_dir . 'tab-pinghub.php'; break;
case 'gsc': require $admin_dir . 'tab-gsc.php'; break;
case 'llms': require $admin_dir . 'tab-llms.php'; break;
case 'license': require $admin_dir . 'tab-license.php'; break;
case 'tracking': require $admin_dir . 'tab-tracking.php'; break;
case 'settings':
default: require $admin_dir . 'tab-settings.php'; break;
}
echo '
';
}
/* ===== Metaboxen ===== */
public function add_score_metabox() {
foreach ( $this->get_opts()['enabled_post_types'] as $t ) {
add_meta_box( 'aije_score', 'WP Rankify – Readiness Score', array( $this, 'render_score_metabox' ), $t, 'side', 'high' );
}
}
public function render_score_metabox( $post ) {
$analysis = $this->calculate_ai_analysis( $post );
$score = $analysis['score'];
$cats = $analysis['categories'];
wp_nonce_field( 'aije_ai_nonce', 'aije_ai_nonce_field' );
$color = $score >= 75 ? '#27ae60' : ( $score >= 50 ? '#e67e22' : '#e74c3c' );
$label = $score >= 75 ? 'Gut' : ( $score >= 50 ? 'Optimierbar' : 'Kritisch' );
echo '';
echo '
' . esc_html( $score ) . '
';
echo '
' . esc_html( $label ) . '
';
echo '
';
echo 'Kategorien
';
$bar_colors = array( 'content' => '#3498db', 'eeat' => '#9b59b6', 'technical' => '#1abc9c', 'linking' => '#e67e22' );
foreach ( $cats as $key => $cat ) {
$bar_color = $bar_colors[ $key ] ?? '#999';
echo '';
echo '
';
echo '' . esc_html( $cat['label'] ) . ' (' . esc_html( $cat['weight'] ) . '%)';
echo '' . esc_html( $cat['score'] ) . '';
echo '
';
echo '
';
echo '
';
}
if ( ! empty( $analysis['issues'] ) ) {
echo '
';
echo 'Optimierungspotenzial
';
$severity_styles = array( 'high' => 'background:#fdecea;color:#c0392b;', 'medium' => 'background:#fef9e7;color:#b7770d;', 'low' => 'background:#eafaf1;color:#1e8449;' );
$severity_labels = array( 'high' => 'Hoch', 'medium' => 'Mittel', 'low' => 'Gering' );
$cat_icons = array( 'content' => '✍', 'eeat' => '🏅', 'technical' => '⚙', 'linking' => '🔗' );
$all_advice = array();
foreach ( $analysis['issues'] as $idx => $issue ) { $all_advice[ $idx ] = $this->build_issue_advice( $issue, $post, $analysis ); }
$total_issues = count( $analysis['issues'] );
$scrollable = $total_issues > 3;
$max_h = $scrollable ? 'max-height:340px;overflow-y:auto;padding-right:4px;' : '';
echo '';
foreach ( $analysis['issues'] as $idx => $issue ) {
$sev_style = $severity_styles[ $issue['severity'] ] ?? '';
$sev_label = $severity_labels[ $issue['severity'] ] ?? '';
$icon = $cat_icons[ $issue['category'] ] ?? '•';
$border_c = $bar_colors[ $issue['category'] ] ?? '#ccc';
echo '
';
echo '
';
echo '' . esc_html( $icon ) . ' ' . esc_html( $issue['msg'] ) . '';
echo '' . esc_html( $sev_label ) . '';
echo '
';
echo '
';
echo '
';
}
echo '
';
if ( $scrollable ) { echo '' . esc_html( $total_issues ) . ' Hinweise – scrollen ↕
'; }
echo '';
}
$this->render_meta_generator_box( $post );
$this->render_topic_analysis_box( $post );
// Advice-Overlay + JS aus separater Datei
require plugin_dir_path( AIJE_PLUGIN_FILE ) . 'admin/metabox-overlay.php';
}
public function add_toggle_metabox() {
foreach ( $this->get_opts()['enabled_post_types'] as $t ) {
add_meta_box( 'aije_toggle', esc_html__( 'AI JSON – Ausgabe', 'ai-json-extractor-auto-embed-lite' ), array( $this, 'render_toggle_metabox' ), $t, 'side', 'default' );
}
}
public function render_toggle_metabox( $post ) {
$no = get_post_meta( $post->ID, self::META_NO_EMBED, true );
wp_nonce_field( 'aije_toggle', 'aije_toggle_nonce' );
echo '';
echo 'Deaktiviert JSON-Embed und Person-Schema für diesen Beitrag.
';
}
public function save_post_meta( $post_id ) {
if ( ! isset( $_POST['aije_toggle_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['aije_toggle_nonce'] ), 'aije_toggle' ) ) { return; }
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; }
if ( ! current_user_can( 'edit_post', $post_id ) ) { return; }
$no = ! empty( $_POST['aije_no_embed'] ) ? '1' : '';
if ( $no ) { update_post_meta( $post_id, self::META_NO_EMBED, '1' ); }
else { delete_post_meta( $post_id, self::META_NO_EMBED ); }
}
public function add_preview_metabox() {
foreach ( $this->get_opts()['enabled_post_types'] as $t ) {
add_meta_box( 'aije_preview', esc_html__( 'AI JSON – Vorschau (readonly)', 'ai-json-extractor-auto-embed-lite' ), array( 'AIJE_Lite_100', 'render_preview_metabox_cb' ), $t, 'side', 'default' );
}
}
public static function render_preview_metabox_cb( $post ) {
$self = new self();
$data = $self->extract_payload( $post );
$flags = 0;
if ( defined( 'JSON_UNESCAPED_UNICODE' ) ) { $flags |= JSON_UNESCAPED_UNICODE; }
if ( defined( 'JSON_UNESCAPED_SLASHES' ) ) { $flags |= JSON_UNESCAPED_SLASHES; }
if ( defined( 'JSON_PRETTY_PRINT' ) ) { $flags |= JSON_PRETTY_PRINT; }
$json = function_exists( 'wp_json_encode' ) ? wp_json_encode( $data, $flags ) : json_encode( $data );
echo '';
$pto = get_post_type_object( $post->post_type );
$base = ( ! empty( $pto->rest_base ) ) ? $pto->rest_base : $post->post_type;
$api_url = rest_url( 'wp/v2/' . $base . '/' . $post->ID );
if ( ! empty( $api_url ) ) {
$url_out = ( $post->post_status === 'publish' ) ? $api_url : add_query_arg( 'context', 'edit', $api_url );
echo 'REST API öffnen
';
}
}
/* ===== SEO-Meta-Box ===== */
public function add_seo_metabox() {
$o = $this->get_opts();
$resolved = $this->get_active_seo_plugin();
if ( $resolved !== 'own' ) { return; }
$conflict = '';
if ( defined( 'WPSEO_VERSION' ) ) { $conflict = 'Yoast SEO'; }
if ( defined( 'RANK_MATH_VERSION' ) ) { $conflict = 'RankMath'; }
if ( defined( 'AIOSEO_VERSION' ) ) { $conflict = 'AIOSEO'; }
foreach ( $o['enabled_post_types'] as $t ) {
add_meta_box( 'aije_seo_meta', 'WP Rankify – SEO' . ( $conflict ? ' ⚠ Konflikt mit ' . $conflict : '' ), array( $this, 'render_seo_metabox' ), $t, 'normal', 'high' );
}
}
public function render_seo_metabox( $post ) {
wp_nonce_field( 'aije_seo_meta', 'aije_seo_meta_nonce' );
$conflict = '';
if ( defined( 'WPSEO_VERSION' ) ) { $conflict = 'Yoast SEO'; }
if ( defined( 'RANK_MATH_VERSION' ) ) { $conflict = 'RankMath'; }
if ( defined( 'AIOSEO_VERSION' ) ) { $conflict = 'AIOSEO'; }
if ( $conflict ) {
echo '⚠
' . esc_html( $conflict ) . ' ist noch aktiv. Deaktiviere ' . esc_html( $conflict ) . ' oder wähle in den
Einstellungen „Auto-Erkennung".
';
}
$seo_title = get_post_meta( $post->ID, '_aije_seo_title', true );
$meta_desc = get_post_meta( $post->ID, '_aije_metadesc', true );
$robots = get_post_meta( $post->ID, '_aije_robots', true ) ?: 'index,follow';
$canonical = get_post_meta( $post->ID, '_aije_canonical', true ) ?: get_permalink( $post->ID );
$title_len = mb_strlen( $seo_title );
$desc_len = mb_strlen( $meta_desc );
$title_col = ( $title_len >= 50 && $title_len <= 65 ) ? '#22c55e' : ( $title_len > 0 ? '#f59e0b' : '#ef4444' );
$desc_col = ( $desc_len >= 120 && $desc_len <= 160 ) ? '#22c55e' : ( $desc_len > 0 ? '#f59e0b' : '#ef4444' );
echo '';
echo '
';
echo '
' . $desc_len . ' / 160 Zeichen
';
if ( ! empty( $seo_title ) || ! empty( $meta_desc ) ) {
$purl = get_permalink( $post->ID );
echo '
Google-Vorschau
' . esc_html( mb_substr( $seo_title ?: get_the_title( $post ), 0, 65 ) ) . '
' . esc_url( $purl ) . '
' . esc_html( mb_substr( $meta_desc, 0, 160 ) ) . '
';
}
echo '
';
echo '
';
?>
$id !== $post_id ) ) );
wp_send_json_success();
}
private function render_dashboard_list( $type, $filter = '' ) {
$types = $this->get_opts()['enabled_post_types'];
$excluded_ids = get_option( 'aije_excluded_posts', array() );
$posts = get_posts( array( 'post_type' => $types, 'posts_per_page' => -1, 'post_status' => 'publish', 'post__not_in' => $excluded_ids ?: array( 0 ) ) );
$colors = array( 'bad' => '#e74c3c', 'medium' => '#e67e22', 'good' => '#27ae60', 'filter' => '#0073aa' );
$filter_map = array( 'no_image' => 'Beitragsbild', 'no_meta' => 'Meta-Description', 'too_short' => 'kurz', 'no_eeat' => 'Berufsbezeichnung', 'no_h2' => 'H2', 'no_internal' => 'Keine internen Links' );
echo '';
$found = false;
foreach ( $posts as $post ) {
$analysis = $this->calculate_ai_analysis( $post );
$score = $analysis['score'];
$show = false;
if ( $type === 'bad' && $score < 50 ) { $show = true; }
if ( $type === 'medium' && $score >= 50 && $score < 75 ) { $show = true; }
if ( $type === 'good' && $score >= 75 ) { $show = true; }
if ( $type === 'filter' ) { $show = true; }
if ( ! $show ) { continue; }
if ( ! empty( $filter ) && isset( $filter_map[ $filter ] ) ) {
$needle = $filter_map[ $filter ];
$matched = false;
foreach ( $analysis['issues'] as $iss ) { if ( mb_stripos( $iss['msg'], $needle ) !== false ) { $matched = true; break; } }
if ( ! $matched ) { continue; }
}
$found = true;
$top_issues = array_slice( $analysis['issues'], 0, 3 );
$sev_bg = array( 'high' => '#fdecea', 'medium' => '#fef9e7', 'low' => '#eafaf1' );
$cat_icons = array( 'content' => '✍', 'eeat' => '🏅', 'technical' => '⚙', 'linking' => '🔗' );
echo '- ';
echo '
';
echo '
' . esc_html( $post->post_title ) . '';
if ( ! empty( $top_issues ) && empty( $filter ) ) {
echo '
';
foreach ( $top_issues as $issue ) {
$ic = $cat_icons[ $issue['category'] ] ?? '•';
$bg = $sev_bg[ $issue['severity'] ] ?? '#f5f5f5';
echo '
' . $ic . '' . esc_html( $issue['msg'] ) . '
';
}
echo '
';
}
echo '
';
echo '
' . esc_html( $score ) . '';
echo '
';
echo '
';
}
if ( ! $found ) { echo '- Keine Artikel in dieser Kategorie.
'; }
echo '
';
}
private function render_exclude_js() { ?>