ACC SHELL

Path : /srv/www/vhosts/tsisystem/app/controllers/components/
File Upload :
Current File : //srv/www/vhosts/tsisystem/app/controllers/components/search.php

<?php

class SearchComponent extends Object {
    var $ft_min = 4;
    var $ft_max = 20;

    var $controller = true; // To give access to the controller
    var $dbConn;
    var $types = array(
        'article', 'product', 'static'
    );

    var $term, $term_db, $term_no;

    /**
     *
     */
    function init()
    {
        $this->dbConn =& ConnectionManager::getDataSource('default');
    }

    /**
     *
     */
    function search($term)
    {
        $this->words = $tmp = array();

        foreach (preg_split('/\s+/', $term) as $word) {
            $this->words[strtolower(__latin2ascii($word))] = 1;
            if (strlen($word) < $this->ft_min || strlen($word) > $this->ft_max) {
                continue;
            }
            $tmp[] = $word;
        }

        if (! $tmp) {
            return array();
        }

        $this->term = join(' ', $tmp);
        $this->term_db = $this->dbConn->value(__latin2ascii($this->term));
        $this->term_no = count($tmp);

        $found = array();

        foreach ($this->dbConn->query(sprintf('
            SELECT id, type, url, content, title FROM search
            WHERE MATCH(content_ascii) AGAINST (%s) >= %d
            ORDER BY MATCH(content_ascii) AGAINST (%s) DESC
            LIMIT 35
        ', $this->term_db, $this->term_no, $this->term_db)) as $row) {
            $found[] = $this->getContext($row);
        }

        return $found;
    }

    /**
     *
     */
    function getContext($row)
    {
        $content = $row['search']['content'];
        $content_a = preg_split('/\s+/', $row['search']['content']);
        $positions = array();
        $i = 0;
        foreach (preg_split('/\s+/', strtolower(__latin2ascii($content))) as $word) {
            if (isset($this->words[$word])) {
                $positions[$i] = 1;
            }
            $i++;
        }

        $context = array();
        $clen = 8;

        foreach (array_keys($positions) as $p) {
            if ($p < $clen) {
                $n = $clen + $p;
                $p = 0;
            }
            else {
                $n = 2 * $clen;
                $p -= $clen;
            }
            $context = array_merge($context, array_keys(array_fill($p, $n, 1)));
        }

        sort($context);
        $context = array_unique($context);

        $context_txt = array();
        $last = NULL;

        foreach ($context as $pos) {
            if (isset($positions[$pos])) {
                $text = '<span class="hilite">' . $content_a[$pos] . '</span>';
            }
            else if (isset($content_a[$pos])) {
                $text = $content_a[$pos];
            }
            else {
                $text = NULL;
            }

            if ($last === NULL && $pos) {
                $text = '...' . $text;
            }
            else if ($last && $last != ($pos - 1)) {
                $text .= '...';
            }
            $last = $pos;
            if ($text !== NULL) {
                $context_txt[] = $text;
            }
        }

        if ($context_txt && $pos != (count($content_a) - 1)) {
            $context_txt[count($context_txt) - 1] .= '...';
        }

        if (! $context_txt) {
            $context_txt = array_slice($content_a, 0, 2 * $clen);
            $context_txt[count($context_txt) - 1] .= '...';
        }

        $row['search']['url'] = $this->_lookupURL($row['search']['id'],
            $row['search']['type'], $row['search']['url']);

        return array(
            'title' => $row['search']['title'],
            'type' => $row['search']['type'],
            'id' => $row['search']['id'],
            'url' => $row['search']['url'],
            'context' => join(' ', $context_txt),
        );
    }

    /**
     *
     */
    function reindex()
    {
        $this->dbConn->query('TRUNCATE search');

        foreach ($this->dbConn->query('
            SELECT id, title, perex, content FROM articles WHERE published = 1
            AND (publish_from <= NOW() OR publish_from IS NULL)
            AND (publish_to >= NOW() OR publish_to IS NULL)
        ') as $row) {
            $text = join(' ', array(
                $row['articles']['title'],
                $row['articles']['title'],
                $row['articles']['perex'],
                $row['articles']['content']
            ));

            $this->_addText($row['articles']['id'], 0, $row['articles']['title'], $text);
        }

        foreach ($this->dbConn->query('
            SELECT products.id, products.name, products.descr,
                GROUP_CONCAT(prod_parameters.par_text) as params FROM products
            LEFT JOIN prod_parameters ON (products.id = prod_parameters.product)
            GROUP BY products.id, products.name, products.descr
        ') as $row) {
            $text = join(' ', array(
                $row['products']['name'],
                $row['products']['name'],
                $row['products']['descr'],
                $row[0]['params']
            ));

            $this->_addText($row['products']['id'], 1, $row['products']['name'], $text);
        }

        $i = 1;
        foreach (array(
                'calibration.thtml' => '/kalibrace',
                'repairs.thtml' => '/opravy',
                'measuration.thtml' => '/mereni-a-zkouseni',
            ) as $page => $url) {

            $text = file_get_contents(ROOT . '/' . APP_DIR . '/views/pages/' . $page);

            preg_match(',<h1>(.*?)</h1>,', $text, $m);
            $this->_addText($i++, 2, strip_tags($m[1]), $text, $url);
        }
    }

    /**
     *
     */
    function _lookupURL($id, $type, $url)
    {
        if ($url) {
            return $url;
        }

        /*
         * article_type: 2 - publikace-inzerce 1 vystavy-konference-seminare 0 /novinky
         */

        if (! $type) {
            $row = $this->dbConn->query('SELECT article_type, title_idx FROM articles WHERE id = ' . (int) $id);
            if ($row[0]['articles']['article_type'] == 1) {
                $url = '/vystavy-konference-seminare/';
            }
            else if ($row[0]['articles']['article_type'] == 2) {
                $url = '/publikace-inzerce/';
            }
            else {
                $url = '/novinky/';
            }

            $url .= substr($row[0]['articles']['title_idx'], 0, 6);
            $url .= '/' . substr($row[0]['articles']['title_idx'], 7);

            return $url;
        }

        $row = $this->dbConn->query('SELECT name_idx FROM products WHERE id = ' . (int) $id);
        $url = '/produkty/' . $row[0]['products']['name_idx'];

        return $url;
    }

    /**
     *
     */
    function _addText($id, $type, $title, $text, $url = '')
    {
        $this->_cleanUp($text);
        $ascii = __latin2ascii($text);

        $this->dbConn->query(sprintf(
            'insert into search (id, type, content, content_ascii, title, url)
                values (%d, %d, %s, %s, %s, %s)',
            $id, $type, $this->dbConn->value(trim(str_replace($title, '', $text))),
            $this->dbConn->value(trim($ascii)),
            $this->dbConn->value(trim($title)),
            $this->dbConn->value(trim($url))
        ));
    }


    /**
     *
     */
    function _cleanUp(&$text)
    {
        static $lat1ent = 'áéíóúýÁÉÍÓÚÝ';
        static $trtbl;

        if (! $trtbl) {
            $tmp = __latin2ascii($lat1ent);
            for ($i = 0; $i < strlen($tmp); $i++) {
                $trtbl['&' . $tmp[$i] . 'acute;'] = $lat1ent[$i];
            }
            $trtbl['&scaron;'] = '¹';
            $trtbl['&Scaron;'] = '©';
            $trtbl['&nbsp;'] = ' ';
            $trtbl["\xa0"] = ' ';
        }

        $text = str_replace(array_keys($trtbl), $trtbl, $text);
        $text = preg_replace('/&(#\d+|[a-z]+);/i', ' ', $text);
        $text = str_replace('<', ' <', $text);
        $text = str_replace('>', '> ', $text);
        $text = strip_tags($text);
        $text = preg_replace('/[\\t\\r\\n ]+/', ' ', $text);
    }

}


?>

ACC SHELL 2018