global $REX; if(!empty($REX[\'ADDON\'][\'rexsearch_plugins\'][\'' . $mypage . '\'])) { foreach($REX[\'ADDON\'][\'rexsearch_plugins\'][\'' . $mypage . '\'] as $plugin => $pluginsettings) if(!empty($pluginsettings[\'subpages\'])) $REX[\'ADDON\'][\'' . $mypage . '\'][\'SUBPAGES\'] = array_merge($REX[\'ADDON\'][\'' . $mypage . '\'][\'SUBPAGES\'], $pluginsettings[\'subpages\']); } ')); } require $REX['ADDON']['dir'][$mypage] . '/classes/class.rexsearch.inc.php'; require $REX['ADDON']['dir'][$mypage] . '/functions/functions.inc.php'; require $REX['ADDON']['dir'][$mypage] . '/functions/functions.mb.inc.php'; if (!file_exists($settingFile = dirname(__FILE__) . '/settings.conf')) { a587_saveSettings(array('logicalmode' => 'and', 'textmode' => 'plain', 'searchmode' => 'like', 'similarwordsmode' => 7, 'indexmode' => 1, 'automaticindex' => 1, 'surroundtags' => array('<strong>', '</strong>'), 'limit' => array(0, 20), 'maxteaserchars' => '200', 'maxhighlightchars' => '50', 'highlight' => 'surroundtextsingle', 'fileextensions' => array('pdf'), 'indexmediapool' => '1', 'dirdepth' => 3)); } $REX['ADDON']['settings'][$mypage] = a587_config_unserialize(rex_get_file_contents($settingFile)); // automatic indexing if ($REX['REDAXO'] and $REX['ADDON']['settings'][$mypage]['automaticindex'] == '1') { $extensionPoints = array('ART_DELETED', 'ART_META_UPDATED', 'ART_STATUS', 'ART_ADDED', 'ART_UPDATED', 'CAT_DELETED', 'CAT_STATUS', 'CAT_ADDED', 'CAT_UPDATED', 'MEDIA_ADDED', 'MEDIA_UPDATED', 'MEDIA_DELETED', 'SLICE_UPDATED'); a587_register_extensionpoints($extensionPoints); } // Including CSS-File for Backend if ($REX['REDAXO'] and rex_request('page', 'string') == $mypage) { function a587_add_css($params) { $mypage = 'rexsearch'; if (function_exists('str_ireplace')) { return str_ireplace('</head>', "\t" . '<link rel="stylesheet" type="text/css" href="../files/addons/' . $mypage . '/' . $mypage . '.css" />' . "\n" . '</head>', $params['subject']); } return str_replace('</head>', "\t" . '<link rel="stylesheet" type="text/css" href="../files/addons/' . $mypage . '/' . $mypage . '.css" />' . "\n" . '</head>', $params['subject']); }
/** * Executes the search. * * @param string $_search * * @return array */ function search($_search) { $startTime = microtime(true); $this->searchString = trim(stripslashes($_search)); $keywordCount = $this->parseSearchString($this->searchString); if (empty($this->searchString) or empty($this->searchArray)) { return array('count' => 0, 'hits' => array(), 'keywords' => array(), 'keywords' => '', 'sql' => 'No search performed.', 'blacklisted' => false, 'hash' => '', 'simwordsnewsearch' => '', 'simwords' => array(), 'time' => 0); } // ask cache if ($this->cache and $this->isCached($this->searchString)) { $this->cachedArray['time'] = microtime(true) - $startTime; if ($this->similarwords and $this->cachedArray['count'] > 0) { $this->storeKeywords($this->searchArray); } // EP registrieren rex_register_extension_point('A587_SEARCH_EXECUTED', $this->cachedArray); //var_dump($this->cachedArray['sql']); return $this->cachedArray; } $return = array(); $return['simwordsnewsearch'] = ''; $return['simwords'] = array(); if ($this->similarwords) { $simwords = array(); foreach ($this->searchArray as $keyword) { $sounds = array(); if ($this->similarwordsMode & A587_SIMILARWORDS_SOUNDEX) { $sounds[] = "soundex = '" . soundex($keyword['search']) . "'"; } if ($this->similarwordsMode & A587_SIMILARWORDS_METAPHONE) { $sounds[] = "metaphone = '" . metaphone($keyword['search']) . "'"; } if ($this->similarwordsMode & A587_SIMILARWORDS_COLOGNEPHONE) { $sounds[] = "colognephone = '" . $this->cologne_phone($keyword['search']) . "'"; } $simwords[] = sprintf("\n SELECT\n GROUP_CONCAT(DISTINCT keyword SEPARATOR ' ') as keyword,\n '%s' AS typedin,\n SUM(count) as count\n FROM `%s`\n WHERE 1\n %s\n AND (%s)", $keyword['search'], $this->tablePrefix . '587_keywords', $this->clang !== false ? 'AND (clang = ' . intval($this->clang) . ' OR clang IS NULL)' : '', implode(' OR ', $sounds)); } // simwords $simWordsSQL = new rex_sql(); foreach ($simWordsSQL->getArray(sprintf("\n %s\n GROUP BY %s\n ORDER BY SUM(count)", implode(' UNION ', $simwords), $this->similarwordsPermanent ? "''" : 'keyword, typedin')) as $simword) { $return['simwords'][$simword['typedin']] = array('keyword' => $simword['keyword'], 'typedin' => $simword['typedin'], 'count' => $simword['count']); } $newsearch = array(); foreach ($this->searchArray as $keyword) { if (preg_match($this->encodeRegex('~\\s~is'), $keyword['search'])) { $quotes = '"'; } else { $quotes = ''; } if (array_key_exists($keyword['search'], $return['simwords'])) { $newsearch[] = $quotes . $return['simwords'][$keyword['search']]['keyword'] . $quotes; } else { $newsearch[] = $quotes . $keyword['search'] . $quotes; } } $return['simwordsnewsearch'] = implode(' ', $newsearch); } if ($this->similarwordsPermanent) { $keywordCount = $this->parseSearchString($this->searchString . ' ' . $return['simwordsnewsearch']); } $searchColumns = array(); switch ($this->textMode) { case 'unmodified': $searchColumns[] = 'unchangedtext'; break; case 'both': $searchColumns[] = 'plaintext'; $searchColumns[] = 'unchangedtext'; break; default: $searchColumns[] = 'plaintext'; } $sql = new rex_sql(); $Awhere = array(); $Amatch = array(); foreach ($this->searchArray as $keyword) { // build MATCH-Array $match = sprintf("(( MATCH (`%s`) AGAINST ('%s')) * %d)", implode('`,`', $searchColumns), $sql->escape($keyword['search']), $keyword['weight']); if ($this->searchEntities) { $match .= ' + ' . sprintf("(( MATCH (`%s`) AGAINST ('%s')) * %d)", implode('`,`', $searchColumns), $sql->escape(htmlentities($keyword['search'], ENT_COMPAT, 'UTF-8')), $keyword['weight']); } $Amatch[] = $match; // build WHERE-Array if ($this->searchMode == 'match') { $AWhere[] = $match; } else { $tmpWhere = array(); foreach ($searchColumns as $searchColumn) { $tmpWhere[] = sprintf("(`%s` LIKE '%%%s%%')", $searchColumn, str_replace(array('%', '_'), array('\\%', '\\_'), $sql->escape($keyword['search']))); if ($this->searchEntities) { $tmpWhere[] = sprintf("(`%s` LIKE '%%%s%%')", $searchColumn, str_replace(array('%', '_'), array('\\%', '\\_'), $sql->escape(htmlentities($keyword['search'], ENT_COMPAT, 'UTF-8')))); } } $AWhere[] = '(' . implode(' OR ', $tmpWhere) . ')'; } /*if($this->logicalMode == ' AND ') $Awhere[] = '+*'.$keyword['search'].'*'; else $AWhere[] = '*'.$keyword['search'].'*';*/ } // build MATCH-String $match = '(' . implode(' + ', $Amatch) . ' + 1)'; // build WHERE-String $where = '(' . implode($this->logicalMode, $AWhere) . ')'; #$where = sprintf("( MATCH (%s) AGAINST ('%s' IN BOOLEAN MODE)) > 0",implode(',',$searchColumns),implode(' ',$Awhere)); // language if ($this->clang !== false) { $where .= ' AND (clang = ' . intval($this->clang) . ' OR clang IS NULL)'; } $AwhereToSearch = array(); if (array_key_exists('articles', $this->searchInIDs) and count($this->searchInIDs['articles'])) { $AwhereToSearch[] = "texttype = 'article'"; $AwhereToSearch[] = "(fid IN (" . implode(',', $this->searchInIDs['articles']) . "))"; } if (array_key_exists('categories', $this->searchInIDs) and count($this->searchInIDs['categories'])) { $AwhereToSearch[] = "(catid IN (" . implode(',', $this->searchInIDs['categories']) . ") AND ftable = '" . $sql->escape($this->tablePrefix) . "article')"; } if (array_key_exists('filecategories', $this->searchInIDs) and count($this->searchInIDs['filecategories'])) { $AwhereToSearch[] = "(catid IN (" . implode(',', $this->searchInIDs['filecategories']) . ") AND ftable = '" . $sql->escape($this->tablePrefix) . "file')"; } if (array_key_exists('db_columns', $this->searchInIDs) and count($this->searchInIDs['db_columns'])) { $AwhereToSearch[] = "texttype = 'db_column'"; $Acolumns = array(); foreach ($this->searchInIDs['db_columns'] as $table => $colArray) { foreach ($colArray as $column) { //$Acolumns[] = sprintf("(ftable = '%s' AND fcolumn = '%s' %s)", $table, $column, $strSearchArticles); $Acolumns[] = sprintf("(ftable = '%s' AND fcolumn = '%s')", $table, $column); } } $AwhereToSearch[] = '(' . implode(' OR ', $Acolumns) . ')'; } if (count($AwhereToSearch)) { if ($this->searchArticles) { $where .= " AND ((texttype = 'article') OR (" . implode(' AND ', $AwhereToSearch) . '))'; } else { $where .= ' AND (' . implode(' AND ', $AwhereToSearch) . ')'; } } if (!empty($this->where)) { $where .= ' AND (' . $this->where . ')'; } // build ORDER-BY-String $Aorder = array(); foreach ($this->order as $col => $dir) { $Aorder[] = $col . ' ' . $dir; } $selectFields = array(); if ($this->groupBy) { $selectFields[] = sprintf('(SELECT SUM%s FROM `%s` summe WHERE summe.fid = r1.fid AND summe.ftable = r1.ftable) AS RELEVANCE587', $match, $this->tablePrefix . '587_searchindex'); $selectFields[] = sprintf('(SELECT COUNT(*) FROM `%s` summe WHERE summe.fid = r1.fid AND (summe.ftable IS NULL OR summe.ftable = r1.ftable) AND (summe.fcolumn IS NULL OR summe.fcolumn = r1.fcolumn) AND summe.texttype = r1.texttype) AS COUNT587', $this->tablePrefix . '587_searchindex'); } else { $selectFields[] = $match . ' AS RELEVANCE587'; } $selectFields[] = '`id`'; $selectFields[] = '`fid`'; $selectFields[] = '`catid`'; $selectFields[] = '`ftable`'; $selectFields[] = '`fcolumn`'; $selectFields[] = '`texttype`'; $selectFields[] = '`clang`'; $selectFields[] = '`unchangedtext`'; $selectFields[] = '`plaintext`'; $selectFields[] = '`teaser`'; $selectFields[] = '`values`'; $selectFields[] = '`filename`'; $selectFields[] = '`fileext`'; if ($this->groupBy) { $query = sprintf(' SELECT SQL_CALC_FOUND_ROWS %s FROM `%s` r1 WHERE (%s) AND ( ( %s = (SELECT MAX%s FROM `%s` r2 WHERE r1.ftable = r2.ftable AND r1.fid = r2.fid %s) AND fid IS NOT NULL ) OR ftable IS NULL ) GROUP BY ftable,fid,clang ORDER BY %s LIMIT %d,%d', implode(",\n", $selectFields), $this->tablePrefix . '587_searchindex', $where, $match, $match, $this->tablePrefix . '587_searchindex', $this->clang !== false ? 'AND (clang = ' . intval($this->clang) . ' OR clang IS NULL)' : '', implode(",\n", $Aorder), $this->limit[0], $this->limit[1]); } else { $query = sprintf(' SELECT SQL_CALC_FOUND_ROWS %s FROM `%s` WHERE %s ORDER BY %s LIMIT %d,%d', implode(",\n", $selectFields), $this->tablePrefix . '587_searchindex', $where, implode(",\n", $Aorder), $this->limit[0], $this->limit[1]); } #echo '<pre>'.$query.'</pre>'; $sqlResult = $sql->getArray($query); $indexIds = array(); $count = 0; $sqlResultCount = $sql->getArray('SELECT FOUND_ROWS() as count'); $return['count'] = intval($sqlResultCount[0]['count']); // hits $return['hits'] = array(); $i = 0; foreach ($sqlResult as $hit) { $indexIds[] = $hit['id']; $return['hits'][$i] = array(); $return['hits'][$i]['id'] = $hit['id']; $return['hits'][$i]['fid'] = $hit['fid']; if (!is_numeric($hit['fid']) and !is_null($json_decode_fid = json_decode($hit['fid'], true))) { $return['hits'][$i]['fid'] = $json_decode_fid; } $return['hits'][$i]['table'] = $hit['ftable']; $return['hits'][$i]['column'] = $hit['fcolumn']; $return['hits'][$i]['type'] = $hit['texttype']; $return['hits'][$i]['clang'] = $hit['clang']; $return['hits'][$i]['unchangedtext'] = $hit['unchangedtext']; $return['hits'][$i]['plaintext'] = $hit['plaintext']; $return['hits'][$i]['teaser'] = $this->getTeaserText($hit['plaintext']); $return['hits'][$i]['highlightedtext'] = $this->getHighlightedText($hit['plaintext']); $return['hits'][$i]['article_teaser'] = $hit['teaser']; $return['hits'][$i]['values'] = a587_config_unserialize($hit['values']); $return['hits'][$i]['filename'] = $hit['filename']; $return['hits'][$i]['fileext'] = $hit['fileext']; $i++; if ($this->groupBy) { $count += $hit['COUNT587']; } } if ($this->groupBy) { $indexIds = array(); foreach ($sql->getArray(sprintf(' SELECT id FROM `%s` WHERE %s LIMIT %d,%d', $this->tablePrefix . '587_searchindex', $where, $this->limit[0], $count)) as $hit) { $indexIds[] = $hit['id']; } } // keywords, which were searched for $return['keywords'] = $this->searchArray; $return['searchterm'] = $this->searchString; // sql $return['sql'] = $query; // was any blacklisted word searched for? $return['blacklisted'] = false; if (count($this->blacklisted) > 0) { $return['blacklisted'] = $this->blacklisted; } $return['hash'] = $this->cacheHash($this->searchString); if ($this->similarwords and $i) { $this->storeKeywords($this->searchArray); } if ($this->cache) { $this->cacheSearch(serialize($return), $indexIds); } // EP registrieren rex_register_extension_point('A587_SEARCH_EXECUTED', $return); $return['time'] = microtime(true) - $startTime; return $return; }
$mypage = 'plaintext'; $dir = dirname(__FILE__); $REX['ADDON']['version'][$mypage] = '0.2'; $REX['ADDON']['author'][$mypage] = 'Robert Rupf'; $REX['ADDON']['supportpage'][$mypage] = 'forum.redaxo.de'; $REX['EXTRAPERM'][] = $parent . '[' . $mypage . ']'; require_once $dir . '/functions/functions.inc.php'; if (is_object($REX['USER']) and ($REX['USER']->hasPerm($parent . '[' . $mypage . ']') or $REX['USER']->isAdmin())) { if ($REX['REDAXO']) { $I18N->appendFile(dirname(__FILE__) . '/lang/'); $REX['ADDON']['rexsearch_plugins'][$parent][$mypage]['subpages'][] = array('plaintext', $I18N->Msg('a587_plaintext_title')); } rex_register_extension('A587_PLAINTEXT', 'a587_doPlaintext'); if (!file_exists($settingFile = dirname(__FILE__) . '/settings.conf')) { a587_plaintext_saveSettings(array('order' => 'selectors,regex,textile,striptags', 'selectors' => "head,\nscript", 'regex' => '', 'textile' => true, 'striptags' => true, 'processparent' => false)); } $REX['ADDON']['rexsearch_plugins'][$parent][$mypage]['settings'] = a587_config_unserialize(rex_get_file_contents($settingFile)); } // Including CSS-File for Backend if ($REX['REDAXO'] and rex_request('page', 'string') == $parent and rex_request('subpage', 'string') == $mypage) { function a587_plaintext_add_css($params) { $parent = 'rexsearch'; $mypage = 'plaintext'; if (function_exists('str_ireplace')) { return str_ireplace('</head>', "\t" . '<script type="text/javascript" src="../files/addons/' . $parent . '/plugins/' . $mypage . '/jquery.ui.custom.js"></script>' . "\n" . '</head>', $params['subject']); } return str_replace('</head>', "\t" . '<script type="text/javascript" src="../files/addons/' . $parent . '/plugins/' . $mypage . '/jquery.ui.custom.js"></script>' . "\n" . '</head>', $params['subject']); } rex_register_extension('OUTPUT_FILTER', 'a587_plaintext_add_css'); }