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