Esempio n. 1
0
 /**
  Process all search query joins
 *
 * @param \Phalcon\Mvc\Model\Relation $relation
 * @param array $joinPath
 * @return array|bool
 */
 protected function _processJoins(Relation $relation, array $joinPath)
 {
     $refModel = $relation->getReferencedModel();
     $refModel = new $refModel();
     $refFields = $relation->getReferencedFields();
     $options = $relation->getOptions();
     $dataSourceIn = $refModel->queryBuilder();
     $dataSourceIn->setColumn($refFields);
     $relation = array_shift($joinPath);
     if ($joinPath) {
         if (!($ids = $this->_processJoins($relation, $joinPath))) {
             return false;
         }
         $fields = $relation->getFields();
         $where = "(" . $fields . " IN (" . implode($ids, ",") . "))";
     } else {
         //$dataSourceIn->joinPath($joinPath);
         $where = $this->_filter->filterWhere($dataSourceIn);
     }
     $dataSourceIn->andWhere($where);
     //$dataSourceIn->columnsId();
     $result = $dataSourceIn->getQuery()->execute()->toArray();
     if (count($result) == 0) {
         return false;
     }
     $ids = [];
     $adapter = $dataSourceIn->getModel()->getReadConnection();
     foreach ($result as $row) {
         $ids[] = $adapter->escapeString($row[$refFields]);
     }
     return $ids;
 }
 /**
  * ez access to the "foreign" model depicted by the relationship
  */
 private function getModel()
 {
     if ($this->model == null) {
         $name = $this->relation->getReferencedModel();
         $this->model = new $name();
     }
     return $this->model;
 }
 /**
  * @param array $relationsArray
  * @param \Phalcon\Mvc\Model $model
  * @param \Phalcon\Mvc\Model\Relation $relation
  */
 public function save(array $relationsArray, $model, $relation)
 {
     $relationAlias = $relation->getOption('alias');
     $needDeleteRelations = $this->getNeedDelete($relationsArray, $model, $relation);
     $this->delete($needDeleteRelations);
     foreach ($relationsArray as $relationData) {
         $relationData = Params::convertDate($relationData, $this->getDI());
         if (empty($relationData['id'])) {
             $this->create($relationData, $model, $relationAlias);
         } else {
             $this->update($relationData, $model, $relationAlias);
         }
     }
 }
 /**
  * @param \Phalcon\Mvc\Model $model
  * @param \Phalcon\Mvc\Model\Relation $relation
  * @param bool $isConvertToArray
  * @return array|Model\Resultset|\Phalcon\Mvc\Model|void
  */
 private function getAssignRelation(Model $model, Relation $relation, $isConvertToArray = true)
 {
     $alias = $relation->getOption('alias');
     if (!$alias) {
         return;
     }
     $data = $model->{$alias};
     return $data && $isConvertToArray ? $data->toArray() : $data;
 }
 /**
  * get the name of the parent model (w/o namespace)
  *
  * @return string or false
  */
 public function getParent()
 {
     $name = $this->relation->getReferencedModel();
     return $name::$parentModel;
 }
 /**
  * load the query object for a hasManyToMany relationship
  * build most of the joins manually since by reference relationship in the model isn't working so well
  * this support joins to distant tables with parent models
  *
  * @param Relation|PhalconRelation $relation
  * @return array
  */
 protected function getHasManyToManyRecords($relation)
 {
     $refModelNameSpace = $relation->getReferencedModel();
     $intermediateModelNameSpace = $relation->getIntermediateModel();
     // determine the key to search against
     $field = $relation->getFields();
     $referencedField = $relation->getReferencedFields();
     $intermediateFields = $relation->getIntermediateReferencedFields();
     $config = $this->getDI()->get('config');
     $modelNameSpace = $config['namespaces']['models'];
     $mm = $this->getDI()->get('modelsManager');
     /** @var Builder $query */
     $query = $mm->createBuilder()->from($intermediateModelNameSpace)->join($refModelNameSpace, $refModelNameSpace . ".{$referencedField} = " . $intermediateModelNameSpace . ".{$intermediateFields}");
     $columns = array();
     // join in parent record if one is detected
     $parentName = $relation->getParent();
     if ($parentName) {
         // load parent model
         /** @var BaseModel $parentModel */
         $parentModelNameSpace = $modelNameSpace . $parentName;
         $parentModel = new $refModelNameSpace();
         // load reference relationship
         $parentRelationship = $parentModel->getRelation($parentName);
         $columns[] = "{$parentModelNameSpace}.*";
         $query->join($parentModelNameSpace, "{$parentModelNameSpace}." . $parentRelationship->getReferencedFields() . " = {$refModelNameSpace}." . $parentRelationship->getFields(), $parentModelNameSpace);
     }
     // Load the main record field at the end, so they are not overwritten
     $columns[] = $refModelNameSpace . ".*, " . $intermediateModelNameSpace . ".*";
     $query->columns($columns);
     if (isset($this->baseRecord[$field])) {
         $fieldValue = $this->baseRecord[$field];
     } else {
         // fall back to using the primaryKeyValue
         $fieldValue = $this->primaryKeyValue;
     }
     $whereField = $intermediateModelNameSpace . '.' . $relation->getIntermediateFields();
     $query->where("{$whereField} = \"{$fieldValue}\"");
     $result = $query->getQuery()->execute();
     return $this->loadRelationRecords($result, $relation);
 }
Esempio n. 7
0
 protected final function hasMany(NgModelBase $model, ModelRelation $relation)
 {
     // check options for alias
     $opts = $relation->getOptions();
     if (!isset($opts["alias"])) {
         return;
     }
     // build needed variable(s)
     $references = $relation->getReferencedFields();
     $modelRelation = $relation->getReferencedModel();
     $query = new Query();
     $query->addCondition(new SimpleCondition($references, Operator::OP_EQUALS, $model->getId()));
     // fetch resultset
     try {
         $handler = new Crud();
         /** @type Resultset $resultSet */
         $resultSet = $handler->read(new $modelRelation(), $query, false);
         unset($handler);
     } catch (CrudException $e) {
         throw new Exception($e->getMessage());
     }
     // check and prepare data.links
     if (!isset($this->data["links"][$references])) {
         $this->data["links"][$references] = array();
     }
     // check and prepare linked
     if (!isset($this->linked[$references])) {
         $this->linked[$references] = array();
     }
     foreach ($resultSet as $ngModel) {
         /** @type NgModelBase $ngModel */
         // check if this model already populated
         if (in_array($ngModel->getId(), $this->hasManyIds)) {
             continue;
         }
         // check if this model already in our data.links
         if (in_array($ngModel->getId(), $this->data["links"][$references])) {
             continue;
         }
         // put relation id on data.links
         $this->data["links"][$references][] = (int) $ngModel->getId();
         // envelope model into relation data
         $relationData = $this->envelope->envelope($ngModel);
         // check if relationData already in our linked
         if (in_array($relationData, $this->linked[$references])) {
             continue;
         }
         // put relation data on our linked
         $this->linked[$references][] = $relationData;
     }
 }
Esempio n. 8
0
 /**
  * Setups a relation n-m between two models
  *
  * @param \Phalcon\Mvc\ModelInterface $model
  * @param string|array $fields
  * @param string $intermediateModel
  * @param string|array $intermediateFields
  * @param string|array $intermediateReferencedFields
  * @param string $referencedModel
  * @param string|array $referencedFields
  * @param array|null $options
  * @return \Phalcon\Mvc\Model\Relation
  * @throws Exception
  */
 public function addHasManyToMany($model, $fields, $intermediateModel, $intermediateFields, $intermediateReferencedFields, $referencedModel, $referencedFields, $options = null)
 {
     if (is_object($model) === false || $model instanceof ModelInterface === false || is_string($intermediateModel) === false || is_string($referencedModel) === false || is_array($options) === false && is_null($options) === false) {
         throw new Exception('Invalid parameter type.');
     }
     $entityName = strtolower(get_class($model));
     $intermediateEntity = strtolower($intermediateModel);
     $referencedEntity = strtolower($referencedModel);
     $keyRelation = $entityName . '$' . $referencedEntity;
     if (isset($this->_hasManyToMany[$keyRelation]) === false) {
         $relations = array();
     } else {
         $relations = $this->_hasManyToMany[$keyRelation];
     }
     //Check if the number of fields is the same from the model to the intermediate model
     if (is_array($intermediateFields) === true && count($fields) !== count($intermediateFields)) {
         throw new Exception('Number of referenced fields are not the same');
         //@note sic!
     }
     //@note this check is doing the same as the check before:
     //Check if the number of fields is the same from the intermediate model to the
     //referenced model
     //Create a relationship instance
     $relation = new Relation(4, $referencedModel, $fields, $referencedFields, $options);
     //Set extended intermediate relation data
     $relation->setIntermediateRelation($intermediateFields, $intermediateModel, $intermediateFields);
     if (isset($options['alias']) === true) {
         $lowerAlias = strtolower($options['alias']);
     } else {
         $lowerAlias = $referencedEntity;
     }
     //Append a new relationship
     $relations[] = $relation;
     //Update the global alias
     $this->_aliases[$entityName . '$' . $lowerAlias] = $relation;
     //Update the relations
     $this->_hasManyToMany[$keyRelation] = $relations;
     //Get existing relations by model
     if (isset($this->_hasManyToManySingle[$entityName]) === false) {
         $singleRelations = array();
     } else {
         $singleRelations = $this->_hasManyToManySingle[$entityName];
     }
     //Append a new relationship
     $singleRelations[] = $relation;
     //Update relations by model
     $this->_hasManyToManySingle[$entityName] = $singleRelations;
     return $relation;
 }