Skip to content

Instantly share code, notes, and snippets.

@ajaxray
Last active July 3, 2018 10:54
Show Gist options
  • Save ajaxray/94b27439ba9c3840d420 to your computer and use it in GitHub Desktop.
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
<?php
/**
* Created by PhpStorm.
* Author: Anis Ahmad <[email protected]>
* 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);
}
}
}
<?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
}
<?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();
// 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
}
@kevinmlong
Copy link

Having issues with embedded documents variables getting set to null. thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment