diff --git a/index.php b/index.php
index 5e1476f..cf3adaf 100644
--- a/index.php
+++ b/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('Start Time in microseconds: ' . microtime(true) . '
');
-echo($ticket->Serialize(true));
-echo('
<');
+echo($ticket->Serialize(true, false, $database));
+echo('
');
echo(var_dump(Ticket::Deserialize($ticket->Serialize(true), true)));
echo('
');
echo(Ticket::Deserialize($ticket->Serialize(true), true))->Serialize(true);
@@ -49,8 +56,8 @@ echo('
');
-echo($ticket->Serialize(false));
-echo('
<');
+echo($ticket->Serialize(false, false, $database));
+echo('
');
echo(var_dump(Ticket::Deserialize($ticket->Serialize(false), false, $database)));
echo('
');
echo(Ticket::Deserialize($ticket->Serialize(false), false, $database))->Serialize(false);
diff --git a/src/SeriousJSON/ExampleEntity/Ticket.php b/src/SeriousJSON/ExampleEntity/Ticket.php
index 2e07c57..8115501 100644
--- a/src/SeriousJSON/ExampleEntity/Ticket.php
+++ b/src/SeriousJSON/ExampleEntity/Ticket.php
@@ -7,4 +7,8 @@ class Ticket extends BaseEntity {
public User $user;
public int $start;
public int $end;
+ /**
+ * @type SeriousJSON\ExampleEntity\User
+ */
+ public array $groups = [];
}
diff --git a/src/SeriousJSON/JsonDatabase.php b/src/SeriousJSON/JsonDatabase.php
index 13a1500..0e84877 100644
--- a/src/SeriousJSON/JsonDatabase.php
+++ b/src/SeriousJSON/JsonDatabase.php
@@ -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
diff --git a/src/SeriousJSON/JsonSerializable.php b/src/SeriousJSON/JsonSerializable.php
index bba1835..ea556cb 100644
--- a/src/SeriousJSON/JsonSerializable.php
+++ b/src/SeriousJSON/JsonSerializable.php
@@ -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