options = get_option('ai_article_writer_options'); // Hook for scheduling add_action('wp', array($this, 'schedule_article_creation')); // Hook for creating articles add_action($this->cron_hook, array($this, 'create_article_from_api')); add_action($this->notification_hook, array($this, 'send_no_topics_notification')); // Hook for plugin activation register_activation_hook(__FILE__, array($this, 'activate')); // Hook for plugin deactivation register_deactivation_hook(__FILE__, array($this, 'deactivate')); // Add settings page add_action('admin_menu', array($this, 'add_settings_page')); add_action('admin_init', array($this, 'register_settings')); // Add AJAX action for manual run add_action('wp_ajax_run_ai_article_writer', array($this, 'ajax_run_article_writer')); // Enqueue admin scripts add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts')); } public function activate() { $this->schedule_cron_jobs(); } private function schedule_cron_jobs() { if (!empty($this->options['cron_enabled']) && $this->options['cron_enabled'] == 'on') { $posts_per_day = isset($this->options['posts_per_day']) ? intval($this->options['posts_per_day']) : 1; $interval = max(1, intval(24 / $posts_per_day)); if (!wp_next_scheduled($this->cron_hook)) { wp_schedule_event(time(), 'hourly', $this->cron_hook); } } else { $this->clear_cron_jobs(); } } private function clear_cron_jobs() { $timestamp = wp_next_scheduled($this->cron_hook); if ($timestamp) { wp_unschedule_event($timestamp, $this->cron_hook); } } public function schedule_article_creation() { $this->schedule_cron_jobs(); } public function create_article_from_api() { if (empty($this->options['api_key']) || empty($this->options['topics'])) { error_log('AI Article Writer: API key or topics not set'); return false; } // Check if it's time to create a post based on posts_per_day setting $posts_per_day = isset($this->options['posts_per_day']) ? intval($this->options['posts_per_day']) : 1; $last_post_time = get_option('ai_article_writer_last_post_time', 0); $time_since_last_post = time() - $last_post_time; $interval = max(1, intval(24 / $posts_per_day)) * HOUR_IN_SECONDS; if ($time_since_last_post < $interval) { return false; } // Step 1: Choose an unused topic $topic = $this->get_unused_topic(); if (!$topic) { $this->all_topics_used(); return false; } // Step 2: Generate an article using AI Story Writer $job_id = $this->generate_article($topic); if (!$job_id) { error_log('AI Article Writer: Failed to generate article'); return false; } // Step 3: Wait for the job to complete $article = $this->wait_for_job_completion($job_id); if (!$article) { error_log('AI Article Writer: Failed to retrieve generated article'); return false; } // Step 4: Process the article content for WordPress blocks $processed_content = $this->process_content_for_blocks($article); // Step 5: Create a post with the generated article $post_data = array( 'post_title' => $topic, 'post_content' => $processed_content, 'post_status' => $this->options['post_status'] ?? 'publish', 'post_author' => 1, // Default admin user 'post_type' => 'post', ); $post_id = wp_insert_post($post_data); if (!is_wp_error($post_id)) { update_option('ai_article_writer_last_post_time', time()); $this->mark_topic_as_used($topic); error_log('AI Article Writer: Successfully created article with ID ' . $post_id); return true; } else { error_log('AI Article Writer: Failed to create article. Error: ' . $post_id->get_error_message()); return false; } } private function generate_article($topic) { $endpoint = $this->api_base_url . '/?action=upload'; $body = array( 'tool' => 'AI Article Writer', 'topic' => $topic, 'lang' => $this->options['language'] ?? 'English', 'format' => 'html', 'request' => 'wp' ); $response = wp_remote_post($endpoint, array( 'headers' => array( 'APIKEY' => $this->options['api_key'], 'Content-Type' => 'application/x-www-form-urlencoded' ), 'body' => $body )); if (is_wp_error($response)) { error_log('AI Article Writer: Failed to generate article. Error: ' . $response->get_error_message()); return false; } $body = json_decode(wp_remote_retrieve_body($response), true); if (isset($body['job_id'])) { return $body['job_id']; } return false; } private function wait_for_job_completion($job_id) { $endpoint = $this->api_base_url . '/?action=status'; $max_attempts = 10; $attempt = 0; while ($attempt < $max_attempts) { $response = wp_remote_post($endpoint, array( 'headers' => array( 'APIKEY' => $this->options['api_key'], 'Content-Type' => 'application/x-www-form-urlencoded' ), 'body' => array('job_id' => $job_id) )); if (is_wp_error($response)) { error_log('AI Article Writer: Failed to check job status. Error: ' . $response->get_error_message()); return false; } $body = json_decode(wp_remote_retrieve_body($response), true); if (isset($body['status']) && $body['status'] === 'Completed') { return $this->download_article($job_id); } $attempt++; sleep(30); // Wait for 30 seconds before checking again } error_log('AI Article Writer: Job did not complete within the expected time'); return false; } private function download_article($job_id) { $endpoint = $this->api_base_url . '/?action=download'; $response = wp_remote_post($endpoint, array( 'headers' => array( 'APIKEY' => $this->options['api_key'], 'Content-Type' => 'application/x-www-form-urlencoded' ), 'body' => array('job_id' => $job_id) )); if (is_wp_error($response)) { error_log('AI Article Writer: Failed to download article. Error: ' . $response->get_error_message()); return false; } $body = json_decode(wp_remote_retrieve_body($response), true); if (isset($body['response']['text'])) { return $body['response']['text']; } return false; } private function process_content_for_blocks($content) { // Ensure that wp_parse_blocks function is available if (!function_exists('wp_parse_blocks')) { require_once(ABSPATH . 'wp-includes/blocks.php'); } // Convert HTML to blocks $blocks = array(); // Split content into paragraphs $paragraphs = preg_split('/<\/?(?:p|h[1-6]|ul|ol|li)>/i', $content, -1, PREG_SPLIT_NO_EMPTY); foreach ($paragraphs as $paragraph) { $paragraph = trim($paragraph); // Skip empty paragraphs if (empty($paragraph)) { continue; } // Check if the paragraph is a heading if (preg_match('/^(.*?)<\/h[1-6]>$/i', $paragraph, $matches)) { $heading_level = $matches[1]; $heading_content = $matches[2]; $blocks[] = array( 'blockName' => 'core/heading', 'attrs' => array('level' => intval($heading_level)), 'innerHTML' => $heading_content, 'innerContent' => array($heading_content), ); } // Check if the paragraph is a list elseif (strpos($paragraph, '