Add backed enum support and typed arrays
This commit is contained in:
parent
00eac092d0
commit
54965b401d
15
index.php
15
index.php
@ -32,16 +32,23 @@ $ticket->start = 1471111;
|
||||
$ticket->end = 1474567;
|
||||
$ticket->user = $user;
|
||||
$ticket->grant = $grant;
|
||||
$ticket->groups[] = new User();
|
||||
$ticket->groups[0]->id = 'baaaa';
|
||||
$ticket->groups[0]->cert = 'Cat';
|
||||
|
||||
|
||||
|
||||
$database->save($service);
|
||||
$database->save($user);
|
||||
$database->save($grant);
|
||||
$database->save($ticket);
|
||||
$database->save($ticket->groups[0]);
|
||||
|
||||
|
||||
echo('<b>Start Time in microseconds: </b>' . microtime(true) . '<br><hr /><br>');
|
||||
echo('<b>Serialize Ticket with Nesting on</b><br><code>');
|
||||
echo($ticket->Serialize(true));
|
||||
echo('</code><br><br><b>Deserialize Ticket with Nesting on (vardump)</b><br><code><');
|
||||
echo($ticket->Serialize(true, false, $database));
|
||||
echo('</code><br><br><b>Deserialize Ticket with Nesting on (vardump)</b><br><code>');
|
||||
echo(var_dump(Ticket::Deserialize($ticket->Serialize(true), true)));
|
||||
echo('</code><br><br><b>Re-Serialize Deserialized Ticket with Nesting on</b><br><code>');
|
||||
echo(Ticket::Deserialize($ticket->Serialize(true), true))->Serialize(true);
|
||||
@ -49,8 +56,8 @@ echo('</code><br><hr /><br><b>End Time in microseconds: </b>' . microtime(true))
|
||||
|
||||
echo('<br><hr><hr><br><b>Start Time in microseconds: </b>' . microtime(true) . '<br><hr /><br>');
|
||||
echo('<b>Serialize Ticket with Nesting off</b><br><code>');
|
||||
echo($ticket->Serialize(false));
|
||||
echo('</code><br><br><b>Deserialize Ticket with Nesting off (vardump)</b><br><code><');
|
||||
echo($ticket->Serialize(false, false, $database));
|
||||
echo('</code><br><br><b>Deserialize Ticket with Nesting off (vardump)</b><br><code>');
|
||||
echo(var_dump(Ticket::Deserialize($ticket->Serialize(false), false, $database)));
|
||||
echo('</code><br><br><b>Re-Serialize Deserialized Ticket with Nesting off</b><br><code>');
|
||||
echo(Ticket::Deserialize($ticket->Serialize(false), false, $database))->Serialize(false);
|
||||
|
@ -7,4 +7,8 @@ class Ticket extends BaseEntity {
|
||||
public User $user;
|
||||
public int $start;
|
||||
public int $end;
|
||||
/**
|
||||
* @type SeriousJSON\ExampleEntity\User
|
||||
*/
|
||||
public array $groups = [];
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class JsonDatabase implements IJsonUnflattener
|
||||
throw new \Exception('JsonDatabase: Unable to create Directory for Path ' . $dirPath . '.');
|
||||
}
|
||||
|
||||
private static function SanitizeIdentifier($identifier)
|
||||
public static function SanitizeIdentifier($identifier)
|
||||
{
|
||||
return trim(preg_replace( '/[^a-zA-Z0-9 ()\-\[\]]+/', '-', strtolower($identifier)));
|
||||
}
|
||||
@ -100,7 +100,7 @@ class JsonDatabase implements IJsonUnflattener
|
||||
return false;
|
||||
|
||||
$class = trim($class);
|
||||
|
||||
|
||||
if (!$this->audit && $timestamp != null)
|
||||
return false;
|
||||
|
||||
@ -302,6 +302,40 @@ class JsonDatabase implements IJsonUnflattener
|
||||
return $this->delete(get_class($obj), $obj->flatIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* List all objects by class
|
||||
* @param string name of class to search for
|
||||
* @return array of identifiers or empty array
|
||||
*/
|
||||
public function listAll(string $className, int $time = null): array
|
||||
{
|
||||
if ($className == null)
|
||||
return [];
|
||||
|
||||
$objStoragePath = $this->getObjectPath($className, '-star-', $time);
|
||||
// Replace -star- with catchall * so that it becomes path/to/*.json
|
||||
// TODO: Do this better
|
||||
$objStoragePath = str_replace('-star-', '*', $objStoragePath);
|
||||
|
||||
if (strlen($objStoragePath) > PHP_MAXPATHLEN)
|
||||
return [];
|
||||
|
||||
$files = glob($objStoragePath);
|
||||
|
||||
// Call the function is_file on every element
|
||||
// and filter those that aren't files aka directories out
|
||||
$files = array_filter($files, 'is_file');
|
||||
|
||||
array_walk($files, function (&$value, $key) {
|
||||
// Remove .json
|
||||
$value = basename($value, JsonDatabase::$EXTENSION);
|
||||
// Remove invalid chars
|
||||
$value = JsonDatabase::SanitizeIdentifier($value);
|
||||
});
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a JsonSerializable from the Database by using it's Identifier reference.
|
||||
* @param string $className the full class name with domain of the JsonSerializable property
|
||||
|
@ -37,6 +37,32 @@ abstract class JsonSerializable
|
||||
return (new \ReflectionClass($typeName))->isSubclassOf(JsonSerializable::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given property extends BackedEnum
|
||||
* @param string $property Property we should check against
|
||||
* @return bool returns true if type/class of property extends BackedEnum
|
||||
*/
|
||||
private static function isPropertyBackedEnum(\ReflectionProperty $property)
|
||||
{
|
||||
if (!isset($property) || $property === null || !$property->hasType())
|
||||
return false;
|
||||
|
||||
// Get builtin type or class of given property
|
||||
$type = $property->getType();
|
||||
|
||||
// A built-in type is any type that is not a class, interface, or trait.
|
||||
// Assume false on simple types, we can only check this on classes
|
||||
if ($type->isBuiltin())
|
||||
return false;
|
||||
|
||||
// String name of property type/class
|
||||
$typeName = $type->getName();
|
||||
|
||||
// Create an reflection instance of the found class name
|
||||
// and check if it is a subclass of parent class
|
||||
return (new \ReflectionClass($typeName))->isSubclassOf(\BackedEnum::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if is strongly typed array of type JsonSerializable and return the type
|
||||
* @param string $property Property we should check against
|
||||
@ -241,7 +267,11 @@ abstract class JsonSerializable
|
||||
else
|
||||
{
|
||||
try {
|
||||
$classInstance->{$key} = $value;
|
||||
// Try to handle backed enums, call method "from" on enum class
|
||||
if (self::isPropertyBackedEnum($property))
|
||||
$classInstance->{$key} = call_user_func(array($property->getType()->getName(), 'from'), $value);
|
||||
else
|
||||
$classInstance->{$key} = $value;
|
||||
}
|
||||
catch (\TypeError $e) {
|
||||
// Assignment might fail due to incompatible data types or other reasons
|
||||
|
Loading…
Reference in New Issue
Block a user