/** * 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(); } }
/** * 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; }
/** * Creates a FOFHalDocument using the provided data * * @param array $data The data to put in the document * @param DataModel $model The model of this view * * @return \Awf\Hal\Document A HAL-enabled document */ protected function _createDocumentWithHypermedia($data, $model = null) { // Create a new HAL document if (is_array($data)) { $count = count($data); } else { $count = null; } if ($count == 1) { reset($data); $document = new \Awf\Hal\Document(end($data)); } else { $document = new \Awf\Hal\Document($data); } // Create a self link $router = $this->container->router; $uri = (string) Uri::getInstance(); $uri = $this->_removeURIBase($uri); $uri = $router->route($uri); $document->addLink('self', new Link($uri)); // Create relative links in a record list context if (is_array($data) && $model instanceof DataModel) { if (!isset($this->total)) { $this->total = $model->count(); } if (!isset($this->limitStart)) { $this->limitStart = $model->getState('limitstart', 0); } if (!isset($this->limit)) { $this->limit = $model->getState('limit', 0); } $pagination = new Pagination($this->total, $this->limitStart, $this->limit, 10, $this->container->application); if ($pagination->pagesTotal > 1) { // Try to guess URL parameters and create a prototype URL // NOTE: You are better off specialising this method $protoUri = $this->_getPrototypeURIForPagination(); // The "first" link $uri = clone $protoUri; $uri->setVar('limitstart', 0); $uri = $router->route($uri); $document->addLink('first', new Link($uri)); // Do we need a "prev" link? if ($pagination->pagesCurrent > 1) { $prevPage = $pagination->pagesCurrent - 1; $limitstart = ($prevPage - 1) * $pagination->limit; $uri = clone $protoUri; $uri->setVar('limitstart', $limitstart); $uri = $router->route($uri); $document->addLink('prev', new Link($uri)); } // Do we need a "next" link? if ($pagination->pagesCurrent < $pagination->pagesTotal) { $nextPage = $pagination->pagesCurrent + 1; $limitstart = ($nextPage - 1) * $pagination->limit; $uri = clone $protoUri; $uri->setVar('limitstart', $limitstart); $uri = $router->route($uri); $document->addLink('next', new Link($uri)); } // The "last" link? $lastPage = $pagination->pagesTotal; $limitstart = ($lastPage - 1) * $pagination->limit; $uri = clone $protoUri; $uri->setVar('limitstart', $limitstart); $uri = $router->route($uri); $document->addLink('last', new Link($uri)); } } return $document; }
/** * Gets the list of IDs from the request data * * @param DataModel $model The model where the record will be loaded * @param bool $loadRecord When true, the record matching the *first* ID found will be loaded into $model * * @return array */ public function getIDsFromRequest(DataModel &$model, $loadRecord = true) { // Get the ID or list of IDs from the request or the configuration $cid = $this->input->get('cid', array(), 'array'); $id = $this->input->getInt('id', 0); $kid = $this->input->getInt($model->getIdFieldName(), 0); $ids = array(); if (is_array($cid) && !empty($cid)) { $ids = $cid; } else { if (empty($id)) { if (!empty($kid)) { $ids = array($kid); } } else { $ids = array($id); } } if ($loadRecord && !empty($ids)) { $id = reset($ids); $model->find(array('id' => $id)); } return $ids; }
/** * 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; }
/** * 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(); }
/** * Overrides the DataModel's buildQuery to allow nested set searches using the provided scopes * * @param bool $overrideLimits * * @return \Awf\Database\Query */ public function buildQuery($overrideLimits = false) { $db = $this->getDbo(); $query = parent::buildQuery($overrideLimits); $query->select(null)->select($db->qn('node') . '.*')->from(null)->from($db->qn($this->tableName) . ' AS ' . $db->qn('node')); if ($this->treeNestedGet) { $query->join('CROSS', $db->qn($this->tableName) . ' AS ' . $db->qn('parent')); } return $query; }