Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in /var/www/html/plugins/system/falangdriver/falangdriver.php on line 534
Joomla 网站API第三方适配程序 - Bluetooth forum - bluetooth蓝牙技术

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/components/com_comprofiler/plugin/user/plug_cbjdownloads/cbjdownloads.php on line 49

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/components/com_comprofiler/plugin/user/plug_cbblogs/cbblogs.php on line 48

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/components/com_comprofiler/plugin/user/plug_cbarticles/cbarticles.php on line 47

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 217

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 219

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 227

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 231

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 234

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
Technical discuss

Joomla 网站API第三方适配程序


Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

  • Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    service
  • [
    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    service]

  • Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    帖子作者

  • Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    离线
  • 管理员
  • 管理员
更多
2026-01-12 13:16 - 2026-01-12 13:53 #1010
Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
by service
新帖
如果第三方程序使用的URL路径与当前joomla网站的组件不匹配。本站组件使用的是Joomla的标准路由格式,而第三方程序期望的是RESTful API格式:
第三方程序期望的是标准的RESTful API端点(如 
Code:
/api/publish
),而本站组件使用的是Joomla格式的URL(
Code:
index.php?option=com_aipublisher&task=publish
)。
以下是一种解决方案:安装包含
Code:
api.php
的适配器版本
  • 提供完整的RESTful API支持
  • 包含URL重写规则
  • 有详细的使用文档
  • 保持向后兼容

创建适配第三方程序的API端点文件
Code:
[code]#!/bin/bash # AI Publisher - 第三方程序API适配器(修复版) echo "🔧 创建第三方程序API适配器(完整功能版)..." echo "==============================================" cd com_aipublisher_final # 1. 修复的API适配器文件 - 修复EOF语法 cat > "site/api.php" << 'API_EOF' <?php defined('_JEXEC') or die; // 设置JSON响应头 header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE'); header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With'); // 处理预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {     http_response_code(200);     exit; } // 获取请求方法和路径 $method = $_SERVER['REQUEST_METHOD']; $requestUri = $_SERVER['REQUEST_URI']; $path = parse_url($requestUri, PHP_URL_PATH); // 移除查询字符串 $path = strtok($path, '?'); // 完整的路由映射表 $routes = [     'POST' => [         '/api/publish' => 'handleApiPublish',         '/api/test-connection' => 'handleApiTestConnection',         '/api/save-config' => 'handleApiSaveConfig',         '/api/conversations' => 'handleApiConversations'     ],     'GET' => [         '/api/conversations' => 'handleApiGetConversations',         '/api/website-configs' => 'handleApiGetWebsiteConfigs',         '/api/health' => 'handleApiHealth',         '/api/info' => 'handleApiInfo',         '/api/status' => 'handleApiStatus'     ],     'PUT' => [         '/api/update-config' => 'handleApiUpdateConfig'     ] ]; // 查找匹配的路由 $handler = null; $matchedRoute = null; if (isset($routes[$method])) {     foreach ($routes[$method] as $route => $handlerName) {         // 精确匹配或路径匹配         if ($path === $route || strpos($path, $route . '/') === 0) {             $handler = $handlerName;             $matchedRoute = $route;             break;         }     } } // 记录请求日志(调试用) logApiRequest($method, $path, $matchedRoute); // 执行处理函数 if ($handler && function_exists($handler)) {     try {         call_user_func($handler);     } catch (Exception $e) {         http_response_code(500);         echo json_encode([             'status' => 'error',             'message' => 'Internal server error: ' . $e->getMessage(),             'code' => 'INTERNAL_ERROR',             'timestamp' => date('Y-m-d H:i:s')         ]);     } } else {     // 提供友好的404错误     http_response_code(404);     echo json_encode([         'status' => 'error',         'message' => 'API endpoint not found',         'details' => [             'requested_path' => $path,             'request_method' => $method,             'available_endpoints' => getAvailableEndpoints()         ],         'suggestions' => [             'Check the endpoint URL',             'Verify the HTTP method (GET/POST/PUT/DELETE)',             'Ensure you have proper authentication token'         ]     ]); } exit; // ==================== API处理函数 ==================== /**  * 处理发布文章请求  */ function handleApiPublish() {     try {         // 获取并解析请求数据         $rawInput = file_get_contents('php://input');                  if (empty($rawInput)) {             throw new Exception('Request body is empty');         }                  $input = json_decode($rawInput, true);                  if (json_last_error() !== JSON_ERROR_NONE) {             throw new Exception('Invalid JSON format: ' . json_last_error_msg());         }                  // 验证必需字段         $requiredFields = ['token', 'content'];         $missingFields = [];                  foreach ($requiredFields as $field) {             if (!isset($input[$field]) || trim($input[$field]) === '') {                 $missingFields[] = $field;             }         }                  if (!empty($missingFields)) {             throw new Exception('Missing required fields: ' . implode(', ', $missingFields));         }                  // 验证API令牌         $tokenValidation = validateApiToken($input['token']);                  if (!$tokenValidation['valid']) {             http_response_code(401);             echo json_encode([                 'status' => 'error',                 'message' => 'Authentication failed',                 'code' => 'INVALID_TOKEN',                 'details' => $tokenValidation             ]);             return;         }                  // 准备文章数据         $articleData = [             'title' => $input['title'] ?? 'AI Generated Content - ' . date('Y-m-d H:i:s'),             'content' => $input['content'],             'category' => $input['category_id'] ?? $input['category'] ?? null,             'state' => $input['state'] ?? $input['published'] ?? null,             'author' => $input['author'] ?? $input['created_by_alias'] ?? null,             'tags' => $input['tags'] ?? $input['keywords'] ?? null,             'meta_description' => $input['description'] ?? $input['meta_description'] ?? null,             'meta_keywords' => $input['keywords'] ?? $input['meta_keywords'] ?? null         ];                  // 调用Joomla发布引擎         $publishResult = publishToJoomla($articleData);                  // 记录成功日志         logApiSuccess('publish', $publishResult['id']);                  // 返回成功响应         echo json_encode([             'status' => 'success',             'message' => 'Article published successfully',             'data' => $publishResult,             'meta' => [                 'timestamp' => date('Y-m-d H:i:s'),                 'request_id' => uniqid('req_', true),                 'processing_time' => getProcessingTime() . 'ms'             ]         ]);              } catch (Exception $e) {         // 记录错误日志         logApiError('publish', $e->getMessage());                  http_response_code(400);         echo json_encode([             'status' => 'error',             'message' => 'Failed to publish article: ' . $e->getMessage(),             'code' => 'PUBLISH_ERROR',             'timestamp' => date('Y-m-d H:i:s')         ]);     } } /**  * 处理测试连接请求  */ function handleApiTestConnection() {     try {         $rawInput = file_get_contents('php://input');                  if (empty($rawInput)) {             // 如果没有提供数据,检查GET参数             $token = $_GET['token'] ?? '';         } else {             $input = json_decode($rawInput, true);             $token = $input['token'] ?? '';         }                  if (empty($token)) {             throw new Exception('API token is required');         }                  $validation = validateApiToken($token);                  if ($validation['valid']) {             echo json_encode([                 'status' => 'success',                 'message' => 'Connection successful',                 'details' => [                     'joomla_version' => JVERSION,                     'php_version' => PHP_VERSION,                     'server_time' => date('Y-m-d H:i:s'),                     'component_version' => '1.1.0',                     'api_status' => 'operational'                 ],                 'system_info' => [                     'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB',                     'max_execution_time' => ini_get('max_execution_time'),                     'upload_max_filesize' => ini_get('upload_max_filesize')                 ]             ]);         } else {             http_response_code(401);             echo json_encode([                 'status' => 'error',                 'message' => 'Connection failed: Invalid API token',                 'code' => 'AUTH_FAILED',                 'details' => $validation             ]);         }              } catch (Exception $e) {         http_response_code(400);         echo json_encode([             'status' => 'error',             'message' => 'Test failed: ' . $e->getMessage(),             'code' => 'TEST_ERROR'         ]);     } } /**  * 处理保存配置请求  */ function handleApiSaveConfig() {     try {         $input = json_decode(file_get_contents('php://input'), true);                  if (!$input) {             throw new Exception('Invalid configuration data');         }                  // 获取当前组件参数         $params = JComponentHelper::getParams('com_aipublisher');         $currentParams = $params->toArray();                  // 合并新配置         $newParams = array_merge($currentParams, $input);                  // 保存到数据库         $db = JFactory::getDbo();         $query = $db->getQuery(true)             ->update('#__extensions')             ->set('params = ' . $db->quote(json_encode($newParams)))             ->where('element = ' . $db->quote('com_aipublisher'));                  $db->setQuery($query);         $result = $db->execute();                  if ($result) {             // 清除缓存             JFactory::getCache('com_aipublisher')->clean();                          echo json_encode([                 'status' => 'success',                 'message' => 'Configuration saved successfully',                 'data' => [                     'updated_fields' => array_keys($input),                     'total_fields' => count($newParams),                     'cache_cleared' => true                 ]             ]);         } else {             throw new Exception('Failed to save configuration to database');         }              } catch (Exception $e) {         http_response_code(500);         echo json_encode([             'status' => 'error',             'message' => 'Failed to save configuration: ' . $e->getMessage(),             'code' => 'CONFIG_SAVE_ERROR'         ]);     } } /**  * 处理获取对话请求(POST)  */ function handleApiConversations() {     try {         $input = json_decode(file_get_contents('php://input'), true);                  // 这里可以实现对话存储逻辑         // 目前返回模拟数据         echo json_encode([             'status' => 'success',             'message' => 'Conversation processed',             'data' => [                 'conversation_id' => uniqid('conv_'),                 'timestamp' => date('Y-m-d H:i:s'),                 'message' => 'Conversation endpoint is ready for implementation'             ]         ]);              } catch (Exception $e) {         http_response_code(400);         echo json_encode([             'status' => 'error',             'message' => 'Failed to process conversation: ' . $e->getMessage()         ]);     } } /**  * 处理获取对话请求(GET)  */ function handleApiGetConversations() {     try {         $db = JFactory::getDbo();                  // 这里可以查询实际的对话数据         // 目前返回模拟数据         $conversations = [             [                 'id' => 1,                 'title' => 'Technical Discussion',                 'summary' => 'Discussion about API implementation',                 'message_count' => 5,                 'last_updated' => date('Y-m-d H:i:s', strtotime('-1 hour')),                 'participants' => ['AI System', 'Administrator']             ],             [                 'id' => 2,                 'title' => 'Content Planning',                 'summary' => 'Planning for upcoming articles',                 'message_count' => 3,                 'last_updated' => date('Y-m-d H:i:s', strtotime('-2 hours')),                 'participants' => ['AI Assistant', 'Editor']             ]         ];                  echo json_encode([             'status' => 'success',             'data' => $conversations,             'meta' => [                 'total' => count($conversations),                 'page' => 1,                 'per_page' => 10,                 'has_more' => false             ]         ]);              } catch (Exception $e) {         http_response_code(500);         echo json_encode([             'status' => 'error',             'message' => 'Failed to retrieve conversations: ' . $e->getMessage()         ]);     } } /**  * 处理获取网站配置请求  */ function handleApiGetWebsiteConfigs() {     try {         $config = JFactory::getConfig();         $params = JComponentHelper::getParams('com_aipublisher');                  $websiteConfig = [             'general' => [                 'site_name' => $config->get('sitename'),                 'site_url' => JUri::root(),                 'joomla_version' => JVERSION,                 'php_version' => PHP_VERSION,                 'server_timezone' => $config->get('offset'),                 'sef_enabled' => $config->get('sef'),                 'sef_rewrite' => $config->get('sef_rewrite')             ],             'api' => [                 'base_url' => JUri::root() . 'api.php',                 'joomla_endpoint' => JUri::root() . 'index.php?option=com_aipublisher',                 'token_configured' => !empty($params->get('api_token')),                 'default_category' => $params->get('default_category', 2),                 'auto_publish' => (bool)$params->get('auto_publish', 1),                 'default_author' => $params->get('default_author', 'AI Assistant'),                 'debug_mode' => (bool)$params->get('debug_mode', 0)             ],             'content' => [                 'article_count' => getArticleCount(),                 'categories' => getCategoryList(),                 'recent_articles' => getRecentArticles(5)             ],             'system' => [                 'max_upload_size' => ini_get('upload_max_filesize'),                 'memory_limit' => ini_get('memory_limit'),                 'max_execution_time' => ini_get('max_execution_time'),                 'timezone' => date_default_timezone_get()             ]         ];                  echo json_encode([             'status' => 'success',             'data' => $websiteConfig,             'meta' => [                 'timestamp' => date('Y-m-d H:i:s'),                 'generated_in' => getProcessingTime() . 'ms'             ]         ]);              } catch (Exception $e) {         http_response_code(500);         echo json_encode([             'status' => 'error',             'message' => 'Failed to retrieve website configs: ' . $e->getMessage()         ]);     } } /**  * 处理健康检查请求  */ function handleApiHealth() {     $healthStatus = [         'status' => 'healthy',         'timestamp' => date('Y-m-d H:i:s'),         'services' => []     ];          // 检查数据库连接     try {         $db = JFactory::getDbo();         $db->connect();         $healthStatus['services']['database'] = [             'status' => 'connected',             'latency' => 'OK'         ];     } catch (Exception $e) {         $healthStatus['services']['database'] = [             'status' => 'disconnected',             'error' => $e->getMessage()         ];         $healthStatus['status'] = 'degraded';     }          // 检查组件状态     $component = JComponentHelper::getComponent('com_aipublisher');     $healthStatus['services']['component'] = [         'status' => $component->enabled ? 'enabled' : 'disabled',         'version' => '1.1.0'     ];          // 检查API状态     $healthStatus['services']['api'] = [         'status' => 'operational',         'endpoints_available' => count(getAvailableEndpoints()['endpoints'])     ];          // 系统资源     $healthStatus['system'] = [         'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB',         'memory_peak' => round(memory_get_peak_usage(true) / 1024 / 1024, 2) . ' MB',         'load_time' => getProcessingTime() . 'ms'     ];          echo json_encode($healthStatus); } /**  * 处理API信息请求  */ function handleApiInfo() {     echo json_encode([         'api_name' => 'AI Publisher REST API',         'version' => '1.1.0',         'description' => 'Complete REST API for AI-powered content publishing to Joomla',         'documentation' => JUri::root() . 'administrator/index.php?option=com_aipublisher',         'base_url' => JUri::root() . 'api.php',         'authentication' => 'Token-based authentication',         'rate_limiting' => 'Not implemented',         'endpoints' => getAvailableEndpoints()['endpoints'],         'supported_formats' => ['JSON'],         'changelog' => [             '1.1.0' => 'Added full REST API support for third-party applications',             '1.0.0' => 'Initial stable release with JTable publishing'         ]     ]); } /**  * 处理API状态请求  */ function handleApiStatus() {     echo json_encode([         'status' => 'operational',         'uptime' => '100%',         'response_time' => getProcessingTime() . 'ms',         'last_updated' => date('Y-m-d H:i:s'),         'metrics' => [             'total_requests' => 0, // 可以添加请求计数             'success_rate' => '100%',             'average_response_time' => getProcessingTime() . 'ms'         ]     ]); } /**  * 处理更新配置请求  */ function handleApiUpdateConfig() {     handleApiSaveConfig(); // 重用保存配置逻辑 } // ==================== 辅助函数 ==================== /**  * 验证API令牌  */ function validateApiToken($token) {     $result = [         'valid' => false,         'checks' => [],         'details' => []     ];          if (empty($token)) {         $result['checks'][] = 'Token is empty';         return $result;     }          $result['checks'][] = 'Token received: ' . substr($token, 0, 8) . '...';          // 从组件参数获取令牌     $params = JComponentHelper::getParams('com_aipublisher');     $storedToken = $params->get('api_token', '');          if (empty($storedToken)) {         $result['checks'][] = 'No token stored in component parameters';         $result['details']['stored_token'] = 'Not set';         return $result;     }          $result['checks'][] = 'Stored token: ' . substr($storedToken, 0, 8) . '...';     $result['details']['stored_token_length'] = strlen($storedToken);     $result['details']['received_token_length'] = strlen($token);          // 安全比较令牌     if (function_exists('hash_equals')) {         $result['valid'] = hash_equals($storedToken, $token);         $result['checks'][] = 'Used hash_equals for comparison';     } else {         $result['valid'] = ($storedToken === $token);         $result['checks'][] = 'Used string comparison (hash_equals not available)';     }          if ($result['valid']) {         $result['checks'][] = 'Token validation successful';     } else {         $result['checks'][] = 'Token validation failed';     }          return $result; } /**  * 发布文章到Joomla  */ function publishToJoomla($data) {     // 获取组件参数     $params = JComponentHelper::getParams('com_aipublisher');          // 准备文章数据     $articleData = [         'title' => $data['title'] ?? 'AI Generated Content - ' . date('Y-m-d H:i:s'),         'content' => $data['content'],         'category' => $data['category'] ?? $params->get('default_category', 2),         'state' => isset($data['state']) ? intval($data['state']) : $params->get('auto_publish', 1),         'author' => $data['author'] ?? $params->get('default_author', 'AI Assistant'),         'tags' => $data['tags'] ?? null,         'meta_description' => $data['meta_description'] ?? '',         'meta_keywords' => $data['meta_keywords'] ?? ''     ];          // 使用JTable创建文章     JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_content/tables');     $table = JTable::getInstance('Content', 'JTable');          if (!$table) {         throw new Exception('Could not load Joomla Content Table');     }          // 生成唯一别名     $alias = JFilterOutput::stringURLSafe($articleData['title']);     $baseAlias = $alias;     $counter = 1;          // 确保别名唯一     while ($table->load(['alias' => $alias, 'catid' => $articleData['category']])) {         $alias = $baseAlias . '-' . $counter;         $counter++;         if ($counter > 100) {             $alias = $baseAlias . '-' . time();             break;         }     }          // 准备完整的数据     $rowData = [         'title' => $articleData['title'],         'alias' => $alias,         'introtext' => nl2br(htmlspecialchars($articleData['content'], ENT_QUOTES, 'UTF-8')),         'fulltext' => '',         'state' => $articleData['state'],         'catid' => $articleData['category'],         'language' => '*',         'created' => JFactory::getDate()->toSql(),         'created_by' => JFactory::getUser()->id,         'created_by_alias' => $articleData['author'],         'modified' => JFactory::getDate()->toSql(),         'modified_by' => JFactory::getUser()->id,         'publish_up' => JFactory::getDate()->toSql(),         'publish_down' => JFactory::getDbo()->getNullDate(),         'featured' => 0,         'access' => 1,         'metadesc' => $articleData['meta_description'],         'metakey' => $articleData['meta_keywords'],         'metadata' => '{"robots":"","author":"","rights":"","xreference":""}',         'note' => 'Published via AI Publisher API v1.1.0',         'images' => '',         'urls' => '',         'attribs' => '{"show_title":"1","link_titles":"","show_intro":"","show_category":"","link_category":"","show_author":"","show_create_date":"","show_modify_date":"","show_publish_date":"","show_hits":""}'     ];          // Joomla 4/5工作流支持     $isJoomla4Plus = version_compare(JVERSION, '4.0', '>=');     if ($isJoomla4Plus) {         $rowData['workflow_id'] = 1;         $rowData['stage_id'] = $articleData['state'] ? 1 : 2;     }          // 绑定数据     if (!$table->bind($rowData)) {         throw new Exception('Failed to bind article data: ' . $table->getError());     }          // 检查数据     if (!$table->check()) {         throw new Exception('Article data validation failed: ' . $table->getError());     }          // 存储数据     if (!$table->store()) {         throw new Exception('Failed to save article: ' . $table->getError());     }          $articleId = $table->id;          if (!$articleId) {         throw new Exception('Failed to get article ID after save');     }          // Joomla 4/5工作流关联     if ($isJoomla4Plus) {         ensureWorkflowAssociation($articleId, $rowData['stage_id']);     }          // 处理标签(如果提供)     if (!empty($articleData['tags'])) {         assignTagsToArticle($articleId, $articleData['tags']);     }          // 清理缓存     clearContentCache();          return [         'id' => $articleId,         'title' => $articleData['title'],         'alias' => $alias,         'state' => $articleData['state'],         'category_id' => $articleData['category'],         'author' => $articleData['author'],         'url' => JUri::root() . 'index.php?option=com_content&view=article&id=' . $articleId,         'admin_url' => JUri::root() . 'administrator/index.php?option=com_content&task=article.edit&id=' . $articleId,         'created' => $rowData['created'],         'metadata' => [             'joomla_version' => JVERSION,             'workflow_supported' => $isJoomla4Plus,             'api_version' => '1.1.0'         ]     ]; } /**  * 确保工作流关联  */ function ensureWorkflowAssociation($articleId, $stageId) {     $db = JFactory::getDbo();          try {         // 检查是否已存在关联         $query = $db->getQuery(true)             ->select('COUNT(*)')             ->from('#__workflow_associations')             ->where('item_id = ' . (int)$articleId)             ->where('extension = ' . $db->quote('com_content.article'));                  $db->setQuery($query);         $exists = $db->loadResult() > 0;                  if (!$exists) {             // 插入工作流关联             $association = new stdClass();             $association->item_id = $articleId;             $association->stage_id = $stageId;             $association->extension = 'com_content.article';                          // 检查表结构             $columns = $db->getTableColumns('#__workflow_associations');             if (isset($columns['workflow_id'])) {                 $association->workflow_id = 1;             }                          $db->insertObject('#__workflow_associations', $association);         }                  // 确保文章状态正确         $state = ($stageId == 1) ? 1 : 0;         $query = $db->getQuery(true)             ->update('#__content')             ->set('state = ' . (int)$state)             ->where('id = ' . (int)$articleId);                  $db->setQuery($query);         $db->execute();              } catch (Exception $e) {         // 工作流错误不影响文章创建         error_log('Workflow association error: ' . $e->getMessage());     } } /**  * 为文章分配标签  */ function assignTagsToArticle($articleId, $tags) {     if (!class_exists('JHelperTags')) {         return;     }          try {         if (is_string($tags)) {             $tags = explode(',', $tags);             $tags = array_map('trim', $tags);         }                  if (!is_array($tags) || empty($tags)) {             return;         }                  $tagsHelper = new JHelperTags();         $tagsHelper->typeAlias = 'com_content.article';         $tagsHelper->tags = $tags;         $tagsHelper->tagMethod = 0; // 替换现有标签         $tagsHelper->tagIds = null;         $tagsHelper->typeId = 0;         $tagsHelper->item = [             'id' => $articleId,             'title' => '',             'alias' => '',             'catid' => 0         ];                  $tagsHelper->postStoreProcess();              } catch (Exception $e) {         error_log('Tag assignment error: ' . $e->getMessage());     } } /**  * 清理内容缓存  */ function clearContentCache() {     try {         $cache = JFactory::getCache('com_content');         $cache->clean();         JFactory::getCache()->clean();     } catch (Exception $e) {         // 忽略缓存错误     } } /**  * 获取可用端点  */ function getAvailableEndpoints() {     return [         'endpoints' => [             ['method' => 'POST', 'path' => '/api/publish', 'description' => 'Publish new article'],             ['method' => 'POST', 'path' => '/api/test-connection', 'description' => 'Test API connection'],             ['method' => 'POST', 'path' => '/api/save-config', 'description' => 'Save configuration'],             ['method' => 'GET', 'path' => '/api/website-configs', 'description' => 'Get website configuration'],             ['method' => 'GET', 'path' => '/api/health', 'description' => 'Health check'],             ['method' => 'GET', 'path' => '/api/info', 'description' => 'API information'],             ['method' => 'GET', 'path' => '/api/status', 'description' => 'API status'],             ['method' => 'GET', 'path' => '/api/conversations', 'description' => 'Get conversations'],             ['method' => 'POST', 'path' => '/api/conversations', 'description' => 'Create conversation']         ],         'authentication' => 'Token-based (required for publish and test endpoints)',         'base_url' => JUri::root() . 'api.php'     ]; } /**  * 获取文章数量  */ function getArticleCount() {     $db = JFactory::getDbo();     $query = $db->getQuery(true)         ->select('COUNT(*)')         ->from('#__content')         ->where('created_by_alias LIKE ' . $db->quote('%AI%'));          $db->setQuery($query);     return $db->loadResult(); } /**  * 获取分类列表  */ function getCategoryList() {     $db = JFactory::getDbo();     $query = $db->getQuery(true)         ->select('id, title')         ->from('#__categories')         ->where('extension = ' . $db->quote('com_content'))         ->where('published = 1')         ->order('lft ASC');          $db->setQuery($query);     return $db->loadObjectList(); } /**  * 获取最近文章  */ function getRecentArticles($limit = 5) {     $db = JFactory::getDbo();     $query = $db->getQuery(true)         ->select('id, title, created, state, hits')         ->from('#__content')         ->where('created_by_alias LIKE ' . $db->quote('%AI%'))         ->order('created DESC')         ->setLimit($limit);          $db->setQuery($query);     return $db->loadObjectList(); } /**  * 记录API请求  */ function logApiRequest($method, $path, $matchedRoute) {     // 这里可以添加请求日志记录     // 例如保存到数据库或文件     if (defined('JDEBUG') && JDEBUG) {         error_log("API Request: $method $path -> " . ($matchedRoute ?: 'NO_MATCH'));     } } /**  * 记录API成功  */ function logApiSuccess($action, $data) {     if (defined('JDEBUG') && JDEBUG) {         error_log("API Success [$action]: " . json_encode($data));     } } /**  * 记录API错误  */ function logApiError($action, $error) {     error_log("API Error [$action]: $error"); } /**  * 获取处理时间  */ function getProcessingTime() {     static $startTime = null;          if ($startTime === null) {         $startTime = microtime(true);         return 0;     }          return round((microtime(true) - $startTime) * 1000, 2); } API_EOF # 2. 创建.htaccess文件 cat > "site/.htaccess" << 'HTACCESS_EOF' # AI Publisher API - URL Rewrite Rules <IfModule mod_rewrite.c>     RewriteEngine On          # 重写API请求到api.php     RewriteCond %{REQUEST_FILENAME} !-f     RewriteCond %{REQUEST_FILENAME} !-d     RewriteRule ^api/(.*)$ api.php [QSA,L]          # 支持直接访问/api路径     RewriteCond %{REQUEST_URI} ^/api$     RewriteRule ^api$ api.php [QSA,L]          # 重写旧的Joomla格式到API格式(可选)     RewriteCond %{QUERY_STRING} option=com_aipublisher&task=([^&]+)     RewriteRule ^index\.php$ api.php?action=%1 [QSA,L,NC] </IfModule> # 安全设置 <IfModule mod_headers.c>     Header set X-Content-Type-Options "nosniff"     Header set X-Frame-Options "SAMEORIGIN"     Header set X-XSS-Protection "1; mode=block" </IfModule> # 压缩设置 <IfModule mod_deflate.c>     AddOutputFilterByType DEFLATE application/json     AddOutputFilterByType DEFLATE application/javascript     AddOutputFilterByType DEFLATE text/css     AddOutputFilterByType DEFLATE text/html </IfModule> HTACCESS_EOF # 3. 更新XML文件 cat > "com_aipublisher.xml" << 'XML_EOF' <?xml version="1.0" encoding="utf-8"?> <extension type="component" method="upgrade" version="5.0">     <name>com_aipublisher</name>     <author>AI Publisher Team</author>     <creationDate>2024</creationDate>     <copyright>Copyright 2024</copyright>     <license>GPL v3</license>     <version>1.1.0</version>     <description>AI对话一键发布组件 - 完整REST API支持</description>          <scriptfile>script.php</scriptfile>          <languages folder="admin/language">         <language tag="en-GB">en-GB/en-GB.com_aipublisher.ini</language>         <language tag="en-GB">en-GB/en-GB.com_aipublisher.sys.ini</language>     </languages>          <administration>         <menu link="option=com_aipublisher">AI Publisher</menu>         <files folder="admin">             <filename>aipublisher.php</filename>             <filename>controller.php</filename>             <filename>config.xml</filename>             <folder>views</folder>             <folder>language</folder>         </files>         <submenu>             <menu link="option=com_aipublisher" view="dashboard">仪表板</menu>             <menu link="option=com_aipublisher&amp;view=articles">文章管理</menu>             <menu link="option=com_config&amp;view=component&amp;component=com_aipublisher">设置</menu>         </submenu>     </administration>          <files folder="site">         <filename>aipublisher.php</filename>         <filename>api.php</filename>         <filename>.htaccess</filename>     </files> </extension> XML_EOF # 4. 创建API文档 cat > "API_DOCUMENTATION.md" << 'DOC_EOF' # AI Publisher REST API 文档 ## 版本 1.1.0 ## 概述 完整的REST API接口,支持第三方程序通过标准HTTP请求与Joomla内容发布系统交互。 ## 基础信息 - **Base URL**: `https://your-domain.com/api.php` - **认证方式**: Token-based Authentication - **数据格式**: JSON - **字符编码**: UTF-8 ## 认证 所有需要认证的端点必须在请求中提供有效的API令牌。 ### 获取令牌 1. 安装组件时自动生成 2. 在管理界面查看 3. 使用调试端点获取 ## 端点列表 ### 1. 发布文章 **POST** `/api/publish` **请求参数**: ```json {   "token": "string (required)",   "content": "string (required)",   "title": "string (optional)",   "category": "integer (optional)",   "state": "integer (optional, 0=draft, 1=published)",   "author": "string (optional)",   "tags": "string or array (optional)",   "meta_description": "string (optional)",   "meta_keywords": "string (optional)" }
[/code]
2. 测试连接POST 
Code:
/api/test-connection
json
Code:
{ "token": "your_api_token" }

3. 获取网站配置
Code:
GET /api/website-configs
4. 保存配置
Code:
POST /api/save-config
json
Code:
{ "config": "配置数据" }

5. 健康检查
Code:
GET /api/health
6. API信息
Code:
GET /api/info
原来的Joomla端点(仍然可用)发布文章POST 
Code:
index.php?option=com_aipublisher&task=publish
json
Code:
{ "token": "your_api_token", "content": "文章内容" }

测试连接
Code:
GET index.php?option=com_aipublisher&task=test&token=your_api_token
获取API令牌
  1. 安装组件后复制显示的令牌
  2. 或在后台管理界面查看
  3. 或使用调试端点:
    Code:
    index.php?option=com_aipublisher&task=debug
示例代码cURL 发布文章
Code:
curl -X POST "https://your-domain.com/api/publish" \ -H "Content-Type: application/json" \ -d '{ "token": "your_token_here", "title": "测试文章", "content": "这是测试内容" }'

cURL 测试连接
Code:
​​​​​​​curl -X POST "https://your-domain.com/api/test-connection" \ -H "Content-Type: application/json" \ -d '{"token": "your_token_here"}'

Python 示例
Code:
import requests import json api_url = "https://your-domain.com/api/publish" token = "your_token_here" data = { "token": token, "title": "Python测试", "content": "通过Python API发布的内容" } response = requests.post(api_url, json=data) print(response.json())

错误代码
  • Code:
    200
    : 成功
  • Code:
    400
    : 请求参数错误
  • Code:
    401
    : 令牌无效
  • Code:
    404
    : 端点不存在
  • Code:
    500
    : 服务器内部错误
兼容性
  • Joomla 3.x, 4.x, 5.x
  • 支持标准RESTful API格式
  • 支持原来的Joomla URL格式
    EOF
cd ..重新打包
Code:
zip -r "com_aipublisher_api_adapter.zip" "com_aipublisher_final"
echo ""
echo "=============================================="
echo "✅ 第三方程序API适配器创建完成!"
echo "=============================================="
echo ""
echo "📦 安装包: com_aipublisher_api_adapter.zip"
echo ""
echo "✨ 新增功能:"
echo " ✅ 新增 site/api.php - RESTful API适配器"
echo " ✅ 新增 site/.htaccess - URL重写规则"
echo " ✅ 支持第三方程序的标准API端点"
echo " ✅ 版本升级到 1.1.0"
echo ""
echo "🔧 支持的第三方API端点:"
echo " ✅ POST /api/publish - 发布文章"
echo " ✅ POST /api/test-connection - 测试连接"
echo " ✅ POST /api/save-config - 保存配置"
echo " ✅ GET /api/conversations - 获取对话"
echo " ✅ GET /api/website-configs - 获取网站配置"
echo " ✅ GET /api/health - 健康检查"
echo " ✅ GET /api/info - API信息"
echo ""
echo "🔄 原来的Joomla端点仍然可用:"
echo " POST index.php?option=com_aipublisher&task=publish"
echo " GET index.php?option=com_aipublisher&task=test"
echo ""
echo "📖 详细文档:"
echo " 安装包中包含 API_USAGE.md 使用说明"
echo ""
echo "🚀 现在第三方程序应该能正常连接了!"
echo ""





 
Last edit: 2026-01-12 13:53 by service.

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 234

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

登录注册一个帐号 参加讨论


Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323
  • service
  • [service]
  • 帖子作者

  • Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    离线
  • 管理员
  • 管理员
更多
2026-01-12 13:32 #1011 by service
简单点的话就是在网站根目录下创建一个API
Code:
## 方案4: 快速修复脚本(如果只需要简单适配) ```bash #!/bin/bash # 快速修复 - 创建简单的API适配器 echo "🔧 快速创建API适配器..." echo "======================================" # 进入网站根目录(假设) cd /home # 创建API适配器 cat > "api.php" << 'EOF' <?php define('_JEXEC', 1); define('JPATH_BASE', __DIR__); require_once JPATH_BASE . '/includes/defines.php'; require_once JPATH_BASE . '/includes/framework.php'; $app = JFactory::getApplication('site'); $app->initialise(); // 设置响应头 header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type, Authorization'); // 处理预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {     http_response_code(200);     exit; } // 获取请求信息 $method = $_SERVER['REQUEST_METHOD']; $path = $_SERVER['REQUEST_URI']; // 简单的路由 if ($method === 'POST' && strpos($path, '/api/publish') !== false) {     handleApiPublish(); } elseif ($method === 'POST' && strpos($path, '/api/test-connection') !== false) {     handleApiTest(); } else {     http_response_code(404);     echo json_encode([         'status' => 'error',         'message' => 'Endpoint not found: ' . $path,         'suggestion' => 'Use /api/publish or /api/test-connection'     ]); } function handleApiPublish() {     try {         $input = json_decode(file_get_contents('php://input'), true);                  if (!$input || empty($input['token']) || empty($input['content'])) {             throw new Exception('Missing required fields: token and content');         }                  // 验证令牌         $params = JComponentHelper::getParams('com_aipublisher');         $storedToken = $params->get('api_token', '');                  if (empty($storedToken) || $input['token'] !== $storedToken) {             http_response_code(401);             echo json_encode(['status' => 'error', 'message' => 'Invalid token']);             return;         }                  // 重定向到Joomla组件         $url = JUri::root() . 'index.php?option=com_aipublisher&task=publish&token=' . urlencode($input['token']);                  // 使用cURL转发请求         $ch = curl_init($url);         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);         curl_setopt($ch, CURLOPT_POST, true);         curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($input));         curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);                  $response = curl_exec($ch);         $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);         curl_close($ch);                  http_response_code($httpCode);         echo $response;              } catch (Exception $e) {         http_response_code(400);         echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);     } } function handleApiTest() {     try {         $input = json_decode(file_get_contents('php://input'), true);                  if (!$input || empty($input['token'])) {             throw new Exception('Token is required');         }                  // 验证令牌         $params = JComponentHelper::getParams('com_aipublisher');         $storedToken = $params->get('api_token', '');                  if (empty($storedToken) || $input['token'] !== $storedToken) {             http_response_code(401);             echo json_encode(['status' => 'error', 'message' => 'Invalid token']);             return;         }                  echo json_encode([             'status' => 'success',             'message' => 'Connection successful',             'timestamp' => date('Y-m-d H:i:s'),             'joomla_version' => JVERSION         ]);              } catch (Exception $e) {         http_response_code(400);         echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);     } } EOF echo "" echo "✅ 快速API适配器创建完成!" echo "" echo "📁 文件位置: /home/api.php" echo "" echo "🔗 现在可以访问:" echo "  POST https://www.com/api/publish" echo "  POST https://www.com/api/test-connection" echo "" echo "📝 示例请求:" echo 'curl -X POST "https://www.com/api/publish" \' echo '  -H "Content-Type: application/json" \' echo '  -d '\''{"token":"YOUR_TOKEN","content":"测试内容"}'\' echo ""

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

登录注册一个帐号 参加讨论


Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323
  • service
  • [service]
  • 帖子作者

  • Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    离线
  • 管理员
  • 管理员
更多
2026-01-12 14:19 - 2026-01-12 14:19 #1012 by service
适配器不好用。考虑到已经有一个稳定工作的版本(使用 task=publish 参数),建议:

保持现有的 aipublisher.php 稳定版不变(它已经工作正常)
将API适配器作为可选功能,让用户可以选择使用REST风格API或传统风格
添加一个兼容层,让REST API调用可以转换为传统调用
或者简单一点:告诉第三方使用传统方式调用:

POST /index.php?option=com_aipublisher&task=publish&token=...
而不是 /api/publish
Last edit: 2026-01-12 14:19 by service.

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

登录注册一个帐号 参加讨论


Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323
  • service
  • [service]
  • 帖子作者

  • Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    离线
  • 管理员
  • 管理员
更多
2026-01-12 14:23 #1013 by service
这个适配器还有很多问题:主要问题分析:
  1. REST API路由问题:你的 
    Code:
    api.php
     使用 
    Code:
    /api/
     前缀,但路由映射中缺少对多种路径格式的支持
  2. Joomla SEF URL问题:可能由于Joomla的URL重写,
    Code:
    /api/publish
     没有正确路由到 
    Code:
    api.php
  3. XML文件冲突:你有两个 
    Code:
    com_aipublisher.xml
     文件,这会导致安装问题
具体修复:1. 修复 
Code:
api.php
 的路由问题修改 
Code:
api.php
 开头的路径处理逻辑:php
Code:
​​​​​​​// 获取请求方法和路径 $method = $_SERVER['REQUEST_METHOD']; $requestUri = $_SERVER['REQUEST_URI']; // 移除查询字符串 $path = parse_url($requestUri, PHP_URL_PATH); $path = strtok($path, '?'); // 处理不同的URL前缀 // 1. 直接访问 /api.php if ($path === '/api.php') { $path = '/api'; } // 2. 访问 /api.php/api/publish 等情况 elseif (strpos($path, '/api.php') === 0) { $path = '/api' . substr($path, 8); } // 完整的路由映射表 $routes = [ 'POST' => [ '/api/publish' => 'handleApiPublish', '/api/test-connection' => 'handleApiTestConnection', '/api/save-config' => 'handleApiSaveConfig', '/api/conversations' => 'handleApiConversations' ], 'GET' => [ '/api/conversations' => 'handleApiGetConversations', '/api/website-configs' => 'handleApiGetWebsiteConfigs', '/api/health' => 'handleApiHealth', '/api/info' => 'handleApiInfo', '/api/status' => 'handleApiStatus', // 添加根路径路由 '/' => 'handleApiInfo', '/api' => 'handleApiInfo' ], 'PUT' => [ '/api/update-config' => 'handleApiUpdateConfig' ] ]; // 查找匹配的路由 - 改进匹配逻辑 $handler = null; $matchedRoute = null; if (isset($routes[$method])) { foreach ($routes[$method] as $route => $handlerName) { // 精确匹配 if ($path === $route) { $handler = $handlerName; $matchedRoute = $route; break; } // 前缀匹配(用于/api/路径) elseif ($route === '/api' && strpos($path, '/api') === 0) { $handler = $handlerName; $matchedRoute = $route; break; } } }
2. 添加Joomla集成函数在 
Code:
api.php
 中添加Joomla环境检测:php​​​​​​​
Code:
// 尝试自动加载Joomla function loadJoomlaEnvironment() { if (defined('_JEXEC')) { return true; } // 寻找Joomla根目录 $possiblePaths = [ dirname(__DIR__), dirname(dirname(__DIR__)), realpath(dirname(__FILE__) . '/../../..'), $_SERVER['DOCUMENT_ROOT'] ]; foreach ($possiblePaths as $basePath) { $joomlaPath = $basePath . '/includes/defines.php'; if (file_exists($joomlaPath)) { define('_JEXEC', 1); define('JPATH_BASE', $basePath); require_once $joomlaPath; require_once JPATH_BASE . '/includes/framework.php'; // 初始化应用程序 $app = JFactory::getApplication('site'); return true; } } return false; } // 加载Joomla环境 if (!loadJoomlaEnvironment()) { http_response_code(500); echo json_encode([ 'status' => 'error', 'message' => 'Joomla environment not found', 'code' => 'JOOMLA_NOT_FOUND' ]); exit; }
3. 修复XML文件冲突不要覆盖原有的 
Code:
com_aipublisher.xml
,而是创建一个新版本:修改 
Code:
third_part_API_adapt.sh
 中的这一部分:bash​​​​​​​
Code:
# 3. 更新XML文件(改为添加而不是覆盖) cat >> "com_aipublisher.xml" << 'XML_EOF' <files folder="site"> <filename>api.php</filename> <filename>.htaccess</filename> </files> XML_EOF
或者更好的方法:创建一个新的XML文件专门用于API适配器。4. 添加API测试端点在 
Code:
api.php
 中添加一个简单的测试端点来验证路由:php​​​​​​​
Code:
/** * 处理API根路径 */ function handleApiRoot() { echo json_encode([ 'status' => 'success', 'message' => 'AI Publisher API is running', 'version' => '1.1.0', 'timestamp' => date('Y-m-d H:i:s'), 'endpoints' => getAvailableEndpoints()['endpoints'] ]); } // 在路由表中添加 $routes = [ // ... 其他路由 'GET' => [ // ... 其他GET路由 '/' => 'handleApiRoot', '/api' => 'handleApiRoot' ] ];
5. 修复 
Code:
.htaccess
 文件更新 
Code:
.htaccess
 以更好地处理API路由:bash​​​​​​​
Code:
cat > "site/.htaccess" << 'HTACCESS_EOF' # AI Publisher API - URL Rewrite Rules <IfModule mod_rewrite.c> RewriteEngine On # 重写API请求到api.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^api/(.*)$ api.php?path=$1 [QSA,L] # 支持直接访问/api路径 RewriteCond %{REQUEST_URI} ^/api$ RewriteRule ^api$ api.php [QSA,L] # 直接访问api.php RewriteCond %{REQUEST_URI} ^/api\.php$ RewriteRule ^api\.php$ api.php [QSA,L] </IfModule> # CORS头部 <IfModule mod_headers.c> Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With" Header set X-Content-Type-Options "nosniff" Header set X-Frame-Options "SAMEORIGIN" Header set X-XSS-Protection "1; mode=block" # 处理OPTIONS预检请求 RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ $1 [R=200,L] </IfModule> HTACCESS_EOF
6. 添加调试信息在API响应中添加更多调试信息:
 php
Code:
// 在所有API响应中添加路径信息 echo json_encode([ 'status' => 'success', 'message' => 'Article published successfully', 'data' => $publishResult, 'meta' => [ 'timestamp' => date('Y-m-d H:i:s'), 'request_id' => uniqid('req_', true), 'processing_time' => getProcessingTime() . 'ms', 'debug' => [ 'request_path' => $path, 'request_method' => $method, 'matched_route' => $matchedRoute ] ] ]);
建议的解决方案:考虑到你已经有一个稳定工作的版本(使用 
Code:
task=publish
 参数),建议:
  1. 保持现有的 
    Code:
    aipublisher.php
     稳定版不变(它已经工作正常)
  2. 将API适配器作为可选功能,让用户可以选择使用REST风格API或传统风格
  3. 添加一个兼容层,让REST API调用可以转换为传统调用
或者简单一点:告诉第三方使用传统方式调用:
  • Code:
    POST /index.php?option=com_aipublisher&task=publish&token=...
  • 而不是 
    Code:
    /api/publish

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

登录注册一个帐号 参加讨论


Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323
  • service
  • [service]
  • 帖子作者

  • Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    离线
  • 管理员
  • 管理员
更多
2026-01-12 15:32 #1014 by service
可以。知识API的访问方式不同

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

登录注册一个帐号 参加讨论


Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323

Deprecated: Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/cbPluginHandler.php on line 323
  • service
  • [service]
  • 帖子作者

  • Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

    Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239
    离线
  • 管理员
  • 管理员
更多
2026-01-12 17:39 #1017 by service
手动测试网站API
Code:
# 测试传统API curl -X POST "https://bluetooth.com.cn/home/index.php?option=com_aipublisher&task=publish&format=json" \   -H "Content-Type: application/json" \   -d '{"title":"Test","content":"Test content","category":"test","api_key":"your_key"}' # 测试REST API curl -X POST "https://bluetooth.com.cn/api.php/api/publish" \   -H "Content-Type: application/json" \   -d '{"title":"Test","content":"Test content","category":"test","api_key":"your_key"}'

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 189

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 237

Deprecated: Using null as an array offset is deprecated, use an empty string instead in /var/www/html/libraries/CBLib/CB/Legacy/LegacyFoundationFunctions.php on line 239

登录注册一个帐号 参加讨论

核心: Kunena 论坛
FaLang translation system by Faboba

Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in /var/www/html/plugins/system/falangdriver/falangdriver.php on line 100

Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in /var/www/html/plugins/system/falangdriver/falangdriver.php on line 100
mysqli object is already closed (500 Whoops, looks like something went wrong.)

Error

HTTP 500 Whoops, looks like something went wrong.

mysqli object is already closed

Exception

Error

  1. */
  2. public function disconnect()
  3. {
  4. // Close the connection.
  5. if (\is_callable([$this->connection, 'close'])) {
  6. $this->connection->close();
  7. }
  8. parent::disconnect();
  9. }
  1. */
  2. public function disconnect()
  3. {
  4. // Close the connection.
  5. if (\is_callable([$this->connection, 'close'])) {
  6. $this->connection->close();
  7. }
  8. parent::disconnect();
  9. }
  1. *
  2. * @since 2.0.0
  3. */
  4. public function __destruct()
  5. {
  6. $this->disconnect();
  7. }
  8. /**
  9. * Alter database's character set.
  10. *
DatabaseDriver->__destruct()

Stack Trace

Error
Error:
mysqli object is already closed

  at /var/www/html/libraries/vendor/joomla/database/src/Mysqli/MysqliDriver.php:318
  at mysqli->close()
     (/var/www/html/libraries/vendor/joomla/database/src/Mysqli/MysqliDriver.php:318)
  at Joomla\Database\Mysqli\MysqliDriver->disconnect()
     (/var/www/html/libraries/vendor/joomla/database/src/DatabaseDriver.php:496)
  at Joomla\Database\DatabaseDriver->__destruct()                

Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in /var/www/html/plugins/system/falangdriver/falangdriver.php on line 100

Deprecated: Method ReflectionProperty::setAccessible() is deprecated since 8.5, as it has no effect since PHP 8.1 in /var/www/html/plugins/system/falangdriver/falangdriver.php on line 100