PageRenderTime 60ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/include/plugins_base/ocms_search/class.ocms_search.php

http://opixido-ocms.googlecode.com/
PHP | 682 lines | 370 code | 143 blank | 169 comment | 75 complexity | d6a07c1747bcf0c0c670c8cb0208c400 MD5 | raw file
Possible License(s): GPL-3.0, Apache-2.0, BSD-3-Clause, LGPL-2.1, GPL-2.0
  1. <?php
  2. /*
  3. @include('../ccsearch/getresults.php');
  4. @include('ccsearch/getresults.php');
  5. */
  6. global $_Gconfig;
  7. $commonWords = array('les', 'des', 'dans', 'mais', 'car', 'elle', 'elles', 'aussi', 'leurs', 'leur', 'nous', 'entre', 'non', 'par', 'ils', 'ainsi', 'ces', 'ses', 'une', 'que', 'aux', 'par', 'est', 'qui', 'sur', 'pour', 'sont', 'plus', 'avec', 'cette', 'pas', 'comme', 'ont', 'peut', 'dont');
  8. $delims = array('�', '&amp;#8217;', '&#8217;', '?', '.', ',', ';', ':', '/', '!', ']', '}', '\'', '{', '[', '(', ')', '-', '>', '<', '|', '#', '?', "\n", "\r", "\t", '?', '"', '?', "?", '?', '?', '*', '?', '�');
  9. //$vipWords = array('pi', 'p�', 'no','or','nu','vu','os','fr','cm','km','ph','ko','g8','ip','3d');
  10. class indexSearch {
  11. var $vipWords = array('pi', 'pô', 'no', 'or', 'nu', 'vu', 'os', 'fr', 'cm', 'km', 'ph', 'ko', 'g8', 'ip', '3d', 'if');
  12. var $minlength = 2;
  13. var $related = array();
  14. var $cachestem;
  15. var $obj;
  16. public $cacheWord = array();
  17. public $useWildCards = false;
  18. function __construct($obj='') {
  19. global $_Gconfig, $relations, $relinv;
  20. /**
  21. * Lemmatisation pas complete mais presque ... voir les problemes qui peuvent se poser
  22. */
  23. $this->stemRemove = array('if', 'ifs', 'ive', 'ives', 'er', 'ant', 'é', 'ée', 'e', 'es', 'és', 'ons', 'ez', 'ent', 'ais', 'ait', 'ions', 'iez', 'aient', 'ai', 'as', 'a', 'âmes', 'âtes', 'èrent', 'erai', 'eras', 'era', 'erons', 'erez', 'eront', 'erais', 'erait', 'erions', 'eriez', 'eraient', 'asse', 'ât', 'assions', 'assiez', 'assent', 's');
  24. /**
  25. * Lemmatisation simple -> Pluriel/singulier Feminin/Masculin
  26. */
  27. $this->stemRemove = array('s', 'e', 'al', 'aux');
  28. /**
  29. * Lemmatisation basée sur http://www.unine.ch/info/clef/frenchStemmerPlus.txt
  30. * http://www.unine.ch/info/clef/
  31. *
  32. * Plus quelques rajouts perso
  33. */
  34. $this->stemReplace = array();
  35. # Rajouts CELIO
  36. $this->stemReplace = array('eaux' => 'eau', 'eux' => 'eu', 'aux' => 'al', 'x' => '', 's' => '', 'atique' => '');
  37. # ORIGINAL
  38. $this->stemReplace = array_merge($this->stemReplace, array('issement' => 'ir', 'issant' => 'ir', 'ement' => 'e', 'ficatrice' => 'fier', 'ficateur' => 'fier', 'catrice' => 'quer', 'atrice' => 'er', 'ateur' => 'er', 'trice' => 'teur', 'ième' => '', 'teuse' => 'ter', 'teur' => 'ter', 'euse' => 'eu', 'ère' => 'er', 'ive' => 'if', 'olle' => 'ou', 'nnelle' => 'n', 'nnel' => 'n', 'ète' => 'et', 'ique' => '', 'esse' => '', 'inage' => '', 'isation' => '', 'isateur' => '', 'ation' => '', 'ition' => ''));
  39. # RAJOUTS CELIO
  40. $this->stemReplace['ance'] = '';
  41. $this->stemReplace['ant'] = '';
  42. $this->stemReplace['ées'] = '';
  43. $this->stemReplace['es'] = '';
  44. $this->stemReplace['ée'] = '';
  45. $this->stemReplace['e'] = '';
  46. $this->stemReplace['é'] = '';
  47. $this->stemSpecialWords = array('yeux' => 'oeil', 'travaux' => 'travail', 'affreux' => 'affreux');
  48. if ($obj) {
  49. $this->obj = $obj;
  50. $this->tab = akev($_Gconfig['iSearches'], $obj);
  51. $this->fields = getTabField($obj);
  52. if (empty($this->tab['champs'])) {
  53. $this->tab['champs'] = array_keys($this->fields);
  54. }
  55. if (empty($this->tab['relations'])) {
  56. $this->tab['relations'] = array();
  57. if (is_array($relations[$obj])) {
  58. foreach ($relations[$obj] as $k => $v) {
  59. $this->tab['relations'][$k] = array_keys(getTabField($v));
  60. }
  61. }
  62. if (is_array($relinv[$obj])) {
  63. foreach ($relinv[$obj] as $k => $v) {
  64. $this->tab['relations'][$k] = array_keys(getTabField($v[0]));
  65. }
  66. }
  67. }
  68. if ($obj == 's_rubrique') {
  69. global $_Gconfig;
  70. $tb = GetTablesToIndex();
  71. foreach ($_Gconfig['duplicateWithRubrique'] as $v) {
  72. if (in_array($v, $tb)) {
  73. //$this->tab['relations'][$k] = array_keys(getTabField($v[0]));
  74. $this->related[] = $v;
  75. }
  76. }
  77. }
  78. $this->pk = getPrimaryKey($obj);
  79. }
  80. }
  81. public function useWildCards() {
  82. $this->useWildCards = true;
  83. }
  84. /**
  85. * Selectionne l'ensemble du texte et des relations de l'objet concerné
  86. *
  87. * @param Identifiant $id
  88. * @return string Texte complet nettoyé
  89. */
  90. function getTextToIndex($id, $res=null) {
  91. global $tablerel, $relinv, $relations, $tabForms, $uploadFields, $_Gconfig;
  92. foreach ($this->related as $v) {
  93. $sql = 'SELECT * FROM ' . $v . ' AS T WHERE fk_rubrique_id = ' . $id;
  94. $res = GetAll($sql);
  95. $ppk = getPrimaryKey($v);
  96. $i = new indexSearch($v);
  97. foreach ($res as $row) {
  98. //echo ('index : '.$v.' '.$row[$ppk]);
  99. $i->indexText($i->getTextToIndex($row[$ppk]), $row[$ppk]);
  100. }
  101. }
  102. if (!$res) {
  103. $sql = 'SELECT * FROM ' . $this->obj . ' WHERE ' . $this->pk . ' = "' . $id . '"';
  104. $res = GetSingle($sql);
  105. }
  106. $txtToIndex = '';
  107. if (in_array($this->obj, $_Gconfig['duplicateWithRubrique'])) {
  108. if (!isRubriqueRealAndOnline($res['fk_rubrique_id'])) {
  109. return false;
  110. }
  111. }
  112. foreach ($this->tab['champs'] as $field) {
  113. if (ake($this->fields, $field)) {
  114. if (arrayInWord($uploadFields, $field) || arrayInWord($_Gconfig['urlFields'], $field)) {
  115. //print('<b>'.$field.'</b>');
  116. //$txt = GETTEXTCONTENTOFFILE();
  117. } else {
  118. $coef = 1;
  119. if (!empty($_Gconfig['searchRatio'][$this->obj][$field])) {
  120. $coef = $_Gconfig['searchRatio'][$this->obj][$field];
  121. } else
  122. if (in_array($field, $tabForms[$this->obj]['titre'])) {
  123. $coef = 10;
  124. } else if (@in_array($field, $tabForms[$this->obj]['desc'])) {
  125. $coef = 4;
  126. }
  127. if ($this->fields[$field]->type == 'date' || $this->fields[$field]->type == 'datetime') {
  128. $txt = niceTextDate($res[$field]);
  129. } else {
  130. $txt = implode(' ', getLgsValues($field, $res, $this->obj));
  131. }
  132. $txtToIndex .= str_repeat($txt . ' ', $coef) . ' ';
  133. }
  134. }
  135. }
  136. foreach ($this->tab['relations'] as $k => $v) {
  137. if (ake($relations[$this->obj], $k) && $v && $res[$k]) {
  138. $sql = 'SELECT * FROM
  139. ' . $relations[$this->obj][$k] . '
  140. WHERE
  141. ' . getPrimaryKey($relations[$this->obj][$k]) . ' = ' . sql($res[$k]);
  142. $r = GetSingle($sql);
  143. foreach ($v as $ch) {
  144. if (arrayInWord($uploadFields, $ch) || arrayInWord($_Gconfig['urlFields'], $ch)) {
  145. } else {
  146. $txtToIndex .= ' ' . implode(' ', getLgsValues($ch, $r, $this->obj)) . ' ';
  147. }
  148. }
  149. } else if (ake($relinv[$this->obj], $k)) {
  150. $sql = 'SELECT * FROM ' . $relinv[$this->obj][$k][0] . ' WHERE ' . $relinv[$this->obj][$k][1] . ' = ' . $res[$this->pk];
  151. $r = GetAll($sql);
  152. foreach ($r as $rv) {
  153. foreach ($v as $ch) {
  154. if (arrayInWord($uploadFields, $ch) || arrayInWord($_Gconfig['urlFields'], $ch)) {
  155. } else {
  156. $txtToIndex .= ' ' . implode(' ', getLgsValues($ch, $rv, $relinv[$this->obj][$k][0])) . ' ';
  157. }
  158. }
  159. }
  160. }
  161. }
  162. return $this->cleanText($txtToIndex);
  163. }
  164. /**
  165. * Nettoie le texte de toute impurtée HTML, des mots inutiles, ...
  166. *
  167. * @param string $str
  168. * @return string
  169. */
  170. function cleanText($str) {
  171. $str = strip_tags($str);
  172. $str = mb_strtolower($str, 'utf-8');
  173. //$str = strtr($str,'é','e');
  174. $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
  175. //
  176. //$str = $this->utf2ascii($str);
  177. //$str = removeaccents($str);
  178. $delims = array('�', '&amp;#8217;', '&#8217;', '?', '.', ',', ';', ':', '/', '\\', '!', ']', '}', '\'', '{', '[', '(', ')', '-', '>', '<', '|', '#', '?', "\n", "\r", "\t", '?', '"', '?', "?", '?', '?', '*', '?', '�', '’', '@', '_', '&', '^', '=', '»', '«');
  179. $str = str_replace($delims, ' ', $str);
  180. $str = $this->removeaccents($str);
  181. $commonWords = array('en_ligne', 'page', 'les', 'des', 'dans', 'mais', 'car', 'elle', 'elles', 'aussi', 'leurs', 'leur', 'nous', 'entre', 'non', 'par', 'ils', 'ainsi', 'ces', 'ses', 'une', 'que', 'aux', 'par', 'est', 'qui', 'sur', 'pour', 'sont', 'plus', 'avec', 'cette', 'pas', 'comme', 'ont', 'peut', 'dont');
  182. $str = ' ' . $str . ' ';
  183. foreach ($commonWords as $word) {
  184. $str = str_replace(' ' . $word . ' ', ' ', $str);
  185. }
  186. return trim($str);
  187. }
  188. function removeaccents($str) {
  189. // LAME WAY TO DO IT ! But PHP is too ....
  190. $str = utf8_decode($str);
  191. $str = strtr($str, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6", "AAAAAAA");
  192. $str = strtr($str, "\xC7", "C");
  193. $str = strtr($str, "\xC8\xC9\xCA\xCB", "EEEE");
  194. $str = strtr($str, "\xCC\xCD\xCE\xCF", "IIII");
  195. $str = strtr($str, "\xD1", "N");
  196. $str = strtr($str, "\xD2\xD3\xD4\xD5\xD6\xD8", "OOOOOO");
  197. $str = strtr($str, "\xDD", "Y");
  198. $str = strtr($str, "\xDF", "S");
  199. $str = strtr($str, "\xE0\xE1\xE2\xE3\xE4\xE5\xE6", "aaaaaaa");
  200. $str = strtr($str, "\xE7", "c");
  201. $str = strtr($str, "\xE8\xE9\xEA\xEB", "eeee");
  202. $str = strtr($str, "\xEC\xED\xEE\xEF", "iiii");
  203. $str = strtr($str, "\xF1", "n");
  204. $str = strtr($str, "\xF2\xF3\xF4\xF5\xF6\xF8", "oooooo");
  205. $str = strtr($str, "\xF9\xFA\xFB\xFC", "uuuu");
  206. $str = strtr($str, "\xFD\xFF", "yy");
  207. return $str;
  208. }
  209. function mb_str_split($str, $length = 1) {
  210. if ($length < 1)
  211. return FALSE;
  212. $result = array();
  213. for ($i = 0; $i < mb_strlen($str); $i += $length) {
  214. $result[] = mb_substr($str, $i, $length);
  215. }
  216. return $result;
  217. }
  218. /**
  219. * Parcourt les mots et les indexe dans la base
  220. *
  221. * @param string $str
  222. * @param mixed $id_obj
  223. */
  224. function indexText($str, $id_obj) {
  225. global $co, $_Gconfig;
  226. if (in_array($this->obj, $_Gconfig['duplicateWithRubrique'])) {
  227. $res = getRowFromId($this->obj, $id_obj);
  228. if (!isRubriqueRealAndOnline($res['fk_rubrique_id'])) {
  229. return false;
  230. }
  231. }
  232. $id = $this->GetIsId($id_obj);
  233. DoSql('DELETE FROM os_rel WHERE fkobj = "' . $id . '"');
  234. $tabMots = $this->getTabWords($str, true);
  235. $sql = ' INSERT INTO os_rel VALUES ';
  236. foreach ($tabMots as $k => $v) {
  237. $sql .= ( '("' . $id . '","' . $k . '","' . $v . '") , ');
  238. }
  239. $sql = substr($sql, 0, -2);
  240. DoSql($sql);
  241. }
  242. /**
  243. *
  244. *
  245. * @param unknown_type $str
  246. * @param unknown_type $getids
  247. * @return unknown
  248. */
  249. function getTabWords($str, $getids = false) {
  250. $mots = explode(' ', $str);
  251. $tabWords = array();
  252. foreach ($mots as $word) {
  253. $word1 = $word;
  254. $word = $this->cleanWord($word);
  255. /*
  256. if($getids) {
  257. $this->insertDict($word1);
  258. }
  259. */
  260. if (strlen($word) > $this->minlength || in_array($word, $this->vipWords)) {
  261. if ($getids) {
  262. $wid = $this->GetWordId($word);
  263. if (!isset($tabWords[$wid])) {
  264. $tabWords[$wid] = 0;
  265. }
  266. $tabWords[$wid]++;
  267. } else {
  268. $tabWords[] = $word;
  269. }
  270. }
  271. }
  272. return $tabWords;
  273. }
  274. function insertDict($word) {
  275. TrySql('INSERT INTO is_dict (mot) VALUES(' . sql($word) . ')');
  276. DoSql('UPDATE is_dict SET nb = nb + 1 WHERE mot = ' . sql($word));
  277. }
  278. /**
  279. * Selectionne un mot et retourne son identifiant
  280. *
  281. * @param string $word
  282. * @return mixed Primary key
  283. *
  284. */
  285. function getWordId($word) {
  286. if (empty($this->cacheWord[$word])) {
  287. $sql = 'SELECT id FROM os_word WHERE word = "' . $word . '" ';
  288. $row = GetSingle($sql);
  289. if (!count($row)) {
  290. DoSql('INSERT INTO os_word VALUES ("","' . $word . '")');
  291. $this->cacheWord[$word] = InsertId();
  292. //debug('insert '.$word);
  293. } else {
  294. $this->cacheWord[$word] = $row['id'];
  295. }
  296. }
  297. return $this->cacheWord[$word];
  298. }
  299. /**
  300. * Nettoie un mot ... a voir avec du stemming, ...
  301. *
  302. * @param string $word
  303. * @return string
  304. */
  305. function cleanWord($word) {
  306. /*
  307. $w = prepareword($word);
  308. dinfo($word.'-'.$w);
  309. return $w;
  310. */
  311. $ow = $word;
  312. if (empty($this->cachestem[$ow])) {
  313. if (!empty($this->stemSpecialWords[$ow])) {
  314. $word = $this->stemSpecialWords[$ow];
  315. } else {
  316. foreach ($this->stemReplace as $k => $v) {
  317. $l = strlen($k);
  318. if (substr($word, -$l) == $k && strlen($word) > $l) {
  319. $word = substr($word, 0, -$l) . $v;
  320. //break;
  321. }
  322. }
  323. }
  324. /*
  325. foreach($stemRemove as $v) {
  326. if(substr($word,-strlen($v)) == $v && strlen($word) > strlen($v)) {
  327. $word = substr($word,0,-strlen($v));
  328. break;
  329. }
  330. }
  331. */
  332. $this->cachestem[$ow] = $word;
  333. }
  334. //dinfo($ow.' : '.$word);
  335. if (strlen($this->cachestem[$ow]) <= $this->minlength && !in_array($this->cachestem[$ow], $this->vipWords)) {
  336. $this->cachestem[$ow] = '';
  337. }
  338. return $this->cachestem[$ow];
  339. }
  340. /**
  341. * Retourne l'identifiant de l'objet IS
  342. *
  343. * @param string $id_obj
  344. * @return string
  345. */
  346. function getIsId($id_obj) {
  347. $sql = 'SELECT id FROM os_obj WHERE fkid = "' . $id_obj . '" AND obj = "' . $this->obj . '"';
  348. $row = GetSingle($sql);
  349. if (is_array($row) && count($row)) {
  350. $this->id = $row['id'];
  351. } else {
  352. DoSql('INSERT INTO os_obj VALUES ("","' . $this->obj . '","' . $id_obj . '")');
  353. $this->id = InsertId();
  354. }
  355. return $this->id;
  356. }
  357. /**
  358. * Effectue une recherche fulltexte sur l'objet courant
  359. *
  360. * @param string $q recherche full texte
  361. * @param string $select
  362. * @param string $from
  363. * @param string $where
  364. * @param string $order
  365. * @return array Tableau de requete SQL
  366. */
  367. function search($q, $select="", $from="", $where="", $order=false, $group = 'IO.id') {
  368. $q = $this->cleanText($q);
  369. //print($q.'<br/>');
  370. $words = $this->getTabWords($q, false);
  371. //debug($words);
  372. if (!$this->obj) {
  373. return $this->searchGlobal($words);
  374. }
  375. if (count($words) > 0 && $words[0] != "") {
  376. if (!$order) {
  377. $order = ' RANK1 DESC , RANK2 DESC ';
  378. }
  379. $sql = 'SELECT O.* ,
  380. COUNT(IO.id) AS CIO,
  381. COUNT(IW.id) AS RANK1,
  382. SUM(IR.nb) AS RANK2,
  383. "' . $this->obj . '" as obj
  384. ' . $select . '
  385. FROM os_obj as IO , os_rel AS IR, os_word AS IW,
  386. ' . $this->obj . ' AS O ' . $from . '
  387. WHERE IO.fkid = O.' . $this->pk . '
  388. AND IO.obj = "' . $this->obj . '"
  389. AND IO.id = IR.fkobj
  390. AND IR.fkword = IW.id
  391. ' . $where . '
  392. ';
  393. //debug($words);
  394. //array_walk($words,'$this->cleanWord');
  395. $sql .= ' AND ( 0 ';
  396. foreach ($words as $word) {
  397. $sql .= ' OR IW.word LIKE "' . $word . '" ';
  398. }
  399. $sql .= ' ) ';
  400. //$sql .= ' COUNT(IW.id) = '.count($words).' ';
  401. $sql .= ' GROUP BY ' . $group . ' HAVING RANK1 = ' . count($words) . ' ORDER BY ' . $order;
  402. // debug($sql);
  403. } else {
  404. if ($order) {
  405. $order = ' ORDER BY ' . $order;
  406. }
  407. $sql = 'SELECT O.*
  408. ' . $select . '
  409. FROM ' . $this->obj . ' AS O ' . $from . '
  410. WHERE 1
  411. ' . $where . '
  412. ' . $order . '
  413. ';
  414. }
  415. echo $sql;
  416. return GetAll($sql);
  417. }
  418. /**
  419. * Recherche dans la base mais sans Objet définit, et retourne tous les objets correspondants
  420. * Il faut ensuite selectionner tous les enregistrements en question pour les afficher
  421. *
  422. * @param array $words
  423. */
  424. function searchGlobal($words) {
  425. $res = array();
  426. if (count($words) > 0 && $words[0] != "") {
  427. $resTot = getSingle('SELECT COUNT(id) AS NB FROM os_obj');
  428. $nbTot = $resTot['NB'];
  429. $sqls = ' ( ';
  430. foreach ($words as $k => $word) {
  431. if ($this->useWildCards) {
  432. $word .= "%";
  433. }
  434. $sql1 = 'SELECT word, COUNT( id ) AS NB
  435. FROM `os_word` AS W, os_rel AS R
  436. WHERE R.fkword = W.id
  437. AND W.word = "' . $word . '"
  438. GROUP BY W.id
  439. ORDER BY `NB` DESC ';
  440. $res1 = GetSingle($sql1);
  441. if (!empty($res1['NB'])) {
  442. $ratio[$word] = ceil($nbTot / $res1['NB']);
  443. } else {
  444. $ratio[$word] = 0;
  445. }
  446. //debug('WORD : '.$word.' '.$ratio[$word]);//$res1['NB']);
  447. $sql = 'SELECT
  448. CONCAT(IO.obj,IO.fkid) AS MACLEF,
  449. IO.obj , IO.fkid ,
  450. COUNT(IO.id) AS CIO,
  451. COUNT(IW.id) AS RANK1,
  452. SUM(IR.nb*' . $ratio[$word] . ') AS RANK2
  453. FROM os_obj as IO , os_rel AS IR, os_word AS IW
  454. WHERE IO.id = IR.fkobj
  455. AND IR.fkword = IW.id
  456. AND IW.word LIKE "' . $word . '"
  457. ';
  458. $sql .= ' GROUP BY IO.id ';
  459. $sql .= ' ORDER BY RANK2 DESC';
  460. if ($k != 0)
  461. $sqls .= ' ) UNION ALL (' . $sql . ' ';
  462. else
  463. $sqls .= $sql;
  464. //$res[$word] = GetAll($sql);
  465. }
  466. $sql = ' SELECT obj, fkid, RANK1, RANK2, SUM(RANK2) AS RANK3 , SUM(RANK1) AS LIMITEUR FROM ( ';
  467. $sql .= $sqls;
  468. $sql .= ' ) ';
  469. if (count($words) > 1) {
  470. $sql .= ' ORDER BY RANK2 DESC ';
  471. }
  472. $sql .= ' ) AS TEST GROUP BY MACLEF HAVING LIMITEUR >= ' . count($words) . ' ORDER BY RANK3 DESC';
  473. $res = GetAll($sql);
  474. //debug(' SELECT obj, fkid, RANK1, RANK2, SUM(RANK2) AS RANK3 , SUM(RANK1) AS LIMITEUR FROM ( '.$sqls.' ) ORDER BY RANK2 DESC ) AS TEST GROUP BY MACLEF HAVING LIMITEUR >= '.count($words).' ORDER BY RANK3 DESC');
  475. //debug(count($res));
  476. //diebug($res);
  477. /**
  478. * VERSION NORMALE SANS PONDERATION DES MOTS
  479. *
  480. *
  481. $sql = 'SELECT
  482. IO.obj , IO.fkid , IW.word ,
  483. COUNT(IO.id) AS CIO,
  484. COUNT(IW.id) AS RANK1,
  485. SUM(IR.nb) AS RANK2
  486. FROM os_obj as IO , os_rel AS IR, os_word AS IW
  487. WHERE IO.id = IR.fkobj
  488. AND IR.fkword = IW.id
  489. ';
  490. //debug($words);
  491. //array_walk($words,'$this->cleanWord');
  492. $sql .= ' AND ( 0 ';
  493. foreach($words as $word)
  494. {
  495. $sql .= ' OR IW.word LIKE "'.$word.'" ';
  496. }
  497. $sql .= ' ) ';
  498. //$sql .= ' COUNT(IW.id) = '.count($words).' ';
  499. $sql .= ' GROUP BY IO.id HAVING RANK1 = '.count($words).' ';
  500. $sql .= ' ORDER BY RANK1 DESC , RANK2 DESC';
  501. // */
  502. } else {
  503. //$sql = ' SELECT * FROM os_obj';
  504. }
  505. $t = getmicrotime();
  506. //$res = GetAll($sql);
  507. //debug($res);
  508. //debug(getmicrotime() - $t);
  509. return $res;
  510. }
  511. }
  512. ?>