__('AI Webmaster Studio: Preserve content and improve layout', 'ai-webmaster-studio'), 'aiwest_seo' => __('AI Webmaster Studio: Improve SEO', 'ai-webmaster-studio'), 'aiwest_improve' => __('AI Webmaster Studio: Expand content', 'ai-webmaster-studio'), 'aiwest_faq' => __('AI Webmaster Studio: Add FAQ', 'ai-webmaster-studio'), 'aiwest_cta' => __('AI Webmaster Studio: Add CTA', 'ai-webmaster-studio'), 'aiwest_image' => __('AI Webmaster Studio: Add image', 'ai-webmaster-studio'), ]; } public static function register_actions($actions) { foreach (self::labels() as $key=>$label) $actions[$key]=$label; return $actions; } public static function handle_action($redirect_url, $action, $post_ids) { if (!isset(self::labels()[$action])) return $redirect_url; if (!current_user_can('edit_posts')) return $redirect_url; $original_count = count($post_ids); $post_ids = array_slice(array_map('intval', (array)$post_ids), 0, self::LIMIT); $results = ['action'=>$action,'label'=>self::labels()[$action],'requested'=>$original_count,'limit'=>self::LIMIT,'processed'=>0,'success'=>0,'errors'=>0,'items'=>[],'started_at'=>current_time('mysql')]; foreach ($post_ids as $post_id) { try { $post = get_post($post_id); if (!$post || !in_array($post->post_type, ['page','post'], true)) throw new Exception(__('Unsupported content type.', 'ai-webmaster-studio')); if (!current_user_can('edit_post', $post_id)) throw new Exception(__('You do not have permission to edit this item.', 'ai-webmaster-studio')); $results['processed']++; $result = self::run_action($action, $post_id); if (is_wp_error($result)) throw new Exception($result->get_error_message()); $results['success']++; $message = is_array($result) ? ($result['summary'] ?? __('Task completed.', 'ai-webmaster-studio')) : __('Task completed.', 'ai-webmaster-studio'); if ($action === 'aiwest_image' && is_numeric($result)) { $message = sprintf( /* translators: %d: WordPress Media Library attachment ID. */ __('Featured image added. Attachment ID: %d.', 'ai-webmaster-studio'), intval($result) ); } $results['items'][] = ['id'=>$post_id,'title'=>get_the_title($post_id),'status'=>'success','message'=>$message,'edit_link'=>get_edit_post_link($post_id,''),'preview_link'=>get_preview_post_link($post_id),'view_link'=>get_permalink($post_id)]; } catch (Throwable $e) { $results['errors']++; $results['items'][] = ['id'=>$post_id,'title'=>get_the_title($post_id),'status'=>'error','message'=>$e->getMessage()]; if (class_exists('AIWEST_Logger')) AIWEST_Logger::warning('AI Web bulk action item failed.', ['post_id'=>$post_id,'action'=>$action,'error'=>$e->getMessage()]); } } $results['completed_at'] = current_time('mysql'); self::store_result($results); if (class_exists('AIWEST_History')) { $hid = AIWEST_History::add_content('bulk_action', __('Bulk action: ', 'ai-webmaster-studio').self::labels()[$action], '', __('Items: ', 'ai-webmaster-studio').$results['processed']); AIWEST_History::update_content( $hid, $results['errors'] ? 'completed_with_warnings' : 'completed', null, sprintf( /* translators: 1: Number of successful items. 2: Number of failed items. */ __('Success: %1$d, errors: %2$d', 'ai-webmaster-studio'), $results['success'], $results['errors'] ) ); } return add_query_arg(['aiwest_bulk_done'=>1,'aiwest_bulk_success'=>$results['success'],'aiwest_bulk_errors'=>$results['errors'],'aiwest_bulk_limited'=>$original_count>self::LIMIT?1:0], $redirect_url); } public static function run_action($action, $post_id) { if ($action === 'aiwest_image') { if (!class_exists('AIWEST_Image_Generator')) return new WP_Error('aiwest_missing_image_generator', __('AI image module is unavailable.', 'ai-webmaster-studio')); return AIWEST_Image_Generator::generate_for_post($post_id); } $mode = ['aiwest_visual'=>'visual','aiwest_seo'=>'seo','aiwest_improve'=>'improve','aiwest_faq'=>'faq','aiwest_cta'=>'cta'][$action] ?? 'improve'; if (class_exists('AIWEST_Content_Development_Action_Service')) { return AIWEST_Content_Development_Action_Service::execute($post_id, $mode); } if (!class_exists('AIWEST_Content_Upgrader')) return new WP_Error('aiwest_missing_content_upgrader', __('Content Development module is unavailable.', 'ai-webmaster-studio')); return AIWEST_Content_Upgrader::improve_post($post_id, $mode); } public static function store_result($results) { set_transient('aiwest_bulk_result_'.get_current_user_id(), $results, HOUR_IN_SECONDS); } public static function admin_notice() { if (!is_admin() || !AIWEST_Security::get_key('aiwest_bulk_done')) return; $results = get_transient('aiwest_bulk_result_'.get_current_user_id()); $success = absint(AIWEST_Security::get_text('aiwest_bulk_success')); $errors = absint(AIWEST_Security::get_text('aiwest_bulk_errors')); $limited = (bool) AIWEST_Security::get_key('aiwest_bulk_limited'); echo '
'.esc_html(__('AI Webmaster Studio — bulk action completed.', 'ai-webmaster-studio')).' '.esc_html(sprintf( /* translators: 1: Number of successful items. 2: Number of failed items. */ __('Success: %1$d, errors: %2$d.', 'ai-webmaster-studio'), $success, $errors )); if ($limited) { echo ' '.esc_html(sprintf( /* translators: %d: Maximum number of items processed in one bulk operation. */ __('For safety, a maximum of %d items was processed at once.', 'ai-webmaster-studio'), self::LIMIT )); } echo '
'; if (is_array($results) && !empty($results['items'])) { echo '