Cerys
6 months ago
7 changed files with 0 additions and 286 deletions
@ -1,15 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
|
|
||||
namespace Darksparrow\Deegraph\examples\SchemaBuilder; |
|
||||
|
|
||||
require_once __DIR__ . "/../../../vendor/autoload.php"; |
|
||||
require_once __DIR__ . "/../../../Examples/SchemaBuilder/Schemas/Message.php"; |
|
||||
|
|
||||
use Darksparrow\Deegraph\Examples\SchemaBuilder\Schemas\Message; |
|
||||
use Darksparrow\DeegraphPHP\SchemaBuilder\SchemaBuilder; |
|
||||
|
|
||||
$example = new Message(); |
|
||||
$result = SchemaBuilder::GenerateSchema($example); |
|
||||
|
|
||||
echo json_encode($result, JSON_PRETTY_PRINT); |
|
@ -1,68 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace Darksparrow\Deegraph\Examples\SchemaBuilder\Schemas; |
|
||||
require_once __DIR__ . "/../../../vendor/autoload.php"; |
|
||||
|
|
||||
use Darksparrow\DeegraphPHP\Enumerators\SchemaFieldExistence; |
|
||||
use Darksparrow\DeegraphPHP\SchemaBuilder\Attributes\SchemaDocument; |
|
||||
use Darksparrow\DeegraphPHP\SchemaBuilder\Attributes\SchemaDocumentField; |
|
||||
|
|
||||
#[SchemaDocument( |
|
||||
Name: "Message", |
|
||||
MimeType: "message/rfc822", |
|
||||
)] |
|
||||
class Message |
|
||||
{ |
|
||||
#[SchemaDocumentField( |
|
||||
Name: "sender", |
|
||||
Existence: SchemaFieldExistence::SHOULD, |
|
||||
Comment: "The sender should be attached to a user object if known", |
|
||||
ValidSchemas: [ |
|
||||
"https://schemas.auxiliumsoftware.co.uk/v1/user.json" |
|
||||
], |
|
||||
)] |
|
||||
public string $Sender; |
|
||||
|
|
||||
#[SchemaDocumentField( |
|
||||
Name: "recipients", |
|
||||
Existence: SchemaFieldExistence::SHOULD, |
|
||||
Comment: "All direct recipients that are known should be attached", |
|
||||
ValidSchemas: [ |
|
||||
"https://schemas.auxiliumsoftware.co.uk/v1/collection.json" |
|
||||
], |
|
||||
MaxSize: 0, |
|
||||
Child: [ |
|
||||
"@comment"=>"All direct recipients should be addressed", |
|
||||
"@valid_schemas"=>[ |
|
||||
"https://schemas.auxiliumsoftware.co.uk/v1/user.json" |
|
||||
] |
|
||||
] |
|
||||
)] |
|
||||
public string $Recipients; |
|
||||
|
|
||||
#[SchemaDocumentField( |
|
||||
Name: "indirect_recipients", |
|
||||
Existence: SchemaFieldExistence::SHOULD, |
|
||||
Comment: "All cc'd recipients that are known should be attached", |
|
||||
ValidSchemas: [ |
|
||||
"https://schemas.auxiliumsoftware.co.uk/v1/collection.json" |
|
||||
], |
|
||||
MaxSize: 0, |
|
||||
Child: [ |
|
||||
"@comment"=>"All direct recipients should be addressed", |
|
||||
"@valid_schemas"=>[ |
|
||||
"https://schemas.auxiliumsoftware.co.uk/v1/user.json" |
|
||||
] |
|
||||
] |
|
||||
)] |
|
||||
public string $IndirectRecipients; |
|
||||
|
|
||||
#[SchemaDocumentField( |
|
||||
Name: "sent_at", |
|
||||
Existence: SchemaFieldExistence::SHOULD, |
|
||||
Comment: "The date the message was actually sent, if supplied MUST be in ISO 8601 format", |
|
||||
MaxSize: 64, |
|
||||
MimeType: "text/plain", |
|
||||
)] |
|
||||
public string $SentAt; |
|
||||
} |
|
@ -1,10 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace Darksparrow\DeegraphPHP\Enumerators; |
|
||||
|
|
||||
enum SchemaFieldExistence: string |
|
||||
{ |
|
||||
case MUST = "MUST"; |
|
||||
case SHOULD = "SHOULD"; |
|
||||
case MAY = "MAY"; |
|
||||
} |
|
@ -1,17 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace Darksparrow\DeegraphPHP\Exceptions; |
|
||||
|
|
||||
use Exception; |
|
||||
|
|
||||
class SchemaNameUnsetException extends Exception |
|
||||
{ |
|
||||
public function __construct( |
|
||||
string $message = "The Name field is required.", |
|
||||
int $code = 422 |
|
||||
) { |
|
||||
parent::__construct($message, $code); |
|
||||
$this->message = "$message"; |
|
||||
$this->code = $code; |
|
||||
} |
|
||||
} |
|
@ -1,29 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace Darksparrow\DeegraphPHP\SchemaBuilder\Attributes; |
|
||||
|
|
||||
|
|
||||
use PhpParser\Node\Attribute; |
|
||||
use ReflectionClass; |
|
||||
use PhpParser\Node\Name; |
|
||||
|
|
||||
#[\Attribute] |
|
||||
class SchemaDocument extends Attribute |
|
||||
{ |
|
||||
public int $MaximumSize; |
|
||||
public string $Comment; |
|
||||
public string $MimeType; |
|
||||
|
|
||||
public function __construct( |
|
||||
string $Name, |
|
||||
int $MaximumSize = 0, |
|
||||
string $Comment = "", |
|
||||
string $MimeType = "" |
|
||||
) |
|
||||
{ |
|
||||
$this->MaximumSize = $MaximumSize; |
|
||||
$this->Comment = $Comment; |
|
||||
$this->MimeType = $MimeType; |
|
||||
parent::__construct(new Name("SchemaDocument"), [], []); |
|
||||
} |
|
||||
} |
|
@ -1,37 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace Darksparrow\DeegraphPHP\SchemaBuilder\Attributes; |
|
||||
|
|
||||
|
|
||||
use Darksparrow\DeegraphPHP\Enumerators\SchemaFieldExistence; |
|
||||
use PhpParser\Node\Attribute; |
|
||||
use PhpParser\Node\Name; |
|
||||
|
|
||||
#[\Attribute] |
|
||||
class SchemaDocumentField extends Attribute |
|
||||
{ |
|
||||
public string $Name; |
|
||||
|
|
||||
public SchemaFieldExistence $Existence; |
|
||||
public string $Comment; |
|
||||
public array $ValidSchemas; |
|
||||
public int $MaxSize; |
|
||||
public string $MimeType; |
|
||||
|
|
||||
public function __construct( |
|
||||
string $Name, |
|
||||
SchemaFieldExistence $Existence = SchemaFieldExistence::MAY, |
|
||||
string $Comment = "", |
|
||||
array $ValidSchemas = [], |
|
||||
int $MaxSize = 0, |
|
||||
string $MimeType = "", |
|
||||
) |
|
||||
{ |
|
||||
$this->Existence = $Existence; |
|
||||
$this->Comment = $Comment; |
|
||||
$this->ValidSchemas = $ValidSchemas; |
|
||||
$this->MimeType = $MimeType; |
|
||||
parent::__construct(new Name("SchemaDocumentField"), [], []); |
|
||||
} |
|
||||
|
|
||||
} |
|
@ -1,110 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
namespace Darksparrow\DeegraphPHP\SchemaBuilder; |
|
||||
|
|
||||
use Darksparrow\DeegraphPHP\Exceptions\SchemaNameUnsetException; |
|
||||
use Darksparrow\DeegraphPHP\SchemaBuilder\Attributes\SchemaDocument; |
|
||||
use Darksparrow\DeegraphPHP\SchemaBuilder\Attributes\SchemaDocumentField; |
|
||||
use ReflectionClass; |
|
||||
|
|
||||
class SchemaBuilder |
|
||||
{ |
|
||||
/** |
|
||||
* Goes through the Attribute classes and makes a list of all the Properties they have. |
|
||||
* This is so if a user adds another variable to the Attribute constructor, it won't appear in the final Schema. |
|
||||
* |
|
||||
* @return array[] |
|
||||
*/ |
|
||||
private static function GetValidKeys(): array |
|
||||
{ |
|
||||
$validDocumentAttributeNames = []; |
|
||||
$validPropertyAttributeNames = []; |
|
||||
|
|
||||
foreach((new ReflectionClass(new SchemaDocument("EMPTY")))->getProperties() as $temp) |
|
||||
$validDocumentAttributeNames[] = $temp->getName(); |
|
||||
foreach((new ReflectionClass(new SchemaDocumentField("EMPTY")))->getProperties() as $temp) |
|
||||
$validPropertyAttributeNames[] = $temp->getName(); |
|
||||
|
|
||||
return [$validDocumentAttributeNames, $validPropertyAttributeNames]; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Checks to see if a value is "okay" for a Schema. |
|
||||
* |
|
||||
* @param string $key |
|
||||
* @param mixed $value |
|
||||
* @param array $valids |
|
||||
* @return bool |
|
||||
*/ |
|
||||
private static function VerifyField(string $key, mixed $value, array $valids): bool |
|
||||
{ |
|
||||
if(!in_array(needle: $key, haystack: $valids)) |
|
||||
return false; |
|
||||
if($value == "") |
|
||||
return false; |
|
||||
|
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Just converts PascalCase to snake_case. |
|
||||
* |
|
||||
* @param string $input |
|
||||
* @return string |
|
||||
*/ |
|
||||
private static function PascalCaseToSnakeCase(string $input): string |
|
||||
{ |
|
||||
return strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $input)); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* @throws SchemaNameUnsetException |
|
||||
*/ |
|
||||
public static function GenerateSchema(object $targetSchema): array |
|
||||
{ |
|
||||
$schema = []; |
|
||||
$validKeys = self::GetValidKeys(); |
|
||||
$reflection = new ReflectionClass($targetSchema); |
|
||||
|
|
||||
/* |
|
||||
* Schema "meta-data" from here... |
|
||||
*/ |
|
||||
foreach($reflection->getAttributes()[0]->getArguments() as $key=>$value) |
|
||||
if(self::VerifyField($key, $value, $validKeys[0])) |
|
||||
$schema["@" . self::PascalCaseToSnakeCase(input: $key)] = $value; |
|
||||
|
|
||||
/* |
|
||||
* Property handling from here... |
|
||||
*/ |
|
||||
foreach ($reflection->getProperties() as $property) |
|
||||
{ |
|
||||
$propertyName = ""; |
|
||||
$propertySchema = []; |
|
||||
|
|
||||
foreach ($property->getAttributes() as $attribute) |
|
||||
{ |
|
||||
if($attribute->getName() != "Darksparrow\DeegraphPHP\SchemaBuilder\Attributes\SchemaDocumentField") |
|
||||
continue; |
|
||||
|
|
||||
foreach($attribute->getArguments() as $key=>$value) |
|
||||
{ |
|
||||
if($key == "Name") |
|
||||
{ |
|
||||
$propertyName = $value; |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
if(self::VerifyField($key, $value, $validKeys[1])) |
|
||||
$propertySchema["@" . self::PascalCaseToSnakeCase(input: $key)] = $value; |
|
||||
} |
|
||||
} |
|
||||
if($propertyName == "") |
|
||||
throw new SchemaNameUnsetException(); |
|
||||
|
|
||||
$schema["$propertyName"] = $propertySchema; |
|
||||
} |
|
||||
|
|
||||
return $schema; |
|
||||
} |
|
||||
} |
|
Loading…
Reference in new issue