/** * Constructor. * @param mixed $modelClass the model class (e.g. 'Post') or the model finder instance * (e.g. <code>Post::model()</code>, <code>Post::model()->published()</code>). * @param array $config configuration (name=>value) to be applied as the initial property values of this class. * @since v1.0 */ public function __construct($modelClass, $config = array()) { if (is_string($modelClass)) { $this->modelClass = $modelClass; $this->model = EMongoDocument::model($modelClass); } else { if ($modelClass instanceof EMongoDocument) { $this->modelClass = get_class($modelClass); $this->model = $modelClass; } else { throw new EMongoException('Invalid model type for ' . __CLASS__); } } $this->_criteria = $this->model->getDbCriteria(); if (isset($config['criteria'])) { $this->_criteria->mergeWith($config['criteria']); unset($config['criteria']); } $this->setId($this->modelClass); foreach ($config as $key => $value) { $this->{$key} = $value; } if ($this->keyField !== null && is_array($this->keyField)) { throw new EMongoException('This DataProvider cannot handle multi-field primary key.'); } else { $this->keyField = '_id'; } }
/** * Validates the attribute of the object. * If there is any error, the error message is added to the object. * @param CModel $object the object being validated * @param string $attribute the attribute being validated */ protected function validateAttribute($object, $attribute) { $value = $object->{$attribute}; if ($this->allowEmpty && $this->isEmpty($value)) { return; } $className = $this->className === null ? get_class($object) : Yii::import($this->className); $attributeName = $this->attributeName === null ? $attribute : $this->attributeName; $finder = EMongoDocument::model($className); $criteria = new EMongoCriteria(); $criteria->{$attribute} = $value; if ($this->criteria !== array()) { $criteria->mergeWith($this->criteria); } if (!$object instanceof EMongoDocument || $object->isNewRecord) { $exists = $finder->exists($criteria); } else { $criteria->limit = 2; $objects = $finder->findAll($criteria); $n = count($objects); if ($n === 1) { if ($column->isPrimaryKey) { // primary key is modified and not unique $exists = $object->getOldPrimaryKey() != $object->getPrimaryKey(); } else { // non-primary key, need to exclude the current record based on PK $exists = $objects[0]->getPrimaryKey() != $object->getOldPrimaryKey(); } } else { $exists = $n > 1; } } if ($exists) { $message = $this->message !== null ? $this->message : Yii::t('yii', '{attribute} "{value}" has already been taken.'); $this->addError($object, $attribute, $message, array('{value}' => $value)); } }
/** * Finds all documents with the specified primary keys. * In MongoDB world every document has '_id' unique field, so with this method that * field is in use as PK by default. * See {@link find()} for detailed explanation about $condition. * @param mixed $pk primary key value(s). Use array for multiple primary keys. For composite key, each key value must be an array (column name=>column value). * @param array|EMongoCriteria $condition query criteria. * @return the document found. An null is returned if none is found. * @since v1.0 */ public function findAllByPk($pk, $criteria = null) { Yii::trace(get_class($this) . '.findAllByPk()', 'ext.MongoDb.EMongoDocument'); $criteria = new EMongoCriteria($criteria); $criteria->mergeWith($this->createPkCriteria($pk, true)); return $this->findAll($criteria); }
public function searchFilter($caseSensitive = false) { $criteria = new EMongoCriteria(); if (isset($_SESSION['id_patient'])) { $criteria->id_patient = new MongoRegex($_SESSION['id_patient']); } if (isset($this->dynamics) && !empty($this->dynamics)) { $index = 0; $nbCriteria = array(); foreach ($this->dynamics as $questionId => $answerValue) { if ($answerValue != null && !empty($answerValue)) { if ($index != 0) { $nbCriteria = '$criteria' . $index; $nbCriteria = new EMongoCriteria(); } if (isset($this->compare[$questionId])) { if ($index == 0) { if ($this->compare[$questionId] == "between") { $answerDate = $this->formatDatePicker($answerValue); $criteria->addCond('answers_group.answers', 'elemmatch', array('id' => $questionId, 'answer.date' => array('$gte' => $answerDate['date_from'] . " 00:00:00.000000", '$lte' => $answerDate['date_to'] . " 23:59:59.000000"))); } else { $criteria->addCond('answers_group.answers', 'elemmatch', array('id' => $questionId, 'answer' => array(EMongoCriteria::$operators[$this->compare[$questionId]] => (int) $answerValue))); } } else { if ($this->compare[$questionId] == "between") { $answerDate = $this->formatDatePicker($answerValue); $nbCriteria->addCond('answers_group.answers', 'elemmatch', array('id' => $questionId, 'answer.date' => array('$gte' => $answerDate['date_from'] . " 00:00:00.000000", '$lte' => $answerDate['date_to'] . " 23:59:59.000000"))); } else { $nbCriteria->addCond('answers_group.answers', 'elemmatch', array('id' => $questionId, 'answer' => array(EMongoCriteria::$operators[$this->compare[$questionId]] => (int) $answerValue))); } } } else { $values = !is_array($answerValue) ? split(',', $answerValue) : $answerValue; if ($index == 0) { $criteria->addCond('answers_group.answers', 'elemmatch', array('id' => $questionId, 'answer' => new MongoRegex($this->regexString($values)))); } else { $nbCriteria->addCond('answers_group.answers', 'elemmatch', array('id' => $questionId, 'answer' => new MongoRegex($this->regexString($values)))); } } } if ($index != 0) { $criteria->mergeWith($nbCriteria, $this->condition[$questionId]); } $index++; } } $criteria->sort('id_patient', EMongoCriteria::SORT_ASC); $criteria->sort('type', EMongoCriteria::SORT_ASC); $criteria->sort('last_updated', EMongoCriteria::SORT_DESC); Yii::app()->session['criteria'] = $criteria; return new EMongoDocumentDataProvider($this, array('criteria' => $criteria)); }
/** * Find some records * @param array|EMongoCriteria $criteria * @param array|string[] $fields * @return EMongoCursor|EMongoDocument[] */ public function find($criteria = array(), $fields = array()) { $this->trace(__FUNCTION__); $this->beforeFind(); // Apparently this is applied before even scopes... if ($criteria instanceof EMongoCriteria) { $c = $criteria->mergeWith($this->getDbCriteria())->toArray(); $criteria = array(); } else { $c = $this->getDbCriteria(); } $query = $this->mergeCriteria(isset($c['condition']) ? $c['condition'] : array(), $criteria); $project = $this->mergeCriteria(isset($c['project']) ? $c['project'] : array(), $fields); Yii::trace('Executing find: ' . '{$query:' . json_encode($query) . ',$project:' . json_encode($project) . (isset($c['sort']) ? ',$sort:' . json_encode($c['sort']) . ',' : '') . (isset($c['skip']) ? ',$skip:' . json_encode($c['skip']) . ',' : '') . (isset($c['limit']) ? ',$limit:' . json_encode($c['limit']) . ',' : '') . '}', 'extensions.MongoYii.EMongoDocument'); if ($this->getDbConnection()->enableProfiling) { $token = 'extensions.MongoYii.EMongoDocument.query.' . $this->collectionName() . '.find(' . '{$query:' . json_encode($query) . ',$project:' . json_encode($project) . (isset($c['sort']) ? ',$sort:' . json_encode($c['sort']) . ',' : '') . (isset($c['skip']) ? ',$skip:' . json_encode($c['skip']) . ',' : '') . (isset($c['limit']) ? ',$limit:' . json_encode($c['limit']) . ',' : '') . '})'; Yii::beginProfile($token, 'extensions.MongoYii.EMongoDocument.find'); } if ($c !== array()) { $cursor = new EMongoCursor($this, $query, $project); if (isset($c['sort'])) { $cursor->sort($c['sort']); } if (isset($c['skip'])) { $cursor->skip($c['skip']); } if (isset($c['limit'])) { $cursor->limit($c['limit']); } $this->resetScope(false); } else { $cursor = new EMongoCursor($this, $criteria, $project); } if ($this->getDbConnection()->enableProfiling) { Yii::endProfile($token, 'extensions.MongoYii.EMongoDocument.find'); } return $cursor; }
/** * Find some records * @param array|EMongoCriteria $criteria * @param array|string[] $fields * @return [] */ protected function find($criteria = [], $fields = []) { $this->trace(__FUNCTION__); $this->beforeFind(); // Apparently this is applied before even scopes... if ($criteria instanceof EMongoCriteria) { $c = $criteria->mergeWith($this->getDbCriteria())->toArray(); $criteria = []; } else { $c = $this->getDbCriteria(); } $query = $this->mergeCriteria(isset($c['condition']) ? $c['condition'] : [], $criteria); $project = $this->mergeCriteria(isset($c['project']) ? $c['project'] : [], $fields); Yii::trace('Executing find: ' . '{$query:' . json_encode($query) . ',$project:' . json_encode($project) . (isset($c['sort']) ? ',$sort:' . json_encode($c['sort']) . ',' : '') . (isset($c['skip']) ? ',$skip:' . json_encode($c['skip']) . ',' : '') . (isset($c['limit']) ? ',$limit:' . json_encode($c['limit']) . ',' : '') . '}', 'extensions.MongoYii.EMongoDocument'); if ($this->getDbConnection()->enableProfiling) { $token = 'extensions.MongoYii.EMongoDocument.query.' . $this->collectionName() . '.find(' . '{$query:' . json_encode($query) . ',$project:' . json_encode($project) . (isset($c['sort']) ? ',$sort:' . json_encode($c['sort']) . ',' : '') . (isset($c['skip']) ? ',$skip:' . json_encode($c['skip']) . ',' : '') . (isset($c['limit']) ? ',$limit:' . json_encode($c['limit']) . ',' : '') . '})'; Yii::beginProfile($token, 'extensions.MongoYii.EMongoDocument.find'); } //$options = []; if ($c !== []) { $builder = new EMongoQueryBuilder($this, $query, $project); if (isset($c['sort'])) { $builder->sort($c['sort']); } if (isset($c['skip'])) { $builder->skip($c['skip']); } if (isset($c['limit'])) { $builder->limit($c['limit']); } $this->resetScope(false); } else { $builder = new EMongoQueryBuilder($this, $criteria, $project); } $finded = $builder->queryAll(); $results = $this->populateRecords($finded, true, null, $project === [] ? false : true); if ($this->getDbConnection()->enableProfiling) { Yii::endProfile($token, 'extensions.MongoYii.EMongoDocument.find'); } return $results; }
/** * Find some records * @param array|EMongoCriteria $criteria * @param array|string[] $fields * @return EMongoCursor|EMongoDocument[] */ public function find($criteria = array(), $fields = array()) { $this->trace(__FUNCTION__); $this->beforeFind(); // Apparently this is applied before even scopes... if ($criteria instanceof EMongoCriteria) { $c = $criteria->mergeWith($this->getDbCriteria())->toArray(); $criteria = array(); } else { $c = $this->getDbCriteria(); } if ($c !== array()) { $cursor = new EMongoCursor($this, $this->mergeCriteria(isset($c['condition']) ? $c['condition'] : array(), $criteria), $this->mergeCriteria(isset($c['project']) ? $c['project'] : array(), $fields)); if (isset($c['sort'])) { $cursor->sort($c['sort']); } if (isset($c['skip'])) { $cursor->skip($c['skip']); } if (isset($c['limit'])) { $cursor->limit($c['limit']); } $this->resetScope(); return $cursor; } return new EMongoCursor($this, $criteria, $fields); }