getProperties(); foreach ($properties as $property) { $name = LuStringUtils::snakeToCamelCase($property->getName(), true); $property->setAccessible(true); $value = $property->getValue($this); $json[$name] = static::serializeValue($value); } return $json; } /** * @param $newClass LuDbo * @return LuDbo */ public function castAs($newClass) { $obj = new $newClass; foreach (get_object_vars($this) as $key => $name) { $obj->$key = $name; } return $obj; } public static function serializeValue($value) { if (is_array($value)) { $array = []; foreach ($value as $key => $v) { $array[$key] = static::serializeValue($v); } return $array; } else { if ($value instanceof LuDbo) { return $value->jsonSerialize(); } else if ($value instanceof Carbon) { return $value->__toString(); } else { return $value; } } } public static function deserializeValue($value, $type, $constraints = []) { if (is_null($value)) { return null; } if (is_null($type) || $type == "") { $type = "mixed"; } else if ($type == "array") { $type = "mixed[]"; } if ($type == "string") { $dbo = LuStringDbo::jsonDeserialize($value); $dbo->checkConstraints($constraints); return $dbo->getString(); } else if ($type == "int" || $type == "integer") { $dbo = LuIntDbo::jsonDeserialize($value); $dbo->checkConstraints($constraints); return $dbo->getInt(); } else if ($type == "float" || $type == "double") { $dbo = LuFloatDbo::jsonDeserialize($value); $dbo->checkConstraints($constraints); return $dbo->getFloat(); } else if ($type == "bool" || $type == "boolean") { $dbo = LuBoolDbo::jsonDeserialize($value); $dbo->checkConstraints($constraints); return $dbo->getBool(); } else if ($type == "datetime" || $type == "date" || $type == "DateTime" || $type == 'Carbon\Carbon' || $type == 'Carbon') { $dbo = LuDateTimeDbo::jsonDeserialize($value); $dbo->checkConstraints($constraints); return $dbo->getDateTime(); } else if ($type == "mixed") { return $value; } else if (LuStringUtils::endsWith($type, "[]")) { if (!is_array($value)) { throw new LuDboDeserializeException("Invalid array value"); } $type = substr($type, 0, strlen($type) - 2); $data = []; foreach ($value as $key => $v) { $value = self::deserializeValue($v, $type, $constraints); $data[$key] = $value; } return $data; } else { $value = call_user_func_array(array($type, "jsonDeserialize"), array($value)); $value->checkConstraints($constraints); return $value; } } /** * Deserialize from a JSON object * @param $json mixed The JSON data to deserialize * @return LuDbo * @throws LuDboConstraintException * @throws LuDboDeserializeException */ public static function jsonDeserialize($json) { if (is_null($json)) { return null; } $dbo = new static(); $reflect = new \ReflectionClass(static::class); $properties = $reflect->getProperties(); foreach ($properties as $property) { $parser = new LuPropertyDocParser($property->getDocComment()); $name = LuStringUtils::snakeToCamelCase($property->getName(), true); $doc = $parser->parse(); $type = is_null($doc) ? null : $doc->getType(); $value = null; if (isset($json[$name])) { $value = static::deserializeValue($json[$name], $type, $doc->getConstraints()); } if ($doc->isNotNull() && is_null($value)) { throw new LuDboConstraintException("Field '" . $name . "' can not be null"); } $property->setAccessible(true); $property->setValue($dbo, $value); } return $dbo; } /** * @param $constraints LuParameterConstraintDbo[] * @throws LuDboConstraintException */ public function checkConstraints($constraints) { foreach ($constraints as $constraint) { if (!is_callable([$this, $constraint->getMethod()])) { throw new LuDboConstraintException("Constraint '" . $constraint->getMethod() . "' could not be found"); } call_user_func_array([$this, $constraint->getMethod()], $constraint->getArguments()); } } /** * Generate a sample JSON object for the DBO * @return array */ public static function generateSample() { return null; } }