Core  3.2
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Class.Collection.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @package FDL
5 */
6 /**
7  * Document Object Definition
8  *
9  * @author Anakeen
10  * @version $Id: $
11  * @package FDL
12  */
13 /**
14  */
15 include_once ("FDL/Class.Document.php");
16 include_once ("FDL/Lib.FullSearch.php");
17 /**
18  * Document Class
19  *
20  */
22 {
23  /**
24  * @var Doc|Dir
25  */
26  protected $doc;
27  private $completeProperties = false;
28  private $contentOnlyValue = true;
29  private $contentOrderBy = '';
30  private $contentSlice = 'ALL';
31  private $contentStart = 0;
32  private $contentKey = '';
33  private $contentKeyMode = '';
34  private $contentSearchProperty = '';
35  private $contentFilter = '';
36  private $contentVerifyHasChild = false;
37  private $contentRecursiveLevel = 0;
38  private $contentMap = null;
39  private $onlyAttributes = null;
40 
41  private $debug = false;
42  /**
43  * Internal document list
44  * @var DocumentList
45  */
46  private $documentList = null;
47  /**
48  * set true to add extra info about query
49  * info are set in info field
50  * @param bool $debug
51  */
52  public function setDebugMode($debug)
53  {
54  $this->debug = (!empty($debug));
55  }
56 
58  {
59  $this->completeProperties = $value;
60  }
61  public function returnsOnlyAttributes(array $value)
62  {
63  $this->onlyAttributes = $value;
64  }
65  public function setContentOnlyValue($value)
66  {
67  $this->contentOnlyValue = $value;
68  }
69  public function setContentOrderBy($value)
70  {
71  $this->contentOrderBy = $value;
72  }
73  public function setContentSlice($value)
74  {
75  $this->contentSlice = $value;
76  }
77  public function setContentStart($value)
78  {
79  $this->contentStart = $value;
80  }
81  public function setContentKey($value)
82  {
83  $this->contentKey = $value;
84  }
85  public function setContentKeyMode($value)
86  {
87  $this->contentKeyMode = $value;
88  }
90  {
91  $this->contentSearchProperty = $value;
92  }
93  public function setContentFilter($value)
94  {
95  $this->contentFilter = $value;
96  }
98  {
99  $this->contentVerifyHasChild = $value;
100  }
102  {
103  $this->contentRecursiveLevel = intval($value);
104  }
105  public function setContentMap($callback)
106  {
107  $this->contentMap = $callback;
108  }
109  /**
110  * return documents list
111  */
112  public function getContent()
113  {
114  if ($this->documentList) return $this->getDocumentListContent();
115  else return $this->getCollectionContent();
116  }
117  /**
118  * return documents list
119  * @param boolean $onlyvalues
120  * @param boolean $completeprop
121  * @param string $filter
122  * @param int $start
123  * @param int $slice
124  * @param string $orderby
125  * @param boolean $verifyhaschild
126  * @return array of raw documents
127  */
128  public function getCollectionContent()
129  {
130  include_once ("FDL/Class.SearchDoc.php");
131  $s = new SearchDoc($this->dbaccess);
132  $s->useCollection($this->getProperty('initid'));
133  if ($this->contentOrderBy) $s->orderby = $this->contentOrderBy;
134  $s->setSlice($this->contentSlice);
135  $s->setStart($this->contentStart);
136  $s->excludeConfidential();
137  $s->recursiveSearch = ($this->contentRecursiveLevel > 0);
138  $s->folderRecursiveLevel = $this->contentRecursiveLevel;
139  $err = '';
140  $out = new stdClass();
141  $content = array();
142  if ($s->dirid > 0) {
143  $s->setObjectReturn();
144  $key = $this->contentKey;
145  if ($key) {
146  if ($this->contentKeyMode == "word") {
147  $sqlfilters = array();
148  $fullorderby = '';
149  $keyword = '';
150  DocSearch::getFullSqlFilters($key, $sqlfilters, $fullorderby, $keyword);
151  foreach ($sqlfilters as $vfilter) $s->addFilter($vfilter);
152  if (!$s->orderby) $s->orderby = $fullorderby;
153  } else {
154  $s->addFilter("%s ~* '%s'", ($this->contentSearchProperty ? $this->contentSearchProperty : "svalues") , $key);
155  }
156  }
157  if ($this->contentFilter) {
158  if (is_string($this->contentFilter)) {
159  $lfilter = strtolower($this->contentFilter);
160  if ((!strstr($lfilter, '--')) && (!strstr($lfilter, ';')) && (!strstr($lfilter, 'insert')) && (!strstr($lfilter, 'alter')) && (!strstr($lfilter, 'delete')) && (!strstr($lfilter, 'update'))) {
161  // try to prevent sql injection
162  $s->addFilter($this->contentFilter);
163  }
164  } elseif (is_object($this->contentFilter)) {
165  $ofamid = 0;
166  $sfilter = '';
167  $err = $this->doc->object2SqlFilter($this->contentFilter, $ofamid, $sfilter);
168  $this->setError($err);
169  if ($ofamid) $s->fromid = $ofamid;
170  $s->addFilter($sfilter);
171  }
172  }
173  if ($this->onlyAttributes !== null) {
174  $s->returnsOnly(array_merge(array_keys(Doc::$infofields) , $this->onlyAttributes));
175  }
176  if ($err == "") {
177  $s->search();
178  if ($this->debug) $out->info = $s->getSearchInfo();
179  $err = $s->getError();
180  if ($err) {
181  $this->setError($out->info["error"]);
182  } else {
183  $dl = $s->getDocumentList();
184  $this->useDocumentList($dl);
185  return $this->getDocumentListContent();
186  }
187  }
188  } else $this->error = sprintf(_("document not initialized"));
189  $out->error = $this->error;
190 
191  foreach ($content as & $v) {
192  $out->content[] = $v;
193  }
194  $out->slice = $s->slice;
195  $out->start = $s->start;
196  $out->date = date('Y-m-d H:i:s');
197 
198  return $out;
199  }
200  /**
201  * use DocumentList instead a folder
202  * @param DocumentList $dl
203  * @return void
204  */
205  public function useDocumentList(DocumentList & $dl)
206  {
207  $this->documentList = $dl;
208  }
209  /**
210  * return documents list
211  * @param boolean $onlyvalues
212  * @param boolean $completeprop
213  * @return array of raw documents
214  */
215  private function getDocumentListContent()
216  {
217 
218  $dl = $this->documentList;
219  $content = null;
220  $out = new stdClass();
221  if (!$dl) {
222  $this->setError("document list uninitialized");
223  } else {
224  $content = array();
225  $s = $dl->getSearchDocument();
226  if ($this->contentMap) $dl->listMap($this->contentMap);
227  if ($this->debug) $out->info = $s->getSearchInfo();
228  $out->slice = $s->slice;
229  $out->start = $s->start;
230  if (isset($out->info["error"])) $this->setError($out->info["error"]);
231  $tmpdoc = new Fdl_Document();
232  if ($this->onlyAttributes !== null) {
233  $tmpdoc->usePartialDocument($this->onlyAttributes);
234  }
235  $kd = 0;
236  $verifyhaschild = $this->contentVerifyHasChild;
237  /*
238  * @var Doc $doc
239  */
240  foreach ($dl as $doc) {
241  $tmpdoc->affect($doc);
242  if (!$doc->isConfidential()) {
243  if ($verifyhaschild) {
244  $tmpdoc->setVolatileProperty("haschildfolder", hasChildFld($this->dbaccess, $tmpdoc->getProperty('initid') , ($doc->doctype == 'S')));
245  }
246  $content[$kd] = $tmpdoc->getDocument($this->contentOnlyValue, $this->completeProperties);
247  $kd++;
248  }
249  }
250 
251  $out->totalCount = $s->count();
252  if (($out->totalCount == $s->slice) || ($s->start > 0)) {
253  $s->slice = 'ALL';
254  $s->start = 0;
255  $s->reset();
256  $oc = $s->onlyCount();
257  if ($this->debug) $out->info["totalCount"] = $s->getSearchInfo();
258  if ($oc) $out->totalCount = $oc;
259  }
260  }
261  $out->error = $this->error;
262  $out->content = $content;
263  $out->date = date('Y-m-d H:i:s');
264  return $out;
265  }
266  /**
267  * return document list from a keyword and optionaly family identifier
268  * @param string $key
269  * @param string $mode search method : regexp or word
270  * @param int $famid filter on family
271  * @param object $filter additionnal filter
272  * @param int $start offset to start search (default is 0)
273  * @param int $slice number of document returned
274  * @param string $orderby order by property or attribute
275  * @param boolean $onlyvalues set to true is want return attribute definition also
276  * @param string $searchproperty property use where key is applied
277  * @param boolean $whl with highlight return also text including keyword. the keyword is between HTML B tag.
278  * @param boolean $verifyhaschild
279  * @return array of raw document
280  */
281  public function simpleSearch($key, $mode = "word", $famid = 0, $filter = "", $start = 0, $slice = 100, $orderby = "", $onlyvalues = true, $searchproperty = "svalues", $whl = false, $verifyhaschild = false)
282  {
283  include_once ("FDL/Class.SearchDoc.php");
284  static $sw = null;
285  $out = new stdClass();
286  $tfid = array();
287  $err = '';
288  $keyword = '';
289  if (strstr($famid, '|')) {
290  // multi family search
291  $tfamids = explode('|', $famid);
292  foreach ($tfamids as $fid) {
293  if (!is_numeric($fid)) $fid = getFamidFromName($this->dbaccess, $fid);
294  if ($fid > 0) $tfid[] = $fid;
295  }
296 
297  $famid = 0;
298  }
299  if (preg_match('/([\w:]*)\s?strict/', trim($famid) , $reg)) {
300  if (!is_numeric($reg[1])) $reg[1] = getFamIdFromName($this->dbaccess, $reg[1]);
301  $famid = '-' . $reg[1];
302  }
303  $s = new SearchDoc($this->dbaccess, $famid);
304  if ($key) {
305  if ($mode == "word") {
306  $sqlfilters = array();
307  $fullorderby = '';
308  $keyword = '';
309  DocSearch::getFullSqlFilters($key, $sqlfilters, $fullorderby, $keyword);
310  foreach ($sqlfilters as $vfilter) $s->addFilter($vfilter);
311  if (!$orderby) $orderby = $fullorderby;
312  } else {
313  $s->addFilter(sprintf("%s ~* '%s'", $searchproperty, $key));
314  }
315  }
316  if ($filter) {
317  if (is_string($filter)) {
318  $lfilter = strtolower($filter);
319  if ((!strstr($lfilter, '--')) && (!strstr($lfilter, ';')) && (!stristr($lfilter, 'insert')) && (!stristr($lfilter, 'alter')) && (!stristr($lfilter, 'delete')) && (!stristr($lfilter, 'update'))) {
320  // try to prevent sql injection
321  $s->addFilter($filter);
322  }
323  } elseif (is_object($filter)) {
324  /**
325  * @var \Dcp\Family\DSEARCH $sw
326  */
327  if (!$sw) {
328  $sw = createTmpDoc($this->dbaccess, "DSEARCH");
329  $sw->setValue("se_famid", $famid);
330  }
331  $ofamid = 0;
332  $sfilter = '';
333  $err = $sw->object2SqlFilter($filter, $ofamid, $sfilter);
334  $this->setError($err);
335  if ($ofamid) {
336  $s->fromid = $ofamid;
337  }
338  $s->addFilter($sfilter);
339  }
340  }
341  if ($err == "") {
342  if (count($tfid) > 0) $s->addFilter(getSqlCond($tfid, 'fromid', true));
343  $completeprop = false;
344  $content = array();
345  $s->slice = $slice;
346  $s->start = $start;
347  if ($orderby) $s->orderby = $orderby;
348  $s->setObjectReturn();
349  $s->excludeConfidential();
350  $s->search();
351  $info = $s->getSearchInfo();
352  $out->error = $info["error"];
353  if ($this->debug) $out->info = $info;
354 
355  if (!$out->error) {
356  /**
357  * @var \Dcp\Family\DSEARCH $ws
358  */
359  $ws = createTmpDoc($this->dbaccess, "DSEARCH");
360  $ws->setValue("ba_title", sprintf(_("search %s") , $key));
361  $ws->add();
362  $ws->addStaticQuery($s->getOriginalQuery());
363  $tmpdoc = new Fdl_Document($ws->id);
364  $out->document = $tmpdoc->getDocument(true, false);
365  $idx = 0;
366  if (!$keyword) $keyword = str_replace(" ", "|", $key);
367  while ($doc = $s->getNextDoc()) {
368  $tmpdoc->affect($doc);
369  if ($verifyhaschild) {
370  $tmpdoc->setVolatileProperty("haschildfolder", hasChildFld($this->dbaccess, $tmpdoc->getProperty('initid') , ($doc->doctype == 'S')));
371  }
372  $content[$idx] = $tmpdoc->getDocument($onlyvalues, $completeprop);
373  if ($whl) $content[$idx]['highlight'] = getHighlight($doc, $keyword);
374  $idx++;
375  }
376 
377  $out->totalCount = $s->count();
378  if (($out->totalCount == $slice) || ($start > 0)) {
379  $s->slice = 'ALL';
380  $s->start = 0;
381  $s->reset();
382  $out->totalCount = $s->onlyCount();
383  $info = $s->getSearchInfo();
384  if (!isset($out->delay)) {
385  $out->delay='';
386  }
387  $out->delay.= ' count:' . $info["delay"];
388  }
389  $out->content = $content;
390  }
391  } else {
392  $out->error = $err;
393  }
394  $out->slice = $slice;
395  $out->start = $start;
396  $out->date = date('Y-m-d H:i:s');
397  return $out;
398  }
399  /**
400  * return child families
401  * @param int $famid the family root
402  * @return array of families where $famid is an ancestor
403  */
404  public function getSubFamilies($famid, $controlcreate = false)
405  {
406  $out = new stdClass();
407  $fam = new_doc($this->dbaccess, $famid);
408  if (!$fam->isAlive()) {
409  $out->error = sprintf(_("data:family %s not alive") , $famid);
410  } elseif ($fam->doctype != 'C') {
411  $out->error = sprintf(_("data:document %s is not a family") , $famid);
412  } else {
413 
414  $content = array();
415  $fld = new Dir($this->dbaccess);
416  if (!is_numeric($famid)) $famid = getFamIdFromName($this->dbaccess, $famid);
417  $tfam = $fld->GetChildFam($famid, $controlcreate);
418  if (count($tfam) > 0) {
419  $tmpdoc = new Fdl_Document();
420  $onlyvalues = true;
421  $completeprop = false;
422  foreach ($tfam as $id => $rawfam) {
423  $fam->affect($rawfam);
424  $tmpdoc->affect($fam);
425  if (!$tmpdoc->error) {
426  $content[] = $tmpdoc->getDocument($onlyvalues, $completeprop);
427  }
428  }
429  }
430  $out->content = $content;
431  $out->totalCount = count($content);
432  }
433  return $out;
434  }
435  /**
436  * insert a document into folder
437  * @param int $docid the document identifier to insert to
438  * @return object with error or message field
439  */
440  public function insertDocument($docid)
441  {
442  $out = new stdClass();
443  if ($this->docisset()) {
444  $err = $this->doc->insertDocument($docid);
445  if ($err != "") {
446  $this->setError($err);
447  $out->error = $err;
448  } else {
449  $out->message = sprintf(_("document %d inserted") , $docid);
450  }
451  } else $out->error = sprintf(_("document not set"));
452  return $out;
453  }
454  /**
455  * unlink a document from folder
456  * @param int $docid the document identifier to unlink
457  * @return object with error or message field
458  */
460  {
461  $out = new stdClass();
462  if ($this->docisset()) {
463  $err = $this->doc->removeDocument($docid);
464  if ($err != "") {
465  $this->setError($err);
466  $out->error = $err;
467  } else {
468  $out->message = sprintf(_("document %d deleted") , $docid);
469  }
470  } else $out->error = sprintf(_("document not set"));
471  return $out;
472  }
473  /**
474  * unlink several documents from folder
475  * @param object $selection selection of document
476  * @return object with error or message field
477  */
478  function unlinkDocuments($selection)
479  {
480  $out = new stdClass();
481  include_once ("DATA/Class.DocumentSelection.php");
482  $os = new Fdl_DocumentSelection($selection);
483  $ids = $os->getIdentificators();
484 
485  if ($this->docisset()) {
486  $out->notunlinked = array();
487  $out->unlinked = array();
488  $err = $this->doc->canModify();
489  if ($err != "") {
490  $out->error = $err;
491  } else {
492  foreach ($ids as $docid) {
493  $err = $this->doc->removeDocument($docid);
494  if ($err != "") {
495  $out->notunlinked[$docid] = $err;
496  } else {
497  $out->unlinked[$docid] = sprintf(_("document %d unlinked") , $docid) . "\n";
498  }
499  }
500  $out->unlinkedCount = count($out->unlinked);
501  $out->notUnlinkedCount = count($out->notunlinked);
502  }
503  } else $out->error = sprintf(_("document not set"));
504  return $out;
505  }
506  /**
507  * unlink all documents from folder
508  * @param object $selection selection of document
509  * @return object with error or message field
510  */
512  {
513  $out = new stdClass();
514  if ($this->docisset()) {
515  $out->error = "";
516  $err = $this->doc->canModify();
517  if ($err != "") {
518  $out->error = $err;
519  } else {
520  $out->error = $this->doc->clear();
521  }
522  } else $out->error = sprintf(_("document not set"));
523  return $out;
524  }
525  /**
526  * move several documents from folder
527  * @param object $selection selection of document
528  * @return object with error or message field
529  */
530  function moveDocuments($selection, $targetId)
531  {
532  $out = new stdClass();
533  include_once ("DATA/Class.DocumentSelection.php");
534  $os = new Fdl_DocumentSelection($selection);
535  $ids = $os->getIdentificators();
536 
537  if ($this->docisset()) {
538  $out->notmoved = array();
539  $out->moved = array();
540  $err = $this->doc->canModify();
541  if ($err == "") {
542  /*
543  * @var Dir $targetDoc
544  */
545  $targetDoc = new_doc($this->dbaccess, $targetId);
546  if ($targetDoc->isAlive()) {
547  if ($targetDoc->defDoctype != 'D') $err = sprintf(_("target folder [%s] is not a folder") , $targetDoc->getTitle());
548  else {
549  $err = $targetDoc->canModify();
550  }
551  } else {
552  $err = sprintf(_("target folder [%s] is not set") , $targetId);
553  }
554  if ($err != "") {
555  $out->error = $err;
556  } else {
557  foreach ($ids as $docid) {
558  $err = $this->doc->moveDocument($docid, $targetDoc->initid);
559  if ($err != "") {
560  $out->notmoved[$docid] = $err;
561  } else {
562  $out->moved[$docid] = sprintf(_("document %d moved") , $docid) . "\n";
563  }
564  }
565  $out->movedCount = count($out->moved);
566  $out->notMovedCount = count($out->notmoved);
567  }
568  } else {
569  $out->error = $err;
570  }
571  } else $out->error = sprintf(_("document not set"));
572  return $out;
573  }
574  /**
575  * insert several documents to folder
576  * @param object $selection selection of document
577  * @return object with error or message field
578  */
579  function insertDocuments($selection)
580  {
581  $out = new stdClass();
582  include_once ("DATA/Class.DocumentSelection.php");
583  $os = new Fdl_DocumentSelection($selection);
584  if ($this->docisset()) {
585  $tdocs = $os->getRawDocuments();
586  $out->notinserted = array();
587  $out->inserted = array();
588  $err = $this->doc->insertMultipleDocuments($tdocs, "latest", false, $out->inserted, $out->notinserted);
589  $out->insertedCount = count($out->inserted);
590  $out->notInsertedCount = count($out->notinserted);
591  $out->error = $err;
592  } else $out->error = sprintf(_("document not set"));
593  return $out;
594  }
595 
597  {
598  if ($this->docisset()) {
599  if (method_exists($this->doc, "getAuthorizedFamilies")) {
600 
601  return array(
602  "restriction" => $this->doc->hasNoRestriction() ? false : true,
603  "families" => $this->doc->getAuthorizedFamilies()
604  );
605  }
606  }
607  return null;
608  }
609 }
610 ?>
static $infofields
Definition: Class.Doc.php:105
setContentOrderBy($value)
static getFullSqlFilters($keyword, &$sqlfilters, &$sqlorder, &$fullkeys)
insertDocuments($selection)
setContentVerifyHasChild($value)
if($famId) $s
setContentFilter($value)
moveDocuments($selection, $targetId)
unlinkDocuments($selection)
getHighlight(&$doc, $keys)
$docid
Definition: cleanFamily.php:13
hasChildFld($dbaccess, $dirid, $issearch=false)
Definition: Lib.Dir.php:862
setContentKeyMode($value)
setContentSearchProperty($value)
setContentRecursiveLevel($value)
returnsOnlyAttributes(array $value)
setContentOnlyValue($value)
getFamIdFromName($dbaccess, $name)
getSubFamilies($famid, $controlcreate=false)
$keyword
setContentMap($callback)
$info
Definition: geticon.php:30
setContentCompleteProperties($value)
createTmpDoc($dbaccess, $fromid, $defaultvalue=true)
if($file) if($subject==""&&$file) if($subject=="") $err
$value
getProperty($idprop)
useDocumentList(DocumentList &$dl)
← centre documentaire © anakeen