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);
 }