16 include_once (
"FDL/Lib.Dir.php");
110 private $debug =
false;
111 private $debuginfo = [];
117 private $excludeFilter =
"";
123 private $iDoc = null;
129 private $cacheDocuments = array();
134 private $mode =
"TABLE";
135 private $count = - 1;
140 private $result =
false;
145 private $pertinenceOrder =
'';
149 private $highlightWords =
'';
150 private $resultPos = 0;
155 private $resultQPos = 0;
179 private function normalizeFromId($id)
183 if ($id ===
"0" || $id ===
"") {
190 if (is_numeric($id)) {
198 $fam =
new_Doc($this->dbaccess, $id);
199 if ($fam->isAlive() && $fam->defDoctype ===
'C') {
200 return $sign * (int)$fam->id;
205 if (substr($id, 0, 1) ==
'-') {
208 $id = substr($id, 1);
210 $fam =
new_Doc($this->dbaccess, $id);
211 if ($fam->isAlive() && $fam->defDoctype ===
'C') {
212 return $sign * (int)$fam->id;
232 $fld =
new_Doc($this->dbaccess, $this->dirid);
237 $this->debuginfo[
"query"] = $tqsql[0];
239 if (!is_array($tqsql)) {
240 if (!isset($this->debuginfo[
"error"]) || $this->debuginfo[
"error"] ==
"") {
241 $this->debuginfo[
"error"] = _(
"cannot produce sql request");
245 foreach ($tqsql as
$sql) {
247 if (preg_match(
'/from\s+(?:only\s+)?([a-z0-9_\-]*)/', $sql, $reg)) $maintable = $reg[1];
248 else $maintable =
'';
249 $maintabledot = ($maintable) ? $maintable .
'.' :
'';
251 $mainid = ($maintable) ?
"$maintable.id" :
"id";
253 if (preg_match(
'/^\s*select\s+distinct(\s+|\(.*?\))/iu', $sql, $m)) {
256 $sql = preg_replace(
'/^\s*select\s+(.*?)\s+from\s/iu',
"select count($distinct$mainid) from ", $sql, 1);
260 $dbid =
getDbid($this->dbaccess);
261 $mb = microtime(
true);
263 simpleQuery($this->dbaccess, $sql, $result,
false,
true,
true);
265 catch(\Dcp\Db\Exception $e) {
266 $this->debuginfo[
"query"] =
$sql;
267 $this->debuginfo[
"error"] = pg_last_error($dbid);
271 $count+= $result[
"count"];
272 $this->debuginfo[
"query"] =
$sql;
273 $this->debuginfo[
"delay"] = sprintf(
"%.03fs", microtime(
true) - $mb);
276 $this->
count = $count;
298 return '{' . implode(
',',
$memberOf) .
'}';
308 return _internalGetDocCollection(
true, $this->dbaccess, $this->dirid, $this->
start, $this->
slice, $this->
getFilters() , $this->userid, $this->searchmode, $this->fromid, $this->distinct, $this->
orderby, $this->latest, $this->trash, $debuginfo, $this->folderRecursiveLevel, $this->
join, $this);
327 public function join($jointure)
329 if (empty($jointure)) {
331 } elseif (preg_match(
'/([a-z0-9_\-:]+)\s*(=|<|>|<=|>=)\s*([a-z0-9_\-:]+)\(([^\)]*)\)/', $jointure, $reg)) {
332 $this->
join = $jointure;
334 throw new \Dcp\SearchDoc\Exception(
"SD0001", $jointure);
349 if ($this->
count == - 1) {
350 if ($this->searchmode ==
"ITEM") {
366 foreach ($this->result as $res) $n+= pg_num_rows($res);
367 reset($this->result);
378 $this->result =
false;
379 $this->resultPos = 0;
380 $this->resultQPos = 0;
381 $this->debuginfo = [];
392 $this->resultPos = 0;
393 $this->resultQPos = 0;
402 return ($this->result !==
false);
411 if (!$this->excludeFilter) {
414 return array_merge(array(
429 if (
count($this->filters) > 0 && $this->dirid > 0) {
431 if (is_object(
$dir) &&
$dir->isAlive() && is_a(
$dir,
'\Dcp\Family\Ssearch')) {
433 throw new \Dcp\SearchDoc\Exception(
"SD0008");
437 if ($this->mode ==
"ITEM") {
444 if (!is_numeric($this->fromid)) {
447 if ($this->fromid != - 1) {
449 if ($this->fromid < - 1) {
452 simpleQuery($this->dbaccess, sprintf(
"select doctype from docfam where id=%d", abs($this->fromid)) , $doctype,
true,
true);
453 if ($doctype !=
'C')
$fromid = 0;
458 $error = sprintf(_(
"%s is not a family") , $this->fromid);
459 $this->debuginfo[
"error"] = $error;
460 error_log(
"ERROR SearchDoc: " . $error);
461 if ($this->mode ==
"ITEM")
return null;
464 if ($this->only) $this->fromid = - (abs(
$fromid));
469 $this->searchmode = $this->mode;
470 if ($this->mode ==
"ITEM") {
473 $fld =
new_Doc($this->dbaccess, $this->dirid);
475 $this->searchmode =
"TABLE";
479 $debuginfo = array();
481 $this->result =
internalGetDocCollection($this->dbaccess, $this->dirid, $this->
start, $this->
slice, $this->
getFilters() , $this->userid, $this->searchmode, $this->fromid, $this->distinct, $this->
orderby, $this->latest, $this->trash, $debuginfo, $this->folderRecursiveLevel, $this->
join, $this);
482 if ($this->searchmode ==
"TABLE") $this->
count =
count($this->result);
483 $this->debuginfo = $debuginfo;
484 if (($this->searchmode ==
"TABLE") && ($this->mode ==
"ITEM")) $this->mode =
"TABLEITEM";
485 $this->resultPos = 0;
486 $this->resultQPos = 0;
487 if ($this->mode ==
"ITEM")
return $this;
489 return $this->result;
507 include_once (
"FDL/Class.DocumentList.php");
517 $fdoc =
createTmpDoc($this->dbaccess, $this->fromid,
false);
518 $fields = array_merge($fdoc->fields, $fdoc->sup_fields);
521 $fields = array_merge($fdoc->fields, $fdoc->sup_fields);
523 foreach ($returns as $k =>
$r) {
524 if (empty(
$r)) unset($returns[$k]);
525 $returns[$k] = strtolower(
$r);
527 if (!in_array(
$r, $fields)) {
531 $this->returnsFields = array_unique(array_merge(array(
542 $fdoc =
createTmpDoc($this->dbaccess, $this->fromid,
false);
543 if ($fdoc->isAlive())
return array_merge($fdoc->fields, $fdoc->sup_fields);
562 if ($this->debuginfo && isset($this->debuginfo[
"error"]))
return $this->debuginfo[
"error"];
574 $this->debug = $debug;
588 $this->recursiveSearch = $recursiveMode;
589 if (!is_int($level) || $level < 0) {
590 throw new \Dcp\SearchDoc\Exception(
"SD0006", $level);
592 $this->folderRecursiveLevel = $level;
603 return $this->debuginfo;
613 return $this->debuginfo;
624 if ((!is_numeric(
$slice)) && (
$slice !=
'ALL'))
return false;
640 $this->
orderby = preg_replace(
'/(^\s*|,\s*)-([A-Z_0-9]{1,63})\b/i',
'$1$2 desc', $this->
orderby);
652 if (
$dir->isAlive()) {
653 $this->dirid =
$dir->initid;
657 $this->debuginfo[
"error"] = sprintf(_(
"collection %s not exists") ,
$dirid);
670 if (!(is_numeric(
$start)))
return false;
703 if ($this->mode ==
"ITEM") {
704 $n = empty($this->result[$this->resultQPos]) ? null : $this->result[$this->resultQPos];
705 if (!$n)
return false;
706 $tdoc = @pg_fetch_array($n, $this->resultPos, PGSQL_ASSOC);
707 if (
$tdoc ===
false) {
709 $n = empty($this->result[$this->resultQPos]) ? null : $this->result[$this->resultQPos];
710 if (!$n)
return false;
711 $this->resultPos = 0;
712 $tdoc = @pg_fetch_array($n, $this->resultPos, PGSQL_ASSOC);
713 if (
$tdoc ===
false)
return false;
717 } elseif ($this->mode ==
"TABLEITEM") {
718 $tdoc = current(array_slice($this->result, $this->resultPos, 1));
719 if (!is_array(
$tdoc))
return false;
723 return current(array_slice($this->result, $this->resultPos++, 1));
734 if ($this->mode ==
"ITEM") {
735 foreach ($this->result as $n) {
736 $c = pg_num_rows($n);
737 for ($i = 0; $i <
$c; $i++) {
738 $ids[] = pg_fetch_result($n, $i,
"id");
743 foreach ($this->result as $raw) {
758 if ($v[
"doctype"] ==
"C") {
759 if (!isset($this->cacheDocuments[
"family"])) $this->cacheDocuments[
"family"] =
new DocFam($this->dbaccess);
760 $this->cacheDocuments[
"family"]->Affect($v,
true);
763 if (!isset($this->cacheDocuments[
$fromid])) {
764 $this->cacheDocuments[
$fromid] =
createDoc($this->dbaccess, $fromid,
false,
false);
765 if (empty($this->cacheDocuments[$fromid])) {
766 throw new Exception(sprintf(
'Document "%s" has an unknow family "%s"', $v[
"id"], $fromid));
771 $this->cacheDocuments[
$fromid]->Affect($v,
true);
772 $this->cacheDocuments[
$fromid]->nocache =
true;
773 if ((!empty($this->returnsFields))) $this->cacheDocuments[
$fromid]->doctype =
"I";
774 return $this->cacheDocuments[
$fromid];
787 $args = func_get_args();
791 $fs[] = pg_escape_string(
$args[$i]);
793 $filter = call_user_func_array(
"sprintf", $fs);
795 if (preg_match(
'/(\s|^|\()(?P<relname>[a-z0-9_\-]+)\./',
$filter, $reg)) {
819 throw new \Dcp\SearchDoc\Exception(
"SD0004", $keywords);
821 $filter = $this->
getGeneralFilter(trim($keywords) , $useSpell, $this->pertinenceOrder, $this->highlightWords, $usePartial);
834 if (preg_match(
'/\(\s*\)/u',
$keyword))
return false;
838 if (substr_count(
$keyword,
'(') != substr_count(
$keyword,
')'))
return false;
841 for ($i = 0; $i < $si; $i++) {
844 if ($pb < 0)
return false;
857 $rank = preg_replace(
'/\s+(OR)\s+/u',
'|',
$keyword);
858 $rank = preg_replace(
'/\s+(AND)\s+/u',
'&', $rank);
859 $rank = preg_replace(
'/\s+/u',
'&', $rank);
860 $this->pertinenceOrder = sprintf(
"ts_rank(fulltext,to_tsquery('french', E'%s')) desc, id desc", pg_escape_string(
unaccent($rank)));
862 if ($this->pertinenceOrder) $this->
setOrder($this->pertinenceOrder);
877 public static function getGeneralFilter($keywords, $useSpell =
false, &$pertinenceOrder =
'', &$highlightWords =
'', $usePartial =
false)
882 $currentOperator =
"and";
883 $parenthesisBalanced = 0;
887 $stringWords = array();
889 $convertOperatorToTs =
function ($operator)
891 if ($operator ===
"") {
894 if ($operator ===
"and") {
896 }
else if ($operator ===
"or") {
899 throw new \Dcp\SearchDoc\Exception(
"SD0002", $operator);
908 foreach ($filterElements as $currentFilter) {
909 if ($usePartial && $currentFilter[
"mode"] === \Dcp\Lex\GeneralFilter::MODE_WORD) {
913 if (!in_array($currentFilter[
"mode"], array(
914 \Dcp\Lex\GeneralFilter::MODE_OR,
915 \Dcp\Lex\GeneralFilter::MODE_AND,
916 \Dcp\Lex\GeneralFilter::MODE_OPEN_PARENTHESIS,
917 \Dcp\Lex\GeneralFilter::MODE_CLOSE_PARENTHESIS,
918 \Dcp\Lex\GeneralFilter::MODE_WORD,
925 foreach ($filterElements as $currentElement) {
926 if ($usePartial && ($currentElement[
"mode"] === \Dcp\Lex\GeneralFilter::MODE_WORD || $currentElement[
"mode"] === \Dcp\Lex\GeneralFilter::MODE_STRING)) {
929 switch ($currentElement[
"mode"]) {
930 case \Dcp\Lex\GeneralFilter::MODE_OR:
931 $currentOperator =
"or";
934 case \Dcp\Lex\GeneralFilter::MODE_AND:
935 $currentOperator =
"and";
938 case \Dcp\Lex\GeneralFilter::MODE_OPEN_PARENTHESIS:
940 $parenthesisBalanced+= 1;
943 case \Dcp\Lex\GeneralFilter::MODE_CLOSE_PARENTHESIS:
945 $parenthesisBalanced-= 1;
948 case \Dcp\Lex\GeneralFilter::MODE_WORD:
949 $filterElement = $currentElement[
"word"];
951 $filterElement = self::testSpell($currentElement[
"word"]);
953 $rankElement =
unaccent($filterElement);
954 if (is_numeric($filterElement)) {
955 $filterElement = sprintf(
"(%s|-%s)", $filterElement, $filterElement);
958 $words[] = $filterElement;
960 $filterElement = pg_escape_string(
unaccent($filterElement));
962 $to_tsquery = sprintf(
"to_tsquery('french', E'%s')", pg_escape_string(
unaccent($filterElement)));
963 $dbObj =
new DbObj(
'');
964 $point = sprintf(
'dcp:%s', uniqid(__METHOD__));
965 $dbObj->savePoint(
$point);
967 simpleQuery(
'', sprintf(
"select %s", $to_tsquery) , $indexedWord,
true,
true);
968 $dbObj->rollbackPoint(
$point);
970 catch(Dcp\Db\Exception $e) {
971 $dbObj->rollbackPoint(
$point);
972 throw new \Dcp\SearchDoc\Exception(
"SD0007",
unaccent($filterElement));
975 $filterElement = sprintf(
"(fulltext @@ E'%s')", pg_escape_string($indexedWord));
983 case \Dcp\Lex\GeneralFilter::MODE_STRING:
984 $rankElement =
unaccent($currentElement[
"word"]);
985 if (!preg_match(
'/\p{L}|\p{N}/u', mb_substr($rankElement, 0, 1))) {
986 $begin =
'[£|\\\\s]';
990 if (!preg_match(
'/\p{L}|\p{N}/u', mb_substr($rankElement, -1))) {
996 $rankElement = trim(preg_replace(
'/[^\w]+/',
' ', $rankElement));
997 $stringWords[] = $rankElement;
999 $filterElement = sprintf(
"svalues ~* E'%s%s%s'", $begin, pg_escape_string(preg_quote($currentElement[
"word"])) , $end);
1002 case \Dcp\Lex\GeneralFilter::MODE_PARTIAL_END:
1003 $rankElement =
unaccent($currentElement[
"word"]);
1005 if (!preg_match(
'/\p{L}|\p{N}/u', mb_substr($rankElement, 0, 1))) {
1006 $begin =
'[£|\\\\s]';
1010 $filterElement = sprintf(
"svalues ~* E'%s%s'", $begin, pg_escape_string(preg_quote($currentElement[
"word"])));
1013 case \Dcp\Lex\GeneralFilter::MODE_PARTIAL_BEGIN:
1014 $rankElement =
unaccent($currentElement[
"word"]);
1016 if (!preg_match(
'/\p{L}|\p{N}/u', mb_substr($rankElement, -1))) {
1017 $end =
'[£|\\\\s]';
1021 $filterElement = sprintf(
"svalues ~* E'%s%s'", pg_escape_string(preg_quote($currentElement[
"word"])) , $end);
1024 case \Dcp\Lex\GeneralFilter::MODE_PARTIAL_BOTH:
1025 $rankElement =
unaccent($currentElement[
"word"]);
1027 $stringWords[] = $currentElement[
"word"];
1029 $filterElement = sprintf(
"svalues ~* E'%s'", pg_escape_string(preg_quote($currentElement[
"word"])));
1032 if ($filterElement) {
1034 $filter.=
$filter ? $convertOperatorToTs($currentOperator) . $filterElement : $filterElement;
1036 $filter.=
$filter ?
" " . $currentOperator .
" " . $filterElement : $filterElement;
1038 $rank.= $rank ? $convertOperatorToTs($currentOperator) . $rankElement : $rankElement;
1039 $filterElement =
"";
1040 $currentOperator =
"and";
1041 }
else if ($parenthesis) {
1044 $filter.=
$filter && $parenthesis ===
"(" ? $convertOperatorToTs($currentOperator) . $parenthesis : $parenthesis;
1046 $filter.=
$filter && $parenthesis ===
"(" ?
" " . $currentOperator .
" " . $parenthesis : $parenthesis;
1048 $rank.= $rank && $parenthesis ===
"(" ? $convertOperatorToTs($currentOperator) . $parenthesis : $parenthesis;
1049 $currentOperator = $parenthesis ===
"(" ?
"" :
"and";
1053 if ($parenthesisBalanced !== 0) {
1054 throw new \Dcp\SearchDoc\Exception(
"SD0003", $keywords);
1058 $filter = sprintf(
"fulltext @@ to_tsquery('french', E'%s')", pg_escape_string(
$filter));
1061 $pertinenceOrder = sprintf(
"ts_rank(fulltext,to_tsquery('french', E'%s')) desc, id desc", pg_escape_string(preg_replace(
'/\s+/u',
'&', $rank)));
1063 $highlightWords = implode(
"|", array_merge($words, $stringWords));
1083 if ($beginTag) $oh->beginTag = $beginTag;
1084 if ($endTag) $oh->endTag = $endTag;
1085 if ($limit > 0) $oh->setLimit($limit);
1086 simpleQuery($this->dbaccess, sprintf(
"select svalues from docread where id=%d", $doc->id) , $text,
true,
true);
1089 $h = $oh->highlight($text, $this->highlightWords);
1091 $h = $oh->rawHighlight($text, $this->highlightWords);
1104 protected static function testSpell($word, $language =
"fr")
1106 static $pspell_link = null;
1107 if (function_exists(
'pspell_new')) {
1108 if (!$pspell_link) $pspell_link = pspell_new($language,
"",
"",
"utf-8", PSPELL_FAST);
1109 if ((!is_numeric($word)) && (!pspell_check($pspell_link, $word))) {
1110 $suggestions = pspell_suggest($pspell_link, $word);
1112 if (isset($suggestions[0])) {
1115 if ($sug && ($sug !=
unaccent($word)) && (!strstr($sug,
' '))) {
1116 $word = sprintf(
"(%s|%s)", $word, $sug);
1131 public static function sqlcond(array $values, $column, $integer =
false)
1134 if (
count($values) > 0) {
1136 $sql_cond =
"$column in (";
1137 $sql_cond.= implode(
",", $values);
1140 foreach ($values as & $v) $v = pg_escape_string($v);
1141 $sql_cond =
"$column in ('";
1142 $sql_cond.= implode(
"','", $values);
1179 if ($returnobject) $this->mode =
"ITEM";
1180 else $this->mode =
"TABLE";
1185 return ($this->mode ==
"ITEM");
1195 $this->mode =
"TABLE";
1206 if ($this->userid != 1) {
1210 $this->excludeFilter =
'';
1216 if ($this->recursiveSearch && $this->dirid) {
1217 if (!$this->originalDirId) {
1224 $tmps->setValue(\Dcp\AttributeIdentifiers\Search::se_famid, $this->fromid);
1225 $tmps->setValue(\Dcp\AttributeIdentifiers\Search::se_idfld, $this->originalDirId);
1226 $tmps->setValue(\Dcp\AttributeIdentifiers\Search::se_latest,
"yes");
1227 $err = $tmps->add();
1229 $tmps->addQuery($tmps->getQuery());
1230 $this->dirid = $tmps->id;
1232 throw new \Dcp\SearchDoc\Exception(
"SD0005",
$err);
1250 $join = $this->join;
1252 $normFromId = $this->normalizeFromId(
$fromid);
1253 if ($normFromId ===
false) {
1254 $this->debuginfo[
"error"] = sprintf(_(
"%s is not a family") ,
$fromid);
1259 preg_match(
'/^(?P<sign>-?)(?P<fromid>.+)$/', trim(
$fromid) , $m);
1262 if ($this->only && strpos(
$fromid,
'-') !== 0) {
1273 $table =
"doc$fromid";
1279 $sqlfilters[-4] =
GetSqlCond(array_merge(array(
1281 ) , array_keys($fdoc->GetChildFam())) ,
"fromid",
true);
1283 $table =
"doc$fromid";
1289 $maintable = $table;
1291 if (preg_match(
'/(?P<attr>[a-z0-9_\-:]+)\s*(?P<operator>=|<|>|<=|>=)\s*(?P<family>[a-z0-9_\-:]+)\((?P<family_attr>[^\)]*)\)/', $join, $reg)) {
1293 $jointable = ($joinid) ?
"doc" . $joinid : $reg[
'family'];
1295 $sqlfilters[] = sprintf(
"%s.%s %s %s.%s", $table, $reg[
'attr'], $reg[
'operator'], $jointable, $reg[
'family_attr']);
1296 $maintable = $table;
1297 $table.=
", " . $jointable;
1299 addWarningMsg(sprintf(_(
"search join syntax error : %s") , $join));
1303 $maintabledot = ($maintable &&
$dirid == 0) ? $maintable .
'.' :
'';
1306 $selectfields =
"distinct on ($maintable.initid) $maintable.*";
1308 $selectfields =
"$maintable.*";
1309 $sqlfilters[-2] = $maintabledot .
"doctype != 'T'";
1314 if (
count($sqlfilters) > 0) $sqlcond =
" (" . implode(
") and (", $sqlfilters) .
")";
1321 if (strpos(implode(
",", $sqlfilters) ,
"archiveid") ===
false) $sqlfilters[-4] = $maintabledot .
"archiveid is null";
1324 $sqlfilters[-3] = $maintabledot .
"doctype = 'Z'";
1325 } elseif (
$trash !==
"also") {
1326 $sqlfilters[-3] = $maintabledot .
"doctype != 'Z'";
1330 $sqlfilters[-1] = $maintabledot .
"locked != -1";
1333 if (
count($sqlfilters) > 0) {
1334 $sqlcond =
" (" . implode(
") and (", $sqlfilters) .
")";
1336 $qsql =
"select $selectfields " .
"from $only $table " .
"where " . $sqlcond;
1337 $qsql = $this->injectFromClauseForOrderByLabel(
$fromid, $this->orderbyLabel, $qsql);
1343 if ($fld->defDoctype !=
'S') {
1347 $hasFilters =
false;
1348 if ($fld && method_exists($fld,
"getSpecificFilters")) {
1349 $specFilters = $fld->getSpecificFilters();
1350 if (is_array($specFilters) && (
count($specFilters) > 0)) {
1351 $sqlfilters = array_merge($sqlfilters, $specFilters);
1355 if (strpos(implode(
",", $sqlfilters) ,
"archiveid") ===
false) $sqlfilters[-4] = $maintabledot .
"archiveid is null";
1357 if (
$trash ==
"only") $sqlfilters[-1] =
"locked = -1";
1358 elseif (
$latest) $sqlfilters[-1] =
"locked != -1";
1360 if (
count($sqlfilters) > 0) $sqlcond =
" (" . implode(
") and (", $sqlfilters) .
")";
1362 $sqlfld =
"dirid=$dirid and qtype='S'";
1363 if (
$fromid == 2) $sqlfld.=
" and doctype='D'";
1364 if (
$fromid == 5) $sqlfld.=
" and doctype='S'";
1366 $sqlcond =
" (" . implode(
") and (", $sqlfilters) .
")";
1367 $qsql =
"select $selectfields from $only $table where $sqlcond ";
1370 $q->AddQuery($sqlfld);
1371 $tfld =
$q->Query(0, 0,
"TABLE");
1374 foreach ($tfld as $onefld) {
1375 $tfldid[] = $onefld[
"childid"];
1377 if (
count($tfldid) > 1000) {
1378 $qsql =
"select $selectfields " .
"from $table where initid in (select childid from fld where $sqlfld) " .
"and $sqlcond ";
1380 $sfldids = implode(
",", $tfldid);
1381 if ($table ==
"docread") {
1385 $qsql =
"select $selectfields " .
"from $table where initid in ($sfldids) " .
"and $sqlcond ";
1390 $qsql =
"select $selectfields " .
"from $only $table where initid in ($sfldids) " .
"and $sqlcond ";
1400 $docsearch->AddQuery(
"dirid=$dirid");
1401 $docsearch->AddQuery(
"qtype = 'M'");
1402 $ldocsearch = $docsearch->Query(0, 0,
"TABLE");
1404 if (($docsearch->nb) > 0) {
1405 switch ($ldocsearch[0][
"qtype"]) {
1413 $fld->setValue(
"se_trash",
$trash);
1415 $trash = $fld->getRawValue(
"se_trash");
1418 $tsqlM = $fld->getQuery();
1420 foreach ($tsqlM as $sqlM) {
1421 if ($sqlM !=
false) {
1422 if (!preg_match(
"/doctype[ ]*=[ ]*'Z'/", $sqlM, $reg)) {
1424 $sqlfilters[-3] =
"doctype != 'Z'";
1428 foreach ($sqlfilters as $kf => $sf) {
1429 if (strstr($sqlM, $sf)) {
1430 unset($sqlfilters[$kf]);
1433 if (
count($sqlfilters) > 0) {
1434 $sqlcond =
" (" . implode(
") and (", $sqlfilters) .
")";
1440 $sqlM = str_replace(
"from doc ",
"from $only $table ", $sqlM);
1442 $fldFromId = (
$fromid == 0) ? $fld->getRawValue(
'se_famid', 0) :
$fromid;
1443 $sqlM = $this->injectFromClauseForOrderByLabel($fldFromId, $this->orderbyLabel, $sqlM);
1445 $qsql[] = $sqlM .
" and " . $sqlcond;
1459 if (is_array($qsql))
return $qsql;
1478 private function injectFromClauseForOrderByLabel(
$fromid, $column, $sqlM)
1480 if ($column ==
'') {
1483 $attr = $this->_getAttributeFromColumn(
$fromid, $column);
1484 if ($attr ===
false || $attr->isMultiple()) {
1487 switch ($attr->type) {
1489 $enumKeyLabelList = $attr->getEnum();
1493 foreach ($enumKeyLabelList as $key => $label) {
1494 $mapValues[] = sprintf(
"('%s', '%s')", pg_escape_string($key) , pg_escape_string($label));
1496 $map = sprintf(
'(VALUES %s) AS map_%s(key, label)',
join(
', ', $mapValues) , $attr->id);
1497 $where = sprintf(
"map_%s.key = coalesce(doc%s.%s, '')", $attr->id,
$fromid, $attr->id);
1499 $sqlM = preg_replace(
'/ where /i',
", $map where ($where) and ", $sqlM);
1500 $this->
orderby = preg_replace(sprintf(
'/\b%s\b/', preg_quote($column,
"/")) , sprintf(
"map_%s.label", $attr->id) , $this->orderby);
1508 $opt_doctitle = $attr->getOption(
'doctitle');
1509 if ($opt_doctitle !=
'') {
1510 if ($opt_doctitle ==
'auto') {
1511 $opt_doctitle = sprintf(
'%s_title', $attr->id);
1513 $this->
orderby = preg_replace(sprintf(
'/\b%s\b/', preg_quote($column,
"/")) , $opt_doctitle, $this->
orderby);
1525 private function _getAttributeFromColumn(
$fromid, $column)
1528 if (!$fam->isAlive()) {
1531 $attrList = $fam->getNormalAttributes();
1533 if ($attr->id == $column) {
getHighLightText(Doc &$doc, $beginTag= '< b >', $endTag= '</b >', $limit=200, $wordMode=true)
if(substr($wsh, 0, 1)!= '/') $args
static sqlcond(array $values, $column, $integer=false)
static getMemberOfVector($uid=0, $strict=false)
excludeConfidential($exclude=true)
static checkGeneralFilter($keyword)
static getUserMemberOf($uid, $strict=false)
setDebugMode($debug=true)
familyNeedDocread($dbaccess, $id)
static getGeneralFilter($keywords, $useSpell=false, &$pertinenceOrder= '', &$highlightWords= '', $usePartial=false)
static analyze($source, $onlyToken=false)
setObjectReturn($returnobject=true)
returnsOnly(array $returns)
setOrder($order, $orderbyLabel= '')
getNextDocument(Array $v)
createDoc($dbaccess, $fromid, $control=true, $defaultvalues=true, $temporary=false)
setPertinenceOrder($keyword= '')
isSimpleFilter($sqlfilters)
if($updateExistingTable) $point
internalGetDocCollection($dbaccess, $dirid, $start="0", $slice="ALL", $sqlfilters=array(), $userid=1, $qtype="LIST", $fromid="", $distinct=false, $orderby="title", $latest=true, $trash="", &$debug=null, $folderRecursiveLevel=2, $join= '',\SearchDoc &$searchDoc=null)
getFamIdFromName($dbaccess, $name)
if(is_numeric($parms['famid'])) $attrList
deprecatedFunction($msg= '')
new_Doc($dbaccess, $id= '', $latest=false)
GetSqlCond($Table, $column, $integer=false)
setRecursiveSearch($recursiveMode=true, $level=2)
addFilter($filter, $args= '')
static testSpell($word, $language="fr")
static getUserViewVector($uid)
simpleQuery($dbaccess, $query, &$result=array(), $singlecolumn=false, $singleresult=false, $useStrict=null)
__construct($dbaccess= '', $fromid=0)
createTmpDoc($dbaccess, $fromid, $defaultvalue=true)
if($file) if($subject==""&&$file) if($subject=="") $err
addGeneralFilter($keywords, $useSpell=false, $usePartial=false)