feat: consolidate docs, backend/session infra, and settings updates
This commit is contained in:
@@ -43,6 +43,41 @@ class WP_Agentic_Writer_Image_Manager {
|
||||
// Private constructor for singleton.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if required tables exist.
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @return bool True if tables exist, false otherwise.
|
||||
*/
|
||||
public function tables_exist() {
|
||||
global $wpdb;
|
||||
$table_images = $wpdb->prefix . 'wpaw_images';
|
||||
|
||||
// Check if table exists using SHOW TABLES
|
||||
$result = $wpdb->get_var( "SHOW TABLES LIKE '{$table_images}'" );
|
||||
|
||||
return $result === $table_images;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure tables exist, create if missing.
|
||||
*
|
||||
* @since 0.1.0
|
||||
* @return true|WP_Error True on success, WP_Error on failure.
|
||||
*/
|
||||
public function ensure_tables() {
|
||||
if ( ! $this->tables_exist() ) {
|
||||
$result = $this->create_tables();
|
||||
if ( ! $result ) {
|
||||
return new WP_Error(
|
||||
'table_creation_failed',
|
||||
__( 'Failed to create image database tables. Please check database permissions.', 'wp-agentic-writer' )
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create database tables on plugin activation.
|
||||
*/
|
||||
@@ -110,6 +145,8 @@ class WP_Agentic_Writer_Image_Manager {
|
||||
|
||||
// Create temp directory.
|
||||
$this->create_temp_directory();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +182,7 @@ class WP_Agentic_Writer_Image_Manager {
|
||||
*/
|
||||
public function analyze_article_for_images( $article_markdown, $post_id ) {
|
||||
$settings = get_option( 'wp_agentic_writer_settings', array() );
|
||||
$writing_model = $settings['writing_model'] ?? 'anthropic/claude-3.5-sonnet';
|
||||
$writing_model = $settings['writing_model'] ?? WPAW_Model_Registry::get_default_model( 'writing' );
|
||||
|
||||
$system_prompt = "You are an expert content strategist analyzing articles for optimal image placement.
|
||||
|
||||
@@ -178,7 +215,8 @@ Return JSON:
|
||||
),
|
||||
);
|
||||
|
||||
$provider = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( 'planning' );
|
||||
$provider_result = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( 'planning' );
|
||||
$provider = $provider_result->provider;
|
||||
$response = $provider->chat( $messages, array( 'temperature' => 0.3 ), 'planning' );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
@@ -207,8 +245,8 @@ Return JSON:
|
||||
*/
|
||||
public function generate_image_prompts( $article_markdown, $placement_data, $post_id ) {
|
||||
$settings = get_option( 'wp_agentic_writer_settings', array() );
|
||||
$writing_model = $settings['writing_model'] ?? 'anthropic/claude-3.5-sonnet';
|
||||
$image_model = $settings['image_model'] ?? 'openai/gpt-4o';
|
||||
$writing_model = $settings['writing_model'] ?? WPAW_Model_Registry::get_default_model( 'writing' );
|
||||
$image_model = $settings['image_model'] ?? WPAW_Model_Registry::get_default_model( 'image' );
|
||||
|
||||
// Get model-specific prompt guidance.
|
||||
$prompt_guidance = $this->get_prompt_guidance_for_model( $image_model );
|
||||
@@ -255,7 +293,8 @@ Return JSON:
|
||||
),
|
||||
);
|
||||
|
||||
$provider = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( 'planning' );
|
||||
$provider_result = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( 'planning' );
|
||||
$provider = $provider_result->provider;
|
||||
$response = $provider->chat( $messages, array( 'temperature' => 0.7 ), 'planning' );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
@@ -318,6 +357,13 @@ Return JSON:
|
||||
* @param array $images Image specifications.
|
||||
*/
|
||||
private function save_image_recommendations( $post_id, $images ) {
|
||||
// Ensure tables exist before saving
|
||||
$check = $this->ensure_tables();
|
||||
if ( is_wp_error( $check ) ) {
|
||||
error_log( 'WPAW Image Manager: Cannot save recommendations - tables not available' );
|
||||
return;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'wpaw_images';
|
||||
|
||||
@@ -348,14 +394,20 @@ Return JSON:
|
||||
* @param string $section_title Section title.
|
||||
* @param string $prompt Image prompt/description.
|
||||
* @param string $alt_text Alt text for image.
|
||||
* @return int|false Insert ID or false on failure.
|
||||
* @return int|false|WP_Error Insert ID, false on failure, or WP_Error if tables don't exist.
|
||||
*/
|
||||
public function save_image_recommendation( $post_id, $agent_image_id, $placement, $section_title, $prompt, $alt_text ) {
|
||||
// Ensure tables exist before saving
|
||||
$check = $this->ensure_tables();
|
||||
if ( is_wp_error( $check ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'wpaw_images';
|
||||
|
||||
$settings = get_option( 'wp_agentic_writer_settings', array() );
|
||||
$image_model = $settings['image_model'] ?? 'openai/gpt-4o';
|
||||
$image_model = $settings['image_model'] ?? WPAW_Model_Registry::get_default_model( 'image' );
|
||||
|
||||
$result = $wpdb->insert(
|
||||
$table,
|
||||
@@ -383,9 +435,15 @@ Return JSON:
|
||||
* Get image recommendations for a post.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return array Image recommendations.
|
||||
* @return array|WP_Error Image recommendations or error if tables don't exist.
|
||||
*/
|
||||
public function get_image_recommendations( $post_id ) {
|
||||
// Ensure tables exist before querying
|
||||
$check = $this->ensure_tables();
|
||||
if ( is_wp_error( $check ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$table = $wpdb->prefix . 'wpaw_images';
|
||||
|
||||
@@ -410,10 +468,17 @@ Return JSON:
|
||||
* @return array|WP_Error Generated variants or error.
|
||||
*/
|
||||
public function generate_image_variants( $post_id, $agent_image_id, $prompt, $variant_count = 2 ) {
|
||||
$settings = get_option( 'wp_agentic_writer_settings', array() );
|
||||
$image_model = $settings['image_model'] ?? 'openai/gpt-4o';
|
||||
// Ensure tables exist before proceeding
|
||||
$check = $this->ensure_tables();
|
||||
if ( is_wp_error( $check ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
$provider = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( 'image' );
|
||||
$settings = get_option( 'wp_agentic_writer_settings', array() );
|
||||
$image_model = $settings['image_model'] ?? WPAW_Model_Registry::get_default_model( 'image' );
|
||||
|
||||
$provider_result = WP_Agentic_Writer_Provider_Manager::get_provider_for_task( 'image' );
|
||||
$provider = $provider_result->provider;
|
||||
|
||||
$variants = array();
|
||||
|
||||
@@ -480,20 +545,36 @@ Return JSON:
|
||||
wp_mkdir_p( $temp_dir );
|
||||
}
|
||||
|
||||
// Download image.
|
||||
$response = wp_remote_get( $image_url, array( 'timeout' => 30 ) );
|
||||
$image_data = '';
|
||||
$extension = 'jpg';
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
if ( preg_match( '#^data:image/([a-zA-Z0-9.+-]+);base64,(.+)$#', (string) $image_url, $matches ) ) {
|
||||
$extension = strtolower( $matches[1] );
|
||||
$extension = 'jpeg' === $extension ? 'jpg' : $extension;
|
||||
$image_data = base64_decode( $matches[2] );
|
||||
if ( false === $image_data ) {
|
||||
return new WP_Error(
|
||||
'invalid_image_data',
|
||||
__( 'Generated image data could not be decoded.', 'wp-agentic-writer' )
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Download image.
|
||||
$response = wp_remote_get( $image_url, array( 'timeout' => 30 ) );
|
||||
|
||||
$image_data = wp_remote_retrieve_body( $response );
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// Determine file extension from content type.
|
||||
$content_type = wp_remote_retrieve_header( $response, 'content-type' );
|
||||
$extension = 'jpg';
|
||||
if ( strpos( $content_type, 'png' ) !== false ) {
|
||||
$extension = 'png';
|
||||
$image_data = wp_remote_retrieve_body( $response );
|
||||
|
||||
// Determine file extension from content type.
|
||||
$content_type = wp_remote_retrieve_header( $response, 'content-type' );
|
||||
if ( strpos( $content_type, 'png' ) !== false ) {
|
||||
$extension = 'png';
|
||||
} elseif ( strpos( $content_type, 'webp' ) !== false ) {
|
||||
$extension = 'webp';
|
||||
}
|
||||
}
|
||||
|
||||
$filename = sprintf(
|
||||
@@ -591,19 +672,37 @@ Return JSON:
|
||||
return new WP_Error( 'variant_not_found', 'Variant not found' );
|
||||
}
|
||||
|
||||
if ( empty( $variant['temp_file_path'] ) || ! file_exists( $variant['temp_file_path'] ) ) {
|
||||
return new WP_Error(
|
||||
'variant_file_missing',
|
||||
__( 'Generated image file is missing. Please generate the variant again.', 'wp-agentic-writer' )
|
||||
);
|
||||
}
|
||||
|
||||
// Upload to Media Library.
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
|
||||
$sideload_tmp = wp_tempnam( basename( $variant['temp_file_path'] ) );
|
||||
if ( ! $sideload_tmp || ! copy( $variant['temp_file_path'], $sideload_tmp ) ) {
|
||||
return new WP_Error(
|
||||
'variant_copy_failed',
|
||||
__( 'Generated image could not be prepared for upload.', 'wp-agentic-writer' )
|
||||
);
|
||||
}
|
||||
|
||||
$file_array = array(
|
||||
'name' => basename( $variant['temp_file_path'] ),
|
||||
'tmp_name' => $variant['temp_file_path'],
|
||||
'tmp_name' => $sideload_tmp,
|
||||
);
|
||||
|
||||
$attachment_id = media_handle_sideload( $file_array, $post_id );
|
||||
|
||||
if ( is_wp_error( $attachment_id ) ) {
|
||||
if ( file_exists( $sideload_tmp ) ) {
|
||||
@unlink( $sideload_tmp );
|
||||
}
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user