PluginProbe
Koala AI / trunk
Koala AI vtrunk
trunk 1.0
koala-ai / koala-ai.php

koala-ai.php in Koala AI trunk, at koala-ai.php

600 lines 30.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Koala AI
4 * Description: Official integration by Koala AI that makes it easy to publish content from Koala AI Writer to WordPress.
5 * Version: 1.0
6 * Author: Koala AI
7 * Author URI: https://koala.sh
8 * Text Domain: koala-ai
9 * License: GPL-2.0+
10 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11 */
12
13 // If this file is called directly, abort.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit; // Exit if accessed directly
16 }
17
18 require_once __DIR__ . '/KoalaAI-API.php';
19 require_once __DIR__ . '/KoalaAI-ImageImporter.php';
20
21 if ( ! class_exists( 'KoalaAI' ) ) {
22 class KoalaAI {
23 const KOALA_AI_CONNECTION_ENDPOINT = 'https://koala.sh/wordpress-callback?uuid={secret_token}&url={url}';
24 const KOALA_AI_CONNECTION_OPTION = 'koala_ai_connection';
25 const KOALA_AI_SECRET_TOKEN_OPTION = 'koala_ai_secret_token';
26 const KOALA_AI_IMAGE_IMPORT_BATCH_SIZE = 5;
27 const KOALA_AI_IMAGE_IMPORT_TRANSIENT = 'koala_ai_image_import_in_progress';
28 const KOALA_AI_IMAGE_IMPORT_LOG_OPTION = 'koala_ai_image_import_log';
29 const KOALA_AI_AUTO_IMPORT_OPTION = 'koala_ai_image_auto_import';
30 const KOALA_AI_POST_TYPES_OPTION = 'koala_ai_image_import_post_types';
31 const KOALA_AI_PROCESS_POST_HOOK = 'koala_ai_process_post_images';
32 const KOALA_AI_PROCESSING_MODE_OPTION = 'koala_ai_processing_mode';
33 const KOALA_AI_FIRST_IMAGE_AS_FEATURED_OPTION = 'koala_ai_first_image_as_featured';
34
35 /**
36 * Initializes the Koala AI plugin by setting up the necessary actions.
37 */
38 public static function init() {
39 add_action( 'admin_menu', array( 'KoalaAI', 'koala_ai_settings_menu' ) );
40
41 // Handle form submissions in admin context only
42 add_action( 'admin_init', array( 'KoalaAI', 'handle_disconnection' ) );
43 add_action( 'admin_init', array( 'KoalaAI', 'handle_image_import_request' ) );
44 add_action( 'admin_init', array( 'KoalaAI', 'handle_settings_update' ) );
45
46 // Add schedule hook for image import background process
47 add_action('koala_ai_process_image_import', array('KoalaAI', 'process_scheduled_image_import'));
48 // Add save_post hook to schedule image processing on publish
49 add_action('save_post', array('KoalaAI', 'process_images_on_publish'), 10, 3);
50 // Add hook for background processing of individual posts
51 add_action(self::KOALA_AI_PROCESS_POST_HOOK, array('KoalaAI', 'process_single_post_images'), 10, 1);
52
53 // Activation redirect
54 add_action('admin_init', array('KoalaAI', 'do_activation_redirect'));
55
56 /**
57 * Register REST endpoints
58 */
59 KoalaAI_API::register_api_endpoints();
60 }
61
62 /**
63 * Handles settings update form submission.
64 */
65 public static function handle_settings_update() {
66 if ( isset( $_POST['update_koala_ai_settings'] ) && $_POST['update_koala_ai_settings'] === '1' ) {
67 // Verify nonce for security
68 if ( isset( $_POST['koala_ai_settings_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['koala_ai_settings_nonce'] ) ), 'koala_ai_settings_action' ) ) {
69 // Update auto import setting
70 $auto_import = isset( $_POST['koala_ai_auto_import'] ) ? 1 : 0;
71 update_option( self::KOALA_AI_AUTO_IMPORT_OPTION, $auto_import );
72
73 // Update post types setting
74 $post_types = isset( $_POST['koala_ai_post_types'] ) ? (array) wp_unslash($_POST['koala_ai_post_types']) : array();
75 $post_types = array_map( 'sanitize_text_field', $post_types );
76 update_option( self::KOALA_AI_POST_TYPES_OPTION, $post_types );
77
78 // Update processing mode setting
79 $processing_mode = isset( $_POST['koala_ai_processing_mode'] ) ? sanitize_text_field( wp_unslash( $_POST['koala_ai_processing_mode'] ) ) : 'background';
80 update_option( self::KOALA_AI_PROCESSING_MODE_OPTION, $processing_mode );
81
82 // Update first image as featured setting
83 $first_image_as_featured = isset( $_POST['koala_ai_first_image_as_featured'] ) ? 1 : 0;
84 update_option( self::KOALA_AI_FIRST_IMAGE_AS_FEATURED_OPTION, $first_image_as_featured );
85
86 wp_safe_redirect( admin_url( 'admin.php?page=koala-ai&settings_updated=1' ) );
87 exit;
88 }
89 }
90 }
91
92 /**
93 * Handles disconnection request from the user.
94 */
95 public static function handle_disconnection() {
96 if ( isset( $_POST['disconnect'] ) && $_POST['disconnect'] === '1' ) {
97 // Verify nonce for security in admin forms
98 if ( isset( $_POST['koala_ai_disconnect_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['koala_ai_disconnect_nonce'] ) ), 'koala_ai_disconnect_action' ) ) {
99 update_option( self::KOALA_AI_CONNECTION_OPTION, 0 );
100 update_option( self::KOALA_AI_SECRET_TOKEN_OPTION, self::generate_secret_token() );
101 wp_safe_redirect( admin_url( 'admin.php?page=koala-ai&disconnected=1' ) );
102 exit;
103 }
104 }
105 }
106
107 /**
108 * Handles the image import request.
109 */
110 public static function handle_image_import_request() {
111 if (isset($_POST['start_image_import']) && $_POST['start_image_import'] === '1') {
112 // Verify nonce for security
113 if (isset($_POST['koala_ai_image_import_nonce']) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['koala_ai_image_import_nonce'] ) ), 'koala_ai_image_import_action')) {
114 // Check if an import is already in progress
115 if (get_transient(self::KOALA_AI_IMAGE_IMPORT_TRANSIENT)) {
116 wp_safe_redirect(admin_url('admin.php?page=koala-ai&import_already_running=1'));
117 exit;
118 }
119
120 // Set transient to indicate import is in progress
121 set_transient(self::KOALA_AI_IMAGE_IMPORT_TRANSIENT, true, HOUR_IN_SECONDS);
122
123 // Clear previous log
124 update_option(self::KOALA_AI_IMAGE_IMPORT_LOG_OPTION, array());
125
126 // Schedule the first batch to run immediately
127 if (!wp_next_scheduled('koala_ai_process_image_import')) {
128 wp_schedule_single_event(time(), 'koala_ai_process_image_import');
129 }
130
131 wp_safe_redirect(admin_url('admin.php?page=koala-ai&import_started=1'));
132 exit;
133 }
134 }
135 }
136
137 /**
138 * Process a batch of posts for image import.
139 */
140 public static function process_scheduled_image_import() {
141 // Check if import is in progress
142 if (!get_transient(self::KOALA_AI_IMAGE_IMPORT_TRANSIENT)) {
143 return;
144 }
145
146 // Get current log
147 $log = get_option(self::KOALA_AI_IMAGE_IMPORT_LOG_OPTION, array());
148 $processed_post_ids = isset($log['processed_posts']) ? $log['processed_posts'] : array();
149
150 // Get selected post types from settings
151 $image_import_post_types = get_option(self::KOALA_AI_POST_TYPES_OPTION, array('post', 'page'));
152
153 // Query for posts that haven't been processed yet
154 $args = array(
155 'post_type' => $image_import_post_types,
156 'post_status' => 'any',
157 'posts_per_page' => self::KOALA_AI_IMAGE_IMPORT_BATCH_SIZE,
158 'post__not_in' => $processed_post_ids,
159 'orderby' => 'date',
160 'order' => 'DESC',
161 );
162
163 $query = new WP_Query($args);
164
165 if ($query->have_posts()) {
166 while ($query->have_posts()) {
167 $query->the_post();
168 $post_id = get_the_ID();
169 $processed_post_ids[] = $post_id;
170
171 // Process this post's content
172 $content = get_post_field('post_content', $post_id);
173 $updated_content = KoalaAI_ImageImporter::process_content($content, $post_id);
174
175 // If content was changed, update the post
176 if ($content !== $updated_content) {
177 wp_update_post(array(
178 'ID' => $post_id,
179 'post_content' => $updated_content
180 ));
181
182 // Log the post that had images updated
183 if (!isset($log['updated_posts'])) {
184 $log['updated_posts'] = array();
185 }
186 $log['updated_posts'][] = array(
187 'post_id' => $post_id,
188 'title' => get_the_title($post_id),
189 'time' => current_time('mysql')
190 );
191 }
192 }
193
194 wp_reset_postdata();
195
196 // Update log with processed posts
197 $log['processed_posts'] = $processed_post_ids;
198 $log['last_run'] = current_time('mysql');
199 update_option(self::KOALA_AI_IMAGE_IMPORT_LOG_OPTION, $log);
200
201 // Schedule the next batch
202 wp_schedule_single_event(time() + 10, 'koala_ai_process_image_import');
203 } else {
204 // No more posts to process, mark as completed
205 $log['status'] = 'completed';
206 $log['completed_time'] = current_time('mysql');
207 update_option(self::KOALA_AI_IMAGE_IMPORT_LOG_OPTION, $log);
208 delete_transient(self::KOALA_AI_IMAGE_IMPORT_TRANSIENT);
209 }
210 }
211
212 /**
213 * Process images in post content when a post or page is published.
214 * Either processes directly or schedules processing based on settings.
215 *
216 * @param int $post_ID Post ID.
217 * @param WP_Post $post Post object.
218 * @param bool $update Whether this is an existing post being updated.
219 */
220 public static function process_images_on_publish($post_ID, $post, $update) {
221 // Check if auto-import is enabled
222 $image_auto_import_enabled = get_option(self::KOALA_AI_AUTO_IMPORT_OPTION, 1);
223 if (!$image_auto_import_enabled) {
224 return;
225 }
226
227 // Get allowed post types
228 $image_import_post_types = get_option(self::KOALA_AI_POST_TYPES_OPTION, array('post', 'page'));
229
230 // Check if current post type is enabled for image import
231 if (!in_array($post->post_type, $image_import_post_types)) {
232 return;
233 }
234
235 // Only process if post is being published
236 if ($post->post_status !== 'publish') {
237 return;
238 }
239
240 // Check processing mode setting (default to background if not set)
241 $processing_mode = get_option(self::KOALA_AI_PROCESSING_MODE_OPTION, 'background');
242
243 if ($processing_mode === 'immediate') {
244 // Process immediately
245 self::process_single_post_images($post_ID);
246 } else {
247 // Schedule the background task to process this post
248 if (!wp_next_scheduled(self::KOALA_AI_PROCESS_POST_HOOK, array($post_ID))) {
249 wp_schedule_single_event(time(), self::KOALA_AI_PROCESS_POST_HOOK, array($post_ID));
250 }
251 }
252 }
253
254 /**
255 * Process images for a single post in the background.
256 *
257 * @param int $post_ID Post ID to process.
258 */
259 public static function process_single_post_images($post_ID) {
260 // Get the post
261 $post = get_post($post_ID);
262 if (!$post) {
263 return;
264 }
265
266 $content = $post->post_content;
267 $updated_content = KoalaAI_ImageImporter::process_content($content, $post_ID);
268
269 if ($content !== $updated_content) {
270 // Avoid infinite loops by removing the action temporarily
271 remove_action('save_post', array('KoalaAI', 'process_images_on_publish'), 10);
272
273 // Update the post with the new content
274 wp_update_post(array(
275 'ID' => $post_ID,
276 'post_content' => $updated_content
277 ));
278
279 // Re-add the action
280 add_action('save_post', array('KoalaAI', 'process_images_on_publish'), 10, 3);
281
282 // Log the post processing if we're keeping logs
283 $log = get_option(self::KOALA_AI_IMAGE_IMPORT_LOG_OPTION, array());
284 if (isset($log['updated_posts'])) {
285 $log['updated_posts'][] = array(
286 'post_id' => $post_ID,
287 'title' => get_the_title($post_ID),
288 'time' => current_time('mysql')
289 );
290 update_option(self::KOALA_AI_IMAGE_IMPORT_LOG_OPTION, $log);
291 }
292 }
293 }
294
295 /**
296 * Adds the Koala AI Settings menu page to the WordPress admin menu.
297 */
298 public static function koala_ai_settings_menu() {
299 add_menu_page(
300 esc_html__( 'Koala AI Settings', 'koala-ai' ),
301 esc_html__( 'Koala AI', 'koala-ai' ),
302 'manage_options',
303 'koala-ai',
304 array( 'KoalaAI', 'koala_ai_settings_page' ),
305 plugin_dir_url( __FILE__ ) . 'assets/logos/logo-small.png?12',
306 80
307 );
308 // Enqueue JS and CSS for our settings page
309 add_action('admin_enqueue_scripts', function($hook) {
310 if ($hook === 'toplevel_page_koala-ai') {
311 // Enqueue admin CSS
312 wp_enqueue_style(
313 'koala-ai-admin',
314 plugin_dir_url(__FILE__) . 'assets/css/koala-ai-admin.css',
315 array(),
316 '1.0'
317 );
318
319 // Enqueue image import JS
320 wp_enqueue_script(
321 'koala-ai-image-import',
322 plugin_dir_url(__FILE__) . 'assets/js/koala-ai-image-import.js',
323 array('jquery'),
324 '1.0',
325 true
326 );
327
328 // Enqueue admin JS
329 wp_enqueue_script(
330 'koala-ai-admin',
331 plugin_dir_url(__FILE__) . 'assets/js/koala-ai-admin.js',
332 array('jquery'),
333 '1.0',
334 true
335 );
336
337 // Set up data for JS
338 wp_localize_script('koala-ai-image-import', 'KoalaAIImageImport', array(
339 'restUrl' => esc_url_raw(rest_url('koala-ai/v1/')),
340 'nonce' => wp_create_nonce('wp_rest'),
341 ));
342
343 // Set up data for admin JS
344 wp_localize_script('koala-ai-admin', 'koalaAIData', array(
345 'disconnectText' => esc_html__('Disconnect', 'koala-ai'),
346 'disconnectConfirm' => esc_html__('Do you really want to disconnect the website? Your content synchronization will be stopped.', 'koala-ai'),
347 ));
348 }
349 });
350 }
351
352 /**
353 * Renders the Koala AI settings page.
354 */
355 public static function koala_ai_settings_page() {
356 $secret_token = self::get_secret_token();
357 $website_url = self::get_website_url();
358 $connection = self::is_connected() ? 'Connected' : 'Disconnected';
359 $import_log = get_option(self::KOALA_AI_IMAGE_IMPORT_LOG_OPTION, array());
360 $import_in_progress = get_transient(self::KOALA_AI_IMAGE_IMPORT_TRANSIENT);
361
362 // Get auto import settings
363 $image_auto_import_enabled = get_option(self::KOALA_AI_AUTO_IMPORT_OPTION, 1);
364 $image_import_post_types = get_option(self::KOALA_AI_POST_TYPES_OPTION, array('post', 'page'));
365 $processing_mode = get_option(self::KOALA_AI_PROCESSING_MODE_OPTION, 'background');
366 $first_image_as_featured_enabled = get_option(self::KOALA_AI_FIRST_IMAGE_AS_FEATURED_OPTION, 0);
367
368 // Get all registered post types
369 $post_types = array_filter(
370 get_post_types(array('public' => true), 'objects'),
371 function($post_type) {
372 return $post_type->name !== 'attachment';
373 }
374 );
375
376 $connection_url = $connection === 'Disconnected'
377 ? str_replace(
378 ['{secret_token}', '{url}'],
379 [esc_attr($secret_token), esc_attr(urlencode($website_url))],
380 self::KOALA_AI_CONNECTION_ENDPOINT
381 )
382 : '#';
383 ?>
384 <h2><?php esc_html_e( 'Koala AI Settings', 'koala-ai' ); ?></h2>
385 <div class="koala-content-container">
386 <form action="<?php echo esc_url( $connection_url ); ?>" method="post">
387 <p style="display: none;">
388 <label for="secret-token"><?php esc_html_e( 'Secret Token', 'koala-ai' ); ?></label> <br/> <input type="text" id="secret-token" name="secret-token" size="32" value="<?php echo esc_attr( $secret_token ); ?>" readonly>
389 </p>
390 <p>
391 <label><?php esc_html_e( 'Connection Status: ', 'koala-ai' ); ?> <span style="color: <?php echo $connection === 'Disconnected' ? 'darkred' : 'darkgreen'; ?>; font-weight: bold"><?php echo esc_html( $connection ); ?></span></label>
392 </p>
393 <?php if ( $connection === 'Connected' ) {
394 ?>
395 <input type="hidden" name="disconnect" value="1">
396 <?php wp_nonce_field('koala_ai_disconnect_action', 'koala_ai_disconnect_nonce'); ?>
397 <?php }
398 // Output submit button
399 if ( $connection === 'Connected' ) {
400 submit_button( esc_html__( 'Disconnect', 'koala-ai' ), 'primary', 'connection-button', false, array( 'onclick' => 'return confirm_disconnect()' ) );
401 } else {
402 echo '<a href="' . esc_url( $connection_url ) . '" target="_blank" class="button button-primary">' . esc_html__( 'Connect', 'koala-ai' ) . '</a>';
403 echo '<a href="' . esc_url( admin_url( 'admin.php?page=koala-ai' ) ) . '" class="button" style="margin-left: 10px;">' . esc_html__( 'Refresh Status', 'koala-ai' ) . '</a>';
404 echo '<div class="connection-note">' . esc_html__( 'After connecting in Koala AI, please come back and click the Refresh Status button to update your connection status.', 'koala-ai' ) . '</div>';
405 }
406
407 // Show disconnection message if needed
408 if (isset($_GET['disconnected']) && $_GET['disconnected'] == '1') {
409 echo '<div class="connection-note" style="border-left-color: #d63638;">' . esc_html__( 'Your WordPress site has been disconnected. For complete disconnection, please also remove this site from your integrations in your Koala AI account.', 'koala-ai' ) . '</div>';
410 }
411 ?>
412 </form>
413 </div>
414
415 <h3 class="section-title"><?php esc_html_e('Automatic Image Import Settings', 'koala-ai'); ?></h3>
416 <div class="koala-content-container">
417
418 <div class="koala-info-banner">
419 <p><?php esc_html_e('These settings control how Koala AI handles images in your content. When enabled, external images from Koala AI will be automatically downloaded to your WordPress media library, allowing them to be hosted directly on your server instead of the koala.sh domain.', 'koala-ai'); ?></p>
420 </div>
421
422 <?php if (isset($_GET['settings_updated']) && $_GET['settings_updated'] == '1') : ?>
423 <div class="success-message"><?php esc_html_e('Your settings have been updated successfully.', 'koala-ai'); ?></div>
424 <?php endif; ?>
425
426 <form method="post" class="settings-form">
427 <p>
428 <label>
429 <input type="checkbox" name="koala_ai_auto_import" value="1" <?php checked($image_auto_import_enabled, 1); ?> id="koala_ai_auto_import">
430 <?php esc_html_e('Enable automatic image import when posts are saved (only applies to Published posts)', 'koala-ai'); ?>
431 </label>
432 </p>
433
434 <div id="koala_ai_auto_import_options" style="margin-left: 24px; <?php echo $image_auto_import_enabled ? '' : 'display: none;'; ?>">
435 <p>
436 <label><?php esc_html_e('Automatic Processing Mode:', 'koala-ai'); ?></label>
437 </p>
438 <div style="margin-left: 24px;">
439 <label style="display: block; margin-bottom: 8px;">
440 <input type="radio" name="koala_ai_processing_mode" value="background" <?php checked($processing_mode, 'background'); ?>>
441 <?php esc_html_e('Background Processing (faster saving, processes soon after the post is saved)', 'koala-ai'); ?>
442 </label>
443 <label style="display: block;">
444 <input type="radio" name="koala_ai_processing_mode" value="immediate" <?php checked($processing_mode, 'immediate'); ?>>
445 <?php esc_html_e('Immediate Processing (slower publishing, but ensures processing before completing save)', 'koala-ai'); ?>
446 </label>
447 </div>
448 </div>
449
450 <p>
451 <label>
452 <input type="checkbox" name="koala_ai_first_image_as_featured" value="1" <?php checked($first_image_as_featured_enabled, 1); ?>>
453 <?php esc_html_e('Set the first image in content as the featured image for the post (only applies to posts without an existing featured image)', 'koala-ai'); ?>
454 </label>
455 </p>
456
457 <p>
458 <label><?php esc_html_e('Choose post types for processing:', 'koala-ai'); ?></label>
459 </p>
460
461 <div class="post-types-container">
462 <?php foreach ($post_types as $post_type) : ?>
463 <label class="post-type-label">
464 <input type="checkbox" class="post-type-checkbox" name="koala_ai_post_types[]" value="<?php echo esc_attr($post_type->name); ?>" <?php checked(in_array($post_type->name, $image_import_post_types), true); ?>>
465 <?php echo esc_html($post_type->labels->singular_name); ?>
466 </label>
467 <?php endforeach; ?>
468 </div>
469
470 <input type="hidden" name="update_koala_ai_settings" value="1">
471 <?php wp_nonce_field('koala_ai_settings_action', 'koala_ai_settings_nonce'); ?>
472 <?php submit_button(esc_html__('Save Settings', 'koala-ai')); ?>
473 </form>
474 </div>
475
476 <h3 class="section-title"><?php esc_html_e('Bulk Image Import Tool', 'koala-ai'); ?></h3>
477 <div class="koala-content-container">
478 <div id="koala-ai-image-import-ui">
479 <div class="note-banner">
480 <p><?php esc_html_e('We recommend creating a backup of your website before using this tool as a best practice.', 'koala-ai'); ?></p>
481 </div>
482 <div class="koala-info-banner">
483 <p><?php esc_html_e('This tool allows you to import all external Koala AI images from existing content. Before using this tool:', 'koala-ai'); ?></p>
484 <ol>
485 <li><?php esc_html_e('Make sure to save your settings in the section above first', 'koala-ai'); ?></li>
486 <li><?php esc_html_e('Only posts of the selected post types above will be processed', 'koala-ai'); ?></li>
487 <li><?php esc_html_e('If you enabled the "Set first image as featured image" option, it will only apply to posts that don\'t already have a featured image', 'koala-ai'); ?></li>
488 </ol>
489 </div>
490 <p><?php esc_html_e('This tool scans your content for images from koala.sh, downloads them to your WordPress media library, and updates your posts to use these local copies. The process runs in your browser and shows real-time progress.', 'koala-ai'); ?></p>
491 <button id="koala-ai-start-btn" class="button button-primary"><?php esc_html_e('Start Bulk Image Import', 'koala-ai'); ?></button>
492 <div id="koala-ai-progress-container" style="margin-top:20px;display:none;max-width:400px;">
493 <div style="background:#eee;border-radius:4px;overflow:hidden;height:24px;">
494 <div id="koala-ai-progress-bar" style="background:#2271b1;height:24px;width:0%;transition:width 0.3s;"></div>
495 </div>
496 <div id="koala-ai-progress-text" style="margin-top:8px;"></div>
497 </div>
498 <div id="koala-ai-status" style="margin-top:10px;"></div>
499 </div>
500 </div>
501
502 <div class="koala-content-container" style="margin-top: 45px;">Visit <a href="https://koala.sh/?utm_source=wp_plugin_footer" target="_blank">Koala AI</a></div>
503 <?php
504 }
505
506 /**
507 * Gets the secret token for the current site.
508 */
509 public static function get_secret_token() {
510 return get_option( self::KOALA_AI_SECRET_TOKEN_OPTION );
511 }
512
513 /**
514 * Gets the website URL for the current site.
515 */
516 public static function get_website_url() {
517 return get_bloginfo('url');
518 }
519
520 /**
521 * Generate Secret Token
522 */
523 private static function generate_secret_token() {
524 return wp_generate_uuid4();
525 }
526
527 /**
528 * Handles redirect to settings page after plugin activation.
529 */
530 public static function do_activation_redirect() {
531 if (get_option('koala_ai_do_activation_redirect', false)) {
532 delete_option('koala_ai_do_activation_redirect');
533 if (!isset($_GET['activate-multi'])) { // Prevent redirect on bulk activation
534 wp_safe_redirect(admin_url('admin.php?page=koala-ai'));
535 exit;
536 }
537 }
538 }
539
540 /**
541 * Activates the Koala AI plugin by checking and setting the necessary options.
542 */
543 public static function activate() {
544 // If secret token option is empty, set value.
545 if ( ! self::get_secret_token() ) {
546 update_option( self::KOALA_AI_SECRET_TOKEN_OPTION, self::generate_secret_token() );
547 }
548
549 // Set default values for auto import settings
550 if (get_option(self::KOALA_AI_AUTO_IMPORT_OPTION) === false) {
551 update_option(self::KOALA_AI_AUTO_IMPORT_OPTION, 1); // Enabled by default
552 }
553
554 // Set default values for post types
555 if (get_option(self::KOALA_AI_POST_TYPES_OPTION) === false) {
556 update_option(self::KOALA_AI_POST_TYPES_OPTION, array('post', 'page'));
557 }
558
559 // Set default processing mode
560 if (get_option(self::KOALA_AI_PROCESSING_MODE_OPTION) === false) {
561 update_option(self::KOALA_AI_PROCESSING_MODE_OPTION, 'background'); // Background processing by default
562 }
563
564 // Set default first image as featured setting (disabled by default)
565 if (get_option(self::KOALA_AI_FIRST_IMAGE_AS_FEATURED_OPTION) === false) {
566 update_option(self::KOALA_AI_FIRST_IMAGE_AS_FEATURED_OPTION, 0);
567 }
568
569 // Set flag for activation redirect
570 update_option('koala_ai_do_activation_redirect', true);
571 }
572
573 /**
574 * Checks if the Koala AI connection is active.
575 */
576 public static function is_connected() {
577 $connection_data = get_option( self::KOALA_AI_CONNECTION_OPTION );
578 return !empty($connection_data);
579 }
580
581 /**
582 * Gets the stored integration ID if connected.
583 * @return string|null
584 */
585 public static function get_integration_id() {
586 $connection_data = get_option( self::KOALA_AI_CONNECTION_OPTION );
587 if (is_array($connection_data) && isset($connection_data['integration_id']) && !empty($connection_data['integration_id'])) {
588 return $connection_data['integration_id'];
589 }
590 return null;
591 }
592 }
593
594 KoalaAI::init();
595 }
596
597 /**
598 * Set secret_token when plugin is activated
599 */
600 register_activation_hook( __FILE__, array( 'KoalaAI', 'activate' ) );