/** * Searches for tags. */ public function actionSearchForTags() { $this->requirePostRequest(); $this->requireAjaxRequest(); $search = craft()->request->getPost('search'); $tagSetId = craft()->request->getPost('tagSetId'); $excludeIds = craft()->request->getPost('excludeIds', array()); $notIds = array(); foreach ($excludeIds as $id) { $notIds[] = 'not ' . $id; } $criteria = craft()->elements->getCriteria(ElementType::Tag); $criteria->setId = $tagSetId; $criteria->search = 'name:' . $search . '*'; $criteria->id = implode(', ', $notIds); $tags = $criteria->find(); $return = array(); $exactMatches = array(); $tagNameLengths = array(); $exactMatch = false; $normalizedSearch = StringHelper::normalizeKeywords($search); foreach ($tags as $tag) { $return[] = array('id' => $tag->id, 'name' => $tag->name); $tagNameLengths[] = strlen($tag->name); $normalizedName = StringHelper::normalizeKeywords($tag->name); if ($normalizedName == $normalizedSearch) { $exactMatches[] = 1; $exactMatch = true; } else { $exactMatches[] = 0; } } array_multisort($exactMatches, SORT_DESC, $tagNameLengths, $return); $this->returnJson(array('tags' => $return, 'exactMatch' => $exactMatch)); }
/** * Fork of tags/searchForTags adjusted to cope with any element */ public function actionSearchForElements() { $this->requirePostRequest(); $this->requireAjaxRequest(); $search = craft()->request->getPost('search'); $excludeIds = craft()->request->getPost('excludeIds', array()); // Get the post data $elementType = craft()->request->getPost('elementType'); $sources = craft()->request->getPost('sources'); // Deal with Entries if ($elementType == ElementType::Entry) { // Start the criteria $criteria = craft()->elements->getCriteria(ElementType::Entry); // Fangle the sections out of the sources $sections = array(); if (is_array($sources)) { foreach ($sources as $source) { switch ($source) { case 'singles': $sections = array_merge($sections, craft()->sections->getSectionsByType(SectionType::Single)); break; default: if (preg_match('/^section:(\\d+)$/', $source, $matches)) { $section = craft()->sections->getSectionById($matches[1]); if ($section) { $sections = array_merge($sections, array($section)); } } } } } $criteria->section = $sections; } else { if ($elementType == ElementType::Category) { // Start the criteria $criteria = craft()->elements->getCriteria(ElementType::Category); } } // Add and exclude ids $notIds = array('and'); foreach ($excludeIds as $id) { $notIds[] = 'not ' . $id; } // Set the rest of the criteria $criteria->title = '*' . DbHelper::escapeParam($search) . '*'; $criteria->id = $notIds; $criteria->status = null; $criteria->limit = 20; $elements = $criteria->find(); $return = array(); $exactMatches = array(); $exactMatch = false; $normalizedSearch = StringHelper::normalizeKeywords($search); foreach ($elements as $element) { if ($elementType == ElementType::Entry) { if (!is_array($sources)) { $sourceKey = "*"; } else { if ($element->section->type == SectionType::Single) { $sourceKey = "singles"; } else { $sourceKey = "section:" . $element->section->id; } } $return[$sourceKey][] = array('id' => $element->id, 'title' => $element->getContent()->title, 'status' => $element->status, 'sourceName' => $element->section->name); } else { if ($elementType == ElementType::Category) { $sourceKey = "group:" . $element->group->id; $return[$sourceKey][] = array('id' => $element->id, 'title' => $element->getContent()->title, 'status' => $element->status, 'sourceName' => $element->group->name); } } $normalizedTitle = StringHelper::normalizeKeywords($element->getContent()->title); if ($normalizedTitle == $normalizedSearch) { $exactMatches[] = 1; $exactMatch = true; } else { $exactMatches[] = 0; } } // NOTE: We’ve lost the sorting by exact match // array_multisort($exactMatches, SORT_DESC, $return); $this->returnJson(array('elements' => $return, 'exactMatch' => $exactMatch)); }
/** * Searches for tags. * * @return null */ public function actionSearchForTags() { $this->requirePostRequest(); $this->requireAjaxRequest(); $search = craft()->request->getPost('search'); $tagGroupId = craft()->request->getPost('tagGroupId'); $excludeIds = craft()->request->getPost('excludeIds', array()); $notIds = array('and'); foreach ($excludeIds as $id) { $notIds[] = 'not ' . $id; } $criteria = craft()->elements->getCriteria(ElementType::Tag); $criteria->groupId = $tagGroupId; $criteria->title = DbHelper::escapeParam($search) . '*'; $criteria->id = $notIds; $tags = $criteria->find(); $return = array(); $exactMatches = array(); $tagTitleLengths = array(); $exactMatch = false; $normalizedSearch = StringHelper::normalizeKeywords($search); foreach ($tags as $tag) { $return[] = array('id' => $tag->id, 'title' => $tag->getContent()->title); $tagTitleLengths[] = mb_strlen($tag->getContent()->title); $normalizedTitle = StringHelper::normalizeKeywords($tag->getContent()->title); if ($normalizedTitle == $normalizedSearch) { $exactMatches[] = 1; $exactMatch = true; } else { $exactMatches[] = 0; } } array_multisort($exactMatches, SORT_DESC, $tagTitleLengths, $return); $this->returnJson(array('tags' => $return, 'exactMatch' => $exactMatch)); }
/** * Normalize term from tokens, keep a record for cache. * * @param string $term * * @return string */ private function _normalizeTerm($term) { static $terms = array(); if (!array_key_exists($term, $terms)) { $terms[$term] = StringHelper::normalizeKeywords($term); } return $terms[$term]; }
/** * Get database records for current collection. */ private function _getRecordsForCollection() { // Get element criteria $criteria = craft()->elements->getCriteria($this->_collection->elementType); $criteria->locale = $this->_getSearchParam('locale'); $criteria->limit = null; // Get element type $elementType = $criteria->getElementType(); // Set element source if ($this->_getCollectionSetting('source')) { $sources = $this->_getCollectionSetting('source'); if (!is_array($sources)) { $sources = array($sources); } // Gather all criteria $sourcesCriteria = array(); foreach ($sources as $source) { $elementSource = $elementType->getSource($source); // Does the source specify any criteria attributes? if ($elementSource && !empty($elementSource['criteria'])) { foreach ($elementSource['criteria'] as $key => $value) { // Add to the gathered criteria if (!isset($sourcesCriteria[$key])) { $sourcesCriteria[$key] = is_array($value) ? $value : array($value); } elseif (is_array($value)) { $sourcesCriteria[$key] = array_merge($sourcesCriteria[$key], $value); } else { $sourcesCriteria[$key][] = $value; } } } } // Criteria fixes switch ($this->_collection->elementType) { case ElementType::Entry: if (isset($sourcesCriteria['editable'])) { unset($sourcesCriteria['editable']); } break; } // Set all criteria now! $criteria->setAttributes($sourcesCriteria); } // Set element status if ($this->_getCollectionSetting('status')) { $criteria->status = $this->_getCollectionSetting('status'); } // Get the element's query $query = craft()->elements->buildElementsQuery($criteria); if (!$query) { return false; } // Set search criteria? $this->_keywords = null; // Always reset first, regardless of param $this->_scoreResults = null; // Always reset first, regardless of param if ($this->_getSearchParam('keywords') && trim($this->_getSearchParam('keywords')) != '') { $this->_keywords = StringHelper::normalizeKeywords($this->_getSearchParam('keywords')); if (!$this->_setSearchCriteria($criteria, $query)) { return false; // No search results! } } // Get user fullName if correct collection is given if ($this->_collection->elementType == ElementType::User) { $query->addSelect('IF (users.lastName != "", CONCAT_WS(" ", users.firstName, users.lastName), users.firstName) AS fullName'); } // Find records! $elements = $query->queryAll(); // Handle found elements if ($elements) { // Handle elements! $this->_handleElements($elements); } }