Platform  3.1
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Lib.Dir.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
5  * @package FDL
6 */
7 /**
8  * Generated Header (not documented yet)
9  *
10  * @author Anakeen 2000
11  * @version $Id: Lib.Dir.php,v 1.149 2008/11/13 16:46:48 eric Exp $
12  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
13  * @package FDL
14  * @subpackage
15  */
16 /**
17  */
18 
19 include_once ('FDL/Class.Dir.php');
20 include_once ('FDL/Class.DocSearch.php');
21 include_once ('FDL/Class.DocRead.php');
22 include_once ('FDL/Class.DocFam.php');
23 
25 {
26  // query to find first directories
27  $qsql = "select id from only doc2 where (doctype='D') order by id LIMIT 1;";
28 
29  $query = new QueryDb($dbaccess, "Doc");
30 
31  $tableq = $query->Query(0, 0, "TABLE", $qsql);
32  if ($query->nb > 0) {
33 
34  return $tableq[0]["id"];
35  }
36 
37  return (0);
38 }
39 
40 function getChildDir($dbaccess, $userid, $dirid, $notfldsearch = false, $restype = "LIST")
41 {
42  // query to find child directories (no recursive - only in the specified folder)
43  if (!($dirid > 0)) return array();
44  // search classid and appid to test privilege
45  if ($notfldsearch) {
46  // just folder no serach
47  return getChildDoc($dbaccess, $dirid, "0", "ALL", array() , $userid, $restype, 2, false, "title");
48  } else {
49  // with folder and searches
50  return array_merge(getChildDoc($dbaccess, $dirid, "0", "ALL", array(
51  "doctype='D'"
52  ) , $userid, $restype, 2, false, "title") , getChildDoc($dbaccess, $dirid, "0", "ALL", array(
53  "doctype='S'"
54  ) , $userid, $restype, 5, false, "title"));
55  }
56 }
57 
58 function isSimpleFilter($sqlfilters)
59 {
60  if (!is_array($sqlfilters)) return true;
61  static $props = false;
62 
63  if (!$props) {
64  $d = new Doc();
65  $props = $d->fields;
66  $props = array_merge($props, $d->sup_fields);
67  $props[] = "fulltext";
68  $props[] = "svalues";
69  }
70 
71  foreach ($sqlfilters as $k => $v) {
72  $tok = ltrim($v, "(");
73  $tok = ltrim($tok, " ");
74  $tok = strtok($tok, " !=~@");
75  if (!(strpos($tok, '.') > 0)) { // join is not in main table
76  //if ($tok == "fulltext") return true;
77  if (($tok !== false) && ($tok !== "true") && ($tok !== "false") && (!in_array(ltrim($tok, "(") , $props))) return false;
78  }
79  }
80  return true;
81 }
82 /**
83  * compose query to serach document
84  *
85  * @param string $dbaccess database specification
86  * @param array $dirid the array of id or single id of folder where search document (0 => in all DB)
87  * @param string $fromid for a specific familly (0 => all familly) (<0 strict familly)
88  * @param array $sqlfilters array of sql filter
89  * @param bool $distinct
90  * @param bool $latest set false if search in all revised doc
91  * @param string $trash (no|only|also) search in trash or not
92  * @param bool $simplesearch set false if search is about specific attributes
93  * @param string $join defined a join table like "id = dochisto(id)"
94  */
95 function getSqlSearchDoc($dbaccess, $dirid, $fromid, $sqlfilters = array() , $distinct = false, // if want distinct without locked
96 $latest = true, // only latest document
97 $trash = "", $simplesearch = false, $folderRecursiveLevel = 2, $join = '')
98 {
99  if (($fromid != "") && (!is_numeric($fromid))) $fromid = getFamIdFromName($dbaccess, $fromid);
100  $table = "doc";
101  $only = "";
102  if ($trash == "only") $distinct = true;
103  if ($fromid == - 1) $table = "docfam";
104  elseif ($simplesearch) $table = "docread";
105  elseif ($fromid < 0) {
106  $only = "only";
107  $fromid = - $fromid;
108  $table = "doc$fromid";
109  } else {
110  if ($fromid != 0) {
111  if (isSimpleFilter($sqlfilters) && (familyNeedDocread($dbaccess, $fromid))) {
112  $table = "docread";
113  $fdoc = new_doc($dbaccess, $fromid);
114  $sqlfilters[-4] = GetSqlCond(array_merge(array(
115  $fromid
116  ) , array_keys($fdoc->GetChildFam())) , "fromid", true);
117  } else {
118  $table = "doc$fromid";
119  }
120  } elseif ($fromid == 0) {
121  if (isSimpleFilter($sqlfilters)) $table = "docread";
122  }
123  }
124  $maintable = $table; // can use join only on search
125  if ($join) {
126  if (preg_match("/([a-z0-9_\-:]+)\s*=\s*([a-z0-9_\-:]+)\(([^\)]*)\)/", $join, $reg)) {
127  $joinid = getFamIdFromName($dbaccess, $reg[2]);
128  $jointable = ($joinid) ? "doc" . $joinid : $reg[2];
129 
130  $sqlfilters[] = sprintf("%s.%s = %s.%s", $table, $reg[1], $jointable, $reg[3]); // "id = dochisto(id)";
131  $maintable = $table;
132  $table.= ", " . $jointable;
133  } else {
134  addWarningMsg(sprintf(_("search join syntax error : %s") , $join));
135  return false;
136  }
137  }
138  $maintabledot = ($maintable && $dirid == 0) ? $maintable . '.' : '';
139 
140  if ($distinct) {
141  $selectfields = "distinct on ($maintable.initid) $maintable.*";
142  } else {
143  $selectfields = "$maintable.*";
144  $sqlfilters[-2] = $maintabledot . "doctype != 'T'";
145  ksort($sqlfilters);
146  }
147  $sqlcond = "true";
148  ksort($sqlfilters);
149  if (count($sqlfilters) > 0) $sqlcond = " (" . implode(") and (", $sqlfilters) . ")";
150 
151  if ($dirid == 0) {
152  //-------------------------------------------
153  // search in all Db
154  //-------------------------------------------
155  if (strpos(implode(",", $sqlfilters) , "archiveid") === false) $sqlfilters[-4] = $maintabledot . "archiveid is null";
156 
157  if ($trash == "only") {
158  $sqlfilters[-3] = $maintabledot . "doctype = 'Z'";
159  } elseif ($trash == "also");
160  else if (!$fromid) $sqlfilters[-3] = $maintabledot . "doctype != 'Z'";
161 
162  if (($latest) && (($trash == "no") || (!$trash))) $sqlfilters[-1] = $maintabledot . "locked != -1";
163  ksort($sqlfilters);
164  if (count($sqlfilters) > 0) $sqlcond = " (" . implode(") and (", $sqlfilters) . ")";
165  $qsql = "select $selectfields " . "from $only $table " . "where " . $sqlcond;
166  } else {
167  //-------------------------------------------
168  // in a specific folder
169  //-------------------------------------------
170  if (!is_array($dirid)) $fld = new_Doc($dbaccess, $dirid);
171  if ((is_array($dirid)) || ($fld->defDoctype != 'S')) {
172  $hasFilters = false;
173  if ($fld && method_exists($fld, "getSpecificFilters")) {
174  $specFilters = $fld->getSpecificFilters();
175  if (is_array($specFilters) && (count($specFilters) > 0)) {
176  $sqlfilters = array_merge($sqlfilters, $specFilters);
177  $hasFilters = true;
178  }
179  }
180  if (strpos(implode(",", $sqlfilters) , "archiveid") === false) $sqlfilters[-4] = $maintabledot . "archiveid is null";
181  //if ($fld->getValue("se_trash")!="yes") $sqlfilters[-3] = "doctype != 'Z'";
182  if ($trash == "only") $sqlfilters[-1] = "locked = -1";
183  elseif ($latest) $sqlfilters[-1] = "locked != -1";
184  ksort($sqlfilters);
185  if (count($sqlfilters) > 0) $sqlcond = " (" . implode(") and (", $sqlfilters) . ")";
186 
187  if (is_array($dirid)) {
188  $sqlfld = GetSqlCond($dirid, "dirid", true);
189  $qsql = "select $selectfields " . "from (select childid from fld where $sqlfld) as fld2 inner join $table on (initid=childid) " . "where $sqlcond ";
190  } else {
191  $sqlfld = "dirid=$dirid and qtype='S'";
192  if ($fromid == 2) $sqlfld.= " and doctype='D'";
193  if ($fromid == 5) $sqlfld.= " and doctype='S'";
194  if ($hasFilters) {
195  $sqlcond = " (" . implode(") and (", $sqlfilters) . ")";
196  $qsql = "select $selectfields from $only $table where $sqlcond ";
197  } else {
198  $q = new QueryDb($dbaccess, "QueryDir");
199  $q->AddQuery($sqlfld);
200  $tfld = $q->Query(0, 0, "TABLE");
201  if ($q->nb > 0) {
202  foreach ($tfld as $onefld) {
203  $tfldid[] = $onefld["childid"];
204  }
205  if (count($tfldid) > 1000) {
206  $qsql = "select $selectfields " . "from $table where initid in (select childid from fld where $sqlfld) " . "and $sqlcond ";
207  } else {
208  $sfldids = implode(",", $tfldid);
209  if ($table == "docread") {
210  /*$qsql= "select $selectfields ".
211  "from $table where initid in (select childid from fld where $sqlfld) ".
212  "and $sqlcond "; */
213  $qsql = "select $selectfields " . "from $table where initid in ($sfldids) " . "and $sqlcond ";
214  } else {
215  /*$qsql= "select $selectfields ".
216  "from (select childid from fld where $sqlfld) as fld2 inner join $table on (initid=childid) ".
217  "where $sqlcond ";*/
218  $qsql = "select $selectfields " . "from $only $table where initid in ($sfldids) " . "and $sqlcond ";
219  }
220  }
221  }
222  }
223  //$qsql= "select $selectfields "."from $table where $dirid = any(fldrels) and "." $sqlcond ";
224 
225  }
226  } else {
227  //-------------------------------------------
228  // search familly
229  //-------------------------------------------
230  $docsearch = new QueryDb($dbaccess, "QueryDir");
231  $docsearch->AddQuery("dirid=$dirid");
232  $docsearch->AddQuery("qtype = 'M'");
233  $ldocsearch = $docsearch->Query(0, 0, "TABLE");
234  // for the moment only one query search
235  if (($docsearch->nb) > 0) {
236  switch ($ldocsearch[0]["qtype"]) {
237  case "M": // complex query
238  // $sqlM=$ldocsearch[0]["query"];
239  $fld = new_Doc($dbaccess, $dirid);
240  if ($trash) $fld->setValue("se_trash", $trash);
241  else $trash = $fld->getValue("se_trash");
242  $fld->folderRecursiveLevel = $folderRecursiveLevel;
243  $tsqlM = $fld->getQuery();
244  foreach ($tsqlM as $sqlM) {
245  if ($sqlM != false) {
246  if (!preg_match("/doctype[ ]*=[ ]*'Z'/", $sqlM, $reg)) {
247  if (($trash != "also") && ($trash != "only")) $sqlfilters[-3] = "doctype != 'Z'"; // no zombie if no trash
248  ksort($sqlfilters);
249  foreach ($sqlfilters as $kf => $sf) { // suppress doubles
250  if (strstr($sqlM, $sf)) {
251  unset($sqlfilters[$kf]);
252  }
253  }
254  if (count($sqlfilters) > 0) $sqlcond = " (" . implode(") and (", $sqlfilters) . ")";
255  else $sqlcond = "";
256  }
257  if ($fromid > 0) $sqlM = str_replace("from doc ", "from $only $table ", $sqlM);
258  if ($sqlcond) $qsql[] = $sqlM . " and " . $sqlcond;
259  else $qsql[] = $sqlM;
260  }
261  }
262  break;
263  }
264  } else {
265  return false; // no query avalaible
266 
267  }
268  }
269  }
270  if (is_array($qsql)) return $qsql;
271  return array(
272  $qsql
273  );
274  }
275  /**
276  * get possibles errors before request of getChildDoc
277  * @param string $dbaccess database specification
278  * @param array $dirid the array of id or single id of folder where search document
279  * @return array error codes
280  */
281  function getChildDocError($dbaccess, $dirid)
282  { // in a specific folder (0 => in all DB)
283  $terr = array();
284 
285  if ($dirid == 0) {
286  //-------------------------------------------
287  // search in all Db
288  //-------------------------------------------
289 
290  } else {
291  //-------------------------------------------
292  // in a specific folder
293  //-------------------------------------------
294  if (!is_array($dirid)) $fld = new_Doc($dbaccess, $dirid);
295 
296  if ($fld->getValue("se_phpfunc") != "") return $terr;
297 
298  if ((is_array($dirid)) || ($fld->defDoctype != 'S')) {
299  } else {
300  //-------------------------------------------
301  // search familly
302  //-------------------------------------------
303  $docsearch = new QueryDb($dbaccess, "QueryDir");
304  $err = $docsearch->AddQuery("dirid=$dirid");
305  if ($err != "") {
306  global $action;
307  $action->AddWarningMsg($err);
308  }
309  $docsearch->AddQuery("qtype = 'M'");
310  $ldocsearch = $docsearch->Query(0, 0, "TABLE");
311  // for the moment only one query search
312  if (($docsearch->nb) > 0) {
313  switch ($ldocsearch[0]["qtype"]) {
314  case "M": // complex query
315  $fld = new_Doc($dbaccess, $dirid);
316  $tsqlM = $fld->getQuery();
317  foreach ($tsqlM as $sqlM) {
318 
319  if ($sqlM == false) $terr[$dirid] = _("uncomplete request"); // uncomplete
320 
321  }
322  break;
323  }
324  } else {
325  $terr[$dirid] = _("request not found"); // not found
326 
327  }
328  }
329  }
330  return $terr;
331  }
332  /**
333  * return array of documents
334  *
335  * @param string $dbaccess database specification
336  * @param array $dirid the array of id or single id of folder where search document
337  * @param string $start the start index
338  * @param string $slice the maximum number of returned document
339  * @param array $sqlfilters array of sql filter
340  * @param int $userid the current user id
341  * @param string $qtype LIST|TABLE the kind of return : list of object or list or values array
342  * @param int $fromid identificator of family document
343  * @param bool $distinct if true all revision of the document are returned else only latest
344  * @param string $orderby field order
345  * @param bool $latest if true only latest else all revision
346  * @param string $trash (no|only|also) search in trash or not
347  * @deprecated use searchDoc instead
348  * @return array/Doc
349  */
350  function getChildDoc($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 = '')
351  {
353  global $action;
354  // query to find child documents
355  if (($fromid != "") && (!is_numeric($fromid))) $fromid = getFamIdFromName($dbaccess, $fromid);
356  if ($fromid == 0) $fromid = "";
357  if (($fromid == "") && ($dirid != 0) && ($qtype == "TABLE")) {
358 
359  $fld = new_Doc($dbaccess, $dirid);
360  // In case of full text search, execute specific code
361  if ($fld->fromid == getFamIdFromName($dbaccess, "FTEXTSEARCH")) return $fld->GetFullTextResultDocs($dbaccess, $dirid, $start, $slice, $sqlfilters, $userid, $qtype, $fromid, $distinct, $orderby, $latest);
362 
363  if ($fld->fromid == getFamIdFromName($dbaccess, "SSEARCH")) return $fld->getDocList($start, $slice, $qtype, $userid);
364 
365  if ($fld->defDoctype != 'S') {
366  // try optimize containt of folder
367  if (!$fld->hasSpecificFilters()) {
368  $td = getFldDoc($dbaccess, $dirid, $sqlfilters);
369  if (is_array($td)) return $td;
370  }
371  } else {
372  if ($fld->getValue("se_famid")) $fromid = $fld->getValue("se_famid");
373  }
374  } elseif ($dirid != 0) {
375  $fld = new_Doc($dbaccess, $dirid);
376  if (($fld->defDoctype == 'S') && ($fld->getValue("se_famid"))) $fromid = $fld->getValue("se_famid");
377  }
378  if ($trash == "only") $distinct = true;
379  // xdebug_var_dump(xdebug_get_function_stack());
380  $tqsql = getSqlSearchDoc($dbaccess, $dirid, $fromid, $sqlfilters, $distinct, $latest, $trash, false, $folderRecursiveLevel, $join);
381 
382  $tretdocs = array();
383  if ($tqsql) {
384  foreach ($tqsql as $k => & $qsql) {
385  if ($qsql == false) unset($tqsql[$k]);
386  }
387  $isgroup = (count($tqsql) > 1);
388  foreach ($tqsql as & $qsql) {
389  if ($fromid != - 1) { // not families
390  if ($fromid != 0) {
391  $fdoc = createDoc($dbaccess, abs($fromid) , false, false);
392  if (preg_match("/from\s+docread/", $qsql) || $isgroup) $fdoc = new DocRead($dbaccess);
393  } else $fdoc = new DocRead($dbaccess);
394  $tsqlfields = array_merge($fdoc->fields, $fdoc->sup_fields);
395  $maintable = '';
396  if ($join) {
397  if (preg_match("/from\s+([a-z0-9]*)/", $qsql, $reg)) {
398  $maintable = $reg[1];
399  $if = 0;
400  if ($maintable) {
401  foreach ($tsqlfields as $kf => $vf) {
402  if ($if++ > 0) $tsqlfields[$kf] = $maintable . '.' . $vf;
403  }
404  }
405  }
406  }
407  $maintabledot = ($maintable) ? $maintable . '.' : '';
408  $sqlfields = implode(", ", $tsqlfields);
409  if ($userid > 1) { // control view privilege
410  $qsql.= " and (${maintabledot}profid <= 0 or hasviewprivilege($userid, ${maintabledot}profid))";
411  // no compute permission here, just test it
412  $qsql = str_replace("* from ", "$sqlfields from ", $qsql);
413  } else {
414 
415  $qsql = str_replace("* from ", "$sqlfields from ", $qsql);
416  }
417  if ((!$distinct) && strstr($qsql, "distinct")) $distinct = true;
418  if ($start == "") $start = "0";
419  if ($distinct) {
420  if ($join) {
421  $qsql.= " ORDER BY $maintable.initid, $maintable.id desc";
422  } else {
423  $qsql.= " ORDER BY initid, id desc";
424  }
425  if (!$isgroup) $qsql.= " LIMIT $slice OFFSET $start";
426  } else {
427  if (($fromid == "") && $orderby == "") $orderby = "title";
428  elseif (substr($qsql, 0, 12) == "select doc.*") $orderby = "title";
429  if ($orderby == "" && (!$isgroup)) $qsql.= " LIMIT $slice OFFSET $start;";
430  else {
431  if ($orderby[0] == '-') $orderby = substr($orderby, 1) . " desc";
432  if (!$isgroup) $qsql.= " ORDER BY $orderby LIMIT $slice OFFSET $start;";
433  }
434  }
435  } else {
436  // families
437  if ($userid > 1) { // control view privilege
438  $qsql.= " and (profid <= 0 or hasviewprivilege($userid, profid))";
439  // and get permission
440  $qsql = str_replace("* from ", "* ,getuperm($userid,profid) as uperm from ", $qsql);
441  }
442  $qsql.= " ORDER BY $orderby LIMIT $slice OFFSET $start;";
443  }
444  if ($fromid != "") {
445  if ($fromid == - 1) {
446  include_once "FDL$GEN/Class.DocFam.php";
447  $fromid = "Fam";
448  } else {
449  $fromid = abs($fromid);
450  if ($fromid > 0) {
451  $GEN = getGen($dbaccess);
452  include_once "FDL$GEN/Class.Doc$fromid.php";
453  }
454  }
455  }
456  }
457  if (count($tqsql) > 0) {
458  if (count($tqsql) == 1) {
459  $query = new QueryDb($dbaccess, "Doc$fromid");
460  $mb = microtime();
461  $tableq = $query->Query(0, 0, $qtype, $tqsql[0]);
462  } else {
463  $usql = implode($tqsql, " union ");
464  if ($orderby) $usql.= " ORDER BY $orderby LIMIT $slice OFFSET $start;";
465  else $usql.= " LIMIT $slice OFFSET $start;";
466 
467  $query = new QueryDb($dbaccess, "Doc");
468  $mb = microtime();
469  $tableq = $query->Query(0, 0, $qtype, $usql);
470  }
471 
472  if ($query->nb > 0) {
473  if ($qtype == "ITEM") {
474  $tretdocs[] = $tableq;
475  } else $tretdocs = array_merge($tretdocs, $tableq);
476  }
477  // print "<HR><br><div style=\"border:red 1px inset;background-color:lightyellow;color:black\">".$query->LastQuery; print " - $qtype<B> [".$query->nb.']'.sprintf("%.03fs",microtime_diff(microtime(),$mb))."</B><b style='color:red'>".$query->basic_elem->msg_err."</b></div>";
478  if ($query->basic_elem->msg_err != "") {
479  addLogMsg($query->basic_elem->msg_err, 200);
480  addLogMsg(array(
481  "query" => $query->LastQuery,
482  "err" => $query->basic_elem->msg_err
483  ));
484  // print_r2(array_pop(debug_backtrace()));
485 
486  }
487  if ($debug !== null) {
488  $debug["count"] = $query->nb;
489  $debug["query"] = $query->LastQuery;
490  $debug["error"] = $query->basic_elem->msg_err;
491  $debug["delay"] = sprintf("%.03fs", microtime_diff(microtime() , $mb));
492  if ($debug["log"]) {
493  addLogMsg($query->basic_elem->msg_err, 200);
494  addLogMsg($debug);
495  }
496  } elseif ($query->basic_elem->msg_err != "") {
497  $debug["query"] = $query->LastQuery;
498  $debug["error"] = $query->basic_elem->msg_err;
499  addLogMsg($debug);
500  }
501  }
502  }
503 
504  reset($tretdocs);
505 
506  return ($tretdocs);
507  }
508  /**
509  * optimization for getChildDoc
510  * @param int $limit if -1 no limit
511  * @param bool $reallylimit if false don't return false if limit is reached
512  */
513  function getFldDoc($dbaccess, $dirid, $sqlfilters = array() , $limit = 100, $reallylimit = true)
514  {
515 
516  if (is_array($dirid)) {
517  $sqlfld = GetSqlCond($dirid, "dirid", true);
518  } else {
519  $sqlfld = "fld.dirid=$dirid";
520  }
521 
522  $mc = microtime();
523 
524  $q = new QueryDb($dbaccess, "QueryDir");
525  $q->AddQuery($sqlfld);
526  $q->AddQuery("qtype='S'");
527 
528  if ($limit > 0) {
529  $tfld = $q->Query(0, $limit + 1, "TABLE");
530  // use always this mode because is more quickly
531  if (($reallylimit) && ($q->nb > $limit)) return false;
532  } else {
533  $tfld = $q->Query(0, $limit + 1, "TABLE");
534  }
535  $t = array();
536  if ($q->nb > 0) {
537  foreach ($tfld as $k => $v) {
538  $t[$v["childid"]] = getLatestTDoc($dbaccess, $v["childid"], $sqlfilters, ($v["doctype"] == "C") ? -1 : $v["fromid"]);
539 
540  if ($t[$v["childid"]] == false) unset($t[$v["childid"]]);
541  elseif ($t[$v["childid"]]["archiveid"]) unset($t[$v["childid"]]);
542  else {
543  if (($t[$v["childid"]]["uperm"] & (1 << POS_VIEW)) == 0) { // control view
544  unset($t[$v["childid"]]);
545  }
546  }
547  }
548  }
549  uasort($t, "sortbytitle");
550  // print "<HR><br><div style=\"border:red 1px inset;background-color:orange;color:black\">"; print " - getFldDoc $dirid [nbdoc:".count($tfld)."]<B>".microtime_diff(microtime(),$mc)."</B></div>";
551  return $t;
552  }
553  function sortbytitle($td1, $td2)
554  {
555  return strcasecmp($td1["title"], $td2["title"]);
556  }
557  /**
558  * optimization for getChildDoc in case of grouped searches
559  * not used
560  */
561  function getMSearchDoc($dbaccess, $dirid, $start = "0", $slice = "ALL", $sqlfilters = array() , $userid = 1, $qtype = "LIST", $fromid = "", $distinct = false, $orderby = "title", $latest = true)
562  {
563 
564  $sdoc = new_Doc($dbaccess, $dirid);
565 
566  $tidsearch = $sdoc->getTValue("SEG_IDCOND");
567  $tdoc = array();
568  foreach ($tidsearch as $k => $v) {
569  $tdoc = array_merge(getChildDoc($dbaccess, $v, $start, $slice, $sqlfilters, $userid, $qtype, $fromid, $distinct, $orderby, $latest) , $tdoc);
570  }
571  return $tdoc;
572  }
573  /**
574  * return array of documents
575  *
576  * based on {@see getChildDoc()} it return document with enum attribute condition
577  * return document which the $aid attribute has the value $kid
578  *
579  * @param string $dbaccess database specification
580  * @param string $famname internal name of family document
581  * @param string $aid the attribute identificator
582  * @param string $kid the key for enum value to search
583  * @param string $name additionnal filter on the title
584  * @param array $sqlfilters array of sql filter
585  * @param int $limit max document returned
586  * @param string $qtype LIST|TABLE the kind of return : list of object or list or values array
587  * @param int $userid the current user id
588  * @return array/Doc
589  */
590  function getKindDoc($dbaccess, $famname, $aid, $kid, $name = "", // filter on title
591  $sqlfilter = array() , $limit = 100, $qtype = "TABLE", $userid = 0)
592  {
593 
594  global $action;
595 
596  if ($userid == 0) $userid = $action->user->id;
597 
598  $famid = getFamIdFromName($dbaccess, $famname);
600  // searches for all fathers kind
601  $a = $fdoc->getAttribute($aid);
602  if ($a) {
603  $tkids = array();;
604  $enum = $a->getEnum();
605  while (list($k, $v) = each($enum)) {
606  if (in_array($kid, explode(".", $k))) {
607  $tkids[] = substr($k, strrpos("." . $k, '.'));
608  }
609  }
610 
611  if ($a->type == "enum") {
612  if ($a->repeat) {
613  $sqlfilter[] = "in_textlist($aid,'" . implode("') or in_textlist($aid,'", $tkids) . "')";
614  } else {
615  $sqlfilter[] = "$aid='" . implode("' or $aid='", $tkids) . "'";
616  }
617  }
618  }
619 
620  if ($name != "") $sqlfilter[] = "title ~* '$name'";
621 
622  return getChildDoc($dbaccess, 0, 0, $limit, $sqlfilter, $userid, "TABLE", getFamIdFromName($dbaccess, $famname) , false, "title");
623  }
624  function sqlval2array($sqlvalue)
625  {
626  // return values in comprehensive structure
627  $rt = array();
628  if ($sqlvalue != "") {
629  $vals = explode("][", substr($sqlvalue, 1, -1));
630  while (list($k1, $v1) = each($vals)) {
631  list($aname, $aval) = explode(";;", $v1);
632  $rt[$aname] = $aval;
633  }
634  }
635  return $rt;
636  }
637  /**
638  * query to find child directories (no recursive - only in the specified folder)
639  * @param string $dbaccess database specification
640  * @param int $dirid the id of folder where search subfolders
641  */
642  function getChildDirId($dbaccess, $dirid)
643  {
644  $tableid = array();
645 
646  $tdir = getChildDoc($dbaccess, $dirid, "0", "ALL", array() , $userid, "TABLE", 2);
647 
648  foreach ($tdir as $k => $v) {
649  $tableid[] = $v["id"];
650  }
651 
652  return ($tableid);
653  }
654  // --------------------------------------------------------------------
655 
656  /**
657  * return array of subfolder id until sublevel 2 (RECURSIVE)
658  *
659  * @param string $dbaccess database specification
660  * @param int $dirid the id of folder where search subfolders
661  * @param array $rchilds use for recursion (dont't set anything)
662  * @param int $level use for recursion (dont't set anything)
663  * @param int $levelmax max recursion level (default 2)
664  * @return array/int
665  * @see getChildDir()
666  */
667  function getRChildDirId($dbaccess, $dirid, $rchilds = array() , $level = 0, $levelmax = 2)
668  {
669  global $action;
670 
671  if ($level > $levelmax) {
672  // $action->addWarningMsg("getRChildDirId::Max dir deep [$level levels] reached");
673  return ($rchilds);
674  }
675 
676  $rchilds[] = $dirid;
677 
678  $childs = getChildDirId($dbaccess, $dirid, true);
679 
680  if (count($childs) > 0) {
681  foreach ($childs as $k => $v) {
682  if (!in_array($v, $rchilds)) {
683  $t = array_merge($rchilds, getRChildDirId($dbaccess, $v, $rchilds, $level + 1, $levelmax));
684  if (is_array($t)) $rchilds = array_values(array_unique($t));
685  }
686  }
687  }
688  return ($rchilds);
689  }
690 
691  function isInDir($dbaccess, $dirid, $docid)
692  {
693  // return true id docid is in dirid
694  $query = new QueryDb($dbaccess, "QueryDir");
695  $query->AddQuery("dirid=" . $dirid);
696  $query->AddQuery("childid=" . $docid);
697 
698  $query->Query(0, 0, "TABLE");
699  return ($query->nb > 0);
700  }
701  /**
702  * return true if dirid has one or more child dir
703  * @param string $dbaccess database specification
704  * @param int $dirid folder id
705  * @return bool
706  */
707  function hasChildFld($dbaccess, $dirid, $issearch = false)
708  {
709 
710  if ($issearch) {
711  $query = new QueryDb($dbaccess, "QueryDir");
712  $query->AddQuery("qtype='M'");
713  $query->AddQuery("dirid=$dirid");
714  $list = $query->Query(0, 1, "TABLE");
715 
716  if ($list) {
717  $oquery = $list[0]["query"];
718  if (preg_match("/select (.+) from (.+)/", $oquery, $reg)) {
719  if (preg_match("/doctype( *)=/", $reg[2], $treg)) return false; // do not test if special doctype searches
720  $nq = sprintf("select count(%s) from %s and ((doctype='D')or(doctype='S')) limit 1", $reg[1], $reg[2]);
721  $count = $query->Query(0, 0, "TABLE", $nq);
722  if (($query->nb > 0) && (is_array($count)) && ($count[0]["count"] > 0)) return true;
723  }
724  }
725  } else {
726  $qfld = new QueryDb($dbaccess, "QueryDir");
727  $qfld->AddQuery("qtype='S'");
728  $qfld->AddQuery("fld.dirid=$dirid");
729  $qfld->AddQuery("doctype='D' or doctype='S'");
730  $lq = $qfld->Query(0, 1, "TABLE");
731 
732  $qids = array();
733  if (!is_array($lq)) return false;
734  return ($qfld->nb > 0);
735  }
736  return false;
737  }
738  /**
739  * return families with the same usefor
740  * @param string $dbaccess database specification
741  * @param int $userid identificator of the user
742  * @param int $classid the reference family to find by usefor (if 0 all families) can be an array of id
743  * @param string $qtype [TABLE|LIST] use TABLE if you can because LIST cost too many memory
744  * @return array the families
745  */
746  function GetClassesDoc($dbaccess, $userid, $classid = 0, $qtype = "LIST")
747  // --------------------------------------------------------------------
748 
749  {
750  $query = new QueryDb($dbaccess, "DocFam");
751 
752  $query->AddQuery("doctype='C'");
753 
754  if (is_array($classid)) {
755  foreach ($classid as $fid) {
756  $tcdoc = getTDoc($dbaccess, $fid);
757  $use[] = $tcdoc["usefor"];
758  }
759  $query->AddQuery(GetSqlCond($use, "usefor"));
760  } else if ($classid > 0) {
761  $cdoc = new DocFam($dbaccess, $classid);
762  $query->AddQuery("usefor = '" . $cdoc->usefor . "'");
763  }
764 
765  if ($userid > 1) $query->AddQuery("hasviewprivilege(" . $userid . ",docfam.profid)");
766 
767  if ($qtype == "TABLE") {
768  $t = $query->Query(0, 0, $qtype);
769  foreach ($t as $k => $v) {
770  $t[$k]["title"] = ucfirst(getFamTitle($v));
771  }
772  usort($t, "cmpfamtitle");
773  return $t;
774  } else {
775  $query->order_by = "lower(title)";
776  return $query->Query(0, 0, $qtype);
777  }
778  }
779  function cmpfamtitle($a, $b)
780  {
781  return strcasecmp(unaccent($a["title"]) , unaccent($b["title"]));
782  }
783  /**
784  * return array of possible profil for profile type
785  *
786  * @param string $dbaccess database specification
787  * @param int $famid the id of family document
788  * @return array/Doc
789  * @see getChildDir()
790  */
791  function GetProfileDoc($dbaccess, $docid, $defProfFamId = "")
792  {
793  global $action;
794  $filter = array();
795 
797  $chdoc = $doc->GetFromDoc();
798  if ($defProfFamId == "") $defProfFamId = $doc->defProfFamId;
799 
800  $cond = GetSqlCond($chdoc, "dpdoc_famid");
801  if ($cond != "") $filter[] = "dpdoc_famid is null or (" . GetSqlCond($chdoc, "dpdoc_famid") . ")";
802  else $filter[] = "dpdoc_famid is null";
803  $filter[] = "fromid=" . $defProfFamId;
804  $tcv = getChildDoc($dbaccess, 0, 0, "ALL", $filter, $action->user->id, "TABLE", $defProfFamId);
805 
806  return $tcv;
807  }
808  /**
809  * get array of family id that the user can create interactivaly
810  *
811  * @param string $dbaccess database specification
812  * @param int $uid user identificator
813  * @param array restriction of this set of family id
814  * @return array of family identificators
815  */
816  function getFamilyCreationIds($dbaccess, $uid, $tfid = array())
817  {
818 
819  $query = new QueryDb($dbaccess, "DocFam");
820  if (count($tfid) > 0) {
821  $query->AddQuery(GetSqlCond($tfid, "id"));
822  }
823  $perm = (2 << (POS_CREATE - 1)) + (2 << (POS_ICREATE - 1));
824 
825  $query->AddQuery("((profid = 0) OR hasdocprivilege($uid, profid, $perm))");
826 
827  $l = $query->Query(0, 0, "TABLE");
828 
829  $lid = array();
830  if ($query->nb > 0) {
831  foreach ($l as $k => $v) {
832  $lid[] = $v["id"];
833  }
834  }
835  return $lid;
836  }
837  /**
838  * get array of document values from array od document id
839  * @param string $dbaccess database specification
840  */
841  function getDocsFromIds($dbaccess, $ids, $userid = 0)
842  {
843  $tdoc = array();
844  foreach ($ids as $k => $id) {
845  $tdoc1 = getTDoc($dbaccess, $id);
846  if ((($userid == 1) || controlTdoc($tdoc1, "view")) && ($tdoc1["doctype"] != 'Z')) $tdoc[$id] = $tdoc1;
847  }
848  return $tdoc;
849  }
850  /**
851  * get array of document values from array od document id
852  * @param string $dbaccess database specification
853  */
854  function getLatestDocsFromIds($dbaccess, $ids, $userid = 0)
855  {
856  $tdoc = array();
857  foreach ($ids as $k => $id) {
858  $tdoc1 = getLatestTDoc($dbaccess, $id);
859  if (($tdoc1 !== false) && (($userid == 1) || controlTdoc($tdoc1, "view")) && ($tdoc1["doctype"] != 'Z')) $tdoc[$id] = $tdoc1;
860  }
861  return $tdoc;
862  }
863  /**
864  * get array of document values from array od document id
865  * @param string $dbaccess database specification
866  * @param string $ids array of init id -only initid-
867  * @param string $userid the user where search visibility
868  */
869  function getVisibleDocsFromIds($dbaccess, $ids, $userid)
870  {
871 
872  $query = new QueryDb($dbaccess, "DocRead");
873  $query->AddQuery("initid in (" . implode(",", $ids) . ')');
874  $query->AddQuery("locked != -1");
875  if ($userid > 1) $query->AddQuery("hasviewprivilege(" . $userid . ",profid)");
876 
877  $tdoc = $query->Query(0, 0, "TABLE");
878 
879  return $tdoc;
880  }
881  /**
882  * return true for optimization select
883  * @param string $dbaccess database specification
884  * @param int $id identificator of the document family
885  *
886  * @return int false if error occured
887  */
889  {
890  if (!is_numeric($id)) $id = getFamIdFromName($dbaccess, $id);
891  $id = abs(intval($id));
892  if ($id == 0) return false;
894  $fromid = false;
895  $result = pg_query($dbid, "select id from docfam where id=$id and usedocread=1");
896  if (pg_numrows($result) > 0) {
897  $result = pg_query($dbid, "select fromid from docfam where fromid=$id;");
898  if (pg_numrows($result) > 0) {
899  return true;
900  }
901  }
902 
903  return false;
904  }
905 ?>
← centre documentaire © anakeen - published under CC License - Dynacase