/src/lib/Views/DoctrineJsonView.php
PHP | 347 lines | 239 code | 45 blank | 63 comment | 45 complexity | 611f53cec79f330a9e18cfa8d45c28af MD5 | raw file
- <?php
- require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR."../Views/HtmlView.php");
- class DoctrineJsonView extends View{
- public function init(){
- }
- public function render(){
- header('Cache-Control: no-cache, must-revalidate');
- header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
- header('Content-Type: application/json; charset=utf-8');
- $jsonData= $this->getModel()->getJsonData();
- echo json_encode(DoctrineEntitySerializer::Serialize($jsonData,10));
- }
- }
- class Serializor {
- /**
- * @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::toArray($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(), $parentObject = null){
- // 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();
- $em = GothConEntityManager::getInstance();
- $metadata = $em->getClassMetadata(get_class($anObject));
- if (is_a($anObject, 'Doctrine\ORM\Proxy\Proxy')){
- return null;
- $parent = $reflectionClass->getParentClass();
- $clazzName = $parent->getName();
- $clazzProps = $parent->getProperties();
- }
- // If this is a entity, get the metadata
- // A new array to hold things for us
- $anArray = array();
- // Lets loop through those class properties now
- $propertyNames =$metadata->fieldNames;
- foreach($metadata->associationMappings as $propertyName => $mappingInformation){
- array_push($propertyNames,$propertyName);
- }
- foreach ($propertyNames as $propName){
- // If a Whitelist exists
- if (@count($whitelist[$clazzName]) > 0)
- {
- // And this class property is not in it
- if (! @in_array($propName, $whitelist[$clazzName])){
- // lets skip it.
- continue;
- }
- // Otherwise, if a blacklist exists
- }
- elseif (@count($blacklist) > 0)
- {
- // And this class property is in it
- if (@in_array($propName, $blacklist)){
- // lets skip it.
- continue;
- }
- }
- // We know the property, lets craft a getProperty method
- $method_name = 'get' . ucfirst($propName) ;
- // 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 (get_class($aValue) === 'DateTime'){
- // If it is a datetime, lets make it a string
- $anArray[$propName] = $aValue->format('Y-m-d H:i:s');
- }
- else{
- // If it is a Doctrine Collection, we need to loop through it
- if(isset($metadata->associationMappings[$propName])){
- if($metadata->associationMappings[$propName]["mappedBy"] != null){
- $_blacklist = array($metadata->associationMappings[$propName]["mappedBy"]);
- }
- else if($metadata->associationMappings[$propName]["inversedBy"] != null) {
- $_blacklist = array($metadata->associationMappings[$propName]["inversedBy"]);
- }
- else{
- $_blacklist = array();
- }
- }
- if(get_class($aValue) ==='Doctrine\ORM\PersistentCollection'){
- if($aValue->isInitialized()){
- $collect = array();
- foreach ($aValue as $val){
- $collect[] = Serializor::toArray($val, $nextDepth, $whitelist, $_blacklist);
- }
- $anArray[$propName] = $collect;
- }else{
- $anArray[$propName] = null;
- }
- // Otherwise, we can simply make it an array
- }else{
- $anArray[$propName] = Serializor::toArray($aValue, $nextDepth, $whitelist, $_blacklist);
- }
- }
- // Otherwise, we just use the base value
- }else{
- $anArray[$propName] = $aValue;
- }
- }
- // All done, send it back!
- return $anArray;
- }
- }
- class DoctrineEntitySerializer{
- private static function propertyIsWhitelisted($propertyName, $className,$whitelist){
- if(!isset($whitelist[$className]) || count($whitelist[$className]) == 0){
- return true;
- }
- return in_array($propertyName, $whitelist[$className]);
- }
- private static function propertyIsBlacklisted($propertyName, $className, $blacklist){
- if(count($blacklist) == 0){
- return false;
- }
- if(!isset($blacklist[$className])){
- return false;
- }
- return in_array($propertyName, $blacklist[$className]);
- }
- private static function _serialize($entity, $depth, $whitelist, $blacklist){
- if($depth < 0 || is_a($entity, 'Doctrine\ORM\Proxy\Proxy')){
- return null;
- }
- else if (is_a($entity, 'DateTime')){
- // If it is a datetime, lets make it a string
- return $entity->format('Y-m-d H:i:s');
- }
- else if(is_array($entity)){
- return static::_serializeArray($entity, $depth, $whitelist, $blacklist);
- }
- else if(is_object($entity)){
- return static::_serializeObject($entity, $depth, $whitelist, $blacklist);
- }else{
- return $entity;
- }
- return null;
- }
- /**
- *
- * @param Doctrine\ORM\PersistentCollection $collection
- * @param int $depth
- * @param array $whitelist
- * @param array $blacklist
- * @return type
- */
- private static function _serializeCollection($collection,$depth,$whitelist,$blacklist){
- if(!$collection->isInitialized()){
- return null;
- }
- $serializableArray = array();
- $items = $collection->getValues();
- foreach($items as $item){
- $serializableArray[] = DoctrineEntitySerializer::_serialize($item,$depth-1,$whitelist,$blacklist);
- }
- return $serializableArray;
- }
- private static function _serializeStandardObject($entity,$depth,$whitelist,$blacklist){
- $reflectionClass = new \ReflectionClass($entity);
- $serializableObject = array();
- $properties = $reflectionClass->getProperties();
- foreach($properties as $property){
- $value = $property->getValue($entity);
- if (is_a($value, 'DateTime')){
- // If it is a datetime, lets make it a string
- $value = $value->format('Y-m-d H:i:s');
- }
- $serializableObject[$property->name] = DoctrineEntitySerializer::_serialize($value, $depth, $whitelist, $blacklist);
- }
- return $serializableObject;
- }
-
- private static function _serializeObject($entity,$depth,$whitelist,$blacklist){
- $reflectionClass = new \ReflectionClass($entity);
- $serializableObject = array();
- $em = GothConEntityManager::getInstance();
- try{
- $metadata = $em->getClassMetadata(get_class($entity));
- }
- catch (Exception $em){
- return DoctrineEntitySerializer::_serializeStandardObject($entity, $depth, $whitelist, $blacklist);
- }
- foreach($metadata->fieldNames as $propertyName){
- if (!static::propertyIsWhitelisted($propertyName, $reflectionClass->getName(), $whitelist)){
- // the whitelist is defined and the property is not in it
- continue;
- }
- elseif (static::propertyIsBlacklisted($propertyName, $reflectionClass->getName(), $blacklist))
- {
- // the blacklist is defined and the property is in it
- continue;
- }
- if(!$reflectionClass->hasMethod("get" . $propertyName )){
- continue;
- }
- $method = $reflectionClass->getMethod("get" . $propertyName);
- $value = $method->invoke($entity);
- if (is_a($value, 'DateTime')){
- // If it is a datetime, lets make it a string
- $value = $value->format('Y-m-d H:i:s');
- }
- $serializableObject[$propertyName] = $value;
- }
- foreach($metadata->associationMappings as $propertyName => $mappingData){
- $_blacklist = array();
- if(!$reflectionClass->hasProperty($propertyName)){
- continue;
- }
- if (!static::propertyIsWhitelisted($propertyName, $reflectionClass->getName(), $whitelist)){
- // the whitelist is defined and the property is not in it
- continue;
- }
- else if (static::propertyIsBlacklisted($propertyName, $reflectionClass->getName(),$blacklist))
- {
- // the blacklist is defined and the property is in it
- continue;
- }
- // if($mappingData["isOwningSide"]){
- $_blacklist[$mappingData["targetEntity"]] = array($mappingData["mappedBy"]);
- // }
- $property = $reflectionClass->getProperty($propertyName);
- $property->setAccessible(true);
- $associationItem = $property->getValue($entity);
- if( get_class($associationItem) === 'Doctrine\ORM\PersistentCollection'){
- $serializableObject[$propertyName] = DoctrineEntitySerializer::_serializeCollection($associationItem, $depth, $whitelist, $_blacklist);
- }
- else if( get_class($associationItem) === 'Doctrine\Common\Collections\ArrayCollection'){
- $serializableObject[$propertyName] = DoctrineEntitySerializer::_serializeArray($associationItem->getValues(), $depth, $whitelist, $_blacklist);
- }else{
- $serializableObject[$propertyName] = DoctrineEntitySerializer::_serialize($associationItem,$depth-1,$whitelist,$_blacklist);
- }
- }
- return $serializableObject;
- }
-
- private static function _isArrayCollection($entity){
-
- $class = get_class($entity);
- if($class === 'Doctrine\ORM\PersistentCollection'){
- return true;
- }
- if($class ==='Doctrine\Common\Collections\ArrayCollection'){
- return true;
- }
- return false;
- }
- private static function _serializeArray($items,$depth,$whitelist,$blacklist){
- $serializableArray = array();
- foreach($items as $key => $item){
- $serializableArray[$key] = DoctrineEntitySerializer::_serialize($item,$depth-1,$whitelist,$blacklist);
- }
- return $serializableArray;
- }
- public static function Serialize($entity, $depth = 6, $whitelist=array(), $blacklist=array()){
- try {
- $serializableEntity = static::_serialize($entity, $depth, $whitelist, $blacklist);
- } catch (Exception $e){
- $foo = $e;
- }
- return $serializableEntity;
- }
- }