function requireDefaultRecords() { parent::requireDefaultRecords(); $dos = SearchHistory::get()->where("\"Title\" = '' OR \"Title\" IS NULL OR LENGTH(\"Title\") < " . Config::inst()->get("SearchHistory", "minimum_length")); if ($dos) { foreach ($dos as $do) { DB::alteration_message("deleting #" . $do->ID . " from SearchHistory as it does not have a search phrase", "deleted"); $do->delete(); } } }
function doProductSearchForm($data, $form) { $searchHistoryObject = null; if (!$this->maximumNumberOfResults) { $this->maximumNumberOfResults = EcommerceConfig::get("ProductGroup", "maximum_number_of_products_to_list"); } if (isset($data["DebugSearch"])) { $this->debug = $data["DebugSearch"] ? true : false; } if ($this->debug) { $this->debugOutput("<hr /><hr /><hr /><h2>Debugging Search Results</h2>"); } //what is the baseclass? $baseClassName = $this->baseClassForBuyables; if (!$baseClassName) { $baseClassName = EcommerceConfig::get("ProductGroup", "base_buyable_class"); } if (!$baseClassName) { user_error("Can not find {$baseClassName} (baseClassName)"); } //basic get $searchableFields = $baseClassName::create()->stat('searchable_fields'); $baseList = $baseClassName::get()->filter(array("ShowInSearch" => 1)); $ecomConfig = EcommerceDBConfig::current_ecommerce_db_config(); if ($ecomConfig->OnlyShowProductsThatCanBePurchased) { $baseList->filter(array("AllowPurchase" => 1)); } $limitToCurrentSection = false; if (isset($data["SearchOnlyFieldsInThisSection"]) && $data["SearchOnlyFieldsInThisSection"]) { $limitToCurrentSection = true; if ($this->productsToSearch instanceof DataList) { $this->productsToSearch = $this->productsToSearch->map("ID", "ID")->toArray(); } $baseList = $baseList->filter(array("ID" => $this->productsToSearch)); } if (isset($data["MinimumPrice"]) && $data["MinimumPrice"]) { $baseList = $baseList->filter(array("Price:GreaterThanOrEqual" => floatval($data["MinimumPrice"]))); } if (isset($data["MaximumPrice"]) && $data["MaximumPrice"]) { $baseList = $baseList->filter(array("Price:LessThanOrEqual" => floatval($data["MaximumPrice"]))); } //defining some variables $isKeywordSearch = false; if ($this->debug) { $this->debugOutput("<hr /><h3>BASE LIST</h3><pre>" . str_replace($this->sqlWords, array_flip($this->sqlWords), $baseList->sql()) . "</pre>"); } //KEYWORD SEARCH - only bother if we have any keywords and results at all ... if (isset($data["ShortKeyword"]) && !isset($data["Keyword"])) { $data["Keyword"] = $data["ShortKeyword"]; } if (isset($data["Keyword"]) && ($keywordPhrase = $data["Keyword"])) { if ($baseList->count()) { if (strlen($keywordPhrase) > 1) { $isKeywordSearch = true; $immediateRedirectLink = ""; $this->resultArrayPos = 0; $this->resultArray = array(); $keywordPhrase = Convert::raw2sql($keywordPhrase); $keywordPhrase = strtolower($keywordPhrase); $searchHistoryObjectID = SearchHistory::add_entry($keywordPhrase); if ($searchHistoryObjectID) { $searchHistoryObject = SearchHistory::get()->byID($searchHistoryObjectID); } // 1) Exact search by code $count = 0; if ($this->debug) { $this->debugOutput("<hr /><h2>SEARCH BY CODE</h2>"); } $list1 = $baseList->filter(array("InternalItemID" => $keywordPhrase)); $count = $list1->count(); if ($count == 1) { $immediateRedirectLink = $this->controller->redirect($list1->First()->Link()); $this->debugOutput("<p style=\"color: red\">Found one answer for potential immediate redirect: " . $immediateRedirectLink . "</p>"); } if ($count > 0) { if ($this->addToResults($list1)) { break; } } if ($this->debug) { $this->debugOutput("<h3>SEARCH BY CODE RESULT: {$count}</h3>"); } // 2) Search of the entire keyword phrase and its replacements $count = 0; if ($this->debug) { $this->debugOutput("<hr /><h3>FULL KEYWORD SEARCH</h3>"); } if ($this->resultArrayPos <= $this->maximumNumberOfResults) { //now we are going to look for synonyms $words = explode(' ', trim(preg_replace('!\\s+!', ' ', $keywordPhrase))); foreach ($words as $wordKey => $word) { if ($this->debug) { $this->debugOutput("checking for aliases of {$word}"); } $replacements = SearchReplacement::get()->where("\n\t\t\t\t\t\t\t\t\tLOWER(\"Search\") = '{$word}' OR\n\t\t\t\t\t\t\t\t\tLOWER(\"Search\") LIKE '%,{$word}' OR\n\t\t\t\t\t\t\t\t\tLOWER(\"Search\") LIKE '{$word},%' OR\n\t\t\t\t\t\t\t\t\tLOWER(\"Search\") LIKE '%,{$word},%'"); if ($replacements->count()) { $replacementsArray = $replacements->map('ID', 'Replace')->toArray(); if ($this->debug) { $this->debugOutput("found alias for {$word}"); } foreach ($replacementsArray as $replacementWord) { $keywordPhrase = str_replace($word, $replacementWord, $keywordPhrase); } } } if ($this->debug) { $this->debugOutput("<pre>WORD ARRAY: " . print_r($keywordPhrase, 1) . "</pre>"); } //work out searches $singleton = $baseClassName::create(); foreach ($this->extraBuyableFieldsToSearchFullText as $tempClassName => $fieldArrayTemp) { if ($singleton instanceof $tempClassName) { $fieldArray = $fieldArrayTemp; break; } } if ($this->debug) { $this->debugOutput("<pre>FIELD ARRAY: " . print_r($fieldArray, 1) . "</pre>"); } $searches = $this->getSearchArrays($keywordPhrase, $fieldArray); //if($this->debug) { $this->debugOutput("<pre>SEARCH ARRAY: ".print_r($searches, 1)."</pre>");} //we search exact matches first then other matches ... foreach ($searches as $search) { $list2 = $baseList->where($search); $count = $list2->count(); if ($this->debug) { $this->debugOutput("<p>{$search}: {$count}</p>"); } if ($count > 0) { if ($this->addToResults($list2)) { break; } } if ($this->resultArrayPos > $this->maximumNumberOfResults) { break; } } } if ($this->debug) { $this->debugOutput("<h3>FULL KEYWORD SEARCH: {$count}</h3>"); } if ($this->debug) { $this->debugOutput("<hr /><h3>PRODUCT GROUP SEARCH</h3>"); } // 3) Do the same search for Product Group names $count = 0; if ($limitToCurrentSection) { //cant search other sections in this case... } else { $searches = $this->getSearchArrays($keywordPhrase); if ($this->debug) { $this->debugOutput("<pre>SEARCH ARRAY: " . print_r($searches, 1) . "</pre>"); } foreach ($searches as $search) { $productGroups = ProductGroup::get()->where($search)->filter(array("ShowInSearch" => 1)); $count = $productGroups->count(); //redirect if we find exactly one match and we have no matches so far... if ($count == 1 && !$this->resultArrayPos && !$limitToCurrentSection) { $immediateRedirectLink = $this->controller->redirect($productGroups->First()->Link()); $this->debugOutput("<p style=\"color: red\">Found one answer for potential immediate redirect: " . $immediateRedirectLink . "</p>"); } if ($count > 0) { foreach ($productGroups as $productGroup) { //we add them like this because we like to keep them in order! if (!in_array($productGroup->ID, $this->productGroupIDs)) { $this->productGroupIDs[] = $productGroup->ID; } } } } if ($this->debug) { $this->debugOutput("<h3>PRODUCT GROUP SEARCH: {$count}</h3>"); } } } } } if (!$isKeywordSearch) { $this->addToResults($baseList); } $redirectToPage = null; //if no specific section is being searched then we redirect to search page: if (!$limitToCurrentSection) { $redirectToPage = ProductGroupSearchPage::get()->first(); } if (!$redirectToPage) { // for section specific search, // redirect to the specific section (basically where we came from) $redirectToPage = $this->controller->dataRecord; } if ($this->debug) { $this->debugOutput("<hr />" . "<h3>Previous Search Products: " . $redirectToPage->SearchResultsSessionVariable(false) . "</h3><p>" . print_r(Session::get($redirectToPage->SearchResultsSessionVariable(false)), 1) . "</p>" . "<h3>Previous Search Groups: " . $redirectToPage->SearchResultsSessionVariable(true) . "</h3><p>" . print_r(Session::get($redirectToPage->SearchResultsSessionVariable(true)), 1) . "</p>"); } Session::set($redirectToPage->SearchResultsSessionVariable(false), implode(",", $this->resultArray)); Session::set($redirectToPage->SearchResultsSessionVariable(true), implode(",", $this->productGroupIDs)); Session::save(); if ($searchHistoryObject) { $searchHistoryObject->ProductCount = count($this->resultArray); $searchHistoryObject->GroupCount = count($this->productGroupIDs); $searchHistoryObject->write(); } if ($this->debug) { $this->debugOutput("<hr />" . "<h3>SAVING Products to session: " . $redirectToPage->SearchResultsSessionVariable(false) . "</h3><p>" . print_r(explode(",", Session::get($redirectToPage->SearchResultsSessionVariable(false))), 1) . "</p>" . "<h3>SAVING Groups to session: " . $redirectToPage->SearchResultsSessionVariable(true) . "</h3><p>" . print_r(explode(",", Session::get($redirectToPage->SearchResultsSessionVariable(true))), 1) . "</p>"); } if ($immediateRedirectLink) { $link = $immediateRedirectLink; } else { $link = $redirectToPage->Link($this->controllerSearchResultDisplayMethod); } if ($this->additionalGetParameters) { $link .= "?" . $this->additionalGetParameters; } if ($this->debug) { die($link); } $this->controller->redirect($link); }