-
-
Save bubba-h57/3714787 to your computer and use it in GitHub Desktop.
<?php | |
namespace H57\Util; | |
class Serializor { | |
/** | |
* Converts the Doctrine Entity into a JSON Representation | |
* | |
* @param object $object The Object (Typically a Doctrine Entity) to convert to an array | |
* @param integer $depth The Depth of the object graph to pursue | |
* @param array $whitelist List of entity=>array(parameters) to convert | |
* @param array $blacklist List of entity=>array(parameters) to skip | |
* @return string | |
*/ | |
public static function json_encode($object, $depth=1, $whitelist=array(), $blacklist=array()){ | |
return json_encode(Serializor::toArray($object, $depth, $whitelist, $blacklist)); | |
} | |
/** | |
* Serializes our Doctrine Entities | |
* | |
* This is the primary entry point, because it assists with handling collections | |
* as the primary Object | |
* | |
* @param object $object The Object (Typically a Doctrine Entity) to convert to an array | |
* @param integer $depth The Depth of the object graph to pursue | |
* @param array $whitelist List of entity=>array(parameters) to convert | |
* @param array $blacklist List of entity=>array(parameters) to skip | |
* @return NULL|Array | |
* | |
*/ | |
public static function toArray($object, $depth = 1,$whitelist=array(), $blacklist=array()){ | |
// If we drop below depth 0, just return NULL | |
if ($depth < 0){ | |
return NULL; | |
} | |
// If this is an array, we need to loop through the values | |
if (is_array($object)){ | |
// Somthing to Hold Return Values | |
$anArray = array(); | |
// The Loop | |
foreach ($object as $value){ | |
// Store the results | |
$anArray[] = Serializor::arrayizor($value, $depth, $whitelist, $blacklist); | |
} | |
// Return it | |
return $anArray; | |
}else{ | |
// Just return it | |
return Serializor::arrayizor($object, $depth, $whitelist, $blacklist); | |
} | |
} | |
/** | |
* This does all the heavy lifting of actually converting to an array | |
* | |
* @param object $object The Object (Typically a Doctrine Entity) to convert to an array | |
* @param integer $depth The Depth of the object graph to pursue | |
* @param array $whitelist List of entity=>array(parameters) to convert | |
* @param array $blacklist List of entity=>array(parameters) to skip | |
* @return NULL|Array | |
*/ | |
private static function arrayizor($anObject, $depth, $whitelist=array(), $blacklist=array()){ | |
// Determine the next depth to use | |
$nextDepth = $depth - 1; | |
// Lets get our Class Name | |
// @TODO: Making some assumptions that only objects get passed in, need error checking | |
$clazzName = get_class($anObject); | |
// Now get our reflection class for this class name | |
$reflectionClass = new \ReflectionClass($clazzName); | |
// Then grap the class properites | |
$clazzProps = $reflectionClass->getProperties(); | |
if (is_a($anObject, 'Doctrine\ORM\Proxy\Proxy')){ | |
$parent = $reflectionClass->getParentClass(); | |
$clazzName = $parent->getName(); | |
$clazzProps = $parent->getProperties(); | |
} | |
// A new array to hold things for us | |
$anArray = array(); | |
// Lets loop through those class properties now | |
foreach ($clazzProps as $prop){ | |
// If a Whitelist exists | |
if (@count($whitelist[$clazzName]) > 0){ | |
// And this class property is not in it | |
if (! @in_array($prop->name, $whitelist[$clazzName])){ | |
// lets skip it. | |
continue; | |
} | |
// Otherwise, if a blacklist exists | |
}elseif (@count($blacklist[$clazzName] > 0)){ | |
// And this class property is in it | |
if (@in_array($prop->name, $blacklist[$clazzName])){ | |
// lets skip it. | |
continue; | |
} | |
} | |
// We know the property, lets craft a getProperty method | |
$method_name = 'get' . ucfirst($prop->name) ; | |
// And check to see that it exists for this object | |
if (! method_exists($anObject, $method_name)){ | |
continue; | |
} | |
// It did, so lets call it! | |
$aValue = $anObject->$method_name(); | |
// If it is an object, we need to handle that | |
if (is_object($aValue)){ | |
// If it is a datetime, lets make it a string | |
if (get_class($aValue) === 'DateTime'){ | |
$anArray[$prop->name] = $aValue->format('Y-m-d H:i:s'); | |
// If it is a Doctrine Collection, we need to loop through it | |
}elseif(get_class($aValue) ==='Doctrine\ORM\PersistentCollection'){ | |
$collect = array(); | |
foreach ($aValue as $val){ | |
$collect[] = Serializor::toArray($val, $nextDepth, $whitelist, $blacklist); | |
} | |
$anArray[$prop->name] = $collect; | |
// Otherwise, we can simply make it an array | |
}else{ | |
$anArray[$prop->name] = Serializor::toArray($aValue, $nextDepth, $whitelist, $blacklist); | |
} | |
// Otherwise, we just use the base value | |
}else{ | |
$anArray[$prop->name] = $val; | |
} | |
} | |
// All done, send it back! | |
return $anArray; | |
} | |
} | |
?> |
Line 138: "$anArray[$prop->name] = $val;" must be "$anArray[$prop->name] = $aValuel;" I think
Line 109:
$method_name = 'get' . preg_replace_callback(
'/_[a-zA-Z]/',
function ($match) {
$s = $match[0];
return strtoupper($s[1]);
},
ucfirst($prop->name));
Replace underscores with next letter uppercase to match naming conventions.
If you pass a persistent collection this will throw warnings...i added a check so it works fine, its in line 41
if (is_array($object) || is_a($object, 'Doctrine\ORM\PersistentCollection')){
Now you can also use https://github.com/Indaxia/doctrine-orm-transformations to convert entities to scalar arrays and back
$val
in https://gist.github.com/bubba-h57/3714787#file-serializor-php-L138 is undefined. It should be $aValue
use H57\Util\Registry as Reg;
$anEntity = Reg::getRepo('Company')->find(1);
$whitelist = array(
'H57\Entity\Company' => array('id', 'name', 'trade', 'address1', 'address2', 'state', 'users', 'groups'),
'H57\Entity\User' => array('id', 'username', 'firstName', 'lastName')
);
print_r(Serializor::toArray($anEntity, 2, $whitelist));
$blacklist = array(
'H57\Entity\Company' => array('address1', 'address2'),
'H57\Entity\User' => array('password', 'lastName')
);
print_r(Serializor::toArray($anEntity, 2, NULL, $blacklist));
exit();