WIP, Pushing to work on another machine.
This commit is contained in:
parent
809ab800a1
commit
0da9c85b43
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Methods\v1;
|
||||
|
||||
class Ping extends \KimchiAPI\Abstracts\Command
|
||||
{
|
||||
|
||||
public function execute()
|
||||
{
|
||||
// TODO: Implement execute() method.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"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,
|
||||
"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": []}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Abstracts;
|
||||
|
||||
use KimchiAPI\KimchiAPI;
|
||||
use KimchiAPI\Objects\Request;
|
||||
|
||||
abstract class Command
|
||||
{
|
||||
/**
|
||||
* Auth level for user commands
|
||||
*/
|
||||
public const AUTH_USER = 'User';
|
||||
|
||||
/**
|
||||
* Auth level for system commands
|
||||
*/
|
||||
public const AUTH_SYSTEM = 'System';
|
||||
|
||||
/**
|
||||
* Auth level for admin commands
|
||||
*/
|
||||
public const AUTH_ADMIN = 'Admin';
|
||||
|
||||
/**
|
||||
* KimchiAPI Object
|
||||
*
|
||||
* @var KimchiAPI
|
||||
*/
|
||||
protected $KimchiAPI;
|
||||
|
||||
/**
|
||||
* Request object
|
||||
*
|
||||
* @var Request
|
||||
*/
|
||||
protected $Request;
|
||||
|
||||
/**
|
||||
* The name of the method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $Name;
|
||||
|
||||
/**
|
||||
* A description of the method
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $Description;
|
||||
|
||||
abstract public function execute();
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Abstracts;
|
||||
|
||||
abstract class Method
|
||||
{
|
||||
protected $KimchiAPI;
|
||||
|
||||
protected $Request;
|
||||
|
||||
protected $Name;
|
||||
|
||||
protected $Description;
|
||||
|
||||
protected $DocumentationURL;
|
||||
|
||||
protected $Version;
|
||||
|
||||
protected $Enabled;
|
||||
|
||||
abstract public function execute();
|
||||
|
||||
|
||||
}
|
|
@ -3,19 +3,10 @@
|
|||
namespace KimchiAPI;
|
||||
|
||||
// Define server information for response headers
|
||||
use Exception;
|
||||
use KimchiAPI\Abstracts\Method;
|
||||
use KimchiAPI\Abstracts\Command;
|
||||
use KimchiAPI\Exceptions\IOException;
|
||||
use KimchiAPI\Exceptions\MethodAlreadyRegisteredException;
|
||||
use KimchiAPI\Exceptions\MethodNotFoundException;
|
||||
use KimchiAPI\Exceptions\MissingComponentsException;
|
||||
use KimchiAPI\Interfaces\MethodInterface;
|
||||
use KimchiAPI\Objects\Request;
|
||||
use KimchiAPI\Objects\Response;
|
||||
use KimchiAPI\Utilities\Converter;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use RegexIterator;
|
||||
use RuntimeException;
|
||||
|
||||
if(defined("KIMCHI_API_SERVER") == false)
|
||||
|
@ -37,117 +28,84 @@
|
|||
class KimchiAPI
|
||||
{
|
||||
/**
|
||||
* An array of declared methods
|
||||
*
|
||||
* @var string[]
|
||||
* @var array
|
||||
*/
|
||||
private $methods_path;
|
||||
private $commands_paths;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $command_classes;
|
||||
|
||||
/**
|
||||
* Server constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->methods_path = [];
|
||||
$this->commands_paths = [];
|
||||
$this->command_classes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of commands paths
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCommandsPaths(): array
|
||||
{
|
||||
return $this->commands_paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of command classes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCommandClasses(): array
|
||||
{
|
||||
return $this->command_classes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a single custom commands path
|
||||
*
|
||||
* @param string $path Custom methods' path to add
|
||||
* @param string $version The version of the methods to add
|
||||
* @param bool $before If the path should be prepended or appended to the list
|
||||
* @param string $path Custom commands path to add
|
||||
* @param bool $before If the path should be prepended or appended to the list
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addMethodsPath(string $path, string $version, bool $before=true)
|
||||
public function addCommandsPath(string $path, bool $before=true)
|
||||
{
|
||||
if (!is_dir($path))
|
||||
{
|
||||
new IOException('Methods path "' . $path . '" does not exist.');
|
||||
throw new IOException('Commands path "' . $path . '" does not exist.');
|
||||
}
|
||||
|
||||
$this->methods_path[$version] = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize Method
|
||||
*
|
||||
* @param string $command
|
||||
* @return string
|
||||
*/
|
||||
protected function sanitizeMethod(string $command): string
|
||||
{
|
||||
return str_replace(' ', '', $this->ucWordsUnicode(str_replace('_', ' ', $command)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace function `ucwords` for UTF-8 characters in the class definition and commands
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $encoding (default = 'UTF-8')
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function ucWordsUnicode(string $str, string $encoding = 'UTF-8'): string
|
||||
{
|
||||
return mb_convert_case($str, MB_CASE_TITLE, $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace function `ucfirst` for UTF-8 characters in the class definition and commands
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $encoding (default = 'UTF-8')
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function ucFirstUnicode(string $str, string $encoding = 'UTF-8'): string
|
||||
{
|
||||
return mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding)
|
||||
. mb_strtolower(mb_substr($str, 1, mb_strlen($str), $encoding), $encoding);
|
||||
}
|
||||
|
||||
public function getCommandsList(): array
|
||||
{
|
||||
$commands = [];
|
||||
|
||||
foreach ($this->methods_path as $version)
|
||||
elseif (!in_array($path, $this->commands_paths, true))
|
||||
{
|
||||
foreach($this->methods_path[$version] as $path)
|
||||
if ($before)
|
||||
{
|
||||
try {
|
||||
//Get all "*Command.php" files
|
||||
$files = new RegexIterator(
|
||||
new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($path)
|
||||
),
|
||||
'/^.+Method.php$/'
|
||||
);
|
||||
|
||||
foreach ($files as $file) {
|
||||
//Remove "Method.php" from filename
|
||||
$command = $this->sanitizeMethod(substr($file->getFilename(), 0, -11));
|
||||
$command_name = mb_strtolower($command);
|
||||
|
||||
if (array_key_exists($command_name, $commands)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
require_once $file->getPathname();
|
||||
|
||||
$command_obj = $this->getMethoddObject($command, $file->getPathname());
|
||||
if ($command_obj instanceof Method)
|
||||
{
|
||||
$commands[$command_name] = $command_obj;
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new IOException('Error getting commands from path: ' . $path, $e);
|
||||
}
|
||||
array_unshift($this->commands_paths, $path);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->commands_paths[] = $path;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $commands;
|
||||
/**
|
||||
* Add multiple custom commands paths
|
||||
*
|
||||
* @param array $paths Custom commands paths to add
|
||||
* @param bool $before If the paths should be prepended or appended to the list
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addCommandsPaths(array $paths, bool $before=true)
|
||||
{
|
||||
foreach ($paths as $path)
|
||||
{
|
||||
$this->addCommandsPath($path, $before);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,23 +115,25 @@
|
|||
* @param string $command
|
||||
* @param string $filepath
|
||||
*
|
||||
* @return Method|null
|
||||
* @return Command|null
|
||||
*/
|
||||
public function getMethoddObject(string $command, string $filepath = ''): ?Method
|
||||
public function getCommandObject(string $command, string $filepath = ''): ?Command
|
||||
{
|
||||
if (isset($this->commands_objects[$command])) {
|
||||
if (isset($this->commands_objects[$command]))
|
||||
{
|
||||
return $this->commands_objects[$command];
|
||||
}
|
||||
|
||||
foreach ($which as $auth) {
|
||||
$which = [Command::AUTH_SYSTEM];
|
||||
$which[] = Command::AUTH_USER;
|
||||
|
||||
foreach ($which as $auth)
|
||||
{
|
||||
$command_class = $this->getCommandClassName($auth, $command, $filepath);
|
||||
|
||||
if ($command_class) {
|
||||
$command_obj = new $command_class($this, $this->update);
|
||||
|
||||
if ($auth === Command::AUTH_SYSTEM && $command_obj instanceof SystemCommand) {
|
||||
return $command_obj;
|
||||
}
|
||||
if ($command_class)
|
||||
{
|
||||
return new $command_class();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,59 +154,7 @@
|
|||
public function getCommandClassName(string $auth, string $command, string $filepath = ''): ?string
|
||||
{
|
||||
$command = mb_strtolower($command);
|
||||
$auth = $this->ucFirstUnicode($auth);
|
||||
|
||||
// First, check for directly assigned command class.
|
||||
if ($command_class = $this->command_classes[$auth][$command] ?? null) {
|
||||
return $command_class;
|
||||
}
|
||||
|
||||
// Start with default namespace.
|
||||
$command_namespace = __NAMESPACE__ . '\\Commands\\' . $auth . 'Commands';
|
||||
|
||||
// Check if we can get the namespace from the file (if passed).
|
||||
if ($filepath && !($command_namespace = $this->getFileNamespace($filepath))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$command_class = $command_namespace . '\\' . $this->ucFirstUnicode($command) . 'Command';
|
||||
|
||||
if (class_exists($command_class)) {
|
||||
return $command_class;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get namespace from php file by src path
|
||||
*
|
||||
* @param string $src (absolute path to file)
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getFileNamespace(string $src): ?string
|
||||
{
|
||||
$content = file_get_contents($src);
|
||||
if (preg_match('#^\s*namespace\s+(.+?);#m', $content, $m)) {
|
||||
return $m[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get classname of predefined commands
|
||||
*
|
||||
* @see command_classes
|
||||
* @param string $auth Auth of command
|
||||
* @param string $command Command name
|
||||
* @param string $filepath Path to the command file
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMethodClassName(string $auth, string $command, string $filepath = ''): ?string
|
||||
{
|
||||
$command = mb_strtolower($command);
|
||||
$auth = $this->ucFirstUnicode($auth);
|
||||
$auth = Converter::ucFirstUnicode($auth);
|
||||
|
||||
// First, check for directly assigned command class.
|
||||
if ($command_class = $this->command_classes[$auth][$command] ?? null)
|
||||
|
@ -258,12 +166,12 @@
|
|||
$command_namespace = __NAMESPACE__ . '\\Commands\\' . $auth . 'Commands';
|
||||
|
||||
// Check if we can get the namespace from the file (if passed).
|
||||
if ($filepath && !($command_namespace = $this->getFileNamespace($filepath)))
|
||||
if ($filepath && !($command_namespace = Converter::getFileNamespace($filepath)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$command_class = $command_namespace . '\\' . $this->ucFirstUnicode($command) . 'Command';
|
||||
$command_class = $command_namespace . '\\' . Converter::ucFirstUnicode($command) . 'Command';
|
||||
|
||||
if (class_exists($command_class))
|
||||
{
|
||||
|
@ -272,6 +180,4 @@
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Objects;
|
||||
|
||||
class Configuration
|
||||
{
|
||||
public $Name;
|
||||
|
||||
public $Version;
|
||||
|
||||
public $Author;
|
||||
|
||||
public $Organization;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace KimchiAPI\Objects\Configuration;
|
||||
|
||||
class ServerConfiguration
|
||||
{
|
||||
/**
|
||||
* Indicates if logging is enabled or not
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $LoggingEnabled;
|
||||
|
||||
/**
|
||||
* The root path of the API for routing purposes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $RootPath;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $FrameworkSignature;
|
||||
|
||||
public $ApiSignature;
|
||||
|
||||
public $Headers;
|
||||
}
|
|
@ -37,4 +37,59 @@
|
|||
{
|
||||
return (strlen($input) > $length) ? substr($input,0, $length).'...' : $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize Method
|
||||
*
|
||||
* @param string $command
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitizeMethod(string $command): string
|
||||
{
|
||||
return str_replace(' ', '', self::ucWordsUnicode(str_replace('_', ' ', $command)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace function `ucwords` for UTF-8 characters in the class definition and commands
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $encoding (default = 'UTF-8')
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ucWordsUnicode(string $str, string $encoding = 'UTF-8'): string
|
||||
{
|
||||
return mb_convert_case($str, MB_CASE_TITLE, $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace function `ucfirst` for UTF-8 characters in the class definition and commands
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $encoding (default = 'UTF-8')
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function ucFirstUnicode(string $str, string $encoding = 'UTF-8'): string
|
||||
{
|
||||
return mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding)
|
||||
. mb_strtolower(mb_substr($str, 1, mb_strlen($str), $encoding), $encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get namespace from php file by src path
|
||||
*
|
||||
* @param string $src (absolute path to file)
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getFileNamespace(string $src): ?string
|
||||
{
|
||||
$content = file_get_contents($src);
|
||||
if (preg_match('#^\s*namespace\s+(.+?);#m', $content, $m))
|
||||
{
|
||||
return $m[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -16,22 +16,22 @@
|
|||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/Command.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Abstracts/RequestMethod.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "KimchiAPI.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/MissingComponentsException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/InternalServerException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/IOException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Exceptions/MethodAlreadyRegisteredException.php"
|
||||
|
@ -42,7 +42,7 @@
|
|||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Utilities/Converter.php"
|
||||
"file": "Exceptions/MissingComponentsException.php"
|
||||
},
|
||||
{
|
||||
"required": true,
|
||||
|
@ -50,11 +50,27 @@
|
|||
},
|
||||
{
|
||||
"required": true,
|
||||
"file": "Objects/Response.php"
|
||||
"file": "KimchiAPI.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"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
|
|
Loading…
Reference in New Issue