We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 26698
    • 148 Posts
    Организовал-таки поиск с помощью FlexSearchForm.
    Но возникла следующая проблема: слово находит, результаты показывает. Однако, при повторном запросе, когда вводится другое слово, выдаёт результаты по предыдущему запросу, то же (предыдущее искомое) слово можно увидеть в форме поиска. Как это победить — не знаю.

    Вызов (в чанке):
    [[FlexSearchForm?&FSF_landing=`12` &FSF_showResults=`0`]]
    

    Вызов на странице результатов поиска (id 12):
     [[FlexSearchForm? &FSF_showForm=`0` ]]

    Код сниппета скачал отсюда: http://www.etomite.com/browsesnippets.html?int_snipid=11
    Слегка изменил (убрал кнопку, так как нажития клавиши Enter вполне достаточно):

    <?php
    // -----------------------
    // Snippet: FlexSearchForm
    // -----------------------
    // Version: 0.6j
    // Date: 2005.02.01
    // [email protected]
    //
    // This snippet was designed to create a search form
    // that is highly flexible in how it is presented. It
    // can be used as both a small, subtle, persistent
    // search field element, as well as present the search
    // results. All elements are branded with classes
    // for easy CSS styling.
    
    // CONFIGURE
    
      // MAIN SNIPPET SETUP OPTIONS
      // --------------------------
    
       // $searchStyle [ 'relevance' | 'partial' ]
       // This option allows you to decide to use a faster,
       // relevance sorted search ('relevance') which WILL NOT
       // inlclude partial matches. Or use a slower, but
       // more inclusive search ('partial') that will include
       // partial matches. Results will NOT be sorted based on
       // relevance.
       //
       // This option contributed by Rich from Snappy Graffix Media to 
       // allow partial matching and LIKE matching of the search term.
       // [email protected]
       $searchStyle = 'partial';
       
       // $useAllWords [ true | false ]
       // If you want only documents which contain ALL words in the 
       // search string, set to true. Otherwise, the search will return
       // all pages with ONE or more of the search words (which can be 
       // a LOT more pages).
       $useAllWords = true;
    
       // $showSearchWithResults [1 | 0]
       // If you would like to turn off the search
       // form when showing results you can set
       // this to false. Can also be set in template
       // by using the snippet variable: FSF_showForm
       // like this (1=true, 0=false):
       // [[FlexSearchForm?FSF_showForm=0]]
       $showSearchWithResults = 1;
    
       // $resultsPage [int]
       // The default behavior is to show the results on
       // the current page, but you may define the results
       // page any way you like. The priority is:
       //
       // 1- snippet variable - set in page template like this:
       //    [[FlexSearchForm?FSF_landing=int]]
       //    where int is the page id number of the page you want
       //    your results on
       // 2- querystring variable FSF_form
       // 3- variable set here
       // 4- use current page
       //
       // This is VERY handy when you want to put the search form in
       // a discrete and/or small place on your page- like a side
       // column, but don't want all your results to show up there!
       // Set to results page or leave 0 as default
       $resultsPage = 0;
    
       // $showResults [1 | 0] (as passed in snippet variable ONLY)
       // You can define whether this snippet will show the results
       // of the search with it. Do this by assigning the snippet
       // variable FSF_showResults as:
       // [[FlexSearchForm?FSF_showResults=0]]
       //
       // This is useful in situations where you want to show the
       // search results in a different place than the search form.
       // In that type of situation, you would include two of these
       // snippets on the same page, one showing results, and one
       // showing the form.
       //
       // Default is true.
    
       // $grabMax [ int ]   
       // Set to the max number of records you would like on
       // each page. Set to 0 if unlimited.
       $grabMax = 10;
    
       // $pageLinkSeparator [ string ]
       // What you want, if anything, between your page link numbers
       $pageLinkSeparator = "";
    
       // $stripHTML [ true | false ]
       // Allow HTML characters in the search? Probably not.
       $stripHTML = true;
    		
       // $stripSnip [ true | false ]
       // Strip out snippet calls etc from the search string?
       $stripSnip = true;
       
       // $stripSnippets [ true | false ]
       // Strip out snippet names so users will not be able to "search"
       // to see what snippets are used in your content. This is a 
       // security benefit, as users will not be able to search for what pages
       // use specific snippets.
       $stripSnippets = true;
       
       // $xhtmlStrict [ true | false ]
       // If you want this form to validate as XHTML Strict compliance, then
       // this needs to be true, but IE has a fieldset bug that I don't know
       // a workaround for. So you can set this to false to avoid it.
       $xhtmlStrict = false;
    
       // $minChars [ int ]
       // Minimum number of characters to require for a word to be valid for
       // searching. MySQL will typically NOT search for words with less than
       // 4 characters (relevance mode). If you have $useAllWords = true and
       // a three or fewer word appears in the search string, the results will
       // always be 0. Setting this drops those words from the search in THAT
       // CIRCUMSTANCE ONLY (relevance mode, useAllWords=true).
       $minChars = 3;
    
    
      // LANGUAGE AND LABELS
      // --------------------------
    
       // $resultsIntroFailure
       // If nothing is found for the search. You should give the user
       // some indication that the search was a failure.
       $resultsIntroFailure = ' Поиск не дал результатов.';
    
       // $searchButtonText [string]
       // Label the search button what
       // you wish
       $searchButtonText = 'Искать';
       
       // $boxText [ string ]
       // What, if anything, you want to have in the search box when the
       // form first loads. When clicked, it will disappear. This uses 
       // JavaScript. If you don't want this feature or the JavaScript,
       // just set to empty string: ''
       $boxText = 'поиск';
    
       // $introMessage [ string ]
       // This is the text that will show up if the person arrives
       // at the search page without having done a search first.
       // You can leave this as an empty string if you like.
       $introMessage = 'Пожалуйста, введите строку для поиска';   
       
       $minSymbols = 'Количество символов строки поиска не должно быть меньше трёх';
       
       // $resultsFoundTextSingle, $resultsFoundTextMultiple [ string patttern ]
       // The string that will tell the user how many results were found.
       // two variables will be provided at runtime:
       // %d    The number of results found (integer)
       // %s    The search string itself.
       $resultsFoundTextSingle = 'Найдено одно соответствие: ';
       $resultsFoundTextMultiple = 'Найдено соответствий: %d';
       
       // $paginationTextSinglePage and $paginationTextMultiplePages [ string ]
       // The text that comes before the links to other pages. In this
       // example, "Result pages: " was the $paginationTextMultiplePages:
       // Result pages: 1 | 2 | 3 | 4
       // Page numbers will only appear if there is more than one page.
       $paginationTextSinglePage = '';
       $paginationTextMultiplePages = 'Страницы: ';
    
    // Styles
    // These styles are included in this snippet:
    //
    // .FSF_form{}
    // .FSF_input {}
    // .FSF_submit {}
    //
    // .FSF_SearchResults {}
    // .FSF_resultsIntroFailure{}
    // .FSF_result {}
    // .FSF_resultLink {}
    // .FSF_resultDescription {}
    // .FSF_pagination{} 
    // .FSF_intro
    
    // -------------
    // End configure
    // -------------
    
    // establish whether to show the form or not
    $showSearchWithResults = (isset($FSF_showForm))? $FSF_showForm : $showSearchWithResults;
    
    // establish whether to show the results or not
    $showResults = (isset($FSF_showResults))? $FSF_showResults : true;
    
    // establish results page
    if (isset($FSF_landing)){ // set in snippet
      $searchAction = "[~".$FSF_landing."~]";
    } elseif ($resultsPage > 0){ // locally set
      $searchAction = "[~".$resultsPage."~]";
    }  else { //otherwise
      $searchAction = "[~".$modx->documentIdentifier."~]";
    }
    
    // Set newline variable
    $newline = "\n";
    
    // Initialize search string
    $searchString = '';
    
    $temp = $_POST['search'];
    if (strlen($temp)>3) 
    {
    	$minimumSymbols = true;
    }
    else 
    {
    	$minimumSymbols = false;
    }
    
    // CLEAN SEARCH STRING
    if ($minimumSymbols){
      // Prefer post to get
      $searchString = (isset($_POST['search']))? $_POST['search'] : urldecode($_GET['FSF_search']) ;
      // block sensitive search patterns
      $searchString =
      (
      $searchString != "{{" &&
      $searchString != "[[" &&
      $searchString != "[!" &&
      $searchString != "[(" &&
      $searchString != "[~" &&
      $searchString != "[*" 
      )
      ?
      $searchString : "" ;
    
      // Remove dangerous tags and such
    
      // Strip HTML too
      if ($stripHTML){
        $searchString = strip_tags($searchString);
      }
    
      // Regular expressions of things to remove from search string
      $modRegExArray[] = '~\[\[(.*?)\]\]~';   // [[snippets]]
      $modRegExArray[] = '~\[!(.*?)!\]~';     // [!noCacheSnippets!]
      $modRegExArray[] = '!\[\~(.*?)\~\]!is'; // [~links~]
      $modRegExArray[] = '~\[\((.*?)\)\]~';   // [(settings)]
      $modRegExArray[] = '~{{(.*?)}}~';       // {{chunks}}
      $modRegExArray[] = '~\[\*(.*?)\*\]~';   // [*attributes*]
      
      // Remove modx sensitive tags
      if ($stripSnip){
        foreach ($modRegExArray as $mReg){
          $searchString = preg_replace($mReg,'',$searchString);
        }
      }
    
      // Remove snippet names
      if ($stripSnippets && $searchString != ''){
        // get all the snippet names
        $tbl = $modx->dbConfig['dbase'] . "." . $modx->dbConfig['table_prefix'] . "site_snippets";
        $snippetSql = "SELECT $tbl.name FROM $tbl;";
        $snippetRs = $modx->dbQuery($snippetSql);
        $snippetCount = $modx->recordCount($snippetRs);
        $snippetNameArray = array();
        for ($s = 0; $s < $snippetCount; $s++){
          $thisSnippetRow = $modx->fetchRow($snippetRs);
          $snippetNameArray[] = strtolower($thisSnippetRow['name']);
        }
        // Split search into strings
        $searchWords = explode(' ',$searchString);
        $cleansedWords = '';
        foreach($searchWords as $word){
          if ($word != '' && 
              !in_array(strtolower($word),$snippetNameArray) &&
                ((!$useAllWords) ||
                ($searchStyle == 'partial') ||
                (strlen($word) >= $minChars && $useAllWords && $searchStyle == 'relevance'))
             ){
            $cleansedWords .= $word.' ';
          }
        }
        // Remove last space
        $cleansedWords = substr($cleansedWords,0,(strlen($cleansedWords)-1));
        
        $searchString = $cleansedWords;
      }
    
    } // End cleansing search string
    
    // check querystring
    $validSearch = ($searchString != '')? true : false ;
    
    //check for offset
    $offset = (isset($_GET['FSF_offset']))? $_GET['FSF_offset'] : 0;
    
    // initialize output
    $SearchForm = '';
    
    // establish form
    if (($validSearch && ($showSearchWithResults)) || $showSearchWithResults){
      $SearchForm .= '<form class="FSF_form" id="bot" action="'.$searchAction.'" method="post">';
      $SearchForm .= ($xhtmlStrict)? '<fieldset><legend>Search</legend>' : '' ;
      // decide what goes in search box
      $searchBoxVal = ($searchString == '' && $boxText != '')? $boxText : $searchString ;
      $SearchForm .= '<input class="input" type="text" name="search" value="'.$searchBoxVal.'"  ';
      $SearchForm .= ($boxText)? 'onfocus="this.value=(this.value==\''.$boxText.'\')? \'\' : this.value ;" />' : '/>';
      $SearchForm .= ($xhtmlStrict)? '</fieldset>' : '';
      $SearchForm .= '</form>'.$newline;
    }
    
    if ($showResults) {
      if($validSearch) {
        $search = explode(" ", $searchString);
        $tbl = $modx->dbConfig['dbase'] . "." . $modx->dbConfig['table_prefix'] . "site_content";
    
        if ($searchStyle == 'partial'){
          $sql = "SELECT id, pagetitle, description ";
          $sql .= "FROM $tbl ";
          $sql .= "WHERE ";
          if (count($search)>1 && $useAllWords){
            foreach ($search as $searchTerm){
              $sql .= "(pagetitle LIKE '%$searchString%' OR description LIKE '%$searchString%' OR content LIKE '%$searchTerm%') AND ";
            }
          } else {
            $sql .= "(pagetitle LIKE '%$searchString%' OR description LIKE '%$searchString%' OR content LIKE '%$searchString%') AND ";
          }
          $sql .= "$tbl.published = 1 AND $tbl.searchable=1 AND $tbl.deleted=0;";
        } else {
          $sql = "SELECT id, pagetitle, description ";
          $sql .= "FROM $tbl WHERE ";
          if (count($search)>1 && $useAllWords){
            foreach ($search as $searchTerm){
              $sql .= "MATCH (pagetitle, description, content) AGAINST ('$searchTerm') AND ";
            }
          } else {
            $sql .= "MATCH (pagetitle, description, content) AGAINST ('$searchString') AND ";
          }
          $sql .= "$tbl.published = 1 AND $tbl.searchable=1 AND $tbl.deleted=0;";
        }
    
        $rs = $modx->dbQuery($sql);
        $limit = $modx->recordCount($rs);
    
        if($limit>0) {
          $SearchForm .= '<div class="FSF_searchResults">'.$newline;
    
          // pagination
    
          if ($grabMax > 0){
            $numResultPages = ceil($limit/$grabMax);
            $resultPageLinks = '<span class="FSF_pages">';
            $resultPageLinks .= ($limit>$grabMax)? $paginationTextMultiplePages : $paginationTextSinglePage ;
            $resultPageLinkNumber = 1;
            for ($nrp=0;$nrp<$limit && $limit > $grabMax;$nrp+=$grabMax){
              if($offset == ($resultPageLinkNumber-1)*$grabMax){
                $resultPageLinks .= '<span id="active">' . $resultPageLinkNumber . '</span>';
              } else {
                $resultPageLinks .= '<span class="passive"><a href="[~' . $modx->documentObject['id'] . '~]&FSF_offset=' . $nrp . '&FSF_search=' . urlencode($searchString) . '">' . $resultPageLinkNumber . '</a></span>';
              }
              $resultPageLinks .= ($nrp+$grabMax < $limit)? $pageLinkSeparator : '' ;
              $resultPageLinkNumber++;
            }
            $resultPageLinks .= "</span>".$newline;
            $SearchForm .= '<p>';
            $resultsFoundText = ($limit > 1)? $resultsFoundTextMultiple : $resultsFoundTextSingle ;
            $SearchForm .= sprintf($resultsFoundText,$limit,$searchString);
            $SearchForm .= "</p>".$newline;
          } // end if grabMax
    
          // search results
          $useLimit = ($grabMax > 0)? $offset+$grabMax : $limit;
          for ($y = $offset; ($y < $useLimit) && ($y<$limit); $y++) {
            $moveToRow = mysql_data_seek($rs,$y);
            $SearchFormsrc=$modx->fetchRow($rs);
            $SearchForm.='<div class="FSF_result">'.$newline;
            $SearchForm.='<a class="FSF_resultLink" href="[~'.$SearchFormsrc['id'].'~]" title="' . $SearchFormsrc['pagetitle'] . '">' . $SearchFormsrc['pagetitle'] . "</a>".$newline;
            $SearchForm.=$SearchFormsrc['description']!='' ? '<span class="FSF_resultDescription">' . $SearchFormsrc['description'] . "</span>".$newline : "" ;
            $SearchForm.='</div><!--end FlexSearchResult-->'.$newline;
          }
          $SearchForm.='<p>'.$resultPageLinks.'</p>';
          $SearchForm.='</div><!--end FlexSearchResults-->'.$newline;
        } else {
          $SearchForm.='<p class="FSF_resultsIntroFailure">'.$resultsIntroFailure.'</p>';
        } // end if records found
    
      } else if (!$minimumSymbols) {
        	
    	$SearchForm .= '<p class="FSF_intro">'.$minSymbols.'</p>';
    	      
      } else if (!$validSearch && isset($_POST['sub'])) {
    
        // message to show if search was performed but for something invalid
        $SearchForm .= '<p class="FSF_resultsIntroFailure">'.$resultsIntroFailure.'</p>';
      
      } else { // end if validSearch
    
        $SearchForm .= '<p class="FSF_intro">'.$introMessage.'</p>';
    
      } // end if not validSearch
    } // end if showResults
    
    return $SearchForm;
    ?>
    


    Подскажите, как справится с проблемой.
      • 26698
      • 148 Posts
      Что? Никто с подобным не сталкивался?
      У меня есть подозрение что там включается что-то наподобие флуд-контроля (хотя зачем это надо в поиске, непонятно), так как через некоторое время (несколько минут) можно делать новый поиск. Но это как-то некруто undecided
        • 2495
        • 30 Posts
        Попробуйте поработать с ajaxSearch...
          • 26698
          • 148 Posts
          Я бы рад, но там вообще дохлый номер. И как там кнопку убрать? Вообще здесь все не советуют Аякс использовать, типа FlexSearchForm проще и лучше. Но, как выясняется, и глючнее. А с Аяксом мне вообще по жизни не срастается никак :-(
            • 2495
            • 30 Posts
            Quote from: serdeles at Jul 22, 2008, 03:47 PM

            Я бы рад, но там вообще дохлый номер. И как там кнопку убрать? Вообще здесь все не советуют Аякс использовать, типа FlexSearchForm проще и лучше. Но, как выясняется, и глючнее. А с Аяксом мне вообще по жизни не срастается никак  :-(

            Сам в своё время метался... Но UTF-8 и чтения манов спасут всех! smiley
            ajaxSearch хоть и глючен в чём-то, но в 95% случаях багфиксы на форуме отписаны, а остальные 5% можно реализовать альтернативно тем же ajaxSearch’ем... smiley
            Просто у него возможностей поболе, ввиду этого и немного по-началу пугает так.
              • 26698
              • 148 Posts
              Самый прикол в том, что заказчик решил, что ему нравится другой вариант дизайна (уже после того. как сайт готов и cms прикручен). И в этом варианте поиск вообще не предусмотрен smiley Маразм, в общем smiley
                • 2495
                • 30 Posts
                Quote from: serdeles at Jul 22, 2008, 03:57 PM

                Самый прикол в том, что заказчик решил, что ему нравится другой вариант дизайна (уже после того. как сайт готов и cms прикручен). И в этом варианте поиск вообще не предусмотрен smiley Маразм, в общем smiley
                Ну, это ж вам на руку... Но знайте - Встретиться с этим монстром все равно придётся! smiley
                Я вот сегодня пытался его заставить работать. И так подлез и эдак - упирался скотино. Расстроился, почитал баш, возвращаюсь, а он работает... В итоге оказалось, что от того варианта, что был вначале исправлений собстно было только одно. И то - как написано в манах, опциональное. Мистика. Так что я теперь только за ajaxSearch! laugh
                  • 26698
                  • 148 Posts
                  Самое интересное, у меня была проблема с кодировкой. В смысле — ModX был на UTF-8, но письма из eForm приходили с иерглифами. Сделал у ModX кодировку windows-1251 — письма приходят нормально, иерголифы — в тексте ошибок eForm. Выход нашёлся неожиданно: пришлось текст ошибок, сохранённый для windows-1251 (но на деле в UTF-8), пересохранять в windows-1251. Только тогда всё заработало. Но когда дело дошло до поиска с FlexSearchForm — тут я и сел в лужу. Я хочу сказать, что, к сожалению, много лажи в самой системе и прогах, да и в переводе. Челевеческий фактор. А страдают потом такие простые смертные, как мы с вами. Но, всё же, на сегодняшний день ModX одна из лучших систем с открытым кодом.
                    • 2495
                    • 30 Posts
                    UTF-8 и только UTF-8!
                    Письма и проч всё лечится. Не видел я ещё ни одного почтовика, который не кушает заголовки, где ему говорится о кодировке... В целом, UTF-8 решает все проблемы с поиском и проблемами с русским языком.
                      • 26698
                      • 148 Posts
                      Я предпочитаю 1251 — имею полное право smiley Подстраиваться под нечто другое не хочу. Как правило, у меня всё нормально в 1251 работает, просто для е-форм надо языковой файл пересохранить, а для корректной доставки писем указать кодировку в phpmailer’е.

                      Я говорю, в ModX кодировки — самая большая проблема. Вот в Друпал, к примеру, при установке системы ОДИН раз задаёшь кодировку — и больше к ней не возвращаешься. Здесь — с чем-нибудь, но обязательно возникнет заморочка с кодировкой. При UTF-8 всё круто, но иероглифы в Tiny. Это уже косяк, хотя обычно я Tiny сношу и ставлю FCK. Да и письма приходат с косяками. Морока, в общем.