PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.10.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.10.0
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / includes / core / class-activator.php

class-activator.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.10.0, at includes/core/class-activator.php

209 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Plugin Activator Class
5 *
6 * Handles plugin activation tasks
7 *
8 * @package ThinkRank\Core
9 * @since 1.0.0
10 */
11
12 declare(strict_types=1);
13
14 namespace ThinkRank\Core;
15
16 use ThinkRank\Database\Database_Schema;
17
18 // Prevent direct access
19 if (!defined('ABSPATH')) {
20 exit;
21 }
22
23 /**
24 * Activator Class
25 *
26 * Single Responsibility: Handle plugin activation tasks only
27 *
28 * @since 1.0.0
29 */
30 class Activator {
31
32 /**
33 * Plugin activation tasks
34 *
35 * @return void
36 * @throws \Exception If activation fails
37 */
38 public function activate(): void {
39 $this->check_requirements();
40 $this->create_database_tables();
41 $this->set_default_options();
42 $this->setup_indexnow_key();
43 $this->schedule_cron_jobs();
44 $this->set_activation_flag();
45 }
46
47 /**
48 * Setup IndexNow API Key
49 *
50 * Generates a unique 128-bit key and creates the key file in the root directory.
51 *
52 * @return void
53 */
54 private function setup_indexnow_key(): void {
55 $option_name = 'thinkrank_instant_indexing_settings';
56 $settings = get_option($option_name, []);
57
58 // Check if key exists
59 if (empty($settings['api_key'])) {
60 try {
61 // Generate 128-bit key (32 hex characters)
62 // Using bin2hex(random_bytes(16)) as requested
63 $key = bin2hex(random_bytes(16));
64
65 // Save to options
66 $settings['api_key'] = $key;
67
68 // Initialize default post types if not set
69 if (!isset($settings['auto_submit_post_types'])) {
70 $settings['auto_submit_post_types'] = ['post', 'page'];
71 }
72
73 update_option($option_name, $settings);
74
75 // Create the key file in WordPress root
76 $file_path = ABSPATH . $key . '.txt';
77 if (wp_is_writable(ABSPATH)) {
78 file_put_contents($file_path, $key);
79 }
80 } catch (\Exception $e) {
81 error_log('ThinkRank: Failed to create IndexNow key file: ' . $e->getMessage());
82 }
83 }
84 }
85
86 /**
87 * Check system requirements
88 *
89 * @return void
90 * @throws \Exception If requirements not met
91 */
92 private function check_requirements(): void {
93 // PHP version check
94 if (version_compare(PHP_VERSION, '8.0', '<')) {
95 throw new \Exception('ThinkRank requires PHP 8.0 or higher');
96 }
97
98 // WordPress version check
99 if (version_compare(get_bloginfo('version'), '6.0', '<')) {
100 throw new \Exception('ThinkRank requires WordPress 6.0 or higher');
101 }
102
103 // Required PHP extensions
104 $required_extensions = ['curl', 'json', 'mbstring'];
105 foreach ($required_extensions as $extension) {
106 if (!extension_loaded($extension)) {
107 throw new \Exception(sprintf("Required PHP extension '%s' is not loaded", esc_html($extension)));
108 }
109 }
110
111 // Check if we can write to WordPress root directory (for robots.txt, llms.txt, sitemaps)
112 if (!wp_is_writable(ABSPATH)) {
113 throw new \Exception('WordPress root directory is not writable');
114 }
115 }
116
117 /**
118 * Create database tables
119 *
120 * Uses the consolidated Database_Schema class to create all 11 ThinkRank tables:
121 * - SEO Tables (7): Settings, Analysis, Keywords, Schema, Social, Performance, Local
122 * - AI/Core Tables (4): AI Cache, AI Usage, Content Briefs, SEO Scores
123 *
124 * @return void
125 * @throws \Exception If table creation fails
126 */
127 private function create_database_tables(): void {
128 try {
129 // Use the Database_Schema class to create all 11 ThinkRank tables
130 $schema = new Database_Schema();
131 $results = $schema->create_tables();
132
133 if (!$results['success']) {
134 $error_message = 'Failed to create database tables: ' . implode(', ', $results['errors']);
135 throw new \Exception($error_message);
136 }
137
138 // Add performance indexes for Phase 2 optimization
139 $index_results = $schema->add_performance_indexes();
140 if (!$index_results) {
141 // Performance indexes could not be created - activation continues
142 }
143
144 // Database tables created successfully
145
146 } catch (\Exception $e) {
147 throw new \Exception('Database table creation failed: ' . esc_html($e->getMessage()));
148 }
149 }
150
151
152
153 /**
154 * Set default plugin options
155 *
156 * @return void
157 */
158 private function set_default_options(): void {
159 $default_options = [
160 'thinkrank_version' => THINKRANK_VERSION,
161
162 'thinkrank_ai_provider' => 'openai',
163 'thinkrank_cache_duration' => 3600, // 1 hour
164 'thinkrank_max_requests_per_minute' => 10,
165 'thinkrank_enable_logging' => true,
166 'thinkrank_auto_optimize' => false,
167 'thinkrank_seo_score_threshold' => 70,
168 ];
169
170 foreach ($default_options as $option_name => $option_value) {
171 if (get_option($option_name) === false) {
172 add_option($option_name, $option_value);
173 }
174 }
175 }
176
177
178 /**
179 * Schedule cron jobs
180 *
181 * @return void
182 */
183 private function schedule_cron_jobs(): void {
184
185 // Schedule cache cleanup
186 if (!wp_next_scheduled('thinkrank_cache_cleanup')) {
187 wp_schedule_event(time(), 'daily', 'thinkrank_cache_cleanup');
188 }
189
190 // Schedule usage analytics
191 if (!wp_next_scheduled('thinkrank_usage_analytics')) {
192 wp_schedule_event(time(), 'weekly', 'thinkrank_usage_analytics');
193 }
194 }
195
196 /**
197 * Set activation flag for first-time setup
198 *
199 * @return void
200 */
201 private function set_activation_flag(): void {
202 update_option('thinkrank_activated', true);
203 update_option('thinkrank_activation_time', time());
204
205 // Set flag for showing welcome screen
206 update_option('thinkrank_show_welcome', true);
207 }
208 }
209