Introduction to Plugin', 'Documentation', 'Rate and Review at WordPress.org', 'Hire for WordPress Web Development', 'PlugIn Developer', ); $plugin_meta = array_merge($plugin_meta, $new_links); } return $plugin_meta; } add_filter('plugin_row_meta', 'aigenerativesearchoptimizer_by_tawhidurrahmandear_add_plugin_links', 10, 2); class AI_Generative_Search_Optimizer { private static $instance = null; private $allowed_html = [ 'a' => ['href' => true, 'title' => true], 'br' => [], 'em' => [], 'strong' => [], 'ul' => [], 'ol' => [], 'li' => [], 'p' => [] ]; public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } public function __construct() { add_action('init', [$this, 'init']); } public function init() { add_action('add_meta_boxes', [$this, 'add_meta_boxes']); add_action('save_post', [$this, 'save_aigso_data'], 10, 2); add_action('wp_head', [$this, 'output_structured_data']); add_action('admin_enqueue_scripts', [$this, 'admin_assets']); } public function admin_assets($hook) { if ('post.php' !== $hook && 'post-new.php' !== $hook) return; // CSS wp_enqueue_style( 'aigso-admin-css', plugins_url('admin.css', __FILE__), [], file_exists(plugin_dir_path(__FILE__) . 'admin.css') ? filemtime(plugin_dir_path(__FILE__) . 'admin.css') : '1.0' ); // JS wp_enqueue_script( 'aigso-admin-js', plugins_url('admin.js', __FILE__), ['jquery', 'jquery-ui-sortable'], file_exists(plugin_dir_path(__FILE__) . 'admin.js') ? filemtime(plugin_dir_path(__FILE__) . 'admin.js') : '1.0', true ); wp_localize_script( 'aigso-admin-js', 'aigso_admin', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('aigso_save_data') ] ); } public function add_meta_boxes() { $post_types = get_post_types(['public' => true]); foreach ($post_types as $post_type) { add_meta_box( 'aigso_meta_box', __('AI Generative Search Optimizer', 'ai-generative-search-optimizer'), [$this, 'render_meta_box'], $post_type, 'normal', 'high' ); } } public function render_meta_box($post) { wp_nonce_field('aigso_save_data', 'aigso_nonce'); $aigso_enabled = get_post_meta($post->ID, '_aigso_enabled', true); $aigso_schema_type = get_post_meta($post->ID, '_aigso_schema_type', true) ?: 'FAQPage'; $aigso_keywords = get_post_meta($post->ID, '_aigso_keywords', true); $aigso_about = get_post_meta($post->ID, '_aigso_about', true); $aigso_sameas = get_post_meta($post->ID, '_aigso_sameas', true); $aigso_faqs = get_post_meta($post->ID, '_aigso_faqs', true) ?: []; $preview = $this->generate_schema_preview($post->ID); ?>


•
•

$faq) : ?>
sanitize_text_field($faq['question']), 'answer' => wp_kses(($faq['answer'] ?? ''), $this->allowed_html) ]; } } update_post_meta($post_id, '_aigso_faqs', $faqs); } else { delete_post_meta($post_id, '_aigso_faqs'); } } public function save_aigso_data($post_id, $post) { // Verify nonce if ( ! isset($_POST['aigso_nonce']) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['aigso_nonce'])), 'aigso_save_data') ) { return; } // Check user permissions if (! current_user_can('edit_post', $post_id)) { return; } $this->save_form_data($post_id, $_POST); } public function output_structured_data() { if (!is_singular()) return; $post_id = get_the_ID(); $aigso_enabled = get_post_meta($post_id, '_aigso_enabled', true); if ('on' !== $aigso_enabled) return; $schema = $this->get_schema($post_id); if (!empty($schema)) { echo ''; } } private function get_schema($post_id) { $schema_type = get_post_meta($post_id, '_aigso_schema_type', true) ?: 'FAQPage'; switch ($schema_type) { case 'FAQPage': return $this->generate_faq_schema($post_id); // Per your requirement: HowTo / Product / Article ONLY include keywords/about/sameAs case 'HowTo': return $this->generate_minimal_schema($post_id, 'HowTo'); case 'Product': return $this->generate_minimal_schema($post_id, 'Product'); case 'Article': return $this->generate_minimal_schema($post_id, 'Article'); } return []; } private function generate_schema_preview($post_id) { return wp_json_encode($this->get_schema($post_id), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); } private function add_common_fields($schema, $post_id) { $keywords = get_post_meta($post_id, '_aigso_keywords', true); $about = get_post_meta($post_id, '_aigso_about', true); $sameas = $this->sanitize_sameas_to_array(get_post_meta($post_id, '_aigso_sameas', true)); if (!empty($keywords)) $schema['keywords'] = $keywords; if (!empty($about)) $schema['about'] = $about; if (!empty($sameas)) $schema['sameAs'] = $sameas; return $schema; } private function generate_faq_schema($post_id) { $faqs = get_post_meta($post_id, '_aigso_faqs', true); if (empty($faqs) || !is_array($faqs)) return []; $schema = [ '@context' => 'https://schema.org', '@type' => 'FAQPage', 'mainEntity' => [] ]; foreach ($faqs as $faq) { $question = isset($faq['question']) ? sanitize_text_field($faq['question']) : ''; $answer = isset($faq['answer']) ? $faq['answer'] : ''; if (!$question) continue; $schema['mainEntity'][] = [ '@type' => 'Question', 'name' => $question, 'acceptedAnswer' => [ '@type' => 'Answer', 'text' => $answer ] ]; } return $this->add_common_fields($schema, $post_id); } private function generate_minimal_schema($post_id, $type) { // Minimal JSON-LD for aigso: only keywords/about/sameAs $schema = [ '@context' => 'https://schema.org', '@type' => $type, ]; return $this->add_common_fields($schema, $post_id); } } add_action('admin_enqueue_scripts', function($hook) { wp_enqueue_script( 'aigso-admin-js', plugins_url('admin.js', __FILE__), ['jquery', 'jquery-ui-sortable', 'wp-i18n'], filemtime(plugin_dir_path(__FILE__) . 'admin.js'), true ); wp_set_script_translations( 'aigso-admin-js', 'ai-generative-search-optimizer', plugin_dir_path(__FILE__) . 'languages' ); }); AI_Generative_Search_Optimizer::get_instance();