Added basic router initialization and basic request handling (Prototype)
This commit is contained in:
parent
eefda29f88
commit
78ce281b0c
5
Makefile
5
Makefile
|
@ -4,12 +4,15 @@ clean:
|
|||
build:
|
||||
mkdir build
|
||||
ppm --no-intro --cerror --compile="src/KimchiAPI" --directory="build"
|
||||
ppm --no-intro --cerror --compile="api_handler" --directory="build"
|
||||
|
||||
update:
|
||||
ppm --generate-package="src/KimchiAPI"
|
||||
|
||||
install:
|
||||
ppm --no-intro --no-prompt --fix-conflict --install="build/net.intellivoid.kimchi_api.ppm"
|
||||
ppm --no-intro --no-prompt --fix-conflict --install="build/net.intellivoid.test_api.ppm"
|
||||
|
||||
install_fast:
|
||||
ppm --no-intro --no-prompt --fix-conflict --skip-dependencies --install="build/net.intellivoid.kimchi_api.ppm"
|
||||
ppm --no-intro --no-prompt --fix-conflict --skip-dependencies --install="build/net.intellivoid.kimchi_api.ppm"
|
||||
ppm --no-intro --no-prompt --fix-conflict --skip-dependencies --install="build/net.intellivoid.test_api.ppm"
|
|
@ -0,0 +1,3 @@
|
|||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule . index.php [L]
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
require 'ppm';
|
||||
require 'net.intellivoid.kimchi_api';
|
||||
|
||||
\KimchiAPI\KimchiAPI::exec('net.intellivoid.test_api==latest');
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Methods\v1;
|
||||
|
||||
class Ping extends \KimchiAPI\Abstracts\Command
|
||||
class PingMethod extends \KimchiAPI\Abstracts\Method
|
||||
{
|
||||
|
||||
public function execute()
|
|
@ -1,32 +1,20 @@
|
|||
{
|
||||
"name": "Example API service",
|
||||
"version": "1.0.0.0",
|
||||
"author": "Zi Xing Narrakas",
|
||||
"organization": "Intellivoid Technologies",
|
||||
"configuration": {
|
||||
"logging_enabled": true,
|
||||
"root_path": "/test",
|
||||
"framework_signature": true,
|
||||
"api_signature": true,
|
||||
"khm_enabled": true,
|
||||
"firewall_deny": [],
|
||||
"headers": {}
|
||||
},
|
||||
"versions": [
|
||||
{
|
||||
"version": "v1",
|
||||
"enabled": true,
|
||||
"namespace": "Methods\\v1",
|
||||
"response_standard": "1.0",
|
||||
"methods": [
|
||||
{"method": ["GET", "POST"], "path": "ping", "class": "Ping", "params": []}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "v2",
|
||||
"enabled": true,
|
||||
"namespace": "Methods\\v2",
|
||||
"response_standard": "2.0",
|
||||
"methods": [
|
||||
{"method": ["GET", "POST"], "path": "ping", "class": "Ping", "params": []}
|
||||
{"methods": ["GET", "POST"], "path": "ping", "class": "PingMethod"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"package": {
|
||||
"package_name": "net.intellivoid.test_api",
|
||||
"name": "Test API",
|
||||
"version": "1.0.0.0",
|
||||
"author": "Test",
|
||||
"organization": "Test",
|
||||
"description": "Test API",
|
||||
"url": "https://example.com/",
|
||||
"dependencies": [
|
||||
{
|
||||
"package": "net.intellivoid.kimchi_api",
|
||||
"version": "latest",
|
||||
"source": "default@github/intellivoid/KimchiAPI",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
"autoload_method": "generated_spl",
|
||||
"main": null,
|
||||
"post_installation": [],
|
||||
"pre_installation": []
|
||||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"required": true,
|
||||
"file": "Methods/v1/PingMethod.php"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
"package.json",
|
||||
"configuration.json"
|
||||
]
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
use KimchiAPI\KimchiAPI;
|
||||
use KimchiAPI\Objects\Request;
|
||||
|
||||
abstract class Command
|
||||
abstract class Method
|
||||
{
|
||||
/**
|
||||
* Auth level for user commands
|
|
@ -0,0 +1,172 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace KimchiAPI\Classes;
|
||||
|
||||
use khm\Exceptions\DatabaseException;
|
||||
use khm\khm;
|
||||
use KimchiAPI\Exceptions\ApiException;
|
||||
use KimchiAPI\Exceptions\ConnectionBlockedException;
|
||||
use KimchiAPI\Exceptions\InternalServerException;
|
||||
use KimchiAPI\Exceptions\IOException;
|
||||
use KimchiAPI\Objects\Configuration;
|
||||
use KimchiAPI\Utilities\Client;
|
||||
|
||||
class API
|
||||
{
|
||||
/**
|
||||
* @var Configuration
|
||||
*/
|
||||
private $Configuration;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $ResourcesPath;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $ConfigurationFilePath;
|
||||
|
||||
/**
|
||||
* @var Router
|
||||
*/
|
||||
private $Router;
|
||||
|
||||
/**
|
||||
* @param string $resources_path
|
||||
* @throws IOException
|
||||
* @throws InternalServerException
|
||||
*/
|
||||
public function __construct(string $resources_path)
|
||||
{
|
||||
$this->ResourcesPath = $resources_path;
|
||||
$this->ConfigurationFilePath = $this->ResourcesPath . DIRECTORY_SEPARATOR . 'configuration.json';
|
||||
|
||||
if(file_exists($this->ConfigurationFilePath) == false)
|
||||
throw new IOException('The API configuration file \'configuration.json\' does not exist');
|
||||
|
||||
$DecodedConfiguration = json_decode(file_get_contents($this->ConfigurationFilePath), true);
|
||||
|
||||
if($DecodedConfiguration == false)
|
||||
throw new InternalServerException('Cannot read configuration file, ' . json_last_error_msg());
|
||||
|
||||
$this->Configuration = Configuration::fromArray($DecodedConfiguration);
|
||||
$this->Router = new Router();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Kimchi API server.
|
||||
*
|
||||
* @return void
|
||||
* @throws ApiException
|
||||
* @throws ConnectionBlockedException
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
if(defined('KIMCHI_API_INITIALIZED'))
|
||||
throw new ApiException('Cannot initialize ' . $this->Configuration->Name . ', another API is already initialized');
|
||||
|
||||
define('KIMCHI_API_RESOURCES_PATH', $this->ResourcesPath);
|
||||
define('KIMCHI_API_CONFIGURATION_PATH', $this->ConfigurationFilePath);
|
||||
define('KIMCHI_API_NAME', $this->Configuration->Name);
|
||||
define('KIMCHI_API_ROOT_PATH', $this->Configuration->ServerConfiguration->RootPath);
|
||||
define('KIMCHI_API_SIGNATURES', $this->Configuration->ServerConfiguration->ApiSignature);
|
||||
define('KIMCHI_API_FRAMEWORK_SIGNATURE', $this->Configuration->ServerConfiguration->FrameworkSignature);
|
||||
define('KIMCHI_API_LOGGING_ENABLED', $this->Configuration->ServerConfiguration->LoggingEnabled);
|
||||
define('KIMCHI_API_HEADERS', $this->Configuration->ServerConfiguration->Headers);
|
||||
|
||||
$this->defineClientDefinitions();
|
||||
$this->defineRoutes();
|
||||
|
||||
define('KIMCHI_API_INITIALIZED', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Configuration
|
||||
*/
|
||||
public function getConfiguration(): Configuration
|
||||
{
|
||||
return $this->Configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getResourcesPath(): string
|
||||
{
|
||||
return $this->ResourcesPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigurationFilePath(): string
|
||||
{
|
||||
return $this->ConfigurationFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Router
|
||||
*/
|
||||
public function getRouter(): Router
|
||||
{
|
||||
return $this->Router;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws \KimchiAPI\Exceptions\RouterException
|
||||
*/
|
||||
private function defineRoutes()
|
||||
{
|
||||
foreach($this->Configuration->Versions as $version)
|
||||
{
|
||||
foreach($version->Methods as $method)
|
||||
{
|
||||
$full_path = '/' . $version->Version . '/' . $method->Path;
|
||||
$this->Router->map(implode('|', $method->Methods), $full_path, function() use ($version, $method, $full_path)
|
||||
{
|
||||
print($full_path);
|
||||
exit();
|
||||
}, $version->Version . '/' . $method->Class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DatabaseException
|
||||
* @throws ConnectionBlockedException
|
||||
*/
|
||||
private function defineClientDefinitions()
|
||||
{
|
||||
define('KIMCHI_CLIENT_IP_ADDRESS', Client::getClientIP());
|
||||
|
||||
if($this->Configuration->ServerConfiguration->KhmEnabled)
|
||||
{
|
||||
$khm = new khm();
|
||||
$IdentifiedClient = $khm->identify();
|
||||
|
||||
define('KIMCHI_KHM_ENABLED', true);
|
||||
define('KIMCHI_KHM_FIREWALL', $this->Configuration->ServerConfiguration->FirewallDeny);
|
||||
define('KIMCHI_KHM_FLAGS', $IdentifiedClient->Flags);
|
||||
|
||||
foreach($this->Configuration->ServerConfiguration->FirewallDeny as $item)
|
||||
{
|
||||
if(in_array($item, $IdentifiedClient->Flags))
|
||||
{
|
||||
throw new ConnectionBlockedException('Firewall block rule ' . $item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
define('KIMCHI_KHM_ENABLED', false);
|
||||
define('KIMCHI_KHM_FIREWALL', null);
|
||||
define('KIMCHI_KHM_FLAGS', null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace KimchiAPI\Classes;
|
||||
|
||||
use KimchiAPI\Abstracts\RequestMethod;
|
||||
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* Defined dynamical parameters
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
private static $definedDynamicParameters;
|
||||
|
||||
/**
|
||||
* Returns the request method that was used
|
||||
*
|
||||
* @return string|RequestMethod
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public static function getRequestMethod(): string
|
||||
{
|
||||
return strtoupper($_SERVER['REQUEST_METHOD']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a POST parameter if it's set
|
||||
*
|
||||
* @param string $value
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getPostParameter(string $value): ?string
|
||||
{
|
||||
if(isset($_POST[$value]))
|
||||
return $_POST[$value];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all POST parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPostParameters(): array
|
||||
{
|
||||
return $_POST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a GET parameter if it's set
|
||||
*
|
||||
* @param string $value
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getGetParameter(string $value): ?string
|
||||
{
|
||||
if(isset($_GET[$value]))
|
||||
return $_GET[$value];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the GET parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getGetParameters(): array
|
||||
{
|
||||
return $_GET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a POST/GET Parameter
|
||||
*
|
||||
* @param string $value
|
||||
* @return string|null
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public static function getParameter(string $value): ?string
|
||||
{
|
||||
if(self::getGetParameter($value) !== null)
|
||||
return self::getGetParameter($value);
|
||||
|
||||
if(self::getPostParameter($value) !== null)
|
||||
return self::getPostParameter($value);
|
||||
|
||||
/** @noinspection PhpConditionAlreadyCheckedInspection */
|
||||
if(isset(self::getDefinedDynamicParameters()[$value]) !== null)
|
||||
return self::getDefinedDynamicParameters()[$value];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the parameters combined, could overwrite existing parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getParameters(): array
|
||||
{
|
||||
return array_merge(
|
||||
self::getGetParameters(),
|
||||
self::getPostParameters(),
|
||||
self::getDefinedDynamicParameters()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a defined Dynamical Parameter
|
||||
*
|
||||
* @param string $value
|
||||
* @return string|null
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public static function getDefinedDynamicParameter(string $value): ?string
|
||||
{
|
||||
if(isset(self::getDefinedDynamicParameters()[$value]))
|
||||
return self::getDefinedDynamicParameters()[$value];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define dynamical parameters
|
||||
*
|
||||
* @return array
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public static function getDefinedDynamicParameters(): array
|
||||
{
|
||||
return (self::$definedDynamicParameters == null ? [] : self::$definedDynamicParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the defined dynamical parameters
|
||||
*
|
||||
* @param array|null $definedDynamicParameters
|
||||
*/
|
||||
public static function setDefinedDynamicParameters(?array $definedDynamicParameters): void
|
||||
{
|
||||
self::$definedDynamicParameters = $definedDynamicParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the post body given by the client
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getPostBody(): ?string
|
||||
{
|
||||
$results = @file_get_contents('php://input');
|
||||
|
||||
if($results == false)
|
||||
$results = stream_get_contents(fopen('php://stdin', 'r'));
|
||||
|
||||
IF($results == false)
|
||||
return null;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,338 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Classes;
|
||||
|
||||
use KimchiAPI\Exceptions\RouterException;
|
||||
use Traversable;
|
||||
|
||||
class Router
|
||||
{
|
||||
/**
|
||||
* @var array Array of all routes (incl. named routes).
|
||||
*/
|
||||
protected $routes = array();
|
||||
|
||||
/**
|
||||
* @var array Array of all named routes.
|
||||
*/
|
||||
protected $namedRoutes = array();
|
||||
|
||||
/**
|
||||
* @var string Can be used to ignore leading part of the Request URL (if main file lives in subdirectory of host)
|
||||
*/
|
||||
protected $basePath = '';
|
||||
|
||||
/**
|
||||
* @var array Array of default match types (regex helpers)
|
||||
*/
|
||||
protected $matchTypes = array(
|
||||
'i' => '[0-9]++',
|
||||
'a' => '[0-9A-Za-z]++',
|
||||
'h' => '[0-9A-Fa-f]++',
|
||||
'*' => '.+?',
|
||||
'**' => '.++',
|
||||
'' => '[^/\.]++'
|
||||
);
|
||||
|
||||
/**
|
||||
* Create router in one call from config.
|
||||
*
|
||||
* @param array $routes
|
||||
* @param string $basePath
|
||||
* @param array $matchTypes
|
||||
* @throws RouterException
|
||||
*/
|
||||
public function __construct(array $routes=[], string $basePath = '', array $matchTypes=[])
|
||||
{
|
||||
$this->addRoutes($routes);
|
||||
$this->setBasePath($basePath);
|
||||
$this->addMatchTypes($matchTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all routes.
|
||||
* Useful if you want to process or display routes.
|
||||
* @return array All routes.
|
||||
*/
|
||||
public function getRoutes(): array
|
||||
{
|
||||
return $this->routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple routes at once from array in the following format:
|
||||
*
|
||||
* $routes = array(
|
||||
* array($method, $route, $target, $name)
|
||||
* );
|
||||
*
|
||||
* @param array $routes
|
||||
* @return void
|
||||
* @throws RouterException
|
||||
*/
|
||||
public function addRoutes(array $routes)
|
||||
{
|
||||
/** @noinspection PhpConditionAlreadyCheckedInspection */
|
||||
if(!is_array($routes) && !$routes instanceof Traversable)
|
||||
{
|
||||
throw new RouterException('Routes should be an array or an instance of Traversable');
|
||||
}
|
||||
|
||||
foreach($routes as $route)
|
||||
{
|
||||
call_user_func_array(array($this, 'map'), $route);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base path.
|
||||
* Useful if you are running your application from a subdirectory.
|
||||
* @param $basePath
|
||||
*/
|
||||
public function setBasePath($basePath)
|
||||
{
|
||||
$this->basePath = $basePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add named match types. It uses array_merge so keys can be overwritten.
|
||||
*
|
||||
* @param array $matchTypes The key is the name and the value is the regex.
|
||||
*/
|
||||
public function addMatchTypes(array $matchTypes)
|
||||
{
|
||||
$this->matchTypes = array_merge($this->matchTypes, $matchTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a route to a target
|
||||
*
|
||||
* @param string $method One of 5 HTTP Methods, or a pipe-separated list of multiple HTTP Methods (GET|POST|PATCH|PUT|DELETE)
|
||||
* @param string $route The route regex, custom regex must start with an @. You can use multiple pre-set regex filters, like [i:id]
|
||||
* @param mixed $target The target where this route should point to. Can be anything.
|
||||
* @param string|null $name Optional name of this route. Supply if you want to reverse route this url in your application.
|
||||
* @throws RouterException
|
||||
* @noinspection PhpMissingParamTypeInspection
|
||||
* @noinspection PhpUnnecessaryCurlyVarSyntaxInspection
|
||||
* @noinspection RedundantSuppression
|
||||
*/
|
||||
public function map(string $method, string $route, $target, string $name=null)
|
||||
{
|
||||
$route = KIMCHI_API_ROOT_PATH . $route;
|
||||
$this->routes[] = array($method, $route, $target, $name);
|
||||
|
||||
if($name)
|
||||
{
|
||||
if(isset($this->namedRoutes[$name]))
|
||||
{
|
||||
throw new RouterException("Can not redeclare route '{$name}'");
|
||||
}
|
||||
|
||||
$this->namedRoutes[$name] = $route;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reversed routing
|
||||
*
|
||||
* Generate the URL for a named route. Replace regexes with supplied parameters
|
||||
*
|
||||
* @param string $routeName The name of the route.
|
||||
* @param array $params
|
||||
* @return string The URL of the route with named parameters in place.
|
||||
* @throws RouterException
|
||||
* @noinspection PhpUnnecessaryCurlyVarSyntaxInspection
|
||||
*/
|
||||
public function generate(string $routeName, array $params=[]): string
|
||||
{
|
||||
|
||||
// Check if named route exists
|
||||
if(!isset($this->namedRoutes[$routeName]))
|
||||
{
|
||||
throw new RouterException("Route '{$routeName}' does not exist.");
|
||||
}
|
||||
|
||||
// Replace named parameters
|
||||
$route = $this->namedRoutes[$routeName];
|
||||
|
||||
// prepend base path to route url again
|
||||
$url = $this->basePath . $route;
|
||||
|
||||
/** @noinspection RegExpRedundantEscape */
|
||||
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER))
|
||||
{
|
||||
|
||||
foreach($matches as $index => $match)
|
||||
{
|
||||
/** @noinspection PhpUnusedLocalVariableInspection */
|
||||
list($block, $pre, $type, $param, $optional) = $match;
|
||||
|
||||
if ($pre)
|
||||
{
|
||||
$block = substr($block, 1);
|
||||
}
|
||||
|
||||
if(isset($params[$param]))
|
||||
{
|
||||
// Part is found, replace for param value
|
||||
$url = str_replace($block, $params[$param], $url);
|
||||
}
|
||||
elseif ($optional && $index !== 0)
|
||||
{
|
||||
// Only strip proceeding slash if it's not at the base
|
||||
$url = str_replace($pre . $block, '', $url);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Strip match block
|
||||
$url = str_replace($block, '', $url);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a given Request Url against stored routes
|
||||
* @param string|null $requestUrl
|
||||
* @param string|null $requestMethod
|
||||
* @return array|boolean Array with route information on success, false on failure (no match).
|
||||
* @noinspection PhpIssetCanBeReplacedWithCoalesceInspection
|
||||
*/
|
||||
public function match(?string $requestUrl=null, string $requestMethod = null)
|
||||
{
|
||||
|
||||
$params = array();
|
||||
/** @noinspection PhpUnusedLocalVariableInspection */
|
||||
$match = false;
|
||||
|
||||
// set Request Url if it isn't passed as parameter
|
||||
if($requestUrl === null)
|
||||
{
|
||||
$requestUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
|
||||
}
|
||||
|
||||
// strip base path from request url
|
||||
$requestUrl = substr($requestUrl, strlen($this->basePath));
|
||||
|
||||
// Strip query string (?a=b) from Request Url
|
||||
/** @noinspection SpellCheckingInspection */
|
||||
if (($strpos = strpos($requestUrl, '?')) !== false)
|
||||
{
|
||||
$requestUrl = substr($requestUrl, 0, $strpos);
|
||||
}
|
||||
|
||||
// set Request Method if it isn't passed as a parameter
|
||||
if($requestMethod === null)
|
||||
{
|
||||
$requestMethod = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
|
||||
}
|
||||
|
||||
foreach($this->routes as $handler)
|
||||
{
|
||||
|
||||
list($methods, $route, $target, $name) = $handler;
|
||||
$method_match = (stripos($methods, $requestMethod) !== false);
|
||||
|
||||
// Method did not match, continue to next route.
|
||||
if (!$method_match) continue;
|
||||
|
||||
if ($route === '*')
|
||||
{
|
||||
// * wildcard (matches all)
|
||||
$match = true;
|
||||
}
|
||||
elseif (isset($route[0]) && $route[0] === '@')
|
||||
{
|
||||
// @ regex delimiter
|
||||
$pattern = '`' . substr($route, 1) . '`u';
|
||||
$match = preg_match($pattern, $requestUrl, $params) === 1;
|
||||
}
|
||||
elseif (($position = strpos($route, '[')) === false)
|
||||
{
|
||||
// No params in url, do string comparison
|
||||
$match = strcmp($requestUrl, $route) === 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compare longest non-param string with url
|
||||
if (strncmp($requestUrl, $route, $position) !== 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$regex = $this->compileRoute($route);
|
||||
$match = preg_match($regex, $requestUrl, $params) === 1;
|
||||
}
|
||||
|
||||
if ($match)
|
||||
{
|
||||
|
||||
if ($params)
|
||||
{
|
||||
foreach($params as $key => $value)
|
||||
{
|
||||
if(is_numeric($key)) unset($params[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
Request::setDefinedDynamicParameters($params);
|
||||
|
||||
return array(
|
||||
'target' => $target,
|
||||
'params' => $params,
|
||||
'name' => $name
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the regex for a given route (EXPENSIVE)
|
||||
* @param $route
|
||||
* @return string
|
||||
*/
|
||||
protected function compileRoute($route): string
|
||||
{
|
||||
/** @noinspection RegExpRedundantEscape */
|
||||
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER))
|
||||
{
|
||||
|
||||
$matchTypes = $this->matchTypes;
|
||||
foreach($matches as $match)
|
||||
{
|
||||
list($block, $pre, $type, $param, $optional) = $match;
|
||||
|
||||
if (isset($matchTypes[$type]))
|
||||
{
|
||||
$type = $matchTypes[$type];
|
||||
}
|
||||
|
||||
if ($pre === '.')
|
||||
{
|
||||
$pre = '\.';
|
||||
}
|
||||
|
||||
$optional = $optional !== '' ? '?' : null;
|
||||
|
||||
//Older versions of PCRE require the 'P' in (?P<named>)
|
||||
$pattern = '(?:'
|
||||
. ($pre !== '' ? $pre : null)
|
||||
. '('
|
||||
. ($param !== '' ? "?P<$param>" : null)
|
||||
. $type
|
||||
. ')'
|
||||
. $optional
|
||||
. ')'
|
||||
. $optional;
|
||||
|
||||
$route = str_replace($block, $pattern, $route);
|
||||
}
|
||||
|
||||
}
|
||||
return "`^(?J)$route$`u";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class ApiException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", int $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class ConnectionBlockedException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", int $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class RouterException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", int $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,25 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace KimchiAPI;
|
||||
|
||||
// Define server information for response headers
|
||||
use KimchiAPI\Abstracts\Command;
|
||||
use Exception;
|
||||
use khm\Exceptions\DatabaseException;
|
||||
use KimchiAPI\Abstracts\Method;
|
||||
use KimchiAPI\Classes\API;
|
||||
use KimchiAPI\Exceptions\IOException;
|
||||
use KimchiAPI\Exceptions\MissingComponentsException;
|
||||
use KimchiAPI\Utilities\Converter;
|
||||
use ppm\Exceptions\AutoloaderException;
|
||||
use ppm\Exceptions\InvalidComponentException;
|
||||
use ppm\Exceptions\InvalidPackageLockException;
|
||||
use ppm\Exceptions\PackageNotFoundException;
|
||||
use ppm\Exceptions\VersionNotFoundException;
|
||||
use ppm\ppm;
|
||||
use RuntimeException;
|
||||
|
||||
// Define server information for response headers
|
||||
if(defined("KIMCHI_API_SERVER") == false)
|
||||
{
|
||||
if(file_exists(__DIR__ . DIRECTORY_SEPARATOR . "package.json") == false)
|
||||
|
@ -70,7 +81,7 @@
|
|||
/**
|
||||
* Add a single custom commands path
|
||||
*
|
||||
* @param string $path Custom commands path to add
|
||||
* @param string $path Custom commands' path to add
|
||||
* @param bool $before If the path should be prepended or appended to the list
|
||||
* @throws IOException
|
||||
*/
|
||||
|
@ -78,7 +89,7 @@
|
|||
{
|
||||
if (!is_dir($path))
|
||||
{
|
||||
throw new IOException('Commands path "' . $path . '" does not exist.');
|
||||
throw new IOException('Method path "' . $path . '" does not exist.');
|
||||
}
|
||||
elseif (!in_array($path, $this->commands_paths, true))
|
||||
{
|
||||
|
@ -115,17 +126,17 @@
|
|||
* @param string $command
|
||||
* @param string $filepath
|
||||
*
|
||||
* @return Command|null
|
||||
* @return Method|null
|
||||
*/
|
||||
public function getCommandObject(string $command, string $filepath = ''): ?Command
|
||||
public function getCommandObject(string $command, string $filepath = ''): ?Method
|
||||
{
|
||||
if (isset($this->commands_objects[$command]))
|
||||
{
|
||||
return $this->commands_objects[$command];
|
||||
}
|
||||
|
||||
$which = [Command::AUTH_SYSTEM];
|
||||
$which[] = Command::AUTH_USER;
|
||||
$which = [Method::AUTH_SYSTEM];
|
||||
$which[] = Method::AUTH_USER;
|
||||
|
||||
foreach ($which as $auth)
|
||||
{
|
||||
|
@ -163,7 +174,7 @@
|
|||
}
|
||||
|
||||
// Start with default namespace.
|
||||
$command_namespace = __NAMESPACE__ . '\\Commands\\' . $auth . 'Commands';
|
||||
$command_namespace = __NAMESPACE__ . '\\Methods\\' . $auth . 'Methods';
|
||||
|
||||
// Check if we can get the namespace from the file (if passed).
|
||||
if ($filepath && !($command_namespace = Converter::getFileNamespace($filepath)))
|
||||
|
@ -171,7 +182,7 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
$command_class = $command_namespace . '\\' . Converter::ucFirstUnicode($command) . 'Command';
|
||||
$command_class = $command_namespace . '\\' . Converter::ucFirstUnicode($command) . 'Method';
|
||||
|
||||
if (class_exists($command_class))
|
||||
{
|
||||
|
@ -180,4 +191,65 @@
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $package
|
||||
* @param bool $import_dependencies
|
||||
* @param bool $throw_error
|
||||
* @throws AutoloaderException
|
||||
* @throws Exceptions\ApiException
|
||||
* @throws Exceptions\ConnectionBlockedException
|
||||
* @throws Exceptions\InternalServerException
|
||||
* @throws IOException
|
||||
* @throws InvalidComponentException
|
||||
* @throws InvalidPackageLockException
|
||||
* @throws PackageNotFoundException
|
||||
* @throws VersionNotFoundException
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
public static function exec(string $package, bool $import_dependencies=true, bool $throw_error=true)
|
||||
{
|
||||
$decoded = explode('==', $package);
|
||||
if($decoded[1] == 'latest')
|
||||
$decoded[1] = ppm::getPackageLock()->getPackage($decoded[0])->getLatestVersion();
|
||||
$path = ppm::getPackageLock()->getPackage($decoded[0])->getPackagePath($decoded[1]); // Find the package path
|
||||
ppm::import($decoded[0], $decoded[1], $import_dependencies, $throw_error); // Import dependencies
|
||||
|
||||
$API = new API($path);
|
||||
$API->initialize();
|
||||
self::handleRequest($API);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the request to the API
|
||||
*
|
||||
* @param API $API
|
||||
* @param string|null $requestUrl
|
||||
* @param string|null $requestMethod
|
||||
* @return void
|
||||
*/
|
||||
public static function handleRequest(API $API, ?string $requestUrl=null, string $requestMethod = null)
|
||||
{
|
||||
$match = $API->getRouter()->match($requestUrl, $requestMethod);
|
||||
|
||||
// call closure or throw 404 status
|
||||
if(is_array($match) && is_callable($match['target']))
|
||||
{
|
||||
try
|
||||
{
|
||||
call_user_func_array($match['target'], array_values($match['params']));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
var_dump($e);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var_dump($API->getRouter()->getRoutes());
|
||||
print("404");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,75 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace KimchiAPI\Objects;
|
||||
|
||||
use KimchiAPI\Objects\Configuration\ServerConfiguration;
|
||||
use KimchiAPI\Objects\Configuration\VersionConfiguration;
|
||||
|
||||
class Configuration
|
||||
{
|
||||
/**
|
||||
* The name of the API service
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Name;
|
||||
|
||||
public $Version;
|
||||
/**
|
||||
* The configuration for the KimchiAPI server
|
||||
*
|
||||
* @var ServerConfiguration
|
||||
*/
|
||||
public $ServerConfiguration;
|
||||
|
||||
public $Author;
|
||||
/**
|
||||
* An array of version configurations
|
||||
*
|
||||
* @var VersionConfiguration[]
|
||||
*/
|
||||
public $Versions;
|
||||
|
||||
public $Organization;
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$versions = [];
|
||||
foreach($this->Versions as $version)
|
||||
$versions[] = $version->toArray();
|
||||
|
||||
return [
|
||||
'name' => $this->Name,
|
||||
'configuration' => $this->ServerConfiguration->toArray(),
|
||||
'versions' => $versions
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array configuration
|
||||
*
|
||||
* @param array $data
|
||||
* @return Configuration
|
||||
*/
|
||||
public static function fromArray(array $data): Configuration
|
||||
{
|
||||
$configuration_object = new Configuration();
|
||||
|
||||
if(isset($data['name']))
|
||||
$configuration_object->Name = $data['name'];
|
||||
|
||||
if(isset($data['configuration']))
|
||||
$configuration_object->ServerConfiguration = ServerConfiguration::fromArray($data['configuration']);
|
||||
|
||||
if(isset($data['versions']))
|
||||
{
|
||||
foreach($data['versions'] as $version)
|
||||
$configuration_object->Versions[] = VersionConfiguration::fromArray($version);
|
||||
}
|
||||
|
||||
return $configuration_object;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Objects\Configuration;
|
||||
|
||||
use KimchiAPI\Abstracts\RequestMethod;
|
||||
|
||||
class MethodConfiguration
|
||||
{
|
||||
/**
|
||||
* An array of accepted request methods that this method accepts
|
||||
*
|
||||
* @var RequestMethod[]
|
||||
*/
|
||||
public $Methods;
|
||||
|
||||
/**
|
||||
* The HTTP route path for this request method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Path;
|
||||
|
||||
/**
|
||||
* The class name to initialize
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Class;
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'methods' => $this->Methods,
|
||||
'path' => $this->Path,
|
||||
'class' => $this->Class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return MethodConfiguration
|
||||
*/
|
||||
public static function fromArray(array $data): MethodConfiguration
|
||||
{
|
||||
$MethodConfigurationObject = new MethodConfiguration();
|
||||
|
||||
if(isset($data['methods']))
|
||||
$MethodConfigurationObject->Methods = $data['methods'];
|
||||
|
||||
if(isset($data['path']))
|
||||
$MethodConfigurationObject->Path = $data['path'];
|
||||
|
||||
if(isset($data['class']))
|
||||
$MethodConfigurationObject->Class = $data['class'];
|
||||
|
||||
return $MethodConfigurationObject;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace KimchiAPI\Objects\Configuration;
|
||||
|
||||
class ServerConfiguration
|
||||
|
@ -19,13 +21,90 @@
|
|||
public $RootPath;
|
||||
|
||||
/**
|
||||
*
|
||||
* Indicates if the framework signature headers are to be returned to the HTTP response
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $FrameworkSignature;
|
||||
|
||||
/**
|
||||
* Indicates if the API Signature headers are to be returned to the HTTP response
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $ApiSignature;
|
||||
|
||||
/**
|
||||
* An array of hard-coded headers to be returned to the HTTP response
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $Headers;
|
||||
|
||||
/**
|
||||
* Indicates if KHM is enabled for this API
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $KhmEnabled;
|
||||
|
||||
/**
|
||||
* An array of flags to deny if KHM detects one
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $FirewallDeny;
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
* @noinspection PhpCastIsUnnecessaryInspection
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'logging_enabled' => (bool)$this->LoggingEnabled,
|
||||
'root_path' => $this->RootPath,
|
||||
'framework_signature' => (bool)$this->FrameworkSignature,
|
||||
'api_signature' => (bool)$this->ApiSignature,
|
||||
'headers' => $this->Headers,
|
||||
'khm_enabled' => (bool)$this->KhmEnabled,
|
||||
'firewall_deny' => $this->FirewallDeny
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation of the object
|
||||
*
|
||||
* @param array $data
|
||||
* @return ServerConfiguration
|
||||
*/
|
||||
public static function fromArray(array $data): ServerConfiguration
|
||||
{
|
||||
$ServerConfigurationObject = new ServerConfiguration();
|
||||
|
||||
if(isset($data['logging_enabled']))
|
||||
$ServerConfigurationObject->LoggingEnabled = $data['logging_enabled'];
|
||||
|
||||
if(isset($data['root_path']))
|
||||
$ServerConfigurationObject->RootPath = $data['root_path'];
|
||||
|
||||
if(isset($data['framework_signature']))
|
||||
$ServerConfigurationObject->FrameworkSignature = $data['framework_signature'];
|
||||
|
||||
if(isset($data['api_signature']))
|
||||
$ServerConfigurationObject->ApiSignature = $data['api_signature'];
|
||||
|
||||
if(isset($data['headers']))
|
||||
$ServerConfigurationObject->Headers = $data['headers'];
|
||||
|
||||
if(isset($data['khm_enabled']))
|
||||
$ServerConfigurationObject->KhmEnabled = (bool)$data['khm_enabled'];
|
||||
|
||||
if(isset($data['firewall_deny']))
|
||||
$ServerConfigurationObject->FirewallDeny = $data['firewall_deny'];
|
||||
|
||||
return $ServerConfigurationObject;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Objects\Configuration;
|
||||
|
||||
class VersionConfiguration
|
||||
{
|
||||
/**
|
||||
* The version name of the configuration
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Version;
|
||||
|
||||
/**
|
||||
* Indicates if the version is enabled or not
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $Enabled;
|
||||
|
||||
/**
|
||||
* @var MethodConfiguration[]
|
||||
*/
|
||||
public $Methods;
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$methods_array = [];
|
||||
foreach($this->Methods as $method)
|
||||
$methods_array[] = $method->toArray();
|
||||
|
||||
return [
|
||||
'version' => $this->Version,
|
||||
'enabled' => (bool)$this->Enabled,
|
||||
'methods' => $methods_array
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation of the object
|
||||
*
|
||||
* @param array $data
|
||||
* @return VersionConfiguration
|
||||
*/
|
||||
public static function fromArray(array $data): VersionConfiguration
|
||||
{
|
||||
$version_configuration = new VersionConfiguration();
|
||||
|
||||
if(isset($data['version']))
|
||||
$version_configuration->Version = $data['version'];
|
||||
|
||||
if(isset($data['enabled']))
|
||||
$version_configuration->Enabled = (bool)$data['enabled'];
|
||||
|
||||
if(isset($data['methods']))
|
||||
{
|
||||
foreach($data['methods'] as $method)
|
||||
$version_configuration->Methods[] = MethodConfiguration::fromArray($method);
|
||||
}
|
||||
|
||||
return $version_configuration;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Utilities;
|
||||
|
||||
class Client
|
||||
{
|
||||
/**
|
||||
* Returns the IP address of the client
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getClientIP(): string
|
||||
{
|
||||
if(isset($_SERVER['HTTP_CF_CONNECTING_IP']))
|
||||
{
|
||||
return $_SERVER['HTTP_CF_CONNECTING_IP'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_CLIENT_IP']))
|
||||
{
|
||||
return $_SERVER['HTTP_CLIENT_IP'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
|
||||
{
|
||||
return $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_X_FORWARDED']))
|
||||
{
|
||||
return $_SERVER['HTTP_X_FORWARDED'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_FORWARDED_FOR']))
|
||||
{
|
||||
return $_SERVER['HTTP_FORWARDED_FOR'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['HTTP_FORWARDED']))
|
||||
{
|
||||
return $_SERVER['HTTP_FORWARDED'];
|
||||
}
|
||||
|
||||
if(isset($_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
return $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
if(getenv('HTTP_CLIENT_IP') !== False)
|
||||
{
|
||||
return getenv('HTTP_CLIENT_IP');
|
||||
}
|
||||
|
||||
if(getenv('HTTP_X_FORWARDED_FOR'))
|
||||
{
|
||||
return getenv('HTTP_X_FORWARDED_FOR');
|
||||
}
|
||||
|
||||
if(getenv('HTTP_X_FORWARDED'))
|
||||
{
|
||||
return getenv('HTTP_X_FORWARDED');
|
||||
}
|
||||
|
||||
if(getenv('HTTP_FORWARDED_FOR'))
|
||||
{
|
||||
return getenv('HTTP_FORWARDED_FOR');
|
||||
}
|
||||
|
||||
if(getenv('HTTP_FORWARDED'))
|
||||
{
|
||||
return getenv('HTTP_FORWARDED');
|
||||
}
|
||||
|
||||
if(getenv('REMOTE_ADDR'))
|
||||
{
|
||||
return getenv('REMOTE_ADDR');
|
||||
}
|
||||
|
||||
return '127.0.0.1';
|
||||
}
|
||||
}
|
|
@ -7,7 +7,14 @@
|
|||
"organization": "Intellivoid Technologies",
|
||||
"description": "The API server that goes good with anything, even toothpaste!",
|
||||
"url": "https://github.com/intellivoid/KimchiAPI",
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
{
|
||||
"package": "net.intellivoid.khm",
|
||||
"version": "latest",
|
||||
"source": "default@github/intellivoid/khm",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
"autoload_method": "generated_spl",
|
||||
"main": null,
|
||||
|
@ -16,61 +23,101 @@
|
|||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/Command.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/RequestMethod.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/InternalServerException.php"
|
||||
"file": "Abstracts/Method.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/IOException.php"
|
||||
"file": "Classes/Router.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/MethodAlreadyRegisteredException.php"
|
||||
"file": "Classes/Request.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/MethodNotFoundException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/MissingComponentsException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Interfaces/MethodInterface.php"
|
||||
"file": "Classes/API.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "KimchiAPI.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/BadEnvironmentException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/MissingComponentsException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/InternalServerException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/ConnectionBlockedException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/MethodAlreadyRegisteredException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/IOException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/RouterException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/ApiException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/MethodNotFoundException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Utilities/Converter.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Utilities/Client.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Interfaces/MethodInterface.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Configuration/MethodConfiguration.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Configuration/VersionConfiguration.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Configuration/ServerConfiguration.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Configuration.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Request.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Response.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Utilities/Converter.php"
|
||||
"file": "Objects/Request.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Configuration.php"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
|
|
Loading…
Reference in New Issue