Go to settings', 'rapidtextai'); ?>
$1', $markdown); // Convert code blocks $markdown = preg_replace('/```(.*?)```/s', '
$1', $markdown);
// Convert inline code
$markdown = preg_replace('/`([^`]+)`/', '$1', $markdown);
// Convert newlines to paragraphs
$markdown = preg_replace('/\n\n/', '', $markdown); $markdown = '
' . $markdown . '
'; // Wrap with paragraph tags // Cleanup multiple paragraph tags $markdown = str_replace('', '', $markdown); return $markdown; } // Add Auto Blogging feature function rapidtextai_add_auto_blogging_menu() { add_submenu_page( 'rapidtextai-settings', // Parent menu slug 'Auto Blogging', // Page title 'Auto Blogging', // Menu title 'manage_options', // Capability 'rapidtextai-auto-blogging', // Menu slug 'rapidtextai_auto_blogging_page' // Callback function ); } add_action('admin_menu', 'rapidtextai_add_auto_blogging_menu'); // Migration function to convert old settings to campaign-based structure function rapidtextai_migrate_to_campaigns() { // Check if migration is needed if (get_option('rapidtextai_campaigns_migrated')) { return; // Already migrated } // Get old settings $old_settings = get_option('rapidtextai_auto_blogging', array()); // If old settings exist, create a default campaign if (!empty($old_settings)) { $campaigns = get_option('rapidtextai_auto_blogging_campaigns', array()); // Create default campaign from old settings $default_campaign = array( 'id' => 'campaign_' . time(), 'name' => 'Default Campaign', 'enabled' => isset($old_settings['enabled']) ? $old_settings['enabled'] : 0, 'schedule' => isset($old_settings['schedule']) ? $old_settings['schedule'] : 'daily', 'post_status' => isset($old_settings['post_status']) ? $old_settings['post_status'] : 'draft', 'post_author' => isset($old_settings['post_author']) ? $old_settings['post_author'] : get_current_user_id(), 'topics' => isset($old_settings['topics']) ? $old_settings['topics'] : '', 'model' => isset($old_settings['model']) ? $old_settings['model'] : 'gpt-3.5-turbo', 'tone' => isset($old_settings['tone']) ? $old_settings['tone'] : 'informative', 'post_category' => isset($old_settings['post_category']) ? $old_settings['post_category'] : array(1), 'generate_tags' => isset($old_settings['generate_tags']) ? $old_settings['generate_tags'] : 1, 'tags_count' => isset($old_settings['tags_count']) ? $old_settings['tags_count'] : 5, 'excerpt_length' => isset($old_settings['excerpt_length']) ? $old_settings['excerpt_length'] : 55, 'taxonomy_limit' => isset($old_settings['taxonomy_limit']) ? $old_settings['taxonomy_limit'] : 5, 'include_images' => isset($old_settings['include_images']) ? $old_settings['include_images'] : 1, 'include_featured_image' => isset($old_settings['include_featured_image']) ? $old_settings['include_featured_image'] : 0, 'max_images' => isset($old_settings['max_images']) ? $old_settings['max_images'] : 5, 'enable_logging' => isset($old_settings['enable_logging']) ? $old_settings['enable_logging'] : 0, 'created' => current_time('mysql'), ); $campaigns[$default_campaign['id']] = $default_campaign; update_option('rapidtextai_auto_blogging_campaigns', $campaigns); // Keep old settings for backward compatibility but mark as migrated update_option('rapidtextai_campaigns_migrated', true); } else { // No old settings, just mark as migrated update_option('rapidtextai_campaigns_migrated', true); } } // Run migration on plugin load add_action('plugins_loaded', 'rapidtextai_migrate_to_campaigns'); // Auto Blogging settings page function rapidtextai_auto_blogging_page() { if (!current_user_can('manage_options')) { return; } // Handle campaign actions if (isset($_GET['action']) && isset($_GET['campaign_id']) && isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'rapidtextai_campaign_action')) { $campaign_id = sanitize_text_field($_GET['campaign_id']); $campaigns = get_option('rapidtextai_auto_blogging_campaigns', array()); $redirect_url = admin_url('admin.php?page=rapidtextai-auto-blogging'); switch ($_GET['action']) { case 'delete': if (isset($campaigns[$campaign_id])) { // Clear the campaign's cron job wp_clear_scheduled_hook('rapidtextai_auto_blogging_cron_' . $campaign_id); unset($campaigns[$campaign_id]); update_option('rapidtextai_auto_blogging_campaigns', $campaigns); $redirect_url = add_query_arg('message', 'deleted', $redirect_url); } break; case 'toggle': if (isset($campaigns[$campaign_id])) { $campaigns[$campaign_id]['enabled'] = !$campaigns[$campaign_id]['enabled']; update_option('rapidtextai_auto_blogging_campaigns', $campaigns); // Update cron if ($campaigns[$campaign_id]['enabled']) { rapidtextai_schedule_campaign_cron($campaign_id, $campaigns[$campaign_id]); } else { wp_clear_scheduled_hook('rapidtextai_auto_blogging_cron_' . $campaign_id); } $status = $campaigns[$campaign_id]['enabled'] ? 'enabled' : 'disabled'; $redirect_url = add_query_arg('message', $status, $redirect_url); } break; } // Redirect to prevent action from being processed again if (!headers_sent()) { wp_redirect($redirect_url); exit; } else { // Use JavaScript redirect if headers already sent echo ''; exit; } } // Display admin messages if (isset($_GET['message'])) { $message = sanitize_text_field($_GET['message']); $messages = array( 'deleted' => 'Campaign deleted successfully.', 'enabled' => 'Campaign enabled successfully.', 'disabled' => 'Campaign disabled successfully.', 'created' => 'Campaign created successfully.', 'updated' => 'Campaign updated successfully.', ); if (isset($messages[$message])) { echo '' . esc_html($messages[$message]) . '
Post generation triggered for selected campaign.
Auto blogging is currently disabled. Enable it here.
'; return; } $next_run = wp_next_scheduled('rapidtextai_auto_blogging_cron'); echo 'Status: Enabled
'; echo 'Schedule: ' . ucfirst($settings['schedule']) . '
'; echo 'Post Status: ' . ucfirst($settings['post_status']) . '
'; echo 'Next scheduled run: ' . ($next_run ? date_i18n('F j, Y, g:i a', $next_run) : 'Not scheduled') . '
'; echo ''; } // Register activation and deactivation hooks register_activation_hook(__FILE__, 'rapidtextai_activate_auto_blogging'); register_deactivation_hook(__FILE__, 'rapidtextai_deactivate_auto_blogging'); register_deactivation_hook(__FILE__, 'rapidtextai_v2_clear_all_schedules'); function rapidtextai_activate_auto_blogging() { // Run migration rapidtextai_migrate_to_campaigns(); // Schedule crons for all enabled campaigns $campaigns = get_option('rapidtextai_auto_blogging_campaigns', array()); foreach ($campaigns as $campaign_id => $campaign) { if (!empty($campaign['enabled'])) { rapidtextai_schedule_campaign_cron($campaign_id, $campaign); } } // Backward compatibility: also check old settings $old_settings = get_option('rapidtextai_auto_blogging', array()); if (!empty($old_settings) && !empty($old_settings['enabled'])) { if (!wp_next_scheduled('rapidtextai_auto_blogging_cron')) { wp_schedule_event(time(), $old_settings['schedule'], 'rapidtextai_auto_blogging_cron'); } } } function rapidtextai_deactivate_auto_blogging() { // Clear all campaign-specific cron jobs $campaigns = get_option('rapidtextai_auto_blogging_campaigns', array()); foreach ($campaigns as $campaign_id => $campaign) { wp_clear_scheduled_hook('rapidtextai_auto_blogging_cron_' . $campaign_id); } // Also clear old cron hook for backward compatibility wp_clear_scheduled_hook('rapidtextai_auto_blogging_cron'); } // Add AJAX handlers for logs functionality add_action('wp_ajax_rapidtextai_get_logs', 'rapidtextai_get_logs_callback'); add_action('wp_ajax_rapidtextai_clear_logs', 'rapidtextai_clear_logs_callback'); function rapidtextai_get_logs_callback() { ini_set('display_errors', 1); ini_set('log_errors', 1); error_reporting(E_ALL); // Verify nonce if (!isset($_GET['nonce']) || !wp_verify_nonce($_GET['nonce'], 'rapidtextai_get_logs_nonce')) { wp_send_json_error(array('message' => 'Security check failed.')); return; } // Check user permissions if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Permission denied.')); return; } $logs = rapidtextai_read_error_logs(); wp_send_json_success(array('logs' => $logs)); } // AJAX handler for getting usage data add_action('wp_ajax_rapidtextai_get_usage_data', 'rapidtextai_get_usage_data_callback'); function rapidtextai_get_usage_data_callback() { // Verify nonce if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'rapidtextai_nonce')) { wp_send_json_error(array('message' => 'Security check failed.')); return; } // Get API key $api_key = get_option('rapidtextai_api_key', ''); if (empty($api_key)) { wp_send_json_error(array('message' => 'API key not found. Please set up your RapidTextAI authentication.')); return; } // Call the usage API endpoint $api_url = 'https://app.rapidtextai.com/api?gigsixkey=' . urlencode($api_key); $response = wp_remote_get($api_url, array( 'timeout' => 30, 'sslverify' => false, )); if (is_wp_error($response)) { wp_send_json_error(array('message' => 'Error connecting to RapidTextAI: ' . $response->get_error_message())); return; } $http_code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($http_code !== 200) { wp_send_json_error(array('message' => 'API request failed with code ' . $http_code)); return; } // Decode the response $usage_data = json_decode($body, true); if (!$usage_data) { wp_send_json_error(array('message' => 'Invalid response from API')); return; } wp_send_json_success($usage_data); } function rapidtextai_clear_logs_callback() { // Verify nonce if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'rapidtextai_clear_logs_nonce')) { wp_send_json_error(array('message' => 'Security check failed.')); return; } // Check user permissions if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Permission denied.')); return; } $cleared = rapidtextai_clear_error_logs(); if ($cleared) { wp_send_json_success(array('message' => 'Logs cleared successfully.')); } else { wp_send_json_error(array('message' => 'Failed to clear logs.')); } } function rapidtextai_read_error_logs() { $logs = array(); // Get PHP error log file path $log_file = ini_get('error_log'); // If not set, try default locations if (empty($log_file) || !file_exists($log_file)) { $possible_paths = array( ABSPATH . 'wp-content/debug.log', ABSPATH . 'error_log', WP_CONTENT_DIR . '/debug.log', '/var/log/php_errors.log', '/var/log/apache2/error.log', $_SERVER['DOCUMENT_ROOT'] . '/logs/php_error.log' ); foreach ($possible_paths as $path) { if (file_exists($path)) { $log_file = $path; break; } } } if (!empty($log_file) && file_exists($log_file) && is_readable($log_file)) { // Check file size first $file_size = filesize($log_file); $max_size = 50 * 1024 * 1024; // 50MB limit if ($file_size > $max_size) { // For large files, read from the end $handle = fopen($log_file, 'r'); if ($handle) { // Seek to near the end of file fseek($handle, max(0, $file_size - $max_size)); // Skip the first incomplete line fgets($handle); while (($line = fgets($handle)) !== false) { if (strpos($line, 'RapidTextAI:') !== false) { $log_entry = rapidtextai_parse_log_line($line); if ($log_entry) { $logs[] = $log_entry; } } } fclose($handle); } } else { // For smaller files, use the original method $file_content = file_get_contents($log_file); $lines = explode("\n", $file_content); foreach ($lines as $line) { if (strpos($line, 'RapidTextAI:') !== false) { $log_entry = rapidtextai_parse_log_line($line); if ($log_entry) { $logs[] = $log_entry; } } } } // Reverse to show newest first $logs = array_reverse($logs); // Limit to last 100 entries $logs = array_slice($logs, 0, 100); } return $logs; } function rapidtextai_parse_log_line($line) { // Parse typical PHP error log format: [timestamp] message $pattern = '/^\[([^\]]+)\].*?RapidTextAI:\s*(.+)$/'; if (preg_match($pattern, $line, $matches)) { $timestamp = $matches[1]; $message = trim($matches[2]); // Determine log level based on message content $level = 'info'; if (stripos($message, 'error') !== false || stripos($message, 'failed') !== false) { $level = 'error'; } elseif (stripos($message, 'warning') !== false || stripos($message, 'warn') !== false) { $level = 'warning'; } elseif (stripos($message, 'success') !== false) { $level = 'success'; } return array( 'timestamp' => $timestamp, 'message' => $message, 'level' => $level ); } return null; } function rapidtextai_clear_error_logs() { // Get PHP error log file path $log_file = ini_get('error_log'); // If not set, try default locations if (empty($log_file) || !file_exists($log_file)) { $possible_paths = array( ABSPATH . 'wp-content/debug.log', ABSPATH . 'error_log', WP_CONTENT_DIR . '/debug.log' ); foreach ($possible_paths as $path) { if (file_exists($path)) { $log_file = $path; break; } } } if (!empty($log_file) && file_exists($log_file) && is_writable($log_file)) { // Read current log content $content = file_get_contents($log_file); $lines = explode("\n", $content); // Filter out RapidTextAI logs $filtered_lines = array(); foreach ($lines as $line) { if (strpos($line, 'RapidTextAI:') === false) { $filtered_lines[] = $line; } } // Write back the filtered content $filtered_content = implode("\n", $filtered_lines); return file_put_contents($log_file, $filtered_content) !== false; } return false; } /** * Deactivation Feedback — asks user for reason when deactivating the plugin. */ add_action('admin_enqueue_scripts', 'rapidtextai_enqueue_deactivate_feedback'); function rapidtextai_enqueue_deactivate_feedback($hook) { if ($hook !== 'plugins.php') return; wp_enqueue_style( 'rapidtextai-deactivate-feedback', RAPIDTEXTAI_PLUGIN_URL . 'assets/css/deactivate-feedback.css', array(), '4.2.0' ); wp_enqueue_script( 'rapidtextai-deactivate-feedback', RAPIDTEXTAI_PLUGIN_URL . 'assets/js/deactivate-feedback.js', array('jquery'), '4.2.0', true ); wp_localize_script('rapidtextai-deactivate-feedback', 'rapidtextai_deactivate', array( 'ajaxurl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('rapidtextai_deactivate_feedback'), )); } add_action('wp_ajax_rapidtextai_deactivate_feedback', 'rapidtextai_deactivate_feedback_handler'); function rapidtextai_deactivate_feedback_handler() { if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'rapidtextai_deactivate_feedback')) { wp_send_json_error(array('message' => 'Security check failed.')); } $reason = isset($_POST['reason']) ? sanitize_text_field($_POST['reason']) : 'unspecified'; $user_message = isset($_POST['user_message']) ? sanitize_textarea_field($_POST['user_message']) : $reason; $api_key = get_option('rapidtextai_api_key', ''); if (empty($api_key)) { $api_key = '0'; } $report_url = 'https://app.rapidtextai.com/api'; $report_url = add_query_arg(array( 'gigsixkey' => urlencode($api_key), 'action' => 'report', 'message' => urlencode('[Plugin Deactivation] Reason: ' . $reason), 'user_message' => urlencode($user_message), ), $report_url); $response = wp_remote_get($report_url, array( 'timeout' => 10, 'sslverify' => false, )); if (is_wp_error($response)) { wp_send_json_success(array('message' => 'Feedback recorded locally (API unreachable).')); } wp_send_json_success(array('message' => 'Feedback sent. Thank you!')); }