Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple PHP Trait to make Doctrine MongoDB ODM Documents serializable to Array or JSON
<?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);
}
}
}
<?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

This comment has been minimized.

Copy link

commented Oct 5, 2015

this doesn't seem to work for me. all I get are empty JSON docs or empty arrays. The object however is not null

@kevinmlong

This comment has been minimized.

Copy link

commented Oct 5, 2015

UPDATE - it does work, but assumes that all the variables have getters....

@kevinmlong

This comment has been minimized.

Copy link

commented Oct 7, 2015

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
You can’t perform that action at this time.