logging system
This commit is contained in:
@@ -81,6 +81,7 @@ class Igny8Bridge {
|
||||
private function load_dependencies() {
|
||||
// Core classes
|
||||
require_once IGNY8_BRIDGE_PLUGIN_DIR . 'includes/functions.php';
|
||||
require_once IGNY8_BRIDGE_PLUGIN_DIR . 'includes/class-igny8-logger.php'; // Load logger first
|
||||
require_once IGNY8_BRIDGE_PLUGIN_DIR . 'includes/class-igny8-api.php';
|
||||
require_once IGNY8_BRIDGE_PLUGIN_DIR . 'includes/class-igny8-site.php';
|
||||
require_once IGNY8_BRIDGE_PLUGIN_DIR . 'includes/class-igny8-rest-api.php';
|
||||
|
||||
@@ -114,6 +114,15 @@ class Igny8API {
|
||||
return !empty($this->access_token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API base URL
|
||||
*
|
||||
* @return string API base URL
|
||||
*/
|
||||
public function get_api_base() {
|
||||
return $this->base_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse unified API response
|
||||
*
|
||||
|
||||
221
igny8-wp-plugin/includes/class-igny8-logger.php
Normal file
221
igny8-wp-plugin/includes/class-igny8-logger.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* IGNY8 File Logger
|
||||
*
|
||||
* Provides file-based logging for all publish/sync workflows
|
||||
*
|
||||
* @package IGNY8_Bridge
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class Igny8_Logger {
|
||||
|
||||
/**
|
||||
* Log directory path
|
||||
*/
|
||||
private static $log_dir = null;
|
||||
|
||||
/**
|
||||
* Initialize logger
|
||||
*/
|
||||
public static function init() {
|
||||
// Set log directory to plugin root/logs/publish-sync-logs
|
||||
self::$log_dir = dirname(dirname(__FILE__)) . '/logs/publish-sync-logs';
|
||||
|
||||
// Create directory if it doesn't exist
|
||||
if (!file_exists(self::$log_dir)) {
|
||||
wp_mkdir_p(self::$log_dir);
|
||||
}
|
||||
|
||||
// Ensure directory is writable
|
||||
if (!is_writable(self::$log_dir)) {
|
||||
@chmod(self::$log_dir, 0755);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write log message to file
|
||||
*
|
||||
* @param string $message Log message
|
||||
* @param string $level Log level (INFO, WARNING, ERROR)
|
||||
* @param string $log_file Log file name (without .log extension)
|
||||
*/
|
||||
public static function log($message, $level = 'INFO', $log_file = 'publish-sync') {
|
||||
if (self::$log_dir === null) {
|
||||
self::init();
|
||||
}
|
||||
|
||||
$timestamp = current_time('Y-m-d H:i:s');
|
||||
$formatted_message = "[{$timestamp}] [{$level}] {$message}\n";
|
||||
|
||||
$file_path = self::$log_dir . '/' . $log_file . '.log';
|
||||
|
||||
// Append to log file
|
||||
error_log($formatted_message, 3, $file_path);
|
||||
|
||||
// Also log to WordPress debug.log if WP_DEBUG is enabled
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log("[IGNY8] [{$level}] {$message}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log info message
|
||||
*/
|
||||
public static function info($message, $log_file = 'publish-sync') {
|
||||
self::log($message, 'INFO', $log_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log warning message
|
||||
*/
|
||||
public static function warning($message, $log_file = 'publish-sync') {
|
||||
self::log($message, 'WARNING', $log_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log error message
|
||||
*/
|
||||
public static function error($message, $log_file = 'publish-sync') {
|
||||
self::log($message, 'ERROR', $log_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log API request
|
||||
*/
|
||||
public static function api_request($method, $endpoint, $data = null) {
|
||||
$message = "API REQUEST: {$method} {$endpoint}";
|
||||
if ($data) {
|
||||
$message .= "\n Data: " . json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
self::log($message, 'INFO', 'wordpress-api');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log API response
|
||||
*/
|
||||
public static function api_response($status_code, $body) {
|
||||
$message = "API RESPONSE: HTTP {$status_code}";
|
||||
if ($body) {
|
||||
$body_str = is_string($body) ? $body : json_encode($body, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
$message .= "\n Body: " . substr($body_str, 0, 500);
|
||||
}
|
||||
self::log($message, 'INFO', 'wordpress-api');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log API error
|
||||
*/
|
||||
public static function api_error($error_message) {
|
||||
self::log("API ERROR: {$error_message}", 'ERROR', 'wordpress-api');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log webhook event
|
||||
*/
|
||||
public static function webhook($event_type, $data) {
|
||||
$message = "WEBHOOK EVENT: {$event_type}";
|
||||
if ($data) {
|
||||
$message .= "\n Data: " . json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
self::log($message, 'INFO', 'webhooks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log workflow separator
|
||||
*/
|
||||
public static function separator($title = '') {
|
||||
$line = str_repeat('=', 80);
|
||||
self::log($line);
|
||||
if ($title) {
|
||||
self::log($title);
|
||||
self::log($line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log file contents
|
||||
*
|
||||
* @param string $log_file Log file name
|
||||
* @param int $lines Number of lines to read (default 100, 0 for all)
|
||||
* @return string Log contents
|
||||
*/
|
||||
public static function get_log_contents($log_file = 'publish-sync', $lines = 100) {
|
||||
if (self::$log_dir === null) {
|
||||
self::init();
|
||||
}
|
||||
|
||||
$file_path = self::$log_dir . '/' . $log_file . '.log';
|
||||
|
||||
if (!file_exists($file_path)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($lines === 0) {
|
||||
return file_get_contents($file_path);
|
||||
}
|
||||
|
||||
// Read last N lines efficiently
|
||||
$file = new SplFileObject($file_path, 'r');
|
||||
$file->seek(PHP_INT_MAX);
|
||||
$total_lines = $file->key() + 1;
|
||||
|
||||
$start_line = max(0, $total_lines - $lines);
|
||||
$file->seek($start_line);
|
||||
|
||||
$content = '';
|
||||
while (!$file->eof()) {
|
||||
$content .= $file->fgets();
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear log file
|
||||
*/
|
||||
public static function clear_log($log_file = 'publish-sync') {
|
||||
if (self::$log_dir === null) {
|
||||
self::init();
|
||||
}
|
||||
|
||||
$file_path = self::$log_dir . '/' . $log_file . '.log';
|
||||
|
||||
if (file_exists($file_path)) {
|
||||
@unlink($file_path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all log files
|
||||
*/
|
||||
public static function get_log_files() {
|
||||
if (self::$log_dir === null) {
|
||||
self::init();
|
||||
}
|
||||
|
||||
if (!is_dir(self::$log_dir)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$files = glob(self::$log_dir . '/*.log');
|
||||
$log_files = array();
|
||||
|
||||
foreach ($files as $file) {
|
||||
$log_files[] = array(
|
||||
'name' => basename($file, '.log'),
|
||||
'path' => $file,
|
||||
'size' => filesize($file),
|
||||
'modified' => filemtime($file),
|
||||
);
|
||||
}
|
||||
|
||||
return $log_files;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize logger
|
||||
Igny8_Logger::init();
|
||||
@@ -71,19 +71,28 @@ function igny8_cache_task_brief($task_id, $post_id, $api = null) {
|
||||
* @return int|WP_Error WordPress post ID or error
|
||||
*/
|
||||
function igny8_create_wordpress_post_from_task($content_data, $allowed_post_types = array()) {
|
||||
error_log('========== IGNY8 CREATE WP POST ==========');
|
||||
error_log('Content ID: ' . (isset($content_data['content_id']) ? $content_data['content_id'] : 'N/A'));
|
||||
error_log('Task ID: ' . (isset($content_data['task_id']) ? $content_data['task_id'] : 'N/A'));
|
||||
error_log('Title: ' . (isset($content_data['title']) ? $content_data['title'] : 'N/A'));
|
||||
// Get site information for logging
|
||||
$site_id = get_option('igny8_site_id', 'unknown');
|
||||
$site_domain = parse_url(home_url(), PHP_URL_HOST);
|
||||
$log_prefix = "[{$site_id}-{$site_domain}]";
|
||||
|
||||
Igny8_Logger::separator("{$log_prefix} 🎯 CREATE WORDPRESS POST FROM IGNY8");
|
||||
Igny8_Logger::info("{$log_prefix} Content ID: " . ($content_data['content_id'] ?? 'N/A'));
|
||||
Igny8_Logger::info("{$log_prefix} Task ID: " . ($content_data['task_id'] ?? 'N/A'));
|
||||
Igny8_Logger::info("{$log_prefix} Title: " . ($content_data['title'] ?? 'N/A'));
|
||||
Igny8_Logger::separator();
|
||||
|
||||
$api = new Igny8API();
|
||||
|
||||
if (!$api->is_authenticated()) {
|
||||
error_log('IGNY8: NOT AUTHENTICATED - Aborting post creation');
|
||||
Igny8_Logger::error("{$log_prefix} ❌ NOT AUTHENTICATED - Aborting post creation");
|
||||
return new WP_Error('igny8_not_authenticated', 'IGNY8 API not authenticated');
|
||||
}
|
||||
|
||||
Igny8_Logger::info("{$log_prefix} ✅ API authenticated");
|
||||
|
||||
$post_type = igny8_resolve_post_type_for_task($content_data);
|
||||
Igny8_Logger::info("{$log_prefix} STEP 1: Resolved post type: {$post_type}");
|
||||
|
||||
if (!empty($allowed_post_types) && !in_array($post_type, $allowed_post_types, true)) {
|
||||
return new WP_Error('igny8_post_type_disabled', sprintf('Post type %s is disabled for automation', $post_type));
|
||||
@@ -204,80 +213,80 @@ function igny8_create_wordpress_post_from_task($content_data, $allowed_post_type
|
||||
|
||||
// Handle categories
|
||||
if (!empty($content_data['categories'])) {
|
||||
error_log('IGNY8: Processing ' . count($content_data['categories']) . ' categories');
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Processing " . count($content_data['categories']) . " categories");
|
||||
$category_ids = igny8_process_categories($content_data['categories'], $post_id);
|
||||
if (!empty($category_ids)) {
|
||||
wp_set_post_terms($post_id, $category_ids, 'category');
|
||||
error_log('IGNY8: ✅ Assigned ' . count($category_ids) . ' categories to post ' . $post_id);
|
||||
Igny8_Logger::info("{$log_prefix} ✅ Assigned " . count($category_ids) . " categories to post {$post_id}");
|
||||
} else {
|
||||
error_log('IGNY8: ⚠️ No category IDs returned from processing');
|
||||
Igny8_Logger::warning("{$log_prefix} ⚠️ No category IDs returned from processing");
|
||||
}
|
||||
} else {
|
||||
error_log('IGNY8: ⚠️ No categories in content_data');
|
||||
Igny8_Logger::warning("{$log_prefix} ⚠️ No categories in content_data");
|
||||
}
|
||||
|
||||
// Handle tags
|
||||
if (!empty($content_data['tags'])) {
|
||||
error_log('IGNY8: Processing ' . count($content_data['tags']) . ' tags');
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Processing " . count($content_data['tags']) . " tags");
|
||||
$tag_ids = igny8_process_tags($content_data['tags'], $post_id);
|
||||
if (!empty($tag_ids)) {
|
||||
wp_set_post_terms($post_id, $tag_ids, 'post_tag');
|
||||
error_log('IGNY8: ✅ Assigned ' . count($tag_ids) . ' tags to post ' . $post_id);
|
||||
Igny8_Logger::info("{$log_prefix} ✅ Assigned " . count($tag_ids) . " tags to post {$post_id}");
|
||||
} else {
|
||||
error_log('IGNY8: ⚠️ No tag IDs returned from processing');
|
||||
Igny8_Logger::warning("{$log_prefix} ⚠️ No tag IDs returned from processing");
|
||||
}
|
||||
} else {
|
||||
error_log('IGNY8: ⚠️ No tags in content_data');
|
||||
Igny8_Logger::warning("{$log_prefix} ⚠️ No tags in content_data");
|
||||
}
|
||||
|
||||
// Handle featured image
|
||||
if (!empty($content_data['featured_image'])) {
|
||||
error_log('IGNY8: Setting featured image from featured_image field');
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Setting featured image from featured_image field");
|
||||
igny8_set_featured_image($post_id, $content_data['featured_image']);
|
||||
} elseif (!empty($content_data['featured_image_url'])) {
|
||||
error_log('IGNY8: Setting featured image from featured_image_url field: ' . $content_data['featured_image_url']);
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Setting featured image from URL: " . $content_data['featured_image_url']);
|
||||
igny8_set_featured_image($post_id, $content_data['featured_image_url']);
|
||||
} else {
|
||||
error_log('IGNY8: ⚠️ No featured image in content_data');
|
||||
Igny8_Logger::warning("{$log_prefix} ⚠️ No featured image in content_data");
|
||||
}
|
||||
// Handle meta title and meta description (SEO)
|
||||
if (!empty($content_data['meta_title'])) {
|
||||
error_log('IGNY8: Setting SEO meta title: ' . $content_data['meta_title']);
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Setting SEO meta title: " . $content_data['meta_title']);
|
||||
update_post_meta($post_id, '_yoast_wpseo_title', $content_data['meta_title']);
|
||||
update_post_meta($post_id, '_seopress_titles_title', $content_data['meta_title']);
|
||||
update_post_meta($post_id, '_aioseo_title', $content_data['meta_title']);
|
||||
// Generic meta
|
||||
update_post_meta($post_id, '_igny8_meta_title', $content_data['meta_title']);
|
||||
} elseif (!empty($content_data['seo_title'])) {
|
||||
error_log('IGNY8: Setting SEO meta title from seo_title: ' . $content_data['seo_title']);
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Setting SEO meta title from seo_title: " . $content_data['seo_title']);
|
||||
update_post_meta($post_id, '_yoast_wpseo_title', $content_data['seo_title']);
|
||||
update_post_meta($post_id, '_seopress_titles_title', $content_data['seo_title']);
|
||||
update_post_meta($post_id, '_aioseo_title', $content_data['seo_title']);
|
||||
update_post_meta($post_id, '_igny8_meta_title', $content_data['seo_title']);
|
||||
} else {
|
||||
error_log('IGNY8: ⚠️ No SEO title in content_data');
|
||||
Igny8_Logger::warning("{$log_prefix} ⚠️ No SEO title in content_data");
|
||||
}
|
||||
|
||||
if (!empty($content_data['meta_description'])) {
|
||||
error_log('IGNY8: Setting SEO meta description');
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Setting SEO meta description");
|
||||
update_post_meta($post_id, '_yoast_wpseo_metadesc', $content_data['meta_description']);
|
||||
update_post_meta($post_id, '_seopress_titles_desc', $content_data['meta_description']);
|
||||
update_post_meta($post_id, '_aioseo_description', $content_data['meta_description']);
|
||||
// Generic meta
|
||||
update_post_meta($post_id, '_igny8_meta_description', $content_data['meta_description']);
|
||||
} elseif (!empty($content_data['seo_description'])) {
|
||||
error_log('IGNY8: Setting SEO meta description from seo_description');
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Setting SEO meta description from seo_description");
|
||||
update_post_meta($post_id, '_yoast_wpseo_metadesc', $content_data['seo_description']);
|
||||
update_post_meta($post_id, '_seopress_titles_desc', $content_data['seo_description']);
|
||||
update_post_meta($post_id, '_aioseo_description', $content_data['seo_description']);
|
||||
update_post_meta($post_id, '_igny8_meta_description', $content_data['seo_description']);
|
||||
} else {
|
||||
error_log('IGNY8: ⚠️ No SEO description in content_data');
|
||||
Igny8_Logger::warning("{$log_prefix} ⚠️ No SEO description in content_data");
|
||||
}
|
||||
|
||||
// Handle gallery images
|
||||
if (!empty($content_data['gallery_images'])) {
|
||||
error_log('IGNY8: Setting gallery with ' . count($content_data['gallery_images']) . ' images');
|
||||
Igny8_Logger::info("{$log_prefix} STEP: Setting gallery with " . count($content_data['gallery_images']) . " images");
|
||||
igny8_set_gallery_images($post_id, $content_data['gallery_images']);
|
||||
}
|
||||
|
||||
@@ -311,9 +320,9 @@ function igny8_create_wordpress_post_from_task($content_data, $allowed_post_type
|
||||
$response = $api->put("/writer/tasks/{$content_data['task_id']}/", $update_data);
|
||||
|
||||
if ($response['success']) {
|
||||
error_log("IGNY8: Updated task {$content_data['task_id']} with WordPress post {$post_id} (status: {$wp_status})");
|
||||
Igny8_Logger::info("{$log_prefix} ✅ Updated IGNY8 task {$content_data['task_id']} with WordPress post {$post_id} (status: {$wp_status})");
|
||||
} else {
|
||||
error_log("IGNY8: Failed to update task: " . ($response['error'] ?? 'Unknown error'));
|
||||
Igny8_Logger::error("{$log_prefix} ❌ Failed to update IGNY8 task: " . ($response['error'] ?? 'Unknown error'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,6 +334,12 @@ function igny8_create_wordpress_post_from_task($content_data, $allowed_post_type
|
||||
// Send status webhook to IGNY8
|
||||
igny8_send_status_webhook($post_id, $content_data, $wp_status);
|
||||
|
||||
Igny8_Logger::separator("{$log_prefix} 🎉 POST CREATION COMPLETED SUCCESSFULLY");
|
||||
Igny8_Logger::info("{$log_prefix} WordPress Post ID: {$post_id}");
|
||||
Igny8_Logger::info("{$log_prefix} Post URL: " . get_permalink($post_id));
|
||||
Igny8_Logger::info("{$log_prefix} Post Status: {$wp_status}");
|
||||
Igny8_Logger::separator();
|
||||
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user