Skip to content

Instantly share code, notes, and snippets.

@ianldgs
Forked from ajaxray/1_DocumentSerializer.php
Last active August 24, 2016 19:42
Show Gist options
  • Save ianldgs/b72d8e8136cd7a0a72b93e3ee95a3d25 to your computer and use it in GitHub Desktop.
Save ianldgs/b72d8e8136cd7a0a72b93e3ee95a3d25 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) || is_null($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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment