Last active
July 3, 2018 10:54
-
-
Save ajaxray/94b27439ba9c3840d420 to your computer and use it in GitHub Desktop.
A simple PHP Trait to make Doctrine MongoDB ODM Documents serializable to Array or JSON
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Created by PhpStorm. | |
* Author: Anis Ahmad <anisniit@gmail.com> | |
* Date: 5/11/14 | |
* Time: 10:44 PM | |
*/ | |
namespace Your\CoreBundle\Traits; | |
trait DocumentSerializer { | |
private $_ignoreFields = array(); | |
/** | |
* Convert Doctrine\ODM Document to Array | |
* | |
* @return array | |
*/ | |
function toArray() { | |
$document = $this->toStdClass(); | |
return get_object_vars($document); | |
} | |
/** | |
* Convert Doctrine\ODM Document to Array | |
* | |
* @return string | |
*/ | |
function toJSON() { | |
$document = $this->toStdClass(); | |
return json_encode($document); | |
} | |
/** | |
* Set properties to ignore when serializing | |
* | |
* @example $this->setIgnoredFields(array('createdDate', 'secretFlag')); | |
* | |
* @param array $fields | |
*/ | |
function setIgnoredFields(array $fields) { | |
$this->_ignoreFields = $fields; | |
} | |
/** | |
* Convert Doctrine\ODM Document to plain simple stdClass | |
* | |
* @return \stdClass | |
*/ | |
function toStdClass() | |
{ | |
$document = new \stdClass(); | |
foreach($this->findGetters() as $getter) { | |
$prop = lcfirst(substr($getter, 3)); | |
if(! in_array($prop, $this->_ignoreFields)) { | |
$value = $this->$getter(); | |
$document->$prop = $this->formatValue($value); | |
} | |
} | |
return $document; | |
} | |
private function findGetters() | |
{ | |
$funcs = get_class_methods(get_class($this)); | |
$getters = array(); | |
foreach($funcs as $func) { | |
if(strpos($func, 'get') === 0) { | |
$getters[] = $func; | |
} | |
} | |
return $getters ; | |
} | |
private function formatValue($value) { | |
if(is_scalar($value)) { | |
return $value; | |
// If the object uses this trait | |
} elseif (in_array(__TRAIT__, class_uses(get_class($value)))) { | |
return $value->toStdClass(); | |
// If it's a collection, format each value | |
} elseif (is_a($value, 'Doctrine\ODM\MongoDB\PersistentCollection')) { | |
$prop = array(); | |
foreach($value as $k => $v) { | |
$prop[] = $this->formatValue($v); | |
} | |
return $prop; | |
// If it's a Date, convert to unix timestamp | |
} else if(is_a($value, 'DateTime')) { | |
return $value->getTimestamp(); | |
// Otherwise leave a note that this type is not formatted | |
// So that I can add formatting for this missed class | |
} else { | |
return 'Not formatted in DocumentSerializer: '. get_class($value); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Your\CoreBundle\Document; | |
// use ... (other classes) | |
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; | |
use Your\CoreBundle\Traits\DocumentSerializer; | |
/** | |
* @ODM\Document(collection="reports") | |
*/ | |
class Report | |
{ | |
use DocumentSerializer; | |
// NOTE: You have to use this trait to all it's embedded documents too | |
public function __construct() { | |
// You can hide some fields in serialized format | |
$this->setIgnoredFields(array('createdDate', 'secretFlag')); | |
} | |
// ... Your as usual document code | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Assuming in a Symfony2 Controller | |
// If you're not, then make your DocmentManager as you want | |
$dm = $this->get('doctrine_mongodb')->getManager(); | |
$report = $dm->getRepository('YourCoreBundle:Report')->find($id); | |
// Will return simple PHP array | |
$docArray = $report->toArray(); | |
// Will return JSON string | |
$docJSON = $report->toJSON(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// today and yesterday has Embedded Documents | |
// Dates are converting to php timestamp | |
{ | |
id: "536fe7778ead0e5500d63b00", | |
today: [ | |
{ | |
id: "536fe7778ead0e5500d63b01", | |
title: "The first task", | |
done: false | |
}, | |
{ | |
id: "536fe7778ead0e5500d63b02", | |
title: "The second task", | |
done: false | |
} | |
], | |
yesterday: [ | |
{ | |
id: "536fe7778ead0e5500d63b03", | |
title: "I did it yesterday", | |
done: true | |
} | |
], | |
created: 1399842679, | |
updated: 1399842679 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Having issues with embedded documents variables getting set to null. thoughts?