|
| 1 | +<?php |
| 2 | +/** |
| 3 | + * Quick Draft Integration Feature. |
| 4 | + * |
| 5 | + * Integrates ClassifAI Content Generation with WordPress Quick Draft widget. |
| 6 | + */ |
| 7 | + |
| 8 | +namespace Classifai\Features; |
| 9 | + |
| 10 | +use Classifai\Features\ContentGeneration; |
| 11 | +use WP_REST_Server; |
| 12 | +use WP_REST_Request; |
| 13 | +use WP_Error; |
| 14 | + |
| 15 | +use function Classifai\get_asset_info; |
| 16 | + |
| 17 | +if ( ! defined( 'ABSPATH' ) ) { |
| 18 | + exit; |
| 19 | +} |
| 20 | + |
| 21 | +/** |
| 22 | + * Quick Draft Integration Feature. |
| 23 | + * |
| 24 | + * Integrates ClassifAI Content Generation with WordPress Quick Draft widget. |
| 25 | + */ |
| 26 | +class QuickDraftIntegration { |
| 27 | + |
| 28 | + /** |
| 29 | + * Content Generation Feature instance. |
| 30 | + * |
| 31 | + * @var ContentGeneration |
| 32 | + */ |
| 33 | + private $content_generation; |
| 34 | + |
| 35 | + /** |
| 36 | + * Constructor. |
| 37 | + */ |
| 38 | + public function __construct() { |
| 39 | + $this->content_generation = new ContentGeneration(); |
| 40 | + } |
| 41 | + |
| 42 | + /** |
| 43 | + * Initialize the Quick Draft integration. |
| 44 | + */ |
| 45 | + public function init() { |
| 46 | + // Check if Quick Draft integration is enabled. |
| 47 | + if ( ! $this->is_quick_draft_enabled() ) { |
| 48 | + return; |
| 49 | + } |
| 50 | + |
| 51 | + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] ); |
| 52 | + add_action( 'rest_api_init', [ $this, 'register_endpoints' ] ); |
| 53 | + } |
| 54 | + |
| 55 | + /** |
| 56 | + * Check if Quick Draft integration is enabled. |
| 57 | + * |
| 58 | + * @return bool |
| 59 | + */ |
| 60 | + public function is_quick_draft_enabled(): bool { |
| 61 | + $settings = $this->content_generation->get_settings(); |
| 62 | + return isset( $settings['enable_quick_draft'] ) ? (bool) $settings['enable_quick_draft'] : true; |
| 63 | + } |
| 64 | + |
| 65 | + /** |
| 66 | + * Enqueue Quick Draft assets on the dashboard. |
| 67 | + */ |
| 68 | + public function enqueue_assets() { |
| 69 | + $screen = get_current_screen(); |
| 70 | + |
| 71 | + // Only load on dashboard. |
| 72 | + if ( ! $screen || 'dashboard' !== $screen->id ) { |
| 73 | + return; |
| 74 | + } |
| 75 | + |
| 76 | + // Only load if user can create posts. |
| 77 | + if ( ! current_user_can( 'edit_posts' ) ) { |
| 78 | + return; |
| 79 | + } |
| 80 | + |
| 81 | + wp_enqueue_script( |
| 82 | + 'classifai-quick-draft-js', |
| 83 | + CLASSIFAI_PLUGIN_URL . 'dist/classifai-quick-draft.js', |
| 84 | + array_merge( get_asset_info( 'classifai-quick-draft', 'dependencies' ), array( 'jquery', 'media-editor', 'lodash' ) ), |
| 85 | + get_asset_info( 'classifai-quick-draft', 'version' ), |
| 86 | + true |
| 87 | + ); |
| 88 | + |
| 89 | + wp_localize_script( |
| 90 | + 'classifai-quick-draft-js', |
| 91 | + 'classifaiQuickDraft', |
| 92 | + [ |
| 93 | + 'createContent' => __( 'Create Draft from Prompt', 'classifai' ), |
| 94 | + 'generating' => __( 'Generating...', 'classifai' ), |
| 95 | + 'error' => __( 'Error generating content. Please try again.', 'classifai' ), |
| 96 | + ] |
| 97 | + ); |
| 98 | + |
| 99 | + wp_enqueue_style( |
| 100 | + 'classifai-quick-draft-css', |
| 101 | + CLASSIFAI_PLUGIN_URL . 'dist/classifai-quick-draft.css', |
| 102 | + [], |
| 103 | + get_asset_info( 'classifai-quick-draft', 'version' ), |
| 104 | + ); |
| 105 | + } |
| 106 | + |
| 107 | + /** |
| 108 | + * Register Quick Draft specific endpoints. |
| 109 | + */ |
| 110 | + public function register_endpoints() { |
| 111 | + register_rest_route( |
| 112 | + 'classifai/v1', |
| 113 | + 'quick-draft-generate', |
| 114 | + [ |
| 115 | + 'methods' => WP_REST_Server::CREATABLE, |
| 116 | + 'callback' => [ $this, 'endpoint_callback' ], |
| 117 | + 'permission_callback' => [ $this, 'permissions_check' ], |
| 118 | + 'args' => [ |
| 119 | + 'title' => [ |
| 120 | + 'required' => true, |
| 121 | + 'type' => 'string', |
| 122 | + 'sanitize_callback' => 'sanitize_text_field', |
| 123 | + 'validate_callback' => 'rest_validate_request_arg', |
| 124 | + 'description' => esc_html__( 'The title of the post.', 'classifai' ), |
| 125 | + ], |
| 126 | + 'content' => [ |
| 127 | + 'required' => true, |
| 128 | + 'type' => 'string', |
| 129 | + 'sanitize_callback' => 'sanitize_textarea_field', |
| 130 | + 'validate_callback' => 'rest_validate_request_arg', |
| 131 | + 'description' => esc_html__( 'The prompt to use for content generation.', 'classifai' ), |
| 132 | + ], |
| 133 | + ], |
| 134 | + ] |
| 135 | + ); |
| 136 | + } |
| 137 | + |
| 138 | + /** |
| 139 | + * Check permissions for Quick Draft generation. |
| 140 | + * |
| 141 | + * @return WP_Error|bool |
| 142 | + */ |
| 143 | + public function permissions_check() { |
| 144 | + // Ensure user can create posts. |
| 145 | + if ( ! current_user_can( 'edit_posts' ) ) { |
| 146 | + return false; |
| 147 | + } |
| 148 | + |
| 149 | + $post_type_obj = get_post_type_object( 'post' ); |
| 150 | + |
| 151 | + // Ensure the post type is allowed in REST endpoints. |
| 152 | + if ( empty( $post_type_obj ) || empty( $post_type_obj->show_in_rest ) ) { |
| 153 | + return false; |
| 154 | + } |
| 155 | + |
| 156 | + // Ensure the Feature is enabled. |
| 157 | + if ( ! $this->content_generation->is_feature_enabled() ) { |
| 158 | + return new WP_Error( 'not_enabled', esc_html__( 'Content Generation is not currently enabled.', 'classifai' ) ); |
| 159 | + } |
| 160 | + |
| 161 | + return true; |
| 162 | + } |
| 163 | + |
| 164 | + /** |
| 165 | + * Handle Quick Draft content generation. |
| 166 | + * |
| 167 | + * @param WP_REST_Request $request The full request object. |
| 168 | + * @return \WP_REST_Response |
| 169 | + */ |
| 170 | + public function endpoint_callback( WP_REST_Request $request ) { |
| 171 | + $title = $request->get_param( 'title' ); |
| 172 | + $content = $request->get_param( 'content' ); |
| 173 | + |
| 174 | + if ( empty( $title ) || empty( $content ) ) { |
| 175 | + return new WP_Error( 'missing_required_parameters', esc_html__( 'Title and content are required.', 'classifai' ) ); |
| 176 | + } |
| 177 | + |
| 178 | + // Create a new auto-draft post. |
| 179 | + $post_data = [ |
| 180 | + 'post_title' => $title, |
| 181 | + 'post_content' => '', |
| 182 | + 'post_status' => 'auto-draft', |
| 183 | + 'post_type' => 'post', |
| 184 | + 'post_author' => get_current_user_id(), |
| 185 | + ]; |
| 186 | + |
| 187 | + $post_id = wp_insert_post( $post_data, true ); |
| 188 | + |
| 189 | + if ( is_wp_error( $post_id ) ) { |
| 190 | + return new WP_Error( 'post_creation_failed', esc_html__( 'Failed to create draft post.', 'classifai' ) ); |
| 191 | + } |
| 192 | + |
| 193 | + // Generate content using the existing content generation logic. |
| 194 | + $result = $this->content_generation->run( |
| 195 | + $post_id, |
| 196 | + 'create_content', |
| 197 | + [ |
| 198 | + 'title' => $title, |
| 199 | + 'summary' => $content, |
| 200 | + ] |
| 201 | + ); |
| 202 | + |
| 203 | + if ( is_wp_error( $result ) ) { |
| 204 | + // Clean up the post if generation failed. |
| 205 | + wp_delete_post( $post_id, true ); |
| 206 | + return $result; |
| 207 | + } |
| 208 | + |
| 209 | + // Update the post with generated content. |
| 210 | + $updated_post = [ |
| 211 | + 'ID' => $post_id, |
| 212 | + 'post_content' => $result, |
| 213 | + 'post_status' => 'draft', |
| 214 | + ]; |
| 215 | + |
| 216 | + $update_result = wp_update_post( $updated_post ); |
| 217 | + |
| 218 | + if ( is_wp_error( $update_result ) ) { |
| 219 | + return new WP_Error( 'post_update_failed', esc_html__( 'Failed to update post with generated content.', 'classifai' ) ); |
| 220 | + } |
| 221 | + |
| 222 | + return rest_ensure_response( |
| 223 | + [ |
| 224 | + 'post_id' => $post_id, |
| 225 | + 'edit_url' => admin_url( "post.php?post={$post_id}&action=edit" ), |
| 226 | + 'content' => $result, |
| 227 | + 'title' => $title, |
| 228 | + 'success' => true, |
| 229 | + ] |
| 230 | + ); |
| 231 | + } |
| 232 | +} |
0 commit comments