public static function resource($path, array $options) { $options = array_replace_recursive(["class" => null, "list_mode" => "list", "sql" => ["table" => null, "raw" => null, "primary_key" => "id"]], $options); $path = rtrim($path, "/") ?: "/"; $resource = $options["class"]; $table = $options["sql"]["table"]; $raw = $options["sql"]["raw"]; $pkey = $options["sql"]["primary_key"]; $sql_list = $raw ?: "SELECT * FROM {$table}"; $sql_single = strpos($sql_list, "WHERE") === false ? "{$sql_list} WHERE {$pkey}=:{$pkey}" : str_replace("WHERE ", "WHERE {$pkey}=:{$pkey} AND ", $sql_list); $sql_single .= " LIMIT 1"; // Ensure endpoint options sanity if (class_exists($resource, false) && ($table || $raw) && $pkey) { // List Route::on($path, function () use($resource, $table, $sql_list, $options) { $resource::setExposure($options["list_mode"]); return $resource::fromSQL($sql_list); }); // Single Route::on("{$path}/:id", function ($id) use($resource, $table, $pkey, $sql_single) { return ['data' => $resource::singleFromSQL($sql_single, ["{$pkey}" => $id]) ?: API::error("Not found", 404)]; }); // Projection short-hand Route::on("{$path}/:id/:parameter", function ($id, $parameter) use($resource, $table, $pkey, $sql_single) { Filter::add("api.{$resource}.getProjectionFields", function ($t) use($parameter) { return $parameter; }); return ['data' => $resource::singleFromSQL($sql_single, ["{$pkey}" => $id]) ?: API::error("Not found", 404)]; }); } }
/** * API initialization * * Launch all needed services to response to API request, first by checking * token and doing authentication if asked * * @version 1.0 * @return void */ public static function init() { // we store HTTP header & body content self::$headers = getallheaders(); self::$body = json_decode(file_get_contents('php://input')); // we check if request method is OPTIONS to send just headers without content if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { self::parsing(); self::result(); } // we search asked module & methods if (isset($_SERVER['PATH_INFO'])) { $path = substr($_SERVER['PATH_INFO'], 1); self::$module = explode('/', $path); } else { self::$module = array(); } // we check if a token exist and we store it if (isset(self::$headers['Authorization']) && substr(self::$headers['Authorization'], 0, 4) == Configuration::read('token')) { $token = explode(' ', self::$headers['Authorization']); self::$token = $token[1]; } // we check if an authenticate is asked or if client have a valid token if (isset(self::$module[0]) && self::$module[0] == 'authenticate') { self::auth(); } else { self::token_auth(); } // we try connection to bdd client $dsn['client'] = 'mysql:host=' . Configuration::read('db.host') . ';port=' . Configuration::read('db.port') . ';dbname=leqg_' . self::$client . ';charset=utf8'; // We try to connect the script to the LeQG Core MySQL DB try { $dbh['client'] = new PDO($dsn['client'], Configuration::read('db.user'), Configuration::read('db.pass')); // We save in configuration class the SQL link Configuration::write('db.client', $dbh['client']); } catch (PDOException $e) { // We store SQL connection error into the API result API::error(503, 'SQLConnectionFail', 'Can not connect to the client database server.'); // We stop script execution exit; } // we launch client asked module if (!empty(self::$module[0]) && class_exists(self::$module[0])) { $module = self::$module[0]; ${$module} = new $module(); } elseif (!empty(self::$module[0]) && self::$module[0] != 'authenticate') { API::error(404, 'UnknownModule', 'Vous demandez un module qui n\'existe pas'); } elseif (empty(self::$module[0])) { API::error(404, 'UnknownModule', 'Vous demandez un module qui n\'existe pas'); } }
/** * 运行控制器 * @access public * @return void */ public static function run() { // 设定错误和异常处理 set_error_handler(array('App', 'appError')); set_exception_handler(array('App', 'appException')); // 时区检查 date_default_timezone_set('PRC'); // Session初始化 if (!session_id()) { session_start(); } // 模版检查 $GLOBALS['time_run_detail']['init_end'] = microtime(true); //检查服务器是否开启了zlib拓展 if (C('GZIP_OPEN') && extension_loaded('zlib') && function_exists('ob_gzhandler')) { ob_end_clean(); ob_start('ob_gzhandler'); } $GLOBALS['time_run_detail']['obstart'] = microtime(true); if (constant('API_VERSION')) { $class_file = SITE_PATH . '/api/' . API_VERSION . '/' . MODULE_NAME . 'Api.class.php'; } else { $class_file = SITE_PATH . '/api/thinksns/' . MODULE_NAME . 'Api.class.php'; } if (!file_exists($class_file)) { $message['msg'] = '接口不存在'; $message['status'] = 404; API::error($message); } //执行当前操作 include $class_file; $className = MODULE_NAME . 'Api'; $module = new $className(); $action = ACTION_NAME; $data = call_user_func(array(&$module, $action)); //格式化输出 if ($_REQUEST['format'] == 'php') { //输出php格式 echo var_export($data); } elseif ($_REQUEST['format'] == 'test') { //测试输出 header('Content-type:text/html;charset=utf-8'); echo '<pre>'; print_r($data); } else { echo json_encode($data); } //输出buffer中的内容,即压缩后的css文件 if (C('GZIP_OPEN') && extension_loaded('zlib') && function_exists('ob_gzhandler')) { ob_end_flush(); } $GLOBALS['time_run_detail']['obflush'] = microtime(true); if (C('LOG_RECORD')) { Log::save(); } return; }
/** * 运行控制器 */ public static function run() { // 设定错误和异常处理 set_error_handler(array('App', 'appError')); set_exception_handler(array('App', 'appException')); // Session初始化 if (!session_id()) { session_start(); } // 模版检查 $GLOBALS['time_run_detail']['init_end'] = microtime(true); //检查服务器是否开启了zlib拓展 if (C('GZIP_OPEN') && extension_loaded('zlib') && function_exists('ob_gzhandler')) { ob_end_clean(); ob_start('ob_gzhandler'); } $GLOBALS['time_run_detail']['obstart'] = microtime(true); $pharApiFile = sprintf('%s/api/ts-api.phar', TS_ROOT); if (constant('API_VERSION') && API_VERSION == 'sociax' && !\Medz\Component\Filesystem\Filesystem::exists(sprintf('%s/api/sociax', TS_ROOT))) { $class_file = sprintf('phar://%s/%sApi.class.php', $pharApiFile, MODULE_NAME); } elseif (constant('API_VERSION')) { $class_file = SITE_PATH . '/api/' . API_VERSION . '/' . MODULE_NAME . 'Api.class.php'; } else { $class_file = SITE_PATH . '/api/thinksns/' . MODULE_NAME . 'Api.class.php'; } if (!file_exists($class_file)) { $message['msg'] = '接口不存在'; $message['status'] = 404; API::error($message); } //执行当前操作 include $class_file; $className = MODULE_NAME . 'Api'; $module = new $className(); $action = ACTION_NAME; $data = call_user_func(array(&$module, $action)); //格式化输出 if ($_REQUEST['format'] == 'php') { //输出php格式 echo var_export($data); } elseif ($_REQUEST['format'] == 'test') { //测试输出 dump($data); } else { header('Content-Type:application/json'); echo json_encode($data); } //输出buffer中的内容,即压缩后的css文件 if (C('GZIP_OPEN') && extension_loaded('zlib') && function_exists('ob_gzhandler')) { ob_end_flush(); } $GLOBALS['time_run_detail']['obflush'] = microtime(true); if (C('LOG_RECORD')) { Log::save(); } return; }
return false; } } // We load configuration file $configuration = parse_ini_file('config.ini', true); // We store token name into Configuration datas Configuration::write('token', $configuration['token']['name']); Configuration::write('url', $configuration['url']['base']); Configuration::write('db.host', $configuration['core']['host']); Configuration::write('db.port', $configuration['core']['port']); Configuration::write('db.user', $configuration['core']['user']); Configuration::write('db.pass', $configuration['core']['pass']); // We prepare the data source name information for LeQG Core MySQL DB $dsn['core'] = 'mysql:host=' . $configuration['core']['host'] . ';port=' . $configuration['core']['port'] . ';dbname=leqg_core;charset=utf8'; // We try to connect the script to the LeQG Core MySQL DB try { $dbh['core'] = new PDO($dsn['core'], $configuration['core']['user'], $configuration['core']['pass']); // We save in configuration class the SQL link Configuration::write('db.core', $dbh['core']); } catch (PDOException $e) { // We store SQL connection error into the API result API::error(503, 'CentralAuthSystemCanConnect', 'Can not connect to the central authentication server.'); // We stop script execution exit; } // We initiate API processing API::init(); // We parse API result to JSON format API::parsing(); // We display API result and return HTTP response code API::result();
/** * Return informations about an interaction * * @version 1.0 * @param int $contact Contact ID * @param int $id Interaction ID * @return void */ public function interaction($contact, $id) { // we search interaction data $query = API::query('contact_interaction'); $query->bindParam(':event', $id, PDO::PARAM_INT); $query->bindParam(':contact', $contact, PDO::PARAM_INT); $query->execute(); // we check if wa have an answer if ($query->rowCount() == 1) { // Yay! we have a contact detail! API::response(200); // we load contact informations $data = $query->fetch(PDO::FETCH_ASSOC); // we put contact into links section $data['links']['contact'] = $data['contact']; API::link('interactions', 'contact', 'contact'); unset($data['contact']); // we put directory data into links section, if exists if (!is_null($data['dossier'])) { $data['links']['dossier'] = $data['dossier']; API::link('interactions', 'dossier', 'dossier'); unset($data['dossier']); } else { unset($data['dossier']); } // we put user data into links section $data['links']['utilisateur'] = $data['utilisateur']; API::link('interactions', 'utilisateur', 'utilisateur'); unset($data['utilisateur']); // we add contact information to JSON response API::add('interactions', $data); } else { // we display an error API::error(404, 'EventUnknown', 'L\'élément d\'historique demandé n\'existe pas.'); } }
$token = $app->request->headers->get('Token'); if (!Token::Validate($token) && $token != ADMIN_TOKEN) { throw new Exception("Invalid token", 400); } } } }); /*====================================================================================================================== * ERROR HANDLERS * Wraps the response of any raised exception into a friendly JSON encoded error message readable by the client =====================================================================================================================*/ /* Render a custom JSON message whenever an exception is thrown **********************************************************************************************************************/ $app->error(function (Exception $e) use($app) { if ($e->getCode() !== 0) { $app->response->setStatus($e->getCode()); } $app->render_json(["error" => $e->getMessage()]); }); // Default message for inexistent api paths $app->notFound(function () { throw new Exception("This endpoint does not exist", 404); }); /*====================================================================================================================== * ROUTES * Main endpoints of the API * The HTTP method is determined by the method called by the $app object (ie. "$app->post()") * The first parameter is the url path from the api * * EXAMLPE: GET https://api.soccerwars.xyz/users/2 will map to the route * $app->get('/users/:id', function($id) ... Where $id will have the value '2' =====================================================================================================================*/
/* |-------------------------------------------------------------------------- | Handle Unauthorised (API Access) |-------------------------------------------------------------------------- */ API::error(function (Zeropingheroes\Lanager\Domain\AuthorisationException $exception) { // Treat as HTTP 403 return handleHttpError(403, ['source' => 'api', 'description' => $exception->getMessage()]); }); /* |-------------------------------------------------------------------------- | Handle Model Not Found (API Access) |-------------------------------------------------------------------------- */ API::error(function (Illuminate\Database\Eloquent\ModelNotFoundException $exception) { // Treat as HTTP 404 return handleHttpError(404, ['source' => 'api']); }); /* |-------------------------------------------------------------------------- | Handler Function for Common HTTP Status Codes |-------------------------------------------------------------------------- */ function handleHttpError($httpStatusCode, $options = []) { switch ($httpStatusCode) { case 400: $httpStatusName = 'Bad request'; $httpDescription = 'The server cannot or will not process the request due to a client error.'; $level = 'notice'; break; case 401: