SimpleSearch - не работает на страницах 3 уровня

При поиске на сайте на страницах ниже второго уровня (например site.ru/catalog/modx) поиск не работает.
На главной и страницах 2 уровня (например site.ru/catalog) поиск прекрасно работает.

Не понимаю почему не работает, подскажите пожалуйста, не нашел ответ нигде.
Сайт показать не могу, в разработке…

Вызываю вот так:
[[!SimpleSearchForm? &landing=`133` &tpl=`search`]]

Шаблон стандартный:

<p class="sisea-results">[[+resultInfo]]</p>
<hr>
<div class="sisea-paging"><span class="sisea-result-pages">[[%sisea.result_pages? &namespace=`sisea` &topic=`default`]]</span>[[+paging]]</div>
<hr>
<div class="sisea-results-list">
    [[+results]]
</div>
<hr>
<div class="sisea-paging"><span class="sisea-result-pages">[[%sisea.result_pages? &namespace=`sisea` &topic=`default`]]</span>[[+paging]]</div>
<hr>

Урлы при поиске:
site.ru/program/search?search=renga&id=133 — не работает
site.ru/search?search=renga&id=133 — работает

Содержимое файла — simplesearch.class.php

<?php
class SimpleSearch {
    /** @var modX $modx */
    public $modx;
    /** @var array $config */
    public $config = array();
    /** @var string $searchString */
    public $searchString = '';
    /** @var array $searchArray */
    public $searchArray = array();
    /** @var int $searchResultsCount */
    public $searchResultsCount = 0;
    /* @var string $ids */
    public $ids = '';
    /** @var array $docs */
    public $docs = array();
    /** @var array $chunks */
    public $chunks = array();
    /** @var SimpleSearchDriver $driver */
    public $driver;
    /** @var siHooks $postHooks */
    public $postHooks;
    /** @var array $response */
    public $response = array();

    function __construct(modX &$modx,array $config = array()) {
    	$this->modx =& $modx;
        $corePath = $this->modx->getOption('sisea.core_path',null,$this->modx->getOption('core_path').'components/simplesearch/');
        $assetsUrl = $this->modx->getOption('sisea.assets_url',null,$this->modx->getOption('assets_url').'components/simplesearch/');

        $this->config = array_merge(array(
            'corePath' => $corePath,
            'chunksPath' => $corePath.'elements/chunks/',
            'snippetsPath' => $corePath.'elements/snippets/',
            'modelPath' => $corePath.'model/',
            'assetsUrl' => $assetsUrl,
        ),$config);
        $this->modx->lexicon->load('sisea:default');
    }

    /**
     * Gets a Chunk and caches it; also falls back to file-based templates
     * for easier debugging.
     *
     * @access public
     * @param string $name The name of the Chunk
     * @param array $properties The properties for the Chunk
     * @return string The processed content of the Chunk
     */
    public function getChunk($name,$properties = array()) {
        $chunk = null;
        if (!isset($this->chunks[$name])) {
            $chunk = $this->_getTplChunk($name);
            if (empty($chunk)) {
                $chunk = $this->modx->getObject('modChunk',array('name' => $name),true);
                if ($chunk == false) return false;
            }
            $this->chunks[$name] = $chunk->getContent();
        } else {
            $o = $this->chunks[$name];
            $chunk = $this->modx->newObject('modChunk');
            $chunk->setContent($o);
        }
        $chunk->setCacheable(false);
        return $chunk->process($properties);
    }

    /**
     * Returns a modChunk object from a template file.
     *
     * @access private
     * @param string $name The name of the Chunk. Will parse to name.chunk.tpl
     * @param string $postFix The postfix to append to the name
     * @return modChunk/boolean Returns the modChunk object if found, otherwise
     * false.
     */
    private function _getTplChunk($name,$postFix = '.chunk.tpl') {
        $chunk = false;
        if (file_exists($name)) {
            $f = $name;
        } else {
            $f = $this->config['chunksPath'].strtolower($name).$postFix;
        }
        if (file_exists($f)) {
            $o = file_get_contents($f);
            /** @var modChunk $chunk */
            $chunk = $this->modx->newObject('modChunk');
            $chunk->set('name',$name);
            $chunk->setContent($o);
        }
        return $chunk;
    }

    /**
     * Load the driver for SimpleSearch
     *
     * @param array $scriptProperties
     * @return SimpleSearchDriver
     */
    public function loadDriver(array $scriptProperties = array()) {
        $driverClass = $this->modx->getOption('sisea.driver_class',$scriptProperties,'SimpleSearchDriverBasic');
        $driverClassPath = $this->modx->getOption('sisea.driver_class_path',$scriptProperties,'');
        if (empty($driverClassPath)) $driverClassPath = $this->config['modelPath'].'simplesearch/driver/';
        $driverDatabaseSpecific = $this->modx->getOption('sisea.driver_db_specific',$scriptProperties,true);
        if ($driverDatabaseSpecific) {
            $dbType = $this->modx->config['dbtype'];
            $driverClassPath = $driverClassPath.$dbType.'/';
            $driverClassName = $driverClass.'_'.$dbType;
        } else {
            $driverClassName = $driverClass;
        }
        $this->modx->loadClass($driverClass,$driverClassPath,true,true);
        $this->driver = new $driverClassName($this,$scriptProperties);
        return $this->driver;
    }

    /**
     * Parses search string and removes any potential security risks in the search string
     *
     * @param string $str The string to parse.
     * @return string The parsed and cleansed string.
     */
    public function parseSearchString($str = '') {
        $minChars = $this->modx->getOption('minChars',$this->config,4);

        $this->searchArray = explode(' ',$str);
        $this->searchArray = $this->modx->sanitize($this->searchArray, $this->modx->sanitizePatterns);
        $reserved = array('AND','OR','IN','NOT');
        foreach ($this->searchArray as $key => $term) {
            $this->searchArray[$key] = strip_tags($term);
            if (strlen($term) < $minChars && !in_array($term,$reserved)) {
                unset($this->searchArray[$key]);
            }
        }
        $this->searchString = implode(' ', $this->searchArray);
        // one last pass to filter for modx tags
        $this->searchString = str_replace(array('[[',']]'),array('[[',']]'),$this->searchString);
        return $this->searchString;
    }

    /**
     * Gets a modResource collection that matches the search terms
     *
     * @param string $str The string to use to search with.
     * @param array $scriptProperties
     * @return array An array of modResource results of the search.
     */
    public function getSearchResults($str = '',array $scriptProperties = array()) {
       /* if (!empty($str)) $this->searchString = strip_tags($this->modx->sanitizeString($str)); */
        $this->loadDriver($scriptProperties);
        $this->response = $this->driver->search($str,$scriptProperties);
        $this->searchResultsCount = $this->response['total'];
        $this->docs = $this->response['results'];
        return $this->response;
    }

    /**
     * Generates the pagination links
     *
     * @param string $searchString The string of the search
     * @param integer $perPage The number of items per page
     * @param string $separator The separator to use between pagination links
     * @param bool|int $total The total of records. Will default to the main count if not passed
     * @return string Pagination links.
     */
    public function getPagination($searchString = '',$perPage = 10,$separator = ' | ',$total = false) {
        if ($total === false) $total = $this->response['total'];
        $pagination = '';

        /* setup default properties */
        $searchIndex = $this->modx->getOption('searchIndex',$this->config,'search');
        $searchOffset = $this->modx->getOption('offsetIndex',$this->config,'sisea_offset');
        $pageTpl = $this->modx->getOption('pageTpl',$this->config,'PageLink');
        $currentPageTpl = $this->modx->getOption('currentPageTpl',$this->config,'CurrentPageLink');
        $urlScheme = $this->modx->getOption('urlScheme',$this->config,-1);

        /* get search string */
        if (empty($searchString)) {
            $searchString = $this->searchString;
        } else {
            $searchString = isset($_REQUEST[$searchIndex]) ? $_REQUEST[$searchIndex] : '';
        }

        $pageLinkCount = ceil($total / $perPage);
        $pageArray = array();
        $id = $this->modx->resource->get('id');
		$pageLimit = $this->modx->getOption('pageLimit',$this->config,0);
		$pageFirstTpl = $this->modx->getOption('pageFirstTpl',$this->config,$pageTpl);
		$pageLastTpl = $this->modx->getOption('pageLastTpl',$this->config,$pageTpl);
		$pagePrevTpl = $this->modx->getOption('pagePrevTpl',$this->config,$pageTpl);
		$pageNextTpl = $this->modx->getOption('pageNextTpl',$this->config,$pageTpl);
        for ($i = 0; $i < $pageLinkCount; ++$i) {
            $pageArray['separator'] = $separator;
            $pageArray['offset'] = $i * $perPage;
            $currentOffset = $this->modx->getOption($searchOffset,$_GET,0);
			if ($pageLimit > 0 && $i+1 == 1 && $pageArray['offset'] != $currentOffset && !empty($pageFirstTpl)) {
				$parameters = $this->modx->request->getParameters();
				$parameters = array_merge($parameters,array(
					$searchOffset => $pageArray['offset'],
					$searchIndex => $searchString,
				));
				$pageArray['text'] = 'First';
				$pageArray['link'] = $this->modx->makeUrl($id, '',$parameters,$urlScheme);
				$pagination .= $this->getChunk($pageFirstTpl,$pageArray);
				if (!empty($pagePrevTpl) && ($currentOffset - $perPage) >= $perPage) {
					$parameters = $this->modx->request->getParameters();
					$parameters = array_merge($parameters,array(
						$searchOffset => $currentOffset - $perPage,
						$searchIndex => $searchString,
					));
					$pageArray['text'] = '<<';
					$pageArray['link'] = $this->modx->makeUrl($id, '',$parameters,$urlScheme);
					$pagination .= $this->getChunk($pagePrevTpl,$pageArray);
				}
			}
			if (empty($pageLimit) || ($pageArray['offset'] >= $currentOffset - ($pageLimit * $perPage) && $pageArray['offset'] <= $currentOffset + ($pageLimit * $perPage))) {
				if ($currentOffset == $pageArray['offset']) {
					$pageArray['text'] = $i+1;
					$pageArray['link'] = $i+1;
					$pagination .= $this->getChunk($currentPageTpl,$pageArray);
				} else {
					$parameters = $this->modx->request->getParameters();
					$parameters = array_merge($parameters,array(
						$searchOffset => $pageArray['offset'],
						$searchIndex => $searchString,
					));
					$pageArray['text'] = $i+1;
					$pageArray['link'] = $this->modx->makeUrl($id, '',$parameters,$urlScheme);
					$pagination .= $this->getChunk($pageTpl,$pageArray);
				}
			}
			if ($pageLimit > 0 && $i+1 == $pageLinkCount && $pageArray['offset'] != $currentOffset && !empty($pageLastTpl)) {
				if (!empty($pageNextTpl) && ($currentOffset + $perPage) <= $total) {
					$parameters = $this->modx->request->getParameters();
					$parameters = array_merge($parameters,array(
						$searchOffset => $currentOffset + $perPage,
						$searchIndex => $searchString,
					));
					$pageArray['text'] = '>>';
					$pageArray['link'] = $this->modx->makeUrl($id, '',$parameters,$urlScheme);
					$pagination .= $this->getChunk($pageNextTpl,$pageArray);
				}
				$parameters = $this->modx->request->getParameters();
				$parameters = array_merge($parameters,array(
					$searchOffset => $pageArray['offset'],
					$searchIndex => $searchString,
				));
				$pageArray['text'] = 'Last';
				$pageArray['link'] = $this->modx->makeUrl($id, '',$parameters,$urlScheme);
				$pagination .= $this->getChunk($pageLastTpl,$pageArray);
			}
            if ($i < $pageLinkCount) {
                $pagination .= $separator;
            }
        }
        return trim($pagination,$separator);
    }

    /**
     * Sanitize a string
     *
     * @param string $text The text to sanitize
     * @return string The sanitized text
     */
    public function sanitize($text) {
        $text = strip_tags($text);
       $text = preg_replace('/(\[\[\+.*?\]\])/iu', '', $text);
        return $this->modx->stripTags($text);
    }

    /**
     * Create an extract from the passed text parameter
     *
     * @param string $text The text that the extract will be created from.
     * @param int $length The length of the extract to be generated.
     * @param string $search The search term to center the extract around.
     * @param string $ellipsis The ellipsis to use to wrap around the extract.
     * @return string The generated extract.
     */
    public function createExtract($text, $length = 200,$search = '',$ellipsis = '...') {
        $text = trim(preg_replace('/\s+/u', ' ', $this->sanitize($text)));
        if (empty($text)) return '';

        $useMb = $this->modx->getOption('use_multibyte',null,false) && function_exists('mb_strlen');
        $encoding = $this->modx->getOption('modx_charset',null,'UTF-8');

        $trimChars = "\t\r\n -_()!~?=+/*\\,.:;\"'[]{}`&";
        if (empty($search)) {
            $stringLength = $useMb ? mb_strlen($text,$encoding) : strlen($text);
            $end = ($length - 1) > $stringLength ? $stringLength : ($length - 1);
            if ($useMb) {
                $pos = min(mb_strpos($text, ' ', $end, $encoding), mb_strpos($text, '.', $end, $encoding));
            } else {
                $pos = min(strpos($text, ' ', $end), strpos($text, '.', $end));
            }
            if ($pos) {
                return rtrim($useMb ? mb_substr($text,0,$pos,$encoding) : substr($text,0,$pos), $trimChars) . $ellipsis;
            } else {
                return $text;
            }
        }

        if ($useMb) {
            $wordPos = mb_strpos(mb_strtolower($text,$encoding), mb_strtolower($search,$encoding),null,$encoding);
            $halfSide = intval($wordPos - $length / 2 + mb_strlen($search, $encoding) / 2);
            if ($halfSide > 0) {
                $halfText = mb_substr($text, 0, $halfSide, $encoding);
                $pos_start = max(mb_strrpos($halfText, ' ', 0, $encoding), mb_strrpos($halfText, '.', 0, $encoding));
                if (!$pos_start) {
                  $pos_start = 0;
                }
            } else {
                $pos_start = 0;
            }
            if ($wordPos && $halfSide > 0) {
                $l = $pos_start + $length - 1;
                $realLength = mb_strlen($text,$encoding);
                if ($l > $realLength) { $l = $realLength; }
                $pos_end = min(mb_strpos($text, ' ',$l, $encoding), mb_strpos($text, '.', $l, $encoding)) - $pos_start;
                if (!$pos_end || $pos_end <= 0) {
                  $extract = $ellipsis . ltrim(mb_substr($text, $pos_start, mb_strlen($text, $encoding), $encoding), $trimChars);
                } else {
                  $extract = $ellipsis . trim(mb_substr($text, $pos_start, $pos_end, $encoding), $trimChars) . $ellipsis;
                }
            } else {
                $l = $length - 1;
                $trueLength = mb_strlen($text,$encoding);
                if ($l > $trueLength) $l = $trueLength;
                $pos_end = min(mb_strpos($text, ' ',$l, $encoding), mb_strpos($text, '.', $l, $encoding));
                if ($pos_end) {
                  $extract = rtrim(mb_substr($text, 0, $pos_end, $encoding), $trimChars) . $ellipsis;
                } else {
                  $extract = $text;
                }
            }
        } else {
            $wordPos = strpos(strtolower($text), strtolower($search));
            $halfSide = intval($wordPos - $length / 2 + strlen($search) / 2);
            if ($halfSide > 0) {
                $halfText = substr($text, 0, $halfSide);
                $pos_start = max(strrpos($halfText, ' '), strrpos($halfText, '.'));
                if (!$pos_start) {
                  $pos_start = 0;
                }
            } else {
                $pos_start = 0;
            }
            if ($wordPos && $halfSide > 0) {
                $l = $pos_start + $length - 1;
                $realLength = strlen($text);
                if ($l > $realLength) { $l = $realLength; }
                $pos_end = min(strpos($text, ' ', $l), strpos($text, '.', $l)) - $pos_start;
                if (!$pos_end || $pos_end <= 0) {
                  $extract = $ellipsis . ltrim(substr($text, $pos_start), $trimChars);
                } else {
                  $extract = $ellipsis . trim(substr($text, $pos_start, $pos_end), $trimChars) . $ellipsis;
                }
            } else {
                $pos_end = min(strpos($text, ' ', $length - 1), strpos($text, '.', $length - 1));
                if ($pos_end) {
                  $extract = rtrim(substr($text, 0, $pos_end), $trimChars) . $ellipsis;
                } else {
                  $extract = $text;
                }
            }
        }
        return $extract;
    }


    /**
     * Adds highlighting to the passed string
     *
     * @param string $string The string to be highlighted.
     * @param string $cls The CSS class to add to the tag wrapper
     * @param string $tag The type of HTML tag to wrap with
     * @return string The highlighted string
     */
    public function addHighlighting($string, $cls = 'sisea-highlight',$tag = 'span') {
        $searchStrings = explode(' ', $this->searchString);
        foreach ($searchStrings as $searchString) {
            $quoteValue = preg_quote($searchString, '/');
            $string = preg_replace('/' . $quoteValue . '/iu', '<'.$tag.' class="'.$cls.'">$0</'.$tag.'>', $string);
        }
        return $string;
    }

    /**
     * Either return a value or set to placeholder, depending on setting
     *
     * @param string $output
     * @param boolean $toPlaceholder
     * @return string
     */
    public function output($output = '',$toPlaceholder = false) {
        if (!empty($toPlaceholder)) {
            $this->modx->setPlaceholder($toPlaceholder,$output);
            return '';
        } else { return $output; }
    }


    /**
     * Loads the Hooks class.
     *
     * @access public
     * @param string $type The type of hook to load.
     * @param array $config An array of configuration parameters for the
     * hooks class
     * @return siHooks An instance of the fiHooks class.
     */
    public function loadHooks($type = 'post',$config = array()) {
        if (!$this->modx->loadClass('simplesearch.siHooks',$this->config['modelPath'],true,true)) {
            $this->modx->log(modX::LOG_LEVEL_ERROR,'[SimpleSearch] Could not load Hooks class.');
            return false;
        }
        $type = $type.'Hooks';
        $this->$type = new siHooks($this,$config);
        return $this->$type;
    }
}
Maxim
02 августа 2018, 11:21
modx.pro
2 109
-3

Комментарии: 12

Баха Волков
02 августа 2018, 14:17
0
Вы про cut не забывайте
    Баха Волков
    02 августа 2018, 21:40
    0
    Вызываю вот так:
    [[!SimpleSearchForm? &landing=`133` &tpl=`search`]]
    Шаблон стандартный:
    Урлы при поиске:
    site.ru/program/search?search=renga&id=133 — не работает
    site.ru/search?search=renga&id=133 — работает
    Содержимое файла — simplesearch.class.php
    Показали всё, что не относится к вашему вопросу, и то что нужно показать как раз не показали.
      Maxim
      03 августа 2018, 15:13
      0
      Спасибо за ответ
      Не могу все-равно разобраться, cut — имеется ввиду &cut=`. (вырезать символы? или что-то другое?)
      Если да то что вырезать нужно?
      Что показать еще для полной картины?
        Баха Волков
        03 августа 2018, 18:39
        0
          Maxim
          06 августа 2018, 12:34
          0
          Добавил cut
          А по вопросу, что нужно показать для решения проблемы?
      Баха Волков
      06 августа 2018, 15:40
      0
      1. Стоят ли галочки «Доступен для поиска» у данных ресурсов
      2. Покажите вызов SimpleSearch
      3. ...
        Maxim
        07 августа 2018, 14:28
        0
        [[!SimpleSearch? &containerTpl=`SimpleSearchOuter`]]
        — вот так вызываю на странице — результаты поиска

        Стоят ли галочки «Доступен для поиска» у данных ресурсов — у всех которых нужно ресурсов стоят

        Чанк — SimpleSearchOuter
        <p class="sisea-results">[[+resultInfo]]</p>
        <hr>
        <div class="sisea-paging"><span class="sisea-result-pages">[[%sisea.result_pages? &namespace=`sisea` &topic=`default`]]</span>[[+paging]]</div>
        <hr>
        <div class="sisea-results-list">
            [[+results]]
        </div>
        <hr>
        <div class="sisea-paging"><span class="sisea-result-pages">[[%sisea.result_pages? &namespace=`sisea` &topic=`default`]]</span>[[+paging]]</div>
        <hr>
          Maxim
          07 августа 2018, 14:30
          0
          Странно именно то что он работает, но если искать на ресурсах глубже 2 уровня, то выдает 404 ошибку
            Алексей Ерохин
            07 августа 2018, 14:34
            +1
            site.ru/program/search?search=renga&id=133 — не работает
            site.ru/search?search=renga&id=133 — работает

            Вы до сих пор не видите разницы?

            У вас неправильная ссылка для поиска. На вложенных страницах он ищет страницу не от корня, а от текущего контейнера. Пропишите правильный action для формы поиска. Или настройте свой сайт (схемы url, base href)
              Maxim
              07 августа 2018, 15:38
              0
              Алексей, спасибо!
              Добавил
              <base href="https://site.ru" />
              в head — и все заработало!
                Maxim
                07 августа 2018, 15:58
                0
                vyachet.ru/base-n-jquery-tabs/
                Вот что у меня произошло, теперь jquery табы подгружают главную из-за этого тэга

                Пропишите правильный action для формы поиска — можете немного подробнее тут пояснить?
                  Баха Волков
                  07 августа 2018, 21:44
                  0
                  Если предоставите доступ, могу глянуть, а то так сложно что-то подсказать
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          12