Skip to content

Instantly share code, notes, and snippets.

@rikkiloades
Created June 3, 2013 21:11
Show Gist options
  • Save rikkiloades/5701450 to your computer and use it in GitHub Desktop.
Save rikkiloades/5701450 to your computer and use it in GitHub Desktop.
PHP ODM for MongoDB
<?php
namespace mongo;
abstract class Collection
{
private $mongoCollection = null;
public function __construct($db, $collection)
{
$mongo = new \MongoCollection();
$this->mongoCollection = $mongo->$db->$collection;
}
public function instance($db, $collection) { return new static($db, $collection); }
protected function find($criteria = array()) { return array(); }
protected function save($document) {}
protected function update($updates, $criteria, $justOne) {}
protected function remove($criteria, $justOne) {}
}
class Cursor
{
public function __construct(\MongoCursor $mc) {}
public function limit($num) {}
public function sort($criteria) {}
public function toArray() {}
public function each(\Callable $func) {}
public function snapshot() {}
}
abstract class Type
{
private $rawValue = null;
public function __construct($rawValue)
{
$this->rawValue = $rawValue;
}
public function toDB()
{
return $this->rawValue;
}
public function fromDB()
{
return $this->rawValue;
}
}
abstract class Document extends DocumentBehaviour
{
public function beforeHydrate() {}
public function afterHydrate() {}
public function beforeCreate() {}
public function afterCreate() {}
public function beforeInsert() {}
public function afterInsert() {}
public function beforeUpdate() {}
public function afterUpdate() {}
public function beforeSave() {}
public function afterSave() {}
public function beforeRemove() {}
public function afterRemove() {}
public static function defineSchema()
{
return array(
'_id' => array(
'type' => 'mongoid'
),
'_type' => array(
'type' => 'array'
),
'_created' => array(
'type' => 'mongodate'
),
'_updated' => array(
'type' => 'mongodate'
)
);
}
}
abstract class EmbeddedDocument extends DocumentBehaviour
{
}
abstract class DocumentBehaviour
{
private $props = array();
private $errors = array();
final public function __set($name, $value)
{
$schema = static::defineSchema();
if (!array_key_exists($name, $schema)) {
throw new \InvalidArgumentException('The property ' . $name . ' is not part of the schema for ' . get_called_class());
}
$this->props[$name] = $value;
}
final public function __get($name)
{
$schema = static::defineSchema();
if (!array_key_exists($name, $schema)) {
throw new \InvalidArgumentException('The property ' . $name . ' is not part of the schema for ' . get_called_class());
}
$rawValue = $this->props[$name];
if (is_subclass_of($schema[$name]['type'], '\mongo\EmbeddedDocument')) {
return $schema[$name]['type']::hydrate($rawValue);
}
return $rawValue;
}
final public function create($props)
{
foreach ($props as $name => $value) {
$this->__set($name, $value);
}
}
public function hydrate($props)
{
foreach ($props as $name => $value) {
$this->__set($name, $value);
}
}
final public function validate()
{
foreach ($this->props as $name => $value) {
$this->validateProperty($name, $value);
}
}
private function validateProperty($name, $value)
{
$schema = static::defineSchema();
if (array_key_exists($name, $this->props)) {
}
else {
}
}
public function getErrors()
{
return $this->errors;
}
final public function filter()
{
}
private function filterProperty($name, $value)
{
}
private function populateDefaults()
{
}
}
class Post extends Document
{
public function addComment(Comment $comment)
{
$this->comments[] = $comment;
}
public static function defineSchema()
{
return array(
'title' => array(
'type' => 'string',
'required' => true,
'filter' => function() {},
'validate' => function() {}
),
'body' => array(
'type' => 'string',
'required' => true,
'filter' => function() {},
'validate' => function() {}
),
'author' => array(
'type' => 'mongol\Author',
'required' => true
),
'comments' => array(
'type' => 'mongol\Comments',
'required' => true
)
);
}
}
class Author extends EmbeddedDocument
{
public static function defineSchema()
{
return array(
'name' => array(
'type' => 'string',
'required' => true,
'filter' => function() {},
'validate' => function() {}
),
'email' => array(
'type' => 'string',
'required' => true,
'filter' => function() {},
'validate' => function() {}
)
);
}
}
class Comments extends EmbeddedCollection
{
protected static $contains = 'mongo\Comment';
}
class Comment extends EmbeddedDocument
{
public static function defineSchema()
{
return array(
'name' => array(
'type' => 'string',
'filter' => function() {},
'validate' => function() {},
'required' => true
),
'email' => array(
'type' => 'string',
'filter' => function() {},
'validate' => function() {},
'required' => true
),
'text' => array(
'type' => 'string',
'filter' => function() {},
'validate' => function() {},
'required' => true
)
);
}
}
abstract class EmbeddedCollection
{
}
class Posts extends Collection
{
public function findAll()
{
return parent::find();
}
}
// test code
$posts = Posts::instance('blog', 'posts');
$post = new Post(array(
'title' => 'My First Post',
'body' => 'My blog post will go here...'
));
$post->author = new Author(array(
'name' => 'Rikki Loades',
'email' => 'rikki1234@gmail.com'
));
$post->addComment(new Comment(array(
'name' => 'Rikki Loades',
'email' => 'rikki1234@gmail.com',
'text' => 'First comment! Whoop! Yea!'
)));
if ($post->validate()) {
$posts->save($post);
}
else {
print_r($post->getErrors());
}
foreach ($posts->findAll() as $post) {
print_r($post);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment