WordPress Publish Handler

Creates posts in the local WordPress installation using a modular handler architecture with specialized processing components for featured images, taxonomies, and source URLs.

Architecture

Base Class: Extends PublishHandler (@since v0.2.1)

Inherited Functionality:

  • Engine data retrieval via getSourceUrl() and getImageFilePath()
  • Image validation via validateImage() with comprehensive error checking
  • Standardized responses via successResponse() and errorResponse()
  • Centralized logging and error handling

Implementation: Tool-first architecture via handle_tool_call() method for AI agents

Handler Components

Main Handler (WordPress.php):

  • Extends PublishHandler base class
  • Implements executePublish() method for WordPress-specific logic
  • Coordinates specialized component processing
  • Uses configuration hierarchy (system defaults override handler settings)

Specialized Components:

  • WordPressPublishHelper: Platform-specific publishing operations (featured images, source attribution)
  • TaxonomyHandler: Dynamic taxonomy assignment with configuration-based selection
  • WordPressSettingsResolver: Configuration resolution with system defaults override

Featured Image Processing (@since v0.2.7)

Implementation: WordPressPublishHelper::attachImageToPost() static method

Purpose: Attaches images from Files Repository to WordPress posts as featured images with media library integration.

Configuration

Configuration checked via include_images setting:

// WordPressPublishHelper checks configuration
$attachment_id = WordPressPublishHelper::attachImageToPost($post_id, $image_path, $config);

Features

Image Processing:

  • File path validation with file_exists()
  • Image type validation with wp_check_filetype()
  • Media library integration with media_handle_sideload()
  • Featured image assignment with set_post_thumbnail()

Error Handling:

  • Missing file detection
  • Invalid image type rejection
  • Attachment creation error handling
  • Temporary file cleanup
  • Comprehensive logging throughout process

Usage Example:

use DataMachineCoreEngineData;
use DataMachineCoreWordPressWordPressPublishHelper;

// Get image path from EngineData
$engine = new EngineData($engine_data, $job_id);
$image_path = $engine->getImagePath();

// Attach image using helper
$attachment_id = WordPressPublishHelper::attachImageToPost($post_id, $image_path, $config);

// Returns: attachment ID (int) or null on failure

TaxonomyHandler

Purpose: Configuration-based taxonomy processing with AI-decided and pre-selected term assignment.

Three Selection Modes

Per Taxonomy Configuration:

  1. 'skip': No processing for this taxonomy
  2. 'ai_decides': Use AI-provided parameters for dynamic assignment
  3. Term name or slug: Pre-selected term assignment (resolved to ID automatically)

Configuration Format

// Handler configuration per taxonomy
$handler_config = [
    'taxonomy_category_selection' => 'ai_decides',        // AI decides categories
    'taxonomy_post_tag_selection' => 'skip',              // Skip tags processing
    'taxonomy_custom_tax_selection' => 'Technology'       // Pre-selected by term name
];

Note: Pre-selected values accept term name, slug, or numeric ID. The backend resolves names/slugs to term IDs automatically.

AI Parameter Mapping

Standard Parameter Names:

  • category → ‘category’ taxonomy
  • tags → ‘post_tag’ taxonomy
  • Custom taxonomy name → corresponding taxonomy

Features

Dynamic Term Creation:

  • Checks term existence with get_term_by()
  • Creates missing terms with wp_insert_term()
  • Assigns terms with wp_set_object_terms()

Taxonomy Discovery:

  • Uses get_taxonomies(['public' => true], 'objects')
  • Excludes system taxonomies: post_format, nav_menu, link_category

Validation:

  • Taxonomy existence verification with taxonomy_exists()
  • Term validation and error handling
  • Comprehensive result tracking per taxonomy

Usage Example:

$taxonomy_handler = new TaxonomyHandler();
$results = $taxonomy_handler->processTaxonomies($post_id, $parameters, $handler_config);

// AI-provided parameters
$parameters = [
    'category' => 'Technology',
    'tags' => ['AI', 'Machine Learning'],
    'custom_taxonomy' => 'Custom Term'
];

// Result structure
[
    'category' => [
        'success' => true,
        'taxonomy' => 'category',
        'term_count' => 1,
        'terms' => ['Technology']
    ],
    'post_tag' => [
        'success' => true,
        'taxonomy' => 'post_tag',
        'term_count' => 2,
        'terms' => ['AI', 'Machine Learning']
    ]
]

Source URL Attribution (@since v0.2.7)

Implementation: WordPressPublishHelper::applySourceAttribution() static method

Purpose: Appends source URLs to content with automatic Gutenberg block generation or plain text formatting.

Engine Data Source: source_url retrieved from fetch handlers via datamachine_engine_data filter

Configuration

Configuration checked via link_handling setting:

// WordPressPublishHelper checks configuration
$content = WordPressPublishHelper::applySourceAttribution($content, $source_url, $config);

Features

Source Processing:

  • URL validation with filter_var($url, FILTER_VALIDATE_URL)
  • URL sanitization with esc_url()
  • Automatic content type detection with has_blocks()
  • Gutenberg block generation for block content
  • Plain text formatting for classic content

Block Generation (for Gutenberg content):

// Generated Gutenberg blocks
"<!-- wp:separator --><hr class="wp-block-separator has-alpha-channel-opacity"/><!-- /wp:separator -->

<!-- wp:paragraph --><p>Source: <a href="{sanitized_url}">{sanitized_url}</a></p><!-- /wp:paragraph -->"

Plain Text Format (for classic content):

"nnSource: {sanitized_url}"

Usage Example:

use DataMachineCoreEngineData;
use DataMachineCoreWordPressWordPressPublishHelper;

// Get source URL from EngineData
$engine = new EngineData($engine_data, $job_id);
$source_url = $engine->getSourceUrl();

// Apply source attribution using helper
$content = WordPressPublishHelper::applySourceAttribution($content, $source_url, $config);

// Returns: modified content with source attribution (if configured)

Main Handler Integration

Tool Call Workflow (@since v0.2.7)

The WordPress handler extends PublishHandler and implements the executePublish() method:

use DataMachineCoreEngineData;
use DataMachineCoreWordPressWordPressPublishHelper;
use DataMachineCoreWordPressTaxonomyHandler;
use DataMachineCoreWordPressWordPressSettingsResolver;

class WordPress extends PublishHandler {
    private $taxonomy_handler;

    public function __construct() {
        parent::__construct('wordpress');
        $this->taxonomy_handler = new TaxonomyHandler();
    }

    protected function executePublish(array $parameters, array $handler_config): array {
        // 1. Validate required parameters
        if (empty($parameters['title']) || empty($parameters['content'])) {
            return $this->errorResponse('Missing required parameters');
        }

        // 2. Create EngineData instance for data access
        $job_id = $parameters['job_id'] ?? null;
        $engine = new EngineData($parameters['engine_data'] ?? [], $job_id);

        // 3. Get source URL and apply source attribution using helper
        $source_url = $engine->getSourceUrl();
        $content = WordPressPublishHelper::applySourceAttribution(
            $parameters['content'],
            $source_url,
            $handler_config
        );

        // 4. Resolve configuration with system defaults
        $resolver = new WordPressSettingsResolver();
        $post_status = $resolver->resolvePostStatus($handler_config);
        $post_author = $resolver->resolvePostAuthor($handler_config);

        // 5. Create WordPress post
        $post_data = [
            'post_title' => sanitize_text_field($parameters['title']),
            'post_content' => $content,
            'post_status' => $post_status,
            'post_type' => $handler_config['post_type'],
            'post_author' => $post_author
        ];

        $post_id = wp_insert_post($post_data);

        // 6. Process taxonomies
        $taxonomy_results = $this->taxonomy_handler->processTaxonomies(
            $post_id, 
            $parameters, 
            $handler_config
        );

        // 7. Attach featured image using helper
        $image_path = $engine->getImagePath();
        $attachment_id = WordPressPublishHelper::attachImageToPost(
            $post_id, 
            $image_path, 
            $handler_config
        );

        // 8. Return standardized success response
        return $this->successResponse([
            'post_id' => $post_id,
            'post_url' => get_permalink($post_id),
            'taxonomy_results' => $taxonomy_results,
            'attachment_id' => $attachment_id
        ]);
    }
}

The handle_tool_call() method is implemented in the base PublishHandler class and calls executePublish().

Required Configuration

All configuration parameters must be provided in handler config:

Parameter Type Required Description
post_author integer Yes WordPress user ID for post authorship
post_status string Yes Post status: publish, draft, private, pending
post_type string Yes WordPress post type: post, page, or custom post type

Tool Call Parameters

Required:

  • title: Post title (sanitized with sanitize_text_field)
  • content: Post content (sanitized with wp_kses_post)

Optional:

  • image_url: Featured image URL (processed by WordPressPublishHelper)
  • source_url: Source attribution URL (processed by WordPressPublishHelper)
  • category: Category assignment for TaxonomyHandler
  • tags: Tags assignment (string or array) for TaxonomyHandler
  • Custom taxonomy parameters for TaxonomyHandler

Configuration Examples

Basic WordPress Publishing

$handler_config = [
    'post_author' => 1,
    'post_status' => 'publish',
    'post_type' => 'post',
    'enable_images' => true,
    'include_source' => false,
    'taxonomy_category_selection' => 'ai_decides',
    'taxonomy_post_tag_selection' => 'skip'
];

Advanced Configuration with System Defaults

// Global WordPress settings (system-wide defaults)
$wp_settings = [
    'default_enable_images' => true,      // Overrides handler config
    'default_include_source' => false     // Overrides handler config
];

// Handler config (fallback values)
$handler_config = [
    'post_author' => 1,
    'post_status' => 'publish',
    'post_type' => 'post',
    'enable_images' => false,             // Ignored - system default wins
    'include_source' => true,             // Ignored - system default wins
    'taxonomy_category_selection' => 'Technology', // Pre-selected by term name
    'taxonomy_post_tag_selection' => 'ai_decides'
];

Tool Response Format

Success Response:

[
    'success' => true,
    'data' => [
        'post_id' => 123,
        'post_title' => 'Original post title',
        'post_url' => 'https://site.com/post-permalink',
        'taxonomy_results' => [
            'category' => [
                'success' => true,
                'taxonomy' => 'category',
                'term_count' => 1,
                'terms' => ['Technology']
            ],
            'post_tag' => [
                'success' => true,
                'taxonomy' => 'post_tag',
                'term_count' => 2,
                'terms' => ['AI', 'Machine Learning']
            ]
        ],
        'featured_image_result' => [
            'success' => true,
            'attachment_id' => 456,
            'attachment_url' => 'https://site.com/wp-content/uploads/image.jpg'
        ]
    ],
    'tool_name' => 'wordpress_publish'
]

Error Response:

[
    'success' => false,
    'error' => 'Missing required configuration: post_author',
    'tool_name' => 'wordpress_publish'
]

Error Handling

Configuration Errors:

  • Missing required handler configuration validation
  • Invalid configuration value detection
  • Component-specific configuration validation

Processing Errors:

  • Image download and attachment failures
  • Taxonomy assignment errors
  • Source URL validation failures
  • WordPress post creation errors

Component Error Isolation:

  • Failed image processing doesn’t prevent post creation
  • Taxonomy errors are isolated per taxonomy
  • Source URL failures don’t affect other components
  • Comprehensive error logging throughout all components

Security Features

Input Sanitization: All components use WordPress security functions (sanitize_text_field, wp_kses_post, esc_url).

Permission Respect: Honors WordPress user capabilities and post type permissions.

Safe Content: Components handle user input safely without compromising WordPress security.

Configuration Validation: Validates all configuration parameters before processing.

Performance Features

Modular Processing: Components can be bypassed based on configuration to optimize performance.

Efficient Media Handling: Uses WordPress native functions for optimal media processing.

Clean Integration: Gutenberg block generation maintains WordPress standards and performance.

Comprehensive Logging: All components provide detailed debug logging for monitoring and troubleshooting.

The modular WordPress publish handler architecture provides enhanced maintainability, configuration flexibility, and feature separation while maintaining backward compatibility and WordPress integration standards.

WordPress Shared Components

The WordPress publish handler uses centralized shared components from /inc/Core/WordPress/ that provide reusable functionality across all WordPress-related handlers (publish, fetch, update).

WordPressPublishHelper

Location: /inc/Core/WordPress/WordPressPublishHelper.php
Purpose: WordPress-specific publishing operations
Since: 0.2.7

Provides static methods for WordPress publishing operations including media attachment and content modification.

Key Methods:

attachImageToPost()

Attaches image from Files Repository to WordPress post as featured image.

$attachment_id = WordPressPublishHelper::attachImageToPost($post_id, $image_path, $config);
// Returns: int (attachment ID) or null on failure

applySourceAttribution()

Appends source URL to content with Gutenberg blocks or plain text.

$content = WordPressPublishHelper::applySourceAttribution($content, $source_url, $config);
// Returns: string (modified content)

TaxonomyHandler

Location: /inc/Core/WordPress/TaxonomyHandler.php
Purpose: Dynamic taxonomy assignment with configuration-based processing
Since: 0.2.1

Processes taxonomy assignments based on configuration (skip, AI-decided, or pre-selected terms).

WordPressSettingsResolver

Location: /inc/Core/WordPress/WordPressSettingsResolver.php
Purpose: Configuration resolution with system defaults override
Since: 0.2.7

Resolves effective configuration values by checking system defaults first, then handler configuration.

Key Methods:

$resolver = new WordPressSettingsResolver();
$post_status = $resolver->resolvePostStatus($handler_config);
$post_author = $resolver->resolvePostAuthor($handler_config);

WordPressSettingsHandler

Location: /inc/Core/WordPress/WordPressSettingsHandler.php
Purpose: Centralized WordPress settings utilities for handler configuration
Since: 0.2.1

Provides reusable WordPress-specific settings utilities for taxonomy fields, post type options, and user options.

Key Methods:

// Generate taxonomy field definitions
$taxonomy_fields = WordPressSettingsHandler::get_taxonomy_fields([...]);

// Get post type options
$post_types = WordPressSettingsHandler::get_post_type_options();

// Get user options
$users = WordPressSettingsHandler::get_user_options();

WordPressFilters

Location: /inc/Core/WordPress/WordPressFilters.php
Purpose: Self-registration filter system for WordPress components
Since: 0.2.0

Handles automatic registration of WordPress handler via filter-based architecture.

Configuration Hierarchy

System-wide WordPress defaults (from Settings page) override handler-specific configuration across all WordPress components:

Hierarchy Order:

  1. System Defaults (Global WordPress settings from Settings page) – Highest priority
  2. Handler Configuration (Flow-specific handler settings) – Fallback

Implementation: WordPressSettingsResolver class handles configuration resolution throughout the handler.

Related Documentation

WordPress Shared Components – WordPressPublishHelper, TaxonomyHandler, WordPressSettingsResolver
WordPress Fetch Handler
WordPress Update Handler
SettingsHandler Base Class