/** * Returns an element at a specific offset. * * @param int $offset The offset. * * @return Events_OutputModel|null The element, if there is one. */ public function nth($offset) { if (!isset($this->_matchedElementsAtOffsets) || !array_key_exists($offset, $this->_matchedElementsAtOffsets)) { $criteria = new Venti_CriteriaModel($this->getAttributes(), $this->_elementType); $criteria->offset = $offset; $criteria->limit = 1; $elements = $criteria->find(); if ($elements) { $this->_matchedElementsAtOffsets[$offset] = $elements[0]; } else { $this->_matchedElementsAtOffsets[$offset] = null; } } return $this->_matchedElementsAtOffsets[$offset]; }
/** * Preps a {@link DbCommand} object for querying for elements, based on a given element criteria. * * @param Venti_CriteriaModel &$criteria The events criteria model * * @return DbCommand|false The DbCommand object, or `false` if the method was able to determine ahead of time that * there’s no chance any elements are going to be found with the given parameters. */ public function buildEventsQuery(Venti_CriteriaModel $criteria) { $elementType = $criteria->getElementType(); if (!$elementType->isLocalized()) { // The criteria *must* be set to the primary locale $criteria->locale = craft()->i18n->getPrimarySiteLocaleId(); } else { if (!$criteria->locale) { // Default to the current app locale $criteria->locale = craft()->language; } } $query = craft()->db->createCommand()->select('venti.startDate, venti.endDate, venti.allDay, venti.isrepeat, venti.eid, venti.eventid, venti.repeat, venti.rRule, venti.summary, elements.id, elements.type, elements.enabled, elements.archived, elements.dateCreated, elements.dateUpdated, elements_i18n.slug, elements_i18n.uri, elements_i18n.enabled AS localeEnabled')->from('venti_events venti')->join('elements elements', 'elements.id = venti.eventid')->join('elements_i18n elements_i18n', 'elements_i18n.elementId = venti.eventid')->where('elements_i18n.locale = :locale', array(':locale' => $criteria->locale))->limit($criteria->limit)->offset($criteria->offset)->order($criteria->order); if ($elementType->hasContent()) { $contentTable = 'content'; if ($contentTable) { $contentCols = 'content.id AS contentId'; if ($elementType->hasTitles()) { $contentCols .= ', content.title'; } $fieldColumns = $this->getContentFieldColumnsForElementsQuery($criteria); foreach ($fieldColumns as $column) { $contentCols .= ', content.' . $column['column']; } $query->addSelect($contentCols); $query->join($contentTable . ' content', 'content.elementId = elements.id'); $query->andWhere('content.locale = :locale'); } } if ($elementType->hasTitles() && $criteria->title) { $query->andWhere(DbHelper::parseParam('content.title', $criteria->title, $query->params)); } if ($criteria->id) { $query->andWhere(DbHelper::parseParam('venti.eventid', $criteria->id, $query->params)); } if ($criteria->eid) { $query->andWhere(DbHelper::parseParam('venti.eid', $criteria->eid, $query->params)); } if ($criteria->isrepeat) { $query->andWhere(DbHelper::parseParam('venti.isrepeat', $criteria->isrepeat, $query->params)); } if ($criteria->startDate) { $query->andWhere(DbHelper::parseDateParam('venti.startDate', $criteria->startDate, $query->params)); } if ($criteria->endDate) { $query->andWhere(DbHelper::parseDateParam('venti.endDate', $criteria->endDate, $query->params)); } if ($criteria->summary) { $query->andWhere(DbHelper::parseParam('venti.summary', $criteria->summary, $query->params)); } if ($criteria->slug) { $query->andWhere(DbHelper::parseParam('elements_i18n.slug', $criteria->slug, $query->params)); } if ($criteria->uri) { $query->andWhere(DbHelper::parseParam('elements_i18n.uri', $criteria->uri, $query->params)); } if ($criteria->localeEnabled) { $query->andWhere('elements_i18n.enabled = 1'); } if ($criteria->dateCreated) { $query->andWhere(DbHelper::parseDateParam('elements.dateCreated', $criteria->dateCreated, $query->params)); } if ($criteria->dateUpdated) { $query->andWhere(DbHelper::parseDateParam('elements.dateUpdated', $criteria->dateUpdated, $query->params)); } if ($criteria->archived) { $query->andWhere('elements.archived = 1'); } else { $query->andWhere('elements.archived = 0'); if ($criteria->status) { $statusConditions = array(); $statuses = ArrayHelper::stringToArray($criteria->status); foreach ($statuses as $status) { $status = StringHelper::toLowerCase($status); // Is this a supported status? if (in_array($status, array_keys($this->getStatuses()))) { if ($status == BaseElementModel::ENABLED) { $statusConditions[] = 'elements.enabled = 1'; } else { if ($status == BaseElementModel::DISABLED) { $statusConditions[] = 'elements.enabled = 0'; } else { $elementStatusCondition = $this->getElementQueryStatusCondition($query, $status); if ($elementStatusCondition) { $statusConditions[] = $elementStatusCondition; } else { if ($elementStatusCondition === false) { return false; } } } } } } if ($statusConditions) { if (count($statusConditions) == 1) { $statusCondition = $statusConditions[0]; } else { array_unshift($statusConditions, 'or'); $statusCondition = $statusConditions; } $query->andWhere($statusCondition); } } } // Relational params // --------------------------------------------------------------------- if ($criteria->relatedTo) { $relationParamParser = new ElementRelationParamParser(); $relConditions = $relationParamParser->parseRelationParam($criteria->relatedTo, $query); if ($relConditions === false) { return false; } $query->andWhere($relConditions); // If there's only one relation criteria and it's specifically for grabbing target elements, allow the query // to order by the relation sort order if ($relationParamParser->isRelationFieldQuery()) { $query->addSelect('sources1.sortOrder'); } } // Search // --------------------------------------------------------------------- if ($criteria->search) { $elementIds = $this->_getElementIdsFromQuery($query); $scoredSearchResults = $criteria->order == 'score'; $filteredElementIds = craft()->search->filterElementIdsByQuery($elementIds, $criteria->search, $scoredSearchResults); // No results? if (!$filteredElementIds) { return array(); } $query->andWhere(array('in', 'venti.eventid', $filteredElementIds)); if ($scoredSearchResults) { // Order the elements in the exact order that SearchService returned them in $query->order(craft()->db->getSchema()->orderByColumnValues('venti.eventid', $filteredElementIds)); } } return $query; }