Skip to content

Commit

Permalink
Added ModelPropertyType. Various bug fixes and refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
milos-pejanovic-devtech committed Jul 5, 2016
1 parent fcee2bd commit e1735c6
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 133 deletions.
108 changes: 54 additions & 54 deletions src/Common/Mapper/ObjectMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
*/

namespace Common\Mapper;
use Common\Models\ModelClassData;
use Common\Models\ModelPropertyData;
use Common\Models\ModelClass;
use Common\Models\ModelProperty;
use Common\Models\ModelPropertyType;

class ObjectMapper {

Expand All @@ -23,14 +24,14 @@ public function map($sourceObject, $customObject) {
if(self::isObjectEmpty($sourceObject)) {
throw new \InvalidArgumentException('Invalid object(s) supplied for mapping.');
}
$modelClassData = new ModelClassData($customObject);
$modelClass = new ModelClass($customObject);

if(self::hasRoot($sourceObject, $modelClassData->rootName)) {
$sourceObject = $sourceObject->{$modelClassData->rootName};
if(self::hasRoot($sourceObject, $modelClass->rootName)) {
$sourceObject = $sourceObject->{$modelClass->rootName};
}

foreach($modelClassData->properties as $property) {
$sourcePropertyValue = $this->findObjectValue($property, $sourceObject);
foreach($modelClass->properties as $property) {
$sourcePropertyValue = $this->findObjectValueByName($property, $sourceObject);

$mappedPropertyValue = $this->mapValueByType($property->type, $sourcePropertyValue);
$property->setPropertyValue($mappedPropertyValue);
Expand All @@ -49,19 +50,19 @@ public function unmap($customObject) {
throw new ObjectMapperException('Invalid object supplied for unmapping.');
}

$modelClassData = new ModelClassData($customObject);
$modelClass = new ModelClass($customObject);
$unmappedObject = new \stdClass();
foreach($modelClassData->properties as $property) {
$propertyKey = $property->name;
foreach($modelClass->properties as $property) {
$propertyKey = $property->getName();
$propertyValue = $property->getPropertyValue();
if(empty($propertyValue)) {
continue;
}
$unmappedObject->$propertyKey = $this->unmapValueByType($property->type, $propertyValue);
}

if(!empty($modelClassData->rootName)) {
$unmappedObject = $this->addRootElement($unmappedObject, $modelClassData->rootName);
if(!empty($modelClass->rootName)) {
$unmappedObject = $this->addRootElement($unmappedObject, $modelClass->rootName);
}

return $unmappedObject;
Expand All @@ -75,12 +76,12 @@ protected function addRootElement($object, string $rootName) {
}

/**
* @param string $type
* @param ModelPropertyType $type
* @param mixed $value
* @return array|mixed|object
* @throws ObjectMapperException
*/
protected function mapValueByType(string $type, $value) {
protected function mapValueByType(ModelPropertyType $type, $value) {
switch(gettype($value)) {
case 'object':
$mappedValue = $this->mapObjectValue($type, $value);
Expand All @@ -104,44 +105,50 @@ protected function mapValueByType(string $type, $value) {
}

/**
* @param string $type
* @param ModelPropertyType $type
* @param object $value
* @return object
*/
protected function mapObjectValue(string $type, $value) {
protected function mapObjectValue(ModelPropertyType $type, $value) {
$mappedValue = $value;
if(self::isCustomType($type)) {
$customTypeObject = new $type();
$mappedValue = $this->map($value, $customTypeObject);
if($type->isCustomType) {
$customClassName = $type->getCustomClassName();
$customClass = new $customClassName();
$mappedValue = $this->map($value, $customClass);
}

return $mappedValue;
}

/**
* @param string $type
* @param ModelPropertyType $type
* @param array $value
* @return array
* @throws ObjectMapperException
*/
protected function mapArrayValue(string $type, array $value) {
$mappedValue = [];
if(strpos($type, '[]')) {
$type = rtrim($type, '[]');
protected function mapArrayValue(ModelPropertyType $type, array $value) {
if(strpos($type->annotatedType, '[]')) {
$arrayType = rtrim($type->annotatedType, '[]');
}

$mappedValue = [];
foreach($value as $key => $val) {
$mappedValue[$key] = $this->mapValueByType($type, $val);
if(empty($arrayType)) {
$arrayType = gettype($val);
}
$newType = new ModelPropertyType(gettype($value), $arrayType, $type->namespace);
$mappedValue[$key] = $this->mapValueByType($newType, $val);
}

return $mappedValue;
}

/**
* @param string $type
* @param ModelPropertyType $type
* @param mixed $value
* @return mixed
*/
protected function unmapValueByType(string $type, $value) {
protected function unmapValueByType(ModelPropertyType $type, $value) {
switch(gettype($value)) {
case 'object':
$unmappedValue = $this->unmapObjectValue($type, $value);
Expand All @@ -158,46 +165,52 @@ protected function unmapValueByType(string $type, $value) {
}

/**
* @param string $type
* @param ModelPropertyType $type
* @param object $value
* @return object
* @throws ObjectMapperException
*/
protected function unmapObjectValue(string $type, $value) {
protected function unmapObjectValue(ModelPropertyType $type, $value) {
$unmappedValue = $value;
if(self::isCustomType($type)) {
if($type->isCustomType) {
$unmappedValue = $this->unmap($value);
}

return $unmappedValue;
}

/**
* @param string $type
* @param ModelPropertyType $type
* @param array $value
* @return array
*/
protected function unmapArrayValue(string $type, array $value) {
$mappedValue = [];
if(strpos($type, '[]')) {
$type = rtrim($type, '[]');
protected function unmapArrayValue(ModelPropertyType $type, array $value) {
if(strpos($type->annotatedType, '[]')) {
$arrayType = rtrim($type->annotatedType, '[]');
}

$unmappedValue = [];
foreach($value as $key => $val) {
$mappedValue[$key] = $this->unmapValueByType($type, $val);
if(empty($arrayType)) {
$arrayType = gettype($val);
}
$newType = new ModelPropertyType(gettype($value), $arrayType, $type->namespace);
$unmappedValue[$key] = $this->unmapValueByType($newType, $val);
}

return $mappedValue;
return $unmappedValue;
}

/**
* @param ModelPropertyData $ModelPropertyData
* Takes default model value if any set
* @param ModelProperty $ModelProperty
* @param $sourceObject
* @return object|null
*/
protected function findObjectValue(ModelPropertyData $ModelPropertyData, $sourceObject) {
$objectValue = null;
protected function findObjectValueByName(ModelProperty $ModelProperty, $sourceObject) {
$objectValue = $ModelProperty->getPropertyValue();
foreach($sourceObject as $key => $value) {
if($ModelPropertyData->name == $key) {
if($ModelProperty->getName() == $key) {
$objectValue = $value;
break;
}
Expand All @@ -206,19 +219,6 @@ protected function findObjectValue(ModelPropertyData $ModelPropertyData, $source
return $objectValue;
}

public static function isCustomType($type) {
$result = true;
$simpleTypes = ['boolean', 'integer', 'double', 'string', 'array', 'object'];
foreach($simpleTypes as $simpleType) {
if($type == $simpleType) {
$result = false;
break;
}
}

return $result;
}

/**
* @param object $sourceObject
* @param string $rootName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Common\Models;

class ModelClassData {
class ModelClass {

/**
* @var string
Expand All @@ -26,7 +26,7 @@ class ModelClassData {
public $rootName;

/**
* @var ModelPropertyData[]
* @var ModelProperty[]
*/
public $properties;

Expand All @@ -42,9 +42,7 @@ class ModelClassData {
public function __construct($customObject) {
$reflectionClass = new \ReflectionClass($customObject);
$this->docBlock = new DocBlock($reflectionClass->getDocComment());

$this->className = $reflectionClass->getName();

$this->namespace = $reflectionClass->getNamespaceName();

$this->rootName = '';
Expand All @@ -54,7 +52,7 @@ public function __construct($customObject) {

$properties = $reflectionClass->getProperties();
foreach($properties as $property) {
$this->properties[] = new ModelPropertyData($property, $customObject, $this->namespace);
$this->properties[] = new ModelProperty($property, $customObject, $this->namespace);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,28 @@
namespace Common\Models;
use Common\Mapper\ObjectMapper;

class ModelPropertyData {
class ModelProperty {

/**
* @var string
*/
public $propertyName;
public $className;

/**
* @var string
*/
public $name;
public $propertyName;

/**
* @var string
* @var ModelPropertyType
*/
public $type;

/**
* @var string
*/
public $annotatedName;

/**
* @var bool
*/
Expand Down Expand Up @@ -61,21 +66,20 @@ public function __construct(\ReflectionProperty $property, $object, string $name
$this->property = $property;
$this->object = $object;
$this->docBlock = new DocBlock($property->getDocComment());
$this->propertyName = $property->getName();

$this->name = $property->getName();
$this->className = get_class($object);

$this->propertyName = $property->getName();
if($this->docBlock->annotationExists('name')) {
$this->name = $this->docBlock->getFirstAnnotation('name');
$this->annotatedName = $this->docBlock->getFirstAnnotation('name');
}

$this->type = 'NULL';
$propertyType = gettype($this->property->getValue($object));
$annotatedType = 'NULL';
if($this->docBlock->annotationExists('var')) {
$type = $this->docBlock->getFirstAnnotation('var');
if(ObjectMapper::isCustomType($type) && !strpos($type, '\\')) {
$type = $namespace . '\\' . $type;
}
$this->type = $type;
$annotatedType = $this->docBlock->getFirstAnnotation('var');
}
$this->type = new ModelPropertyType($propertyType, $annotatedType, $namespace);

$this->isRequired = false;
if($this->docBlock->annotationExists('required')) {
Expand All @@ -97,4 +101,17 @@ public function setPropertyValue($value) {
public function getPropertyValue() {
return $this->property->getValue($this->object);
}

/**
* Returns the given property name, or @name value, if set
* @return string
*/
public function getName() {
$name = $this->propertyName;
if(!empty($this->annotatedName)) {
$name = $this->annotatedName;
}

return $name;
}
}
Loading

0 comments on commit e1735c6

Please sign in to comment.