Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 145 additions & 1 deletion lib/BaseMongoRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ abstract class BaseMongoRecord
protected $errors;
private $new;

// document fields definition
protected static $fields = array();

public static $database = null;
public static $connection = null;
public static $findTimeout = 20000;
Expand All @@ -37,8 +40,28 @@ public function __construct($attributes = array(), $new = true)
$this->afterNew();
}

// start the database connection
public static function start_db($host=null, $db=null, $force=false)
{
if (self::$connection && !$force)
return true;

if (!$host && defined('MONGO_HOST'))
$host = MONGO_HOST;
if (!$db && defined('MONGO_DB'))
$db = MONGO_DB;

self::$connection = new MongoClient('mongodb://'. $host);
self::$database = $db;

return true;
}

public function validate()
{
// validate fields types before running object validation
$this->parseFields($this->attributes);

$this->beforeValidation();
$retval = $this->isValid();
$this->afterValidation();
Expand Down Expand Up @@ -72,7 +95,10 @@ public function destroy()
}
}
private static function _find($query = array(), $options = array()){


// validate/cast the query params
$query = self::parseQuery($query);

$collection = self::getCollection();
if (isset($options['fields'])){
$documents = $collection->find($query, $options['fields']);
Expand Down Expand Up @@ -150,6 +176,22 @@ private static function instantiate($document)
}
}

public static function remove($query = array(), $options = array())
{
$query = self::parseQuery($query);

$col = self::getCollection();
$col->remove($query, $options);
}

public static function batchInsert(array $data, $options = array())
{
self::parseFields($data);

self::getCollection()
->batchInsert( $data );
}

public function getID()
{
return $this->attributes['_id'];
Expand Down Expand Up @@ -236,6 +278,8 @@ protected static function getCollection()
{
$className = get_called_class();

self::start_db();

if (null !== static::$collectionName)
{
$collectionName = static::$collectionName;
Expand Down Expand Up @@ -278,4 +322,104 @@ public function getAttributes()
{
return $this->attributes;
}



protected static function parseQuery($query)
{
$data = array();

foreach ($query as $field => &$value)
{
// special query param
if (is_array($value))
{
foreach ($value as $op => &$val)
{
// dont check $in yet
if ($op == '$in')
continue;

// cast the special query value as reference
self::parseFields( [$field=>$val] );
}
}
else
{
$data[$field] = $value;
}
}

// cast the simple queries in batch
self::parseFields($data);

$query = array_merge($query, $data);

return $query;
}

// ensure fields casting based on self::$fields configuration
public static function parseFields(&$data)
{
// recursively check array of rows (batch)
if (is_array( current($data) )) {
foreach ($data as &$row)
self::parseFields($row);
return true;
}

$class = get_called_class();

// check defined fields validation
foreach ($data as $field => &$value)
{
// field options defined?
if (!array_key_exists($field, $class::$fields))
continue;

$field_opt = $class::$fields[$field];

// string option means type
if ( is_string($field_opt) )
$field_opt = ['type'=>$field_opt];

// cast the field data type
switch ($field_opt['type']) {
case 'bool':
case 'boolean':
$value = (bool) $value;
break;
case 'int':
case 'integer':
$value = (int) $value;
break;
case 'float':
case 'double':
case 'real':
$value = (float) $value;
break;
case 'str':
case 'string':
$value = (string) $value;
break;
case 'arr':
case 'array':
$value = (array) $value;
break;
case 'obj':
case 'object':
$value = (object) $value;
break;
case 'date':
$value = new MongoDate(strtotime($value));
default:
# code...
break;
}

}

return true;
}

}