Skip to content
This repository has been archived by the owner on Nov 29, 2022. It is now read-only.

Commit

Permalink
changed object to array, array to object manipulation
Browse files Browse the repository at this point in the history
  • Loading branch information
Erman Titiz committed Nov 24, 2017
1 parent fca5276 commit c86d587
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 21 deletions.
159 changes: 154 additions & 5 deletions Services/ClassDataManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,26 @@
namespace BiberLtd\Bundle\Phorient\Services;
use BiberLtd\Bundle\Phorient\Odm\Entity\BaseClass;
use BiberLtd\Bundle\Phorient\Odm\Types\BaseType;
use BiberLtd\Bundle\Phorient\Odm\Types\ORecordId;
use PhpOrient\Protocols\Binary\Data\Record;

class ClassDataManipulator
{

private $ignored = array('index', 'parent','modified','versionHash', 'typePath', 'updatedProps', 'dateAdded', 'dateRemoved', 'versionHistory','dtFormat');

private $cm;

/**
* ClassDataManipulator constructor.
* @param $cm
*/
public function __construct($cm)
{
$this->cm = $cm;
}


/**
* @param $object
* @param string $to
Expand All @@ -29,7 +43,7 @@ public function output($object, $to = 'json', array $props = array())
case 'xml':
return $this->outputToXml($object,$props);
case 'array':
return json_decode($this->outputToJson($object,$props), true);
return json_decode($this->outputToJson($object,$props));
}
}

Expand Down Expand Up @@ -77,18 +91,153 @@ public function sortArray($array)
public function toArray($object,$ignored=array())
{
$this->ignored=array_merge($ignored,$this->ignored);
$array = $object instanceof BaseClass ? $this->getToMapProperties($object) : (is_object($object) ? get_object_vars($object) : $object);
$array = $object instanceof BaseClass ? $this->toJson($this->getToMapProperties($object)): (is_object($object) ? get_object_vars($object) : $object);

if(!is_array($array)) return $array;
array_walk_recursive($array, function (&$value, $index) use($object) {
array_walk_recursive($array, function (&$value, $index) use($object,$ignored) {
$value = $value instanceof BaseType ? (method_exists($object,'get'.ucfirst($index)) ? $object->{'get'.ucfirst($index)}() : $value->getValue()) : $value;
$value = (is_object($value) && property_exists($value,'cluster') && property_exists($value,'position')) ? '#'.implode(':',(array)$value) : $value;
if ($value instanceof BaseClass) {
$value = $this->toArray($value);

if (is_object($value)) {
$value = $this->toJson($value);
$value = $this->toArray($value,$ignored);
}else{
$value = is_object($value) || is_array($value) ? (array) $value : $value;
}
});

$this->sortArray($array);
return $array;
}
public function toJson($object)
{
$data = (array) $object;
if(count($data)==0)
{
return [];
}
$namespace = implode('', array_slice(explode('\\', get_class($object)),0, -1));
$data['@class'] = implode('', array_slice(explode('\\', get_class($object)), -1));
foreach ($data as $key => $value) {

if($this->checkisRecord($value)) $value = $this->toJson($value);

$newKey = preg_replace('/[^a-z]/i', null, $key);
$newKey = str_replace(implode('', explode('\\', get_class($object))), null, $newKey);
$newKey = str_replace($namespace, null, $newKey);
if(strpos($newKey,"BiberLtdBundlePhorientOdmEntityBaseClass")!==false){
unset($data[$key]);
continue;
}
if (is_string($value)) {
$data[$newKey] = str_replace('%', 'pr.', $value);
} else {
$data[$newKey] = $value;
}
unset($data[$key]);
if (is_object($value)) {
//$object = $value->__invoke();
$data[$newKey] = $this->toJson($value);
} elseif ($value instanceof \DateTime) {
$data[$newKey] = $value->format('Y-m-d H:i:s');
}
}

if(method_exists($object,'getRid'))
$data['rid'] = $object->getRid();
if (array_key_exists('version', $data)) {
$data['@version'] = $data['version'];
unset($data['version']);
}
if (array_key_exists('type', $data)) {
$data['@type'] = $data['type'];
unset($data['type']);
}
return $data;
}

public function objectToRecord($object)
{
$record = new Record();
$data=[];
foreach ($object as $index => $value)
{
switch ($index)
{
case '@type':
break;
case '@fieldTypes':
break;
case '@rid':
$record->setRid(new \PhpOrient\Protocols\Binary\Data\ID($value));
break;
case '@version':
$record->getVersion($value);
break;
case '@class':
$record->setOClass($value);
break;
default:
if(is_array($value) && array_key_exists('@class',$value))
{
$value = $this->objectToRecord($value);
}
$data[$index]=$value;
}
$record->setOData($data);

}
return $record;
}
public function checkisRecord($data)
{
if($data instanceof Record) return true;
if(is_array($data) && array_key_exists('@class',$data)) return true;
if(is_object($data) && property_exists($data,'class')) return true;
return false;
}

public function convertRecordToOdmObject($record,$bundle)
{
if(is_array($record) && array_key_exists('@class',$record))
{
$record = $this->objectToRecord($record);
//dump($record);
}
$oClass = $record->getOClass();
$oData = $record->getOData();;
$class = $this->cm->getEntityPath($bundle).$oClass;
if (!class_exists($class)) return $record->getOData();
$entityClass = new $class;
$metadata = $this->cm->getMetadata($entityClass);
$recordData = $oData;
foreach ($metadata->getColumns()->toArray() as $propName => $annotations)
{

if(array_key_exists($propName, $recordData)) {
$value = $this->checkisRecord($recordData[$propName]) ? $this->convertRecordToOdmObject($recordData[$propName],$bundle) : $this->arrayToObject($recordData[$propName],$bundle);
$methodName = 'set' . ucfirst( $propName );
if ( method_exists( $entityClass, $methodName ) ) {
$entityClass->{$methodName}( $value);
} elseif( property_exists( $entityClass, $propName ) ) {
$entityClass->{$key} = $value;
} else {
// skip not existent configuration params
}

}
}
if(method_exists($entityClass,'setRid'))
$entityClass->setRid($record->getRid());
return $entityClass;
}

private function arrayToObject($arrayObject,$bundle)
{

if(is_array($arrayObject))
foreach ($arrayObject as &$value) $value = $this->checkisRecord($value) ? $this->convertRecordToOdmObject($value,$bundle) : (is_array($value) ? $this->arrayToObject($value,$bundle): $value);

return $arrayObject;
}
}
61 changes: 47 additions & 14 deletions Services/ClassManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use BiberLtd\Bundle\Phorient\Odm\Entity\BaseClass;
use BiberLtd\Bundle\Phorient\Odm\Repository\BaseRepository;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\Mapping\Id;
use PhpOrient\PhpOrient;
use Symfony\Component\DependencyInjection\ContainerInterface;
use PhpOrient\Protocols\Binary\Data\Record;
Expand All @@ -38,7 +39,7 @@ public function __construct(ContainerInterface $container = null, CMConfig $con
$this->cRepositoryFactory = new ClassRepositoryFactory();
$this->cMetadataFactory = new ClassMetadataFactory();
$this->annotationReader = new AnnotationReader();
$this->dataManipulator = new ClassDataManipulator();
$this->dataManipulator = new ClassDataManipulator($this);

}

Expand All @@ -61,8 +62,26 @@ public function createConnection($dbName,$dbInfo=null)
$this->config[$dbName]->setToken($dbInfo['database'][$dbName]['token']);
$this->config[$dbName]->setDbUser($dbInfo['database'][$dbName]['username']);
$this->config[$dbName]->setDbPass($dbInfo['database'][$dbName]['password']);

$this->oService[$dbName] = new PhpOrient($this->config[$dbName]->getHost(), $this->config[$dbName]->getPort(), $this->config[$dbName]->getToken());
/**
* Protocol can be either of the following two values:
* - binary
* - rest
*/
$this->config[$dbName]->setProtocol($dbInfo['database'][$dbName]['protocol']);
switch($dbInfo['database'][$dbName]['protocol']){
case 'binary':
$this->oService[$dbName] = new PhpOrient($this->config[$dbName]->getHost(), $this->config[$dbName]->getPort(), $this->config[$dbName]->getToken());
break;
case 'rest':
$this->oService[$dbName] = new OrientRest(
$this->config[$dbName]->getHost(),
$this->config[$dbName]->getPort(),
$dbName,
['username' => $this->config[$dbName]->getDbUser(), 'password' => $this->config[$dbName]->getDbPass()],
$this->isSecure ?? false
);
break;
}
$this->oService[$dbName]->connect($this->config[$dbName]->getDbUser(), $this->config[$dbName]->getDbPass());
$this->oService[$dbName]->dbOpen($dbName, $this->config[$dbName]->getDbUser(), $this->config[$dbName]->getDbPass());
return $this->setConnection($dbName);
Expand Down Expand Up @@ -105,41 +124,55 @@ public function getEntityPath($bundleName=null)
*/
public function getMetadata($entityClass)
{
$entityClass = $entityClass instanceof BaseClass ? get_class($entityClass) : $entityClass;
//$entityClass = (!class_exists($entityClass, false)) ? get_class($entityClass) : $entityClass;
return $this->cMetadataFactory->getMetadata($this,$entityClass);

}
public function convertRecordToOdmObject(Record $record,$bundle)
public function convertRecordToOdmObject($record,$bundle)
{
$class = $this->getEntityPath($bundle).$record->getOClass();
if(is_array($record) && array_key_exists('@class',$record))
{
$record = $this->dataManipulator->objectToRecord($record);
}
$oClass = $record->getOClass();
$oData = $record->getOData();;
$class = $this->getEntityPath($bundle).$oClass;
if (!class_exists($class)) return $record->getOData();
$entityClass = new $class;
$metadata = $this->getMetadata($entityClass);
$recordData = $record->getOData();
$recordData = $oData;
foreach ($metadata->getColumns()->toArray() as $propName => $annotations)
{

if(array_key_exists($propName, $recordData)) {
$entityClass->$propName = $recordData[$propName] instanceof Record ? $this->convertRecordToOdmObject($recordData[$propName],$bundle) : $this->arrayToObject($recordData[$propName],$bundle);
} else {
if(property_exists($entityClass,$propName))
$entityClass->$propName = null;
else
$entityClass->parameterBag->set($propName,null);
$value = $this->dataManipulator->checkisRecord($recordData[$propName]) ? $this->convertRecordToOdmObject($recordData[$propName],$bundle) : $this->arrayToObject($recordData[$propName],$bundle);
$methodName = 'set' . ucfirst( $propName );
if ( method_exists( $entityClass, $methodName ) ) {
$entityClass->{$methodName}( $value);
} elseif( property_exists( $entityClass, $propName ) ) {
$entityClass->{$key} = $value;
} else {
// skip not existent configuration params
}

}
}
if(method_exists($entityClass,'setRid'))
$entityClass->setRid($record->getRid());
return $entityClass;
}

private function arrayToObject($arrayObject,$bundle)
{

if(is_array($arrayObject))
foreach ($arrayObject as &$value) $value = $value instanceof Record ? $this->convertRecordToOdmObject($value,$bundle) : (is_array($value) ? $this->arrayToObject($value,$bundle): $value);
foreach ($arrayObject as &$value) $value = $this->dataManipulator->checkisRecord($arrayObject) ? $this->convertRecordToOdmObject($value,$bundle) : (is_array($value) ? $this->arrayToObject($value,$bundle): $value);

return $arrayObject;
}
public function getDataManipulator()
{
return $this->dataManipulator;
}

}
7 changes: 5 additions & 2 deletions Services/ClassMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class ClassMetadataFactory
*/
public function getMetadata(ClassManager $classManager, $entityClass)
{
$metaHash = md5($entityClass) . spl_object_hash($classManager);
$metaHash = md5(is_string($entityClass) ? $entityClass : get_class($entityClass)) . spl_object_hash($classManager);

if (isset($this->metadataList[$metaHash])) {
return $this->metadataList[$metaHash];
Expand Down Expand Up @@ -55,7 +55,10 @@ private function createMetadata(ClassManager $classManager, $entityClass)
final private function prepareProps($class, Metadata $metadata)
{
$reflectionClass = new \ReflectionClass($class);
$metadata->setProps($reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC));
$arr1 = $reflectionClass->getProperties(\ReflectionProperty::IS_PRIVATE);
$arr2 = $reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC);
$arr3 = $reflectionClass->getProperties(\ReflectionProperty::IS_PROTECTED);
$metadata->setProps(array_merge($arr1,$arr2,$arr3));

return $metadata;
}
Expand Down

0 comments on commit c86d587

Please sign in to comment.