/** * Public constructor. Initialises the relation. * * @param DataModel $parentModel The data model we are attached to * @param string $foreignModelClass The class name of the foreign key's model * @param string $localKey The local table key for this relation, default: parentModel's ID field name * @param string $foreignKey The foreign key for this relation, default: parentModel's ID field name * @param string $pivotTable IGNORED * @param string $pivotLocalKey IGNORED * @param string $pivotForeignKey IGNORED */ public function __construct(DataModel $parentModel, $foreignModelClass, $localKey = null, $foreignKey = null, $pivotTable = null, $pivotLocalKey = null, $pivotForeignKey = null) { parent::__construct($parentModel, $foreignModelClass, $localKey, $foreignKey, $pivotTable, $pivotLocalKey, $pivotForeignKey); if (empty($localKey)) { // Get a model instance $container = Application::getInstance($this->foreignModelApp)->getContainer(); /** @var DataModel $foreignModel */ $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container); $this->localKey = $foreignModel->getIdFieldName(); } if (empty($foreignKey)) { if (!isset($foreignModel)) { // Get a model instance $container = Application::getInstance($this->foreignModelApp)->getContainer(); /** @var DataModel $foreignModel */ $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container); } $this->foreignKey = $foreignModel->getIdFieldName(); } }
/** * Returns the count subquery for DataModel's has() and whereHas() methods. * * @return Query */ public function getCountSubquery() { // Get a model instance $container = Application::getInstance($this->foreignModelApp)->getContainer(); /** @var DataModel $foreignModel */ $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container); $db = $foreignModel->getDbo(); $query = $db->getQuery(true)->select('COUNT(*)')->from($db->qn($foreignModel->getTableName()) . ' AS ' . $db->qn('reltbl'))->innerJoin($db->qn($this->pivotTable) . ' AS ' . $db->qn('pivotTable') . ' ON(' . $db->qn('pivotTable') . '.' . $db->qn($this->pivotForeignKey) . ' = ' . $db->qn('reltbl') . '.' . $db->qn($foreignModel->getFieldAlias($this->foreignKey)) . ')')->where($db->qn('pivotTable') . '.' . $db->qn($this->pivotLocalKey) . ' =' . $db->qn($this->parentModel->getTableName()) . '.' . $db->qn($this->parentModel->getFieldAlias($this->localKey))); return $query; }
/** * Get the relation data. * * If you want to apply additional filtering to the foreign model, use the $callback. It can be any function, * static method, public method or closure with an interface of function(DataModel $foreignModel). You are not * supposed to return anything, just modify $foreignModel's state directly. For example, you may want to do: * $foreignModel->setState('foo', 'bar') * * @param callable $callback The callback to run on the remote model. * @param Collection $dataCollection * * @return Collection|DataModel */ public function getData(callable $callback = null, Collection $dataCollection = null) { if (is_null($this->data)) { // Initialise $this->data = new Collection(); // Get a model instance $container = Application::getInstance($this->foreignModelApp)->getContainer(); /** @var DataModel $foreignModel */ $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container)->setIgnoreRequest(true); $filtered = $this->filterForeignModel($foreignModel, $dataCollection); if (!$filtered) { return $this->data; } // Apply the callback, if applicable if (!is_null($callback) && is_callable($callback)) { call_user_func($callback, $foreignModel); } // Get the list of items from the foreign model and cache in $this->data $this->data = $foreignModel->get(true); } return $this->data; }
/** * Returns a new item of the foreignModel type, pre-initialised to fulfil this relation * * @return DataModel * * @throws DataModel\Relation\Exception\NewNotSupported when it's not supported */ public function getNew() { // Get a model instance $container = Application::getInstance($this->foreignModelApp)->getContainer(); /** @var DataModel $foreignModel */ $foreignModel = DataModel::getTmpInstance($this->foreignModelApp, $this->foreignModelName, $container); // Prime the model $foreignModel->setFieldValue($this->foreignKey, $this->parentModel->getFieldValue($this->localKey)); // Make sure we do have a data list if (!$this->data instanceof Collection) { $this->getData(); } // Add the model to the data list $this->data->add($foreignModel); return $this->data->last(); }