/** 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 * @return \Phalcon\Mvc\Model\ResultsetInterface */ private function getNeedDelete(array $relationsArray, $model, $relation) { $modelRelation = $relation->getReferencedModel(); $referencedField = $relation->getReferencedFields(); $relationsArrayIdList = $this->getRelationsArrayIdList($relationsArray); /** * @var \Phalcon\Mvc\Model\Criteria $q */ $q = $modelRelation::query(); if (!empty($relationsArrayIdList)) { $q->notInWhere('id', $relationsArrayIdList); } $q->andWhere($referencedField . ' = :referencedField:', array('referencedField' => $model->id)); $result = $q->execute(); return $result; }
/** * 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); }
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; } }