/**
  * creates a new entry if you are not a shop admin
  *
  * @param String $keywordString
  * @return Int
  */
 static function add_entry($keywordString, $productCount = 0, $groupCount = 0)
 {
     if ($member = Member::currentUser()) {
         if ($member->IsShopAdmin()) {
             return -1;
         }
     }
     $obj = new SearchHistory();
     $obj->Title = $keywordString;
     $obj->ProductCount = $productCount;
     $obj->GroupCount = $groupCount;
     return $obj->write();
 }
 function doProductSearchForm($data, $form)
 {
     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;
                 $this->resultArrayPos = 0;
                 $this->resultArray = array();
                 $keywordPhrase = Convert::raw2sql($keywordPhrase);
                 $keywordPhrase = strtolower($keywordPhrase);
                 SearchHistory::add_entry($keywordPhrase);
                 // 1) Exact search by code
                 $count = 0;
                 if ($this->debug) {
                     $this->debugOutput("<hr /><h2>SEARCH BY CODE</h2>");
                 }
                 if ($code = intval($keywordPhrase)) {
                     $list1 = $baseList->filter(array("InternalItemID" => $code));
                     $count = $list1->count();
                     if ($count == 1) {
                         if (!$this->debug) {
                             return $this->controller->redirect($list1->First()->Link());
                         }
                     } elseif ($count > 1) {
                         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 == 1) {
                             if (!$this->debug) {
                                 return $this->controller->redirect($list2->First()->Link());
                             }
                         } elseif ($count > 1) {
                             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) {
                             if (!$this->debug) {
                                 return $this->controller->redirect($productGroups->First()->Link());
                             }
                         } elseif ($count) {
                             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 ($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>");
     }
     $link = $redirectToPage->Link($this->controllerSearchResultDisplayMethod);
     if ($this->additionalGetParameters) {
         $link .= "?" . $this->additionalGetParameters;
     }
     if ($this->debug) {
         die($link);
     }
     $this->controller->redirect($link);
 }
 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();
         }
     }
 }
Example #4
0
 public static function addSearchLog($phrase, $query, $info)
 {
     $sh = new SearchHistory();
     $sh->phrase = $phrase;
     $sh->query = $query;
     $sh->info = $info;
     $sh->date = time();
     $sh->ip = HU::getUserIp();
     $sh->save();
 }
 function results($data)
 {
     if (isset($data["Search"]) || isset($data["MainSearch"])) {
         // there is a search
         Requirements::themedCSS("searchpluspage_searchresults", "searchplus");
         if (isset($data["MainSearch"]) || !isset($data["Search"])) {
             $data["Search"] = $data["MainSearch"];
         }
         //redirect if needed
         $data["Search"] = urldecode($data["Search"]);
         $form = $this->SearchPlusForm();
         if (!isset($_GET["redirect"])) {
             self::$search_history_object = SearchHistory::add_entry($data["Search"]);
             if (self::$search_history_object) {
                 if (self::$search_history_object->RedirectTo && self::$search_history_object->RedirectTo != self::$search_history_object->Title) {
                     $this->redirect(str_replace("Search=" . urlencode(self::$search_history_object->Title), "Search=" . urlencode(self::$search_history_object->RedirectTo), HTTP::RAW_setGetVar('redirect', 1, null)));
                 }
             }
         } else {
             self::$search_history_object = SearchHistory::find_entry($data["Search"]);
         }
         //load data for recommended pages
         $recommendationsSet = $this->Recommendations();
         $matchArrayRecommended = array();
         $matchArrayResults = array();
         if ($recommendationsSet) {
             foreach ($recommendationsSet as $rec) {
                 $matchArrayRecommended[$rec->ClassName . $rec->ID] = $rec->ClassName . $rec->ID;
             }
         }
         //work out positions
         $results = $form->getResults();
         $query = $form->getSearchQuery();
         $startingPosition = isset($_REQUEST["start"]) ? $_REQUEST["start"] : 0;
         $endingPosition = $startingPosition + Config::inst()->get("SearchPlusPage", "result_length");
         $startingPosition++;
         if ($results) {
             $total = $results->TotalItems();
         } else {
             $total = 0;
         }
         if ($endingPosition > $total) {
             $endingPosition = $total;
         }
         //highlight search text and check which ones are recommended
         if ($total) {
             foreach ($results as $result) {
                 $title = $result->getTitle();
                 $dbField = DBField::create_field($className = "Text", $title);
                 $result->HighlightedTitle = $dbField->ContextSummary();
                 $result->IsRecommended = false;
                 $matchArrayResults[$result->ClassName . $result->ID] = $result->ClassName . $result->ID;
                 if (isset($matchArrayRecommended[$result->ClassName . $result->ID])) {
                     $result->IsRecommended = true;
                 }
             }
         }
         $data = array('Results' => $results, 'Query' => $query, 'From' => $startingPosition, 'To' => $endingPosition, 'Total' => $total, 'HasResults' => $total ? true : false, 'Recommendations' => $this->Recommendations(), 'RecommendedSearchPlusSection' => $this->dataRecord->RecommendedSearchPlusSections());
         $this->Title = 'Search Results';
         $this->MenuTitle = 'Search Results';
         return $this->customise($data)->renderWith(array('SearchPlusPage_results', 'Page'));
     }
     return array();
 }