Add @type phpdoc to allow for typed arrays
This commit is contained in:
parent
006437f670
commit
f1d00615b6
@ -189,22 +189,22 @@ class JsonDatabase implements IJsonUnflattener
|
|||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete(string $className, $identifier): bool
|
public function delete(string $className, $identifier, ?int $timestamp = null): bool
|
||||||
{
|
{
|
||||||
if ($class == null || empty(trim($name)))
|
if ($className == null || empty(trim($identifier)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ($name != null && !empty(trim(strval($name))))
|
if ($identifier != null && !empty(trim(strval($identifier))))
|
||||||
$name = JSONDatabase::SanitizeIdentifier($name);
|
$identifier = JSONDatabase::SanitizeIdentifier($identifier);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
$class = trim($class);
|
$class = trim($className);
|
||||||
|
|
||||||
if (!$this->audit && $timestamp != null)
|
if (!$this->audit && $timestamp != null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
$objPath = $this->getObjectPath($class, $name, ($timestamp != null));
|
$objPath = $this->getObjectPath($className, $identifier, ($timestamp != null));
|
||||||
|
|
||||||
if (strlen($objPath) > PHP_MAXPATHLEN)
|
if (strlen($objPath) > PHP_MAXPATHLEN)
|
||||||
return false;
|
return false;
|
||||||
@ -215,7 +215,7 @@ class JsonDatabase implements IJsonUnflattener
|
|||||||
return unlink($objPath);
|
return unlink($objPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete(IJsonIdentifiable $obj): bool
|
public function deleteObj(IJsonIdentifiable $obj): bool
|
||||||
{
|
{
|
||||||
return $this->delete(get_class($obj), $obj->flatIdentifier());
|
return $this->delete(get_class($obj), $obj->flatIdentifier());
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,52 @@ abstract class JsonSerializable
|
|||||||
return (new \ReflectionClass($typeName))->isSubclassOf(JsonSerializable::class);
|
return (new \ReflectionClass($typeName))->isSubclassOf(JsonSerializable::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if is strongly typed array of type JsonSerializable and return the type
|
||||||
|
* @param string $property Property we should check against
|
||||||
|
* @return bool returns class name if type/class of property extends JsonSerializable
|
||||||
|
*/
|
||||||
|
private static function getPropertyArrayType(\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() && $type->getName() != 'array')
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$docComment = $property->getDocComment();
|
||||||
|
|
||||||
|
if (!$docComment)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
$line = strtok($docComment, "\r\n");
|
||||||
|
|
||||||
|
// TODO: Maybe use preg_match here, maybe faster: https://stackoverflow.com/a/6250269
|
||||||
|
while ($line !== false) {
|
||||||
|
$docType = substr($line, strpos($line, '@type ') + 6);
|
||||||
|
if (!empty(trim($docType)))
|
||||||
|
{
|
||||||
|
$docType = trim($docType);
|
||||||
|
if (class_exists($docType)) {
|
||||||
|
$refClass = new \ReflectionClass($docType);
|
||||||
|
if ($refClass->isSubclassOf(JsonSerializable::class))
|
||||||
|
return $refClass->getName();
|
||||||
|
}
|
||||||
|
// We found a type property, do not further iterate
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$line = strtok( "\r\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize a JsonSerializable Object to an array or to a json string
|
* Serialize a JsonSerializable Object to an array or to a json string
|
||||||
* @param bool $nested Indicates if we should also serialize nested object instances
|
* @param bool $nested Indicates if we should also serialize nested object instances
|
||||||
@ -68,6 +114,13 @@ abstract class JsonSerializable
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (isset($value) && $value != null && is_array($value)) {
|
||||||
|
$arrayType = self::getPropertyArrayType(new \ReflectionProperty($this, $key));
|
||||||
|
if ($arrayType != null)
|
||||||
|
$result[$key] = self::SerializeArray($value, $nested, true);
|
||||||
|
else
|
||||||
|
$result[$key] = $value;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
$result[$key] = $value;
|
$result[$key] = $value;
|
||||||
}
|
}
|
||||||
@ -86,17 +139,29 @@ abstract class JsonSerializable
|
|||||||
* @param bool $nested Indicates if we should also serialize nested object instances
|
* @param bool $nested Indicates if we should also serialize nested object instances
|
||||||
* @return string returns a json formatted string
|
* @return string returns a json formatted string
|
||||||
*/
|
*/
|
||||||
public static function SerializeArray($objects = [], $nested = false)
|
public static function SerializeArray($objects = [], $nested = false, $to_array = false)
|
||||||
{
|
{
|
||||||
// Initialize a an array of results
|
// Initialize a an array of results
|
||||||
$results = array();
|
$results = array();
|
||||||
|
|
||||||
// Iterate through provided JsonSerializable Objects and serialize them
|
// Iterate through provided JsonSerializable Objects and serialize them
|
||||||
foreach ($objects as $object)
|
foreach ($objects as $object) {
|
||||||
$results[] = $object->Serialize($nested, true);
|
if ($object instanceof JsonSerializable)
|
||||||
|
{
|
||||||
|
if ($nested)
|
||||||
|
$results[] = $object->Serialize(nested: true, to_array: true);
|
||||||
|
else if ($object instanceof IJsonIdentifiable && $object->flatIdentifier() !== null)
|
||||||
|
$results[] = $object->flatIdentifier();
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return the json encoded string
|
// If json is demanded, encode, else just return the array
|
||||||
return json_encode($results);
|
if ($to_array)
|
||||||
|
return $results;
|
||||||
|
else
|
||||||
|
return json_encode($results);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,7 +200,15 @@ abstract class JsonSerializable
|
|||||||
// If simple data type, just assign it to var in class
|
// If simple data type, just assign it to var in class
|
||||||
// TODO: Exception handling, what if class specifies an int but string was provided?
|
// TODO: Exception handling, what if class specifies an int but string was provided?
|
||||||
$selfSubclass = self::isPropertyJsonSerializable($property);
|
$selfSubclass = self::isPropertyJsonSerializable($property);
|
||||||
if ($selfSubclass)
|
$arrayType = self::getPropertyArrayType($property);
|
||||||
|
if ($arrayType != null)
|
||||||
|
{
|
||||||
|
if (is_array($value))
|
||||||
|
$classInstance->{$key} = self::DeserializeArray($value, $nested, $callback, $arrayType);
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
elseif ($selfSubclass)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
@ -183,7 +256,7 @@ abstract class JsonSerializable
|
|||||||
* @param string|array $json json string containing the array or array to decode
|
* @param string|array $json json string containing the array or array to decode
|
||||||
* @return JsonSerializable[] Returns an Array of Instances of JsonSerializable
|
* @return JsonSerializable[] Returns an Array of Instances of JsonSerializable
|
||||||
*/
|
*/
|
||||||
public static function DeserializeArray(string|array $json, bool $nested = false)
|
public static function DeserializeArray(string|array $json, bool $nested = false, IJsonUnflattener $callback = null, string $className = null)
|
||||||
{
|
{
|
||||||
// Check if we need to decode from json first
|
// Check if we need to decode from json first
|
||||||
if (is_string($json))
|
if (is_string($json))
|
||||||
@ -194,14 +267,12 @@ abstract class JsonSerializable
|
|||||||
// Loop through the array
|
// Loop through the array
|
||||||
foreach ($json as $item)
|
foreach ($json as $item)
|
||||||
{
|
{
|
||||||
// Uh oh, check if there is an nested array within the array and deserialize children
|
if (is_array($item))
|
||||||
// If not, or if we are not supposed to, just deserialize the current layer or ignore
|
$items[] = self::Deserialize(json: $item, nested: $nested, callback: $callback, className: $className);
|
||||||
if ($nested && is_array($item))
|
else if ($className != null && $callback != null && !is_object($item))
|
||||||
$items[] = self::DeserializeArray(json: $item, nested: $nested);
|
$items[] = call_user_func([$callback, 'unflattenByID'], $className, $item);
|
||||||
else if (is_array($item))
|
|
||||||
continue;
|
|
||||||
else
|
else
|
||||||
$items[] = self::Deserialize(json: $item, nested: $nested);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the result
|
// Returns the result
|
||||||
|
Loading…
Reference in New Issue
Block a user