/* Plugin Name: AI Snippet SEO Pro Plugin URI: https://rankpilotai.com Description: Centralized snippet generation via RankPilot AI. Uses a site token. Generates SEO-optimized snippets for posts, pages, and taxonomies with usage-limited tokens. Version: 1.0.0 Author: RankPilotAI Text Domain: ai-snippet-seo-pro Domain Path: /languages Requires at least: 5.8 Tested up to: 6.7.3 Requires PHP: 7.4 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html */ if ( ! defined('ABSPATH') ) exit; define('AISSP_FILE', __FILE__); function aissp_plugin_activate() { $option_key = 'aissp_settings'; $opts = get_option($option_key,[]); if(!is_array($opts)) $opts=[]; if(empty($opts['site_token'])){ $opts['site_token'] = 'rp_'.wp_generate_password(20,false,false); update_option($option_key,$opts); } } register_activation_hook(__FILE__,'aissp_plugin_activate'); final class AI_Snippet_SEO_Pro { protected static $instance = null; private $supported_taxonomies = ['category','post_tag','product_cat','product_tag']; public static function get_instance(){ if(self::$instance===null){ self::$instance = new self(); } return self::$instance; } private function __construct(){ $this->define_constants(); $this->includes(); $this->init_hooks(); } private function define_constants(){ define('AISSP_VERSION','1.0.0'); define('AISSP_PATH', plugin_dir_path(__FILE__)); define('AISSP_URL', plugin_dir_url(__FILE__)); define('AISSP_SETTINGS_SLUG','aissp_settings'); } private function includes(){ require_once AISSP_PATH.'admin/settings-page.php'; require_once AISSP_PATH.'admin/meta-box.php'; require_once AISSP_PATH.'includes/helper-functions.php'; } private function init_hooks(){ add_filter('plugin_action_links_'.plugin_basename(__FILE__),[$this,'settings_link']); add_action('admin_menu',[$this,'register_admin_menu']); add_action('admin_init',[$this,'register_settings']); // Metabox add_action('add_meta_boxes',[ 'AISSP_Meta_Box','register_meta_boxes']); add_action('save_post',[ 'AISSP_Meta_Box','save_meta_box_data']); // Taxonomies foreach($this->supported_taxonomies as $tax){ add_action("{$tax}_edit_form_fields",[ 'AISSP_Meta_Box','render_term_edit_ui'],10,2); add_action("edited_{$tax}",[ 'AISSP_Meta_Box','save_term_edit_ui'],10,2); } // Bulk snippet for terms foreach($this->supported_taxonomies as $tax){ add_filter("bulk_actions-edit-{$tax}",[$this,'bulk_actions_terms']); add_filter("handle_bulk_actions-edit-{$tax}",[$this,'handle_bulk_terms'],10,3); } // Ajax snippet generation for single post add_action('wp_ajax_aissp_generate_snippet',[$this,'ajax_generate_snippet']); // Head meta add_action('wp_head',[$this,'inject_head_meta'],1); // Admin CSS/JS add_action('admin_enqueue_scripts',[$this,'enqueue_assets']); // Bulk + Filter for posts add_action('admin_init',[$this,'init_posttype_bulk_and_filter']); add_action('admin_init',[$this,'listing_columns_setup']); // Notices add_action('admin_notices',[$this,'show_bulk_notices']); } public function settings_link($links){ $settings_url = admin_url('admin.php?page=ai-snippet-seo-pro'); array_unshift($links,'Settings'); return $links; } public function register_admin_menu(){ add_menu_page( 'AI Snippet SEO Pro', 'AI Snippet SEO Pro', 'manage_options', 'ai-snippet-seo-pro', [$this,'render_settings_page'], 'dashicons-chart-line', 25 ); } public function render_settings_page(){ aissp_render_settings_page(); } public function register_settings(){ aissp_register_settings(); } public function enqueue_assets($hook){ $pages = ['post.php','post-new.php','term.php','edit-tags.php','admin.php?page=ai-snippet-seo-pro']; if(in_array($hook,$pages,true)){ wp_enqueue_style('aissp-admin-css',AISSP_URL.'admin/assets/css/admin.css',[],AISSP_VERSION); wp_enqueue_script('aissp-admin-js',AISSP_URL.'admin/assets/js/admin.js',['jquery'],AISSP_VERSION,true); $opts = get_option( AISSP_SETTINGS_SLUG, [] ); wp_localize_script( 'aissp-admin-js', 'AISSP_Ajax', // Aynı isim – çakışma yok, objeyi güncellersiniz [ 'ajaxurl' => admin_url( 'admin-ajax.php' ), // yine küçük “l” 'nonce' => wp_create_nonce( 'aissp_ajax_nonce' ), 'site_token' => $opts['site_token'] ?? '', 'rest_url' => esc_url_raw( rest_url( 'rankpilotai/v1' ) ), 'site_url' => home_url(), 'model' => $opts['model_choice'] ?? 'gpt-4-turbo', ] ); } } public function ajax_generate_snippet(){ check_ajax_referer('aissp_ajax_nonce','nonce'); $post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0; if(!$post_id) wp_send_json_error(['msg'=>'Invalid post ID']); try{ AISSP_Meta_Box::generate_ai_snippet_for_post($post_id,false); $fw = get_post_meta($post_id,'_aissp_focus_keyword',true); $ti = get_post_meta($post_id,'_aissp_seo_title',true); $de = get_post_meta($post_id,'_aissp_seo_description',true); $slug = get_post_field('post_name',$post_id); $sc = aissp_calc_score($fw,$ti,$de,$slug); wp_send_json_success([ // Eski isimler korunuyor ➜ başka yerleri bozmaz 'keyword' => $fw, 'title' => $ti, 'desc' => $de, // JS’in beklediği kısaltmalar 'kw' => $fw, 'ti' => $ti, 'de' => $de, 'slug' => $slug, 'score' => aissp_score_text( $sc['score'] ), 'color' => $sc['color'], ]); }catch(\Exception $ex){ wp_send_json_error(['msg'=>$ex->getMessage()]); } } // Bulk terms public function bulk_actions_terms($actions){ $actions['aissp_generate_seo'] = 'Generate with AI Snippet SEO Pro'; return $actions; } public function handle_bulk_terms($redirect,$action,$term_ids){ if($action!=='aissp_generate_seo') return $redirect; $opts = get_option(AISSP_SETTINGS_SLUG); if(empty($opts['site_token'])){ return add_query_arg('aissp_berror','notoken',$redirect); } $s=0;$f=0; foreach($term_ids as $tid){ try{ AISSP_Meta_Box::generate_ai_snippet_for_term($tid); $s++; }catch(\Exception $ex){ $f++; } usleep(200000); } return add_query_arg(['aissp_bsuccess'=>$s,'aissp_bfailed'=>$f],$redirect); } // Head meta public function inject_head_meta(){ if(is_singular()){ global $post; if(!$post) return; $opts = get_option(AISSP_SETTINGS_SLUG); $noindex=false; $pt = get_post_type($post->ID); if(isset($opts["index_{$pt}"]) && $opts["index_{$pt}"]==='no'){ $noindex=true; } if($noindex){ echo ''."\n"; } $fw=get_post_meta($post->ID,'_aissp_focus_keyword',true); $ti=get_post_meta($post->ID,'_aissp_seo_title',true); $de=get_post_meta($post->ID,'_aissp_seo_description',true); if($ti) echo '
AI SEO Error: No Site Token configured.
AI SEO: Generated snippets for '.$s.' item(s).
AI SEO: Failed for '.$f.' item(s).