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