<?php
declare(strict_types=1);
namespace frdlweb\Api\Rpc;
use frdlweb\Api\Rpc\MethodDiscoverableInterface;
use frdlweb\Api\Rpc\Server;
use stdClass;
use Webfan\Homepagesystem\EventFlow\State as EventEmitter;
class DiscoverMethod implements MethodDiscoverableInterface
{
protected $server;
protected $meta = [
//'$schema' => 'https://raw.githubusercontent.com/open-rpc/meta-schema/master/schema.json#',
'openrpc' => '1.0.0-rc1',
"info" => [
"title" => "JSON-RPC Server",
"description" => "This the RPC-part of an Frdlweb API Server definition https://look-up.webfan3.de/?goto=oid%3A1.3.6.1.4.1.37553.8.1.8.1.13878",
"version" => "1.0.0",
],
'servers' => [
[
'name' => 'Webfan Homepagesystem RPC API',
'summary' => 'Webfan Homepagesystem RPC API methods description',
'description' => 'This is the RPC part of an implementation of the Frdlweb API Specification (1.3.6.1.4.1.37553.8.1.8.1.13878)',
// 'url' => 'https://'.$_SERVER['SERVER_NAME'].'/software-center/modules-api/rpc/0.0.2/',
]
],
'methods' => [],
'components' => [
'links' => [],
'contentDescriptors' => [],
'schemas' => [
// 'JSONRpcRequestParameter' =>
],
'examples' => [],
],
];
protected $outputfile = null;
protected $cacheTime;
public function __construct( $server,string $outputfile = null /* false=no output */, int $cacheTime = 300){
$this->cacheTime = $cacheTime;
$this->server = $server;
if (in_array('blog', stream_get_wrappers())) {
$this->outputfile = (null !== $outputfile) ? $outputfile : 'blog://www_root/software-center/modules-api/rpc/0.0.2/openrpc.json';
} else {
$this->outputfile = (null !== $outputfile) ? $outputfile : $_SERVER['DOCUMENT_ROOT'] . \DIRECTORY_SEPARATOR . 'openrpc.json';
}
$config = $this->server->getConfig();
$this->meta = array_merge($this->meta, $config['meta']);
$this->schema('JSONRpcRequestParameterSpec', ['$ref' => 'https://json-schema.org/draft-07/schema#']);
}
public function getMeta(){
foreach($this->server->getMethodDefinitions() as $method_name => $serviceId){
$procedure = $this->server->getContainer()->get($serviceId);
$method = new \stdclass;
$method->name = $method_name;
// $method->params = $procedure->getSpec();
if($procedure instanceof MethodDiscoverableInterface){
$method->params = $procedure->getParametersSpec();
$method->result = $procedure->getResultSpec();
if($procedure->getSummary()){
$method->summary = $procedure->getSummary();
}
if($procedure->getDescription()){
$method->description = $procedure->getDescription();
}
$examples = $procedure->getExamples();
if($examples){
$method->examples = $examples;
}
$links = $procedure->getLinks();
if($links){
$method->links = $links;
}
if(method_exists($procedure,'getTags') ){
$method->tags = $procedure->getTags();
}
if(method_exists($procedure,'getExternalDocs') ){
$method->externalDocs = $procedure->getExternalDocs();
}
if(method_exists($procedure,'getDeprecated') ){
$method->deprecated = $procedure->getDeprecated();
}
if(method_exists($procedure,'getErrors') ){
$method->errors = $procedure->getErrors();
}
if(method_exists($procedure,'getParamStructure') ){
//"by-name" | "by-position" | "either"
$method->paramStructure = $procedure->getParamStructure();
}
if(method_exists($procedure,'getServers') ){
$method->servers = $procedure->getServers();
}
$procedure->discover($this);
}elseif($procedure instanceof \UMA\JsonRpc\Procedure){
/*
$method->params =[
[
'name' => 'JSON-Result',
//$procedure->getSpec()
'$schema' => 'https://json-schema.org/draft-07/schema#',
]
];
*/
/*
$method->result = \json_decode('
{
"$ref": "https://json-schema.org/draft-07/schema#"
}
'
);
*/
// $method->paramStructure = 'by-name';
$method->description = '!!!The metadescription of this method is not complete!!!';
}else{
throw new MetadataException('Procedure does not match an valid interface in '.__METHOD__);
}
$this->meta['methods'][] = $method;
}
//$this->meta['openrpc'] = 'GENERATED FIELD: Do Not Edit';
$this->meta['components']['examples'] = (object)$this->meta['components']['examples'];
$this->meta['components']['links'] = (object)$this->meta['components']['links'];
$this->meta['components']['contentDescriptors'] = (object)$this->meta['components']['contentDescriptors'];
$this->meta['components']['schemas'] = (object)$this->meta['components']['schemas'];
return $this->meta;
}
/**
* {@inheritdoc}
*/
public function __invoke(\UMA\JsonRpc\Request $request): \UMA\JsonRpc\Response
{
$params = $request->params();
$openrpc = (isset($this->meta['openrpc']))?$this->meta['openrpc']:'1.0.0-rc1';
try{
$meta = $this->getMeta();
if(is_string($this->outputfile)){
if(!is_dir(dirname($this->outputfile))){
mkdir(dirname($this->outputfile), 0755, true);
}
file_put_contents($this->outputfile, json_encode($meta));
}
if($this->server instanceof EventEmitter){
$this->server->once('validate.before', static function($name,$emitter,$event){
$payload = $event->getArgument('payload');
$payload->openrpc = 'GENERATED FIELD: Do Not Edit';
$event->setArgument('payload', $payload);
});
}
return new \UMA\JsonRpc\Success($request->id(), $meta);
}catch(\Exception $e){
return new \UMA\JsonRpc\Error($request->id(), sprintf('Error: `%s`', $e->getMessage()));
}
}
public function getSpec(): ?\stdClass
{
return \json_decode('
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": ["null", "array", "object"],
"properties": {
},
"required" : [],
"additionalProperties": true
}
'
);
}
public function getParametersSpec(): ?array
{
return [];
}
public function getExamples(): ?array
{
return [];
}
public function getLinks(): ?array
{
return [];
}
public function getSummary(): ?string
{
return 'Method as specified in https://spec.open-rpc.org/';
}
public function getDescription(): ?string
{
return "Returns an OpenRPC schema as a description of this service";
}
/**
* {@inheritdoc}
*/
public function discover(MethodDiscoverableInterface $DiscoverMethod) : void {
}
public function getResultSpec(): ?\stdClass {
return \json_decode('
{
"schema": "https://raw.githubusercontent.com/open-rpc/meta-schema/master/schema.json",
"name" : "OpenRPC Document"
}
'
);
}
public function descriptor($key = null, $value = null){
$args = func_get_args();
if(0===count($args)){
return $this->meta['components']['contentDescriptors'];
}elseif(1===count($args)){
return $this->meta['components']['contentDescriptors'][$args[0]];
}elseif(2===count($args)){
if(null === $args[0]){
$this->meta['components']['contentDescriptors'] = $args[1];
}else{
$this->meta['components']['contentDescriptors'][$args[0]] = $args[1];
}
}
}
public function example($key = null, $value = null){
$args = func_get_args();
if(0===count($args)){
return $this->meta['components']['examples'];
}elseif(1===count($args)){
return $this->meta['components']['examples'][$args[0]];
}elseif(2===count($args)){
if(null === $args[0]){
$this->meta['components']['examples'] = $args[1];
}else{
$this->meta['components']['examples'][$args[0]] = $args[1];
}
}
}
public function link($key = null, $value = null){
$args = func_get_args();
if(0===count($args)){
return $this->meta['components']['links'];
}elseif(1===count($args)){
return $this->meta['components']['links'][$args[0]];
}elseif(2===count($args)){
if(null === $args[0]){
$this->meta['components']['links'] = $args[1];
}else{
$this->meta['components']['links'][$args[0]] = $args[1];
}
}
}
public function info($key = null, $value = null){
$args = func_get_args();
if(0===count($args)){
return $this->meta['info'];
}elseif(1===count($args)){
return $this->meta['info'][$args[0]];
}elseif(2===count($args)){
if(null === $args[0]){
$this->meta['info'] = $args[1];
}else{
$this->meta['info'][$args[0]] = $args[1];
}
}
}
public function schema($key = null, $value = null){
$args = func_get_args();
if(0===count($args)){
return $this->meta['components']['schemas'];
}elseif(1===count($args)){
return $this->meta['components']['schemas'][$args[0]];
}elseif(2===count($args)){
if(null === $args[0]){
$this->meta['components']['schemas'] = $args[1];
}else{
$this->meta['components']['schemas'][$args[0]] = $args[1];
}
}
}
public function config($key = null, $value = null){
$args = func_get_args();
if(0===count($args)){
return $this->meta;
}elseif(1===count($args)){
return $this->meta[$args[0]];
}elseif(2===count($args)){
if(null === $args[0]){
$this->meta = $args[1];
}else{
$this->meta[$args[0]] = $args[1];
}
}
}
}
|