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);
?>
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();