Offline Server  1.6
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Method.OfflineDomain.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  * Offline domain
9  *
10  * @author Anakeen
11  * @version $Id: $
12  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
13  * @package OFFLINE
14  */
15 /**
16  */
17 /*
18  * @begin-method-ignore
19  * this part will be deleted when construct document class until end-method-ignore
20 */
21 /**
22  * offline domain fonctionalities
23  *
24  */
25 class _OFFLINEDOMAIN extends Dir
26 {
27  /*
28  * @end-method-ignore
29  */
30 
31  private $hookObject = null;
32  /**
33  * Add new supported family in offline domain
34  *
35  * @param string $familyId family identificator
36  * @param boolean $includeSubFamily set to false to not include sub families
37  *
38  * @return string error message (empty string if no errors)
39  */
40  public function addFamily($familyId, $includeSubFamily = true)
41  {
42  $err = '';
43  if ($familyId) {
44  $fam = new_doc($this->dbaccess, $familyId);
45  if ($fam->isAlive()) {
46  if ($fam->doctype == "C") {
47  $famids = $this->getTValue("off_families");
48  $subfamids = $this->getTValue("off_subfamilies");
49  $key = array_search($fam->id, $famids);
50  if ($key === false) {
51  $famids[] = $fam->id;
52  $subfamids[] = ($includeSubFamily ? 'yes' : 'no');
53  } else {
54  $famids[$key] = $fam->id;
55  $subfamids[$key] = ($includeSubFamily ? 'yes' : 'no');
56  }
57  $err.= $this->setValue("off_families", $famids);
58  $err.= $this->setValue("off_subfamilies", $subfamids);
59  if (!$err) $err = $this->store();
60  } else {
61  $err.= sprintf("not a family %s [%d] not alive", $fam->getTitle() , $fam->id);
62  }
63  } else {
64  $err.= sprintf("no family %s [%d] not alive", $fam->getTitle() , $fam->id);
65  }
66  } else {
67  $err.= sprintf("no family given");
68  }
69  if ($err) {
70  AddLogMsg(__METHOD__ . $err);
71  }
72  return $err;
73  }
74 
75  public function addFollowingStates(Doc & $doc)
76  {
77  if (!$doc->wid) {
78  return false;
79  }
80  if (($doc->lockdomainid == $this->id) && ($doc->locked == $this->getSystemUserId())) {
81  $wdoc = new_doc($this->dbaccess, $doc->wid);
82  /* @var $wdoc WDoc */
83  if (!$wdoc->isAlive()) {
84  return false;
85  }
86  if (!$this->canUseWorkflow($doc->fromid)) {
87  return false;
88  }
89  try {
90  $wdoc->Set($doc);
91  $fs = $wdoc->getFollowingStates(true);
92  $fsout = array();
93  foreach ($fs as $state) {
94  $tr = $wdoc->getTransition($doc->state, $state);
95  $fsout[$state] = array(
96  "label" => _($state) ,
97  "color" => $wdoc->getColor($state) ,
98  "activity" => $wdoc->getActivity($state) ,
99  "transition" => isset($tr["id"]) ? _($tr["id"]) : sprintf(_("OFFLINE:Transition non authorized from %s to %s") , _($doc->state) , _($state))
100  );
101  }
102  $this->addExtraData($doc, "followingStates", $fsout);
103  return true;
104  }
105  catch(Exception $e) {
106  AddLogMsg(__METHOD__ . $e->getMessage());
107  }
108  }
109  return false;
110  }
111 
112  public function addExtraData(Doc & $doc, $key, $value)
113  {
114  /** @noinspection PhpUndefinedFieldInspection */
115  $doc->addfields["pullextradata"] = "pullextradata";
116  /** @noinspection PhpUndefinedFieldInspection */
117  $doc->pullextradata[$key] = $value;
118  }
119  /**
120  * remove supported family in offline domain
121  * @param string $familyId family identificator
122  * @return string error message (empty string if no errors)
123  */
124  public function removeFamily($familyId)
125  {
126  $err = '';
127  $fam = new_doc($this->dbaccess, $familyId);
128  if ($fam->isAlive()) {
129  if ($fam->doctype == "C") {
130  $famids = $this->getTValue("off_families");
131  $subfamids = $this->getTValue("off_subfamilies");
132  $key = array_search($fam->id, $famids);
133  if ($key !== false) {
134  unset($famids[$key]);
135  unset($subfamids[$key]);
136  }
137  $err = $this->setValue("off_families", $famids);
138  $err.= $this->setValue("off_subfamilies", $subfamids);
139  if (!$err) $err = $this->store();
140  } else {
141  $err = sprintf("not a family %s [%d] not alive", $fam->getTitle() , $fam->id);
142  }
143  }
144  return $err;
145  }
146  /**
147  * Add new supported family in offline domain
148  *
149  * @param string $familyId family identificator
150  * @param boolean $includeSubFamily set to false to not include sub families
151  * @param int $maskId id of a specific mask for family 0 means no mask
152  *
153  * @return string error message (empty string if no errors)
154  */
155  public function setFamilyMask($familyId, $includeSubFamily = true, $maskId)
156  {
157  $err = '';
158  if ($familyId) {
159  $fam = new_doc($this->dbaccess, $familyId);
160  if ($fam->isAlive()) {
161  if ($fam->doctype == "C") {
162  $domainFamily = $this->getFamDoc();
163  if ($maskId) {
164  $newMask = new_doc($this->dbaccess, $maskId);
165  /* @var $newMask _MASK */
166  /** @noinspection PhpUndefinedFieldInspection */
167  if ((!$newMask->isAlive()) || ($newMask->fromname != 'MASK')) {
168  $err = sprintf("not a mask %s", $maskId);
169  }
170  }
171 
172  if (!$err) {
173  $maskId = isset($newMask) ? $newMask->id : 0;
174  $famids = $domainFamily->getParamTValue("off_mskfamilies");
175  $subfamids = $domainFamily->getParamTValue("off_msksubfamilies");
176  $masks = $domainFamily->getParamTValue("off_masks");
177  $key = array_search($fam->id, $famids);
178  if ($key === false) {
179  if ($maskId > 0) {
180  $famids[] = $fam->id;
181  $subfamids[] = ($includeSubFamily ? 'yes' : 'no');
182  $masks[] = $maskId;
183  }
184  } else {
185  if ($maskId > 0) {
186  $famids[$key] = $fam->id;
187  $subfamids[$key] = ($includeSubFamily ? 'yes' : 'no');
188  $masks[$key] = $maskId;
189  } else {
190  unset($famids[$key]);
191  unset($subfamids[$key]);
192  unset($masks[$key]);
193  }
194  }
195  $domainFamily->setParam("off_mskfamilies", $famids);
196  $domainFamily->setParam("off_msksubfamilies", $subfamids);
197  $domainFamily->setParam("off_masks", $masks);
198  if (!$err) {
199  $err = $domainFamily->modify();
200  }
201  }
202  } else {
203  $err = sprintf("not a family %s [%d] not alive", $fam->getTitle() , $fam->id);
204  }
205  } else {
206 
207  $err = sprintf("no family %s [%d] not alive", $fam->getTitle() , $fam->id);
208  }
209  } else {
210  $err = sprintf("no family given");
211  }
212  return $err;
213  }
214  /**
215  * return families restriction
216  * @return array of families identificator
217  */
218  public function getFamilies()
219  {
220  $famids = $this->getTValue("off_allfamilies");
221  if (count($famids) == 0) {
222  $families = $this->getAValues("off_t_families");
223  $fams = array();
224  foreach ($families as $currentFamily) {
225  if ($currentFamily["off_families"]) {
226  $fams[] = $currentFamily["off_families"];
227  if ($currentFamily["off_subfamilies"] != "no") {
228  $fams = array_merge(array_keys($this->getChildFam($currentFamily["off_families"], false)) , $fams);
229  }
230  }
231  }
232 
233  $famids = array_unique($fams);
234 
235  $this->disableEditControl();
236  $err = $this->setValue("off_allfamilies", $famids);
237  $err.= $this->modify();
238 
239  if ($err) {
240  AddLogMsg($err);
241  }
242 
243  $this->enableEditControl();
244  }
245  return $famids;
246  }
247 
248  public function canUseWorkflow($familyId)
249  {
250  $families = $this->getAValues("off_t_families");
251  foreach ($families as $currentFamily) {
252  if ($currentFamily["off_families"] == $familyId) {
253  if ($currentFamily["off_useworkflow"] == "yes") {
254  return true;
255  }
256  }
257  }
258  return false;
259  }
260  /**
261  * Generate a report file based on log for a user
262  * @param int $userId
263  * @param string $report
264  * @return string error message (empty string if no errors)
265  */
266  public function updateReport($userId, &$report)
267  {
268  $userId = $this->getDomainUserId($userId);
269  $folder = $this->getUserFolder($userId);
270  $tmpfile = tempnam(getTmpDir() , 'syncReport');
271  $report = $this->generateReport($userId);
272  file_put_contents($tmpfile, $report);
273 
274  $folder->disableEditControl();
275  $err = $folder->storeFile("off_report", $tmpfile, sprintf(_("Sync report %s.html") , date('Y-m-d')));
276  if (!$err) $err = $folder->modify();
277  $folder->enableEditControl();
278  @unlink($tmpfile);
279  return $err;
280  }
281 
282  public function generateReport($userId)
283  {
284  global $action;
285  $lay = new Layout(getLayoutFile("OFFLINE", "syncreport.html") , $action);
286  $q = new QueryDb($this->dbaccess, "DocLog");
287  $q->addQuery(sprintf("initid=%d", $this->id));
288  $q->addQuery(sprintf("uid=%d", $userId));
289  $q->order_by = "date desc";
290 
291  $r = $q->query(0, 1000, "TABLE");
292  $tsync = array();
293  foreach ($r as $k => $v) {
294 
295  $v = (object)$v;
296  $v->arg = unserialize($v->arg);
297 
298  $tsync[] = array(
299  "oddClass" => ($k % 2 == 0) ? "even" : "odd",
300  "syncDate" => $this->reportGetDate($v) ,
301  "syncCode" => substr($v->code, strlen('DomainSyncApi::')) ,
302  "syncAction" => $this->reportGetAction($v) ,
303  "syncMessage" => $this->reportGetMessage($v) ,
304  "syncStatus" => $this->reportGetStatus($v)
305  );
306  }
307  $lay->setBlockData("MSG", $tsync);
308  $lay->set("date", FrenchDateToLocaleDate($this->getTimeDate()));
309  $lay->set("domain", $this->getHTMLTitle());
310  $lay->set("username", User::getDisplayName($this->getSystemUserId()));
311  //print $lay->gen();
312  return $lay->gen();
313  }
314 
315  private function reportGetDate($sync)
316  {
317  return FrenchDateToLocaleDate(strtok($sync->date, '.'));
318  }
319 
320  private function reportGetStatus($sync)
321  {
322  $status = "";
323  switch ($sync->code) {
324  case 'DomainSyncApi::endTransaction':
325  switch ($sync->arg->status) {
327  $status = "ok";
328  foreach ($sync->arg->detailStatus as $dstatus) {
329  $dstatus = (object)$dstatus;
330  if ($dstatus->saveInfo->onAfterSaveChangeState || $dstatus->saveInfo->onAfterSaveDocument) {
331  $status = "warn";
332  break;
333  }
334  }
335  break;
336 
338  $status = "partial";
339  break;
340 
342  $status = "ko";
343  break;
344  }
345  break;
346 
347  default:
348  if ($sync->arg->error != '') {
349  $status = "ko";
350  } else {
351  $status = "ok";
352  }
353  }
354  return $status;
355  }
356 
357  private function reportGetAction($sync)
358  {
359  return _($sync->code); # _("DomainSyncApi::bookDocument");_("DomainSyncApi::unbookDocument"); _("DomainSyncApi::removeUserDocument");_("DomainSyncApi::endTransaction"); _("DomainSyncApi::beginTransaction");_("DomainSyncApi::getUserDocuments");_("DomainSyncApi::getSharedDocuments"); _("DomainSyncApi::revertDocument"); _("DomainSyncApi::pushDocument");
360 
361  }
362 
363  private function reportGetMessage($sync)
364  {
365  $message = "";
366  $updateMessage = "";
367  $deleteMessage = "";
368 
369  switch ($sync->code) {
370  case 'DomainSyncApi::endTransaction':
371  $list = new DocumentList();
372  $list->addDocumentIdentificators(array_keys($sync->arg->detailStatus));
373  $msgdoc = array();
374  foreach ($sync->arg->detailStatus as $docid => $status) {
375  if ($docid < 0) {
376  $msgdoc[$docid] = $this->reportFormatEndStatus((object)$status, _("new document"));
377  }
378  }
379  foreach ($list as $id => $doc) {
380  /* @var $doc Doc */
381  $status = (object)$sync->arg->detailStatus[$doc->initid];
382  $msgdoc[$id] = $this->reportFormatEndStatus($status, sprintf("%s <span>%s</span>", $doc->getTitle() , $doc->initid));
383  }
384  if (count($msgdoc) > 1) {
385  $message = '<ul><li>' . implode('</li><li>', $msgdoc) . '</li></ul>';
386  } elseif (count($msgdoc) == 1) {
387  $message = current($msgdoc);
388  } else {
389  $message.= _("no documents uploaded");
390  }
391  break;
392 
393  case 'DomainSyncApi::pushDocument':
394  if ($sync->arg->refererinitid < 0) {
395  $message = sprintf(_("document creation %s") , $message = $sync->arg->title);
396  } elseif ($sync->arg->refererinitid == null) {
397  $message = sprintf(_("document creation failed"));
398  } else {
399  $message = $sync->arg->title;
400  }
401  if ($sync->arg->error) {
402  $message.= ' : ' . $sync->arg->error;
403  }
404  if ($sync->arg->message) {
405  $message.= ' : ' . $sync->arg->message;
406  }
407  break;
408 
409  case 'DomainSyncApi::beginTransaction':
410  $message = $sync->arg->error;
411  break;
412 
413  case 'DomainSyncApi::bookDocument':
414  case 'DomainSyncApi::unbookDocument':
415  case 'DomainSyncApi::revertDocument':
416  if ($sync->arg->error) {
417  $message = sprintf("%s : %s", $sync->arg->title, $sync->arg->error);
418  } else {
419  $message = sprintf(_("%s has been downloaded") , sprintf("%s <span>%s</span>", $sync->arg->title, $sync->arg->initid));
420  }
421  break;
422 
423  case 'DomainSyncApi::getUserDocuments':
424  case 'DomainSyncApi::getSharedDocuments':
425  if (is_array($sync->arg->documentsToUpdate)) {
426  $list = new DocumentList();
427  $list->addDocumentIdentificators($sync->arg->documentsToUpdate);
428  $msgdoc = array();
429  foreach ($list as $docid => $doc) {
430  /* @var $doc Doc */
431  $msgdoc[$docid] = sprintf("%s <span>%s</span>", $doc->getTitle() , $doc->initid);
432  }
433  if (count($msgdoc) > 1) {
434  $updateMessage = _("download documents :") . '<ul><li>' . implode('</li><li>', $msgdoc) . '</li></ul>';
435  } elseif (count($msgdoc) == 1) {
436  $updateMessage = sprintf(_("download document %s") , current($msgdoc));
437  } else {
438  $updateMessage = '';
439  }
440  }
441  if (is_array($sync->arg->documentsToDelete)) {
442  $list = new DocumentList();
443  $list->addDocumentIdentificators($sync->arg->documentsToDelete);
444  $msgdoc = array();
445  foreach ($list as $docid => $doc) {
446  $msgdoc[$docid] = $doc->getTitle();
447  }
448  if (count($msgdoc) > 1) {
449  $deleteMessage = _("delete documents :") . '<ul><li>' . implode('</li><li>', $msgdoc) . '</li></ul>';
450  } elseif (count($msgdoc) == 1) {
451  $deleteMessage = sprintf(_("delete document %s") , current($msgdoc));
452  } else {
453  $deleteMessage = '';
454  }
455  }
456  $message = '';
457  if ($sync->arg->error) $message = $sync->arg->error;
458  if ($updateMessage && $deleteMessage) {
459  $message.= nl2br($updateMessage . "\n" . $deleteMessage);
460  } elseif ($updateMessage) {
461  $message.= $updateMessage;
462  } elseif ($deleteMessage) {
463  $message.= $deleteMessage;
464  } else {
465  $message.= _("no documents to retrieve");
466  }
467  break;
468 
469  default:
470  $message = "-";
471  }
472  return $message;
473  }
474 
475  private function reportFormatEndStatus($status, $title = '')
476  {
477  $msgConstraint = "";
478  $msgdoc = "";
479  $status->saveInfo = (object)$status->saveInfo;
480  switch ($status->statusCode) {
481  case 'constraint':
482  if (count($status->saveInfo->constraint) > 0) {
483  $msgConstraint = '';
484 
485  foreach ($status->saveInfo->constraint as $constraint) {
486  $msgConstraint.= sprintf("%s : %s", $constraint["label"], $constraint["err"]);
487  }
488  $statusMessage = $msgConstraint;
489  $msgdoc = sprintf(_("%s following constraints are not validated: %s") , $title, $statusMessage);
490  }
491  break;
492 
493  case 'uptodate':
494  $msgdoc = sprintf(_("%s has been recorded") , $title);
495  break;
496 
497  default:
498  $msgdoc = '';
499  }
500  $statusMessage = '';
501  if ($status->saveInfo->onAfterSaveDocument) {
502  $statusMessage.= sprintf(_("after save warning:%s\n") , $status->saveInfo->onAfterSaveDocument);
503  }
504  if ($status->saveInfo->onAfterSaveChangeState) {
505  $statusMessage.= sprintf(("%s\n") , $status->saveInfo->onAfterSaveChangeState);
506  }
507  if (!$msgConstraint) {
508  $statusMessage.= $status->statusMessage;
509  }
510 
511  return $statusMessage . $msgdoc;
512  }
513  /**
514  * add new member in offline domain
515  * @param integer $userId system identificator for a group or a single user. Can use also logical name of relative document or login
516  * @param boolean $hasManagePrivilege set to false if the user/group cannot has privilege to choice document to synchronise
517  * @return string error message (empty string if no errors)
518  */
519  public function addMember($userId, $hasManagePrivilege = false)
520  {
521  $userId = $this->getDomainUserId($userId);
522 
523  $err = '';
524  if ($userId) {
525  $user = new User($this->dbaccess, $userId);
526  /* @var $user User */
527  if ($user->isAffected()) {
528  /** @noinspection PhpUndefinedFieldInspection */
529  if ($user->isgroup == 'Y') {
530  $aidMember = 'off_group_members';
531  $aidMode = 'off_group_mode';
532  } else {
533  $aidMember = 'off_user_members';
534  $aidMode = 'off_user_mode';
535  }
536  $members = $this->getTValue($aidMember);
537  $mode = $this->getTValue($aidMode);
538  /** @noinspection PhpUndefinedFieldInspection */
539  $key = array_search($user->fid, $members);
540  if ($key === false) {
541  /** @noinspection PhpUndefinedFieldInspection */
542  $members[] = $user->fid;
543  $mode[] = ($hasManagePrivilege ? 'advanced' : 'standard');
544  } else {
545  /** @noinspection PhpUndefinedFieldInspection */
546  $members[$key] = $user->fid;
547  $mode[$key] = ($hasManagePrivilege ? 'advanced' : 'standard');
548  }
549  $err.= $this->setValue($aidMember, $members);
550  $err.= $this->setValue($aidMode, $mode);
551  if (!$err) $err = $this->store();
552  } else {
553  $err.= sprintf("no user %s not alive", $userId);
554  }
555  } else {
556  $err.= sprintf("no user given");
557  }
558  return $err;
559  }
560  /**
561  * remove new member in offline domain
562  * @param integer $userId system identificator for a group or a single user. Can use also logical name of relative document
563  * @return string error message (empty string if no errors)
564  */
565  public function removeMember($userId)
566  {
567  $userId = $this->getDomainUserId($userId);
568  $err = '';
569  if ($userId) {
570  $user = new User($this->dbaccess, $userId);
571  if ($user->isAffected()) {
572  /** @noinspection PhpUndefinedFieldInspection */
573  if ($user->isgroup == 'Y') {
574  $aidMember = 'off_group_members';
575  $aidMode = 'off_group_mode';
576  } else {
577  $aidMember = 'off_user_members';
578  $aidMode = 'off_user_mode';
579  }
580  $members = $this->getTValue($aidMember);
581  $mode = $this->getTValue($aidMode);
582  /** @noinspection PhpUndefinedFieldInspection */
583  $key = array_search($user->fid, $members);
584  if ($key !== false) {
585  unset($members[$key]);
586  unset($mode[$key]);
587  }
588  $err.= $this->setValue($aidMember, $members);
589  $err.= $this->setValue($aidMode, $mode);
590  if (!$err) {
591  $err = $this->store();
592  }
593  } else {
594  $err.= sprintf("no user %s not alive", $userId);
595  }
596  } else {
597  $err.= sprintf("no user given");
598  }
599  return $err;
600  }
601  /**
602  * change privilege of a group/user
603  * @param integer $userId system identificator for a group or a single user. Can use also logical name of relative document
604  * @param boolean $hasManagePrivilege set to false if the user/group cannot has privilege to choice document to synchronise
605  * @return string error message (empty string if no errors)
606  */
607  public function setManagePrivilege($userId, $hasManagePrivilege)
608  {
609  $userId = $this->getDomainUserId($userId);
610  $fid = $this->uid2fid($userId);
611  $fids = $this->getTValue("off_user_members");
612  $fids+= $this->getTValue("off_group_members");
613  if (in_array($fid, $fids)) {
614  $err = $this->addMember($userId, $hasManagePrivilege);
615  } else {
616  $err = sprintf("user %s is not a member", $userId);
617  }
618  return $err;
619  }
620  /**
621  * verify if user has manage privilege
622  * @param integer $userId system identificator for a group or a single user. Can use also logical name of relative document
623  * @return boolean true if has, false else. - null if $userId not exists
624  */
625  public function hasManagePrivilege($userId)
626  {
627  return ($this->getUserMode($userId) == 'advanced');
628  }
629  /**
630  * retrieve all user members system id or document id - inspect groups and sub groups)
631  * @param boolean $useSystemId set to true to set the associative key to system id else use document id
632  * @return array array of [key]=>["id"=>, "docid"=>,"displayName"=>, "login"=>]
633  */
634  public function getUserMembersInfo($useSystemId = true)
635  {
636  /** @noinspection PhpIncludeInspection */
637  include_once ("FDL/Class.SearchDoc.php");
638 
639  $out = array();
640  // group members
641  $um = $this->getTValue("off_group_members");
642  foreach ($um as $k => $v) {
643  if (!$v) unset($um[$k]);
644  }
645  if (count($um) > 0) {
646  $s = new SearchDoc($this->dbaccess, "IGROUP");
647  $s->addFilter($s->sqlCond($um, "initid", true));
648  $s->noViewControl();
649  $users = $s->search();
650  foreach ($users as $guser) {
651  $g = new User($this->dbaccess, $guser["us_whatid"]);
652  if ($g->isAffected()) {
653  $members = $g->getUserMembers();
654  foreach ($members as $user) {
655  $index = $useSystemId ? $user["id"] : $user["fid"];
656  $out[$index] = array(
657  "id" => $user["id"],
658  "docid" => $user["fid"],
659  "displayName" => trim($user["firstname"] . " " . $user["lasttname"]) ,
660  "login" => $user["login"]
661  );
662  }
663  }
664  }
665  }
666  // user members
667  $um = $this->getTValue("off_user_members");
668  foreach ($um as $k => $v) {
669  if (!$v) unset($um[$k]);
670  }
671  if (count($um) > 0) {
672  $s = new SearchDoc($this->dbaccess, "IUSER");
673  $s->addFilter($s->sqlCond($um, "initid", true));
674  $users = $s->search();
675  foreach ($users as $user) {
676  $index = $useSystemId ? $user["us_whatid"] : $user["initid"];
677  $out[$index] = array(
678  "id" => $user["us_whatid"],
679  "docid" => $user["initid"],
680  "displayName" => $user["title"],
681  "login" => $user["us_login"]
682  );
683  }
684  }
685  return $out;
686  }
687  /**
688  * verify if user is member of domain
689  *
690  * @param int $uid system identificator for a group or a single user. Can use also logical name of relative document
691  *
692  * @return boolean true if has, false else. - null if $userId not exists
693  */
694  public function isMember($uid = 0)
695  {
696  /** @noinspection PhpIncludeInspection */
697  include_once ("FDL/Class.SearchDoc.php");
698  $userId = $this->getDomainUserId($uid);
699  $fid = $this->uid2fid($userId);
700 
701  if ($fid) {
702  $um = $this->getTValue("off_user_members");
703  if (in_array($fid, $um)) return true;
704 
705  $um = $this->getTValue("off_group_members");
706  foreach ($um as $k => $v) {
707  if (!$v) unset($um[$k]);
708  }
709  if (count($um) > 0) {
710  $s = new SearchDoc($this->dbaccess, "IGROUP");
711  $s->addFilter($s->sqlCond($um, "initid", true));
712  $s->noViewControl();
713  $users = $s->search();
714  foreach ($users as $guser) {
715  $g = new User($this->dbaccess, $guser["us_whatid"]);
716  if ($g->isAffected()) {
717  if ($g->isMember($userId)) return true;
718  }
719  }
720  }
721  }
722  return false;
723  }
724  /**
725  * retrieve group or user recorded in the domain
726  *
727  * @param int $uid member systeme identificator
728  *
729  * @return array ["id"=>, "docid"=>,"displayName"=>,"managePrivilege"=>true/false,isGroup=>true/false]
730  */
731  public function getMemberInfo($uid)
732  {
733  $out = null;
734  if ($this->isMember($uid)) {
735  $user = new User($this->dbaccess, $uid);
736  $userMode = $this->getUserMode($uid);
737  /** @noinspection PhpUndefinedFieldInspection */
738  $out = array(
739  "id" => $user->id,
740  "docid" => $user->fid,
741  "displayName" => trim($user->firstname . ' ' . $user->lastname) ,
742  "login" => $user->login,
743  "managePrivilege" => ($userMode == 'advanced')
744  );
745  }
746  return $out;
747  }
748 
749  private function uid2fid($uid)
750  {
751  $err = simpleQuery($this->dbaccess, sprintf("select fid from users where id=%d", $uid) , $docuid, true, true);
752  if (!$err) return $docuid;
753  return 0;
754  }
755  /**
756  * GetUserMode : advanced or standard mode
757  *
758  * @param int $uid user what id
759  * @return string advanced or standard
760  */
761  public function getUserMode($uid)
762  {
763  $userMode = "";
764 
765  $uid = $this->getDomainUserId($uid);
766  $docuid = $this->uid2fid($uid);
767  if ($docuid) {
768  $umembers = $this->getTValue("off_user_members");
769  $key = array_search($docuid, $umembers);
770  if ($key !== false) {
771  $userMode = $this->getTValue("off_user_mode", '', $key);
772  } else {
773  // search in groups
774  $ugroups = $this->getTValue("off_group_members");
775  $gu = new User($this->dbaccess);
776  foreach ($ugroups as $k => $gid) {
777  if ($gu->setFid($gid)) {
778  $members = $gu->getUserMembers();
779  foreach ($members as $member) {
780  if ($member['id'] == $uid) {
781  $userMode = $this->getTValue("off_group_mode", '', $k);
782  break;
783  }
784  }
785  if ($userMode === 'advanced') {
786  break;
787  }
788  }
789  }
790  }
791  }
792  return $userMode;
793  }
794  /**
795  * add new document into share folder
796  * @param integer $documentId document identificator
797  * @param int $reservedBy user identificator which reserved document
798  * @return string error message (empty string if no errors)
799  */
800  public function insertSharedDocument($documentId, $reservedBy = null)
801  {
802 
803  $sfolder = $this->getSharedFolder();
804  $doc = new_doc($this->dbaccess, $documentId, true);
805 
806  return $this->domainInsertDocument($sfolder, $doc, $reservedBy, ($reservedBy > 0));
807  }
808  /**
809  * remove document of share folder
810  * @param integer $documentId document identificator
811  * @return string error message (empty string if no errors)
812  */
813  public function removeSharedDocument($documentId)
814  {
815  $err = '';
816  $sfolder = $this->getSharedFolder();
817  $doc = new_doc($this->dbaccess, $documentId, true);
818 
819  if ($doc->isAlive()) {
820  $err = $sfolder->delFile($doc->initid);
821  $this->sendEvents($doc);
822  }
823  return $err;
824  }
825  /**
826  * add new document into user folder
827  * if reserve is true and document is reserved by another user, the document is not added
828  * @param integer $documentId document identificator
829  * @param int $userId user identificator (system id/or logical name)
830  * @param boolean $reserve set to false if want readonly else reserved by $userId
831  * @param ReserveInfo[] $documentstatus information on inserted document (id, title, status...)
832  * @return string error message (empty string if no errors)
833  */
834  public function insertUserDocument($documentId, $userId = 0, $reserve = true, &$documentstatus = array())
835  {
836 
837  $userId = $this->getDomainUserId($userId);
838  $ufolder = $this->getUserFolder($userId);
839  $doc = new_doc($this->dbaccess, $documentId, true);
840 
841  return $this->domainInsertDocument($ufolder, $doc, $userId, $reserve, $documentstatus);
842  }
843  /**
844  * add new document into folder
845  * if reserve is true and document is reserved by another user, the document is not added
846  *
847  * @param Dir $folder
848  * @param Doc $doc
849  * @param int $userId user identificator (system id/or logical name)
850  * @param boolean $reserve set to false if want readonly else reserved by $userId
851  * @param ReserveInfo[] $documentstatus information on inserted document (id, title, status...)
852  * @return string error message (empty string if no errors)
853  */
854  private function domainInsertDocument(Dir $folder, Doc & $doc, $userId = 0, $reserve = true, &$documentstatus = array())
855  {
856  $status = "";
857  $statusErrorMessage = "";
858  if ($doc->isAlive()) {
859  if ($reserve && ($doc->lockdomainid > 0) && ($doc->lockdomainid != $this->id)) {
860  $err = sprintf(_("document is already book in other domain : %s") , $this->getTitle($doc->lockdomainid));
861  } else {
862  $point = "domainInsertDocument" . $doc->id;
863  $this->savePoint($point);
864  $err = $folder->AddFile($doc->initid);
865  if (!$err) {
866  $status = "inserted";
867  if ($reserve) {
868  $statusErrorMessage = $doc->canEdit(false);
869  if ($statusErrorMessage == "") {
870  $err = $doc->lockToDomain($this->id);
871  $status = "reserved";
872  }
873  }
874  }
875  if ($err) $this->rollbackPoint($point);
876  else {
877  $this->commitPoint($point);
878  $this->sendEvents($doc);
879  }
880  }
881  $documentstatus[$doc->id] = new ReserveInfo($doc->id, $doc->getTitle() , $err ? "error" : $status, $err ? $err : "", $statusErrorMessage);
882  } else {
883  $err = sprintf(_("document to book not exists %s") , $doc->id);
884  }
885  return $err;
886  }
887  /**
888  * send events for workspace interface
889  * @param Doc $doc
890  */
891  private static function sendEvents(Doc & $doc)
892  {
893  global $action;
894  $fdlids = $doc->getParentFolderIds();
895  foreach ($fdlids as $fldid) {
896  $action->AddActionDone("MODFOLDERCONTAINT", $fldid);
897  }
898  }
899  /**
900  * insert all documents where are into collection in share folder (not recursive in subfolders)
901  * if reserve is true and document is reserved by another user, the document is not added
902  * @code
903  $s=new SearchDoc($action->dbaccess, "ZOO_ENCLOS");
904  $s->setObjectReturn();
905  $list=$s->search()->getDocumentList();
906  $err=$domain->insertShareCollection($list);
907  * @endcode
908  * @param DocumentList $collection document identificator
909  * @param int $reservedBy user identificator which reserved document
910  * @param ReserveInfo[] $documentstatus information on inserted document (id, title, status...)
911  * @return string error message (empty string if no errors)
912  */
913  public function insertShareCollection(DocumentList $collection, $reservedBy = 0, &$documentstatus = array())
914  {
915  $sfolder = $this->getSharedFolder();
916  if ($sfolder) {
917  $err = $this->insertCollection($sfolder, $collection, $reservedBy, ($reservedBy > 0) , $documentstatus);
918  } else {
919  $err = sprintf("share folder not found");
920  }
921  return $err;
922  }
923  /**
924  * insert all documents where are into collection in user folder (not recursive in subfolders)
925  * if reserve is true and document is reserved by another user, the document is not added
926  * @param DocumentList $collection document identificator
927  * @param int $userId user identificator (system id/or logical name)
928  * @param boolean $reserve set to false if want readonly else reserved by $userId
929  * @param ReserveInfo[] $documentstatus information on inserted document (id, title, status...)
930  * @return string error message (empty string if no errors)
931  */
932  public function insertUserCollection(DocumentList $collection, $userId, $reserve = true, &$documentstatus = array())
933  {
934  $userId = $this->getDomainUserId($userId);
935  $ufolder = $this->getUserFolder($userId);
936  if ($ufolder) {
937  $err = $this->insertCollection($ufolder, $collection, $userId, $reserve, $documentstatus);
938  } else {
939  $err = sprintf("user folder %s noy found", $userId);
940  }
941  return $err;
942  }
943  /**
944  * insert all documents where are into collection in user folder (not recursive in subfolders)
945  * if reserve is true and document is reserved by another user, the document is not added
946  * @param Dir $folder
947  * @param DocumentList $collection document identificator
948  * @param int $userId user identificator (system id/or logical name)
949  * @param boolean $reserve set to false if want readonly else reserved by $userId
950  * @param ReserveInfo[] $documentstatus information on inserted document (id, title, status...)
951  * @return string error message (empty string if no errors)
952  */
953  private function insertCollection(Dir & $folder, DocumentList $collection, $userId, $reserve = true, &$documentstatus = array())
954  {
955  $err = '';
956  foreach ($collection as $doc) {
957  $err.= $this->domainInsertDocument($folder, $doc, $userId, $reserve, $documentstatus);
958  }
959  return $err;
960  }
961  /**
962  * clear all documents from user folder
963  * if unlock is true all document lock by user are unlocked
964  * @param int $userId user identificator (system id/or logical name)
965  * @param boolean $unlock set to false to not unlock documents
966  * @return string error message (empty string if no errors)
967  */
968  public function clearUserFolder($userId = 0, $unlock = true)
969  {
970  $userId = $this->getDomainUserId($userId);
971  $ufolder = $this->getUserFolder($userId);
972  return $this->clearFolder($ufolder);
973  }
974  /**
975  * clear all documents from user foldder
976  * if unlock is true all document lock by current user are unlocked
977  * @param boolean $unlock set to false to not unlock documents
978  * @return string error message (empty string if no errors)
979  */
980  public function clearSharedFolder($unlock = true)
981  {
982  /* TODO implement unlock */
983  $ufolder = $this->getSharedFolder();
984  return $this->clearFolder($ufolder);
985  }
986  /**
987  * clear all documents from foldder
988  * if unlock is true all document lock by current user are unlocked
989  * @param Dir $folder
990  * @param boolean $unlock set to false to not unlock documents
991  * @return string error message (empty string if no errors)
992  */
993  private function clearFolder(Dir & $folder, $unlock = true)
994  {
995  $dl = $folder->getDocumentList();
996  $err = $folder->clear();
997  if ($err == "") {
998  foreach ($dl as $doc) {
999  /* @var $doc _OFFLINEDOMAIN */
1000  $doc->updateDomains();
1001  if ($unlock) {
1002  $doc->unlock();
1003  }
1004  }
1005  /** @noinspection PhpIncludeInspection */
1006  include_once ("FDL/Class.DocWaitManager.php");
1007  DocWaitManager::clearWaitingDocs($this->domain, $this->getSystemUserId());
1008  } else {
1009  $this->setError($err);
1010  }
1011  return $err;
1012  }
1013  /**
1014  * remove document of share folder
1015  * no errors are set if document is not in user folder
1016  * @param integer $documentId document identificator
1017  * @param int $userId user identificator (system id/or logical name)
1018  * @return string error message (empty string if no errors)
1019  */
1020  public function removeUserDocument($documentId, $userId)
1021  {
1022  $err = '';
1023  $userId = $this->getDomainUserId($userId);
1024  $ufolder = $this->getUserFolder($userId);
1025  $doc = new_doc($this->dbaccess, $documentId, true);
1026 
1027  if ($doc->isAlive()) {
1028  $err = $ufolder->delFile($doc->initid);
1029  if ($err != '') {
1030  return $err;
1031  }
1032  $err = $this->setReservation($doc->id, 0);
1033  if ($err != '') {
1034  return $err;
1035  }
1036  $this->sendEvents($doc);
1037  }
1038  return $err;
1039  }
1040  /**
1041  * change reservation
1042  * @param integer $documentId document identificator
1043  * @param int $reservedBy user identificator which reserved document set to null to cancel reservation
1044  * @return string error message (empty string if no errors)
1045  */
1046  public function setReservation($documentId, $reservedBy)
1047  {
1048  $doc = new_doc($this->dbaccess, $documentId, true);
1049  if ($doc->isAlive()) {
1050  $err = $doc->canEdit(false);
1051  if (!$err) {
1052  if ($reservedBy > 0) {
1053  $err = $doc->lockToDomain($this->id, $reservedBy);
1054  } else {
1055  // cancel book
1056  $err = $doc->lockToDomain(0);
1057  }
1058  }
1059  } else {
1060  $err = sprintf("document %s not exists", $documentId);
1061  }
1062  return $err;
1063  }
1064  /**
1065  * get share folder
1066  * @return Dir the folder document
1067  */
1068  public function getSharedFolder()
1069  {
1070  $shared = new_doc($this->dbaccess, $this->getShareId());
1071  if ($shared->isAlive()) return $shared;
1072  return null;
1073  }
1074 
1075  private function getDomainUserId($userId)
1076  {
1077  if (!$userId) {
1078  $userId = $this->getSystemUserId();
1079  } else {
1080  if (!is_numeric($userId)) {
1081  // search by login
1082  $user = new User($this->dbaccess);
1083  $user->SetLoginName($userId);
1084  if ($user->isAffected()) {
1085  /** @noinspection PhpUndefinedFieldInspection */
1086  $userId = $user->id;
1087  }
1088  }
1089  }
1090  return $userId;
1091  }
1092  /**
1093  * get mask to be applied in a document when view it with offline application
1094  * @param int $family family identificator
1095  * @return int mask identificator - 0 of not found
1096  */
1097  public function getOfflineMask($family)
1098  {
1099  $fam = $this->getFamDoc();
1100  $families = $fam->getParamTValue("off_mskfamilies");
1101  $familyMask = new_doc($this->dbaccess, $family);
1102  if ($familyMask->isAlive()) {
1103  // first : easy test
1104  $key = array_search($familyMask->id, $families);
1105 
1106  if ($key !== false) {
1107  return $fam->getParamTValue("off_masks", '', $key);
1108  }
1109  // second search in sub
1110  $sub = $fam->getParamTValue("off_msksubfamilies");
1111  foreach ($families as $k => $famid) {
1112  if ($sub[$k] == "yes") {
1113  $subFamIds = array_keys($this->getChildFam($famid, false));
1114  if (in_array($familyMask->id, $subFamIds)) return $fam->getParamTValue("off_masks", '', $k);
1115  }
1116  }
1117  }
1118  return null;
1119  }
1120  /**
1121  * get user folder
1122  * @param int $userId user identificator (system id/or logical name)
1123  *
1124  * @throws Exception
1125  *
1126  * @return Dir the folder document (null is user is not recorded)
1127  */
1128  public function getUserFolder($userId = 0)
1129  {
1130  $userId = $this->getDomainUserId($userId);
1131  $user = new User($this->dbaccess, $userId);
1132  $userFolder = null;
1133  if ($user->isAffected()) {
1134  /** @noinspection PhpUndefinedFieldInspection */
1135  $login = $user->login;
1136  $userFolderId = $this->getUserFolderId($login);
1137  $userFolder = new_doc($this->dbaccess, $userFolderId);
1138  if (!$userFolder->isAlive()) {
1139  /* Quircks to handle old user notation*/
1140  /** @noinspection PhpUndefinedFieldInspection */
1141  $userArray = array(
1142  "id" => $user->id,
1143  "docid" => $user->fid,
1144  "displayName" => trim($user->firstname . " " . $user->lasttname) ,
1145  "login" => $user->login
1146  );
1147  $usersFolder = $this->getUsersFolder();
1148  $userFolder = $this->generateUserFolder($userFolderId, $userArray, $usersFolder);
1149  }
1150  } else {
1151  throw new Exception(__METHOD__ . " user $userId is not affected");
1152  }
1153  return $userFolder;
1154  }
1155  /**
1156  * return all documents reserved by user
1157  * @param int $userId system user identificator
1158  * @return array of document id
1159  */
1160  public function getReservedDocumentIds($userId = 0)
1161  {
1162  $ids = array();
1163  $userId = $this->getDomainUserId($userId);
1164  $userFolder = $this->getUserFolder($userId);
1165  if ($userFolder) {
1166  $s = new SearchDoc($this->dbaccess);
1167  $s->useCollection($userFolder->initid);
1168  $s->setObjectReturn();
1169  $s->addFilter("locked = %d", $userId);
1170  $s->addFilter("lockdomainid = %d", $this->id);
1171  $dl = $s->search()->getDocumentList();
1172  foreach ($dl as $v) {
1173  $ids[] = $v->initid;
1174  }
1175  }
1176 
1177  $shareFolder = $this->getSharedFolder();
1178  if ($shareFolder) {
1179  $s = new SearchDoc($this->dbaccess);
1180  $s->useCollection($shareFolder->initid);
1181  $s->setObjectReturn();
1182  $s->addFilter("locked = %d", $userId);
1183  $s->addFilter("lockdomainid = %d", $this->id);
1184  $dl = $s->search()->getDocumentList();
1185  foreach ($dl as $v) {
1186  $ids[] = $v->initid;
1187  }
1188  }
1189  return array_unique($ids);
1190  }
1191  /**
1192  * get user folder documents
1193  * @param int $userId user identificator (system id/or logical name)
1194  * @code
1195  $domains=DomainManager::getDomains();
1196  foreach ($domains as $doc) {
1197  print "doc=".$doc->getTitle()."\n";
1198  $k=0;
1199  $contents=$doc->getUserDocuments();
1200  foreach ($contents as $id=>$cdoc) {
1201  printf("%4d) id:%s - %s\n", $k++ , $id, $cdoc->getTitle());
1202  }
1203  }
1204  * @endcode
1205  * @return DocumentList the folder document (null is user is not recorded)
1206  */
1207  public function getUserDocuments($userId = 0)
1208  {
1209  $userFolder = $this->getUserFolder($userId);
1210  if ($userFolder) {
1211  return $userFolder->getDocumentList();
1212  }
1213  return null;
1214  }
1215  /**
1216  * get share folder documents
1217  * @return DocumentList the folder document (null is user is not recorded)
1218  */
1219  public function getSharedDocuments()
1220  {
1221  $shareFolder = $this->getSharedFolder();
1222  if ($shareFolder) {
1223  return $shareFolder->getDocumentList();
1224  }
1225  return null;
1226  }
1227  /**
1228  * postModify : create subdirectories
1229  *
1230  * @return string|void
1231  */
1232  public function postModify()
1233  {
1234  $err = $this->createSubDirectories();
1235  $err.= $this->deleteValue("off_allfamilies");
1236  return $err;
1237  }
1238  /**
1239  * preCreated : check if reference is unique
1240  *
1241  * @return string|void
1242  */
1243  public function preCreated()
1244  {
1245  $ref = $this->getValue("off_ref");
1246  if ($ref) {
1247  $exists = $this->getTitle($ref);
1248  if ($exists) {
1249  return sprintf(_("reference %s exists") , $ref);
1250  }
1251  }
1252  return '';
1253  }
1254  /**
1255  * postCreated : create user subdirectories
1256  *
1257  * @return string|void
1258  */
1259  public function postCreated()
1260  {
1261  $ref = $this->getValue("off_ref");
1262  if ($ref) {
1263  $err = $this->setLogicalIdentificator($ref);
1264  return $err;
1265  }
1266  $err = $this->createSubDirectories();
1267  return $err;
1268  }
1269  /**
1270  * add unique logical name for shared folder
1271  *
1272  * @return string
1273  */
1274  private function getShareId()
1275  {
1276  return sprintf("offshared_%s", $this->name);
1277  }
1278  /**
1279  * add unique logical name for user folder
1280  *
1281  * @param string $login user login
1282  * @return string
1283  */
1284  private function getUserFolderId($login)
1285  {
1286  return sprintf("offuser_%s_%s", $this->name, $login);
1287  }
1288  /**
1289  * Create subdir of the offline domain
1290  *
1291  * Create shared folder and users folders
1292  *
1293  * @return string
1294  */
1295  public function createSubDirectories()
1296  {
1297  $err = "";
1298  if (!$this->name) {
1299  $err.= $this->setLogicalIdentificator($this->getValue("off_ref"));
1300  }
1301  if (($this->getValue("off_sharepolicy") == "admin") || ($this->getValue("off_sharepolicy") == "users")) {
1302  $sharedID = $this->getShareId();
1303  $sharedFolder = new_doc($this->dbaccess, $sharedID);
1304  if (!$sharedFolder->isAlive()) {
1305  $sharedFolder = createDoc($this->dbaccess, "OFFLINEGLOBALFOLDER", false);
1306  $sharedFolder->setValue("ba_title", sprintf(_("%s Share folder") , $this->getTitle()));
1307  $sharedFolder->setValue("off_domain", $this->id);
1308  $err.= $sharedFolder->add();
1309  $err.= $sharedFolder->setLogicalIdentificator($sharedID);
1310  $err.= $this->addFile($sharedFolder->initid);
1311  } else {
1312  $sharedFolder = new_doc($this->dbaccess, $sharedID);
1313  $err.= $this->addFile($sharedFolder->initid);
1314  }
1315  $sharedFolder->disableEditControl();
1316  $sharedFolder->setValue("off_admins", $this->getValue("off_admins"));
1317  $sharedFolder->setValue("off_users", array_merge($this->getTValue("off_group_members") , $this->getTValue("off_user_members")));
1318  $sharedFolder->setValue("fld_allbut", "1"); // add restrictions
1319  $sharedFolder->setValue("fld_famids", $this->getValue("off_families"));
1320  $sharedFolder->setValue("fld_subfam", $this->getValue("off_subfamilies"));
1321  $err.= $sharedFolder->modify();
1322  if ($this->getValue("off_sharepolicy") == "admin") {
1323  $sharedFolder->setProfil("PRF_OFFGLOBFOLDERADMIN");
1324  } elseif ($this->getValue("off_sharepolicy") == "users") {
1325  $sharedFolder->setProfil("PRF_OFFGLOBFOLDERUSER");
1326  }
1327  $sharedFolder->enableEditControl();
1328  } else {
1329  $sharedID = $this->getShareId();
1330  $sharedFolder = new_doc($this->dbaccess, $sharedID);
1331  if ($sharedFolder->isAlive()) {
1332  // need to delete it
1333  $err.= $this->clearSharedFolder();
1334  if ($err == "") {
1335  $sharedFolder->delete();
1336  }
1337  }
1338  }
1339  $usersID = $this->getUsersFolderId();
1340  try {
1341  $usersFolder = $this->generateUsersFolder($usersID);
1342  $members = $this->getUserMembersInfo(true);
1343  foreach ($members as $member) {
1344  $userFolderID = $this->getUserFolderId($member["login"]);
1345  $this->generateUserFolder($userFolderID, $member, $usersFolder);
1346  }
1347  }
1348  catch(Exception $e) {
1349  $err.= $e->getMessage();
1350  }
1351 
1352  return $err;
1353  }
1354  /**
1355  * Return or generateUser Folder
1356  *
1357  * @param string $usersID users folder Id
1358  *
1359  * @return DIR
1360  *
1361  * @throws Exception
1362  */
1363  public function generateUsersFolder($usersID)
1364  {
1365  $err = "";
1366  $usersFolder = new_doc($this->dbaccess, $usersID);
1367  /* @var $usersFolder DIR */
1368  if (!$usersFolder->isAlive()) {
1369  $usersFolder = createDoc($this->dbaccess, "DIR", false);
1370  $usersFolder->setValue("ba_title", sprintf(_("%s Users folder") , $this->getTitle()));
1371  $usersFolder->setValue("off_domain", $this->id);
1372 
1373  $err.= $usersFolder->add();
1374  $err.= $usersFolder->setLogicalIdentificator($usersID);
1375  $err.= $this->addFile($usersFolder->initid);
1376  } else {
1377  $usersFolder = new_doc($this->dbaccess, $usersID);
1378  $err.= $this->addFile($usersFolder->initid);
1379  }
1380  $usersFolder->disableEditControl();
1381  $usersFolder->setValue("fld_allbut", "1"); // add restrictions
1382  $usersFolder->setValue("fld_famids", getFamIdFromName($this->dbaccess, "OFFLINEFOLDER"));
1383  $usersFolder->setValue("fld_subfam", "no");
1384  $usersFolder->setValue("off_admins", $this->getValue("off_admins"));
1385  $usersFolder->setValue("off_users", array_merge($this->getTValue("off_group_members") , $this->getTValue("off_user_members")));
1386  $err.= $usersFolder->modify();
1387  $usersFolder->enableEditControl();
1388  if ($err) {
1389  throw new Exception(__METHOD__ . $err);
1390  }
1391  return $usersFolder;
1392  }
1393 
1394  protected function getUsersFolderId()
1395  {
1396  $usersID = sprintf("offusers_%s", $this->name);
1397  return $usersID;
1398  }
1399  /**
1400  * getUsersFolder
1401  *
1402  * @return Dir
1403  * @throws Exception
1404  */
1405  protected function getUsersFolder()
1406  {
1407  $usersFolderId = $this->getUsersFolderId();
1408  $usersFolder = new_Doc("", $usersFolderId);
1409  if (!$usersFolder->isAlive()) {
1410  throw new Exception(__METHOD__ . " usersFolder : $usersFolderId");
1411  }
1412  return $usersFolder;
1413  }
1414  /**
1415  * Generate a userFolder
1416  *
1417  * @param String $userFolderID
1418  * @param Array $member
1419  * @param Dir $usersFolder
1420  *
1421  * @throws Exception
1422  *
1423  * @return Dir
1424  */
1425  protected function generateUserFolder($userFolderID, $member, Dir $usersFolder)
1426  {
1427  $err = "";
1428  $userFolder = new_doc($this->dbaccess, $userFolderID);
1429  if (!$userFolder->isAlive()) {
1430  $userFolder = createDoc($this->dbaccess, "OFFLINEFOLDER", false);
1431  $userFolder->setValue("ba_title", sprintf(_("%s User folder") , $member["login"]));
1432  $userFolder->setValue("off_domain", $this->id);
1433  $userFolder->setValue("off_user", $member["docid"]);
1434 
1435  $err.= $userFolder->add();
1436  $err.= $userFolder->setLogicalIdentificator($userFolderID);
1437  $err.= $usersFolder->addFile($userFolder->initid);
1438  } else {
1439  $userFolder = new_doc($this->dbaccess, $userFolderID);
1440  $err.= $usersFolder->addFile($userFolder->initid);
1441  }
1442  $userFolder->disableEditControl();
1443  if ($this->hasManagePrivilege($member["id"])) {
1444  $userFolder->setValue("off_advanceduser", $member["docid"]);
1445  } else {
1446  $userFolder->deleteValue("off_advanceduser");
1447  }
1448  $userFolder->setValue("fld_allbut", "1"); // add restrictions
1449  $userFolder->setValue("fld_famids", $this->getValue("off_families"));
1450  $userFolder->setValue("fld_subfam", $this->getValue("off_subfamilies"));
1451  $err.= $userFolder->modify();
1452  $userFolder->enableEditControl();
1453  if ($err) {
1454  throw new Exception(__METHOD__ . ' ' . $err);
1455  }
1456  return $userFolder;
1457  }
1458  /**
1459  * Test if the file exist and if it contains a class that implements DomainHook
1460  *
1461  * @param $filepath
1462  * @return string
1463  */
1464  public function isPHPFile($filepath)
1465  {
1466  if ($filepath) {
1467  if (strstr($filepath, '..')) {
1468  return sprintf(_("file %s must be relative") , $filepath);
1469  }
1470  if (!file_exists(sprintf("%s/%s", DEFAULT_PUBDIR, $filepath))) {
1471  return sprintf(_("file %s not exists") , $filepath);
1472  }
1473  if (!preg_match('/\.php$/', $filepath)) {
1474  return sprintf(_("file %s must be a PHP file") , $filepath);
1475  }
1476  $fileContent = file_get_contents($filepath);
1477  /* TODO : use reflection */
1478  if (!preg_match('/class\s+([a-z_0-9]+)\s+implements\s+DomainHook/ims', $fileContent, $regs)) {
1479  return sprintf(_("file %s not implement DomainHook") , $filepath);
1480  }
1481  }
1482  return "";
1483  }
1484  /**
1485  * return object hook
1486  * @return DomainHook
1487  */
1488  public function hook()
1489  {
1490  if (!$this->hookObject) {
1491  $hookPath = $this->getValue('off_hookpath');
1492  if ($hookPath) {
1493  if (!strstr($hookPath, '..')) {
1494  /** @noinspection PhpIncludeInspection */
1495  require_once $hookPath;
1496  // search the classname
1497  $fileContent = file_get_contents($hookPath);
1498  if (preg_match('/class\s+([a-z_0-9]+)\s+implements\s+DomainHook/i', $fileContent, $regs)) {
1499  $className = $regs[1];
1500  $this->hookObject = new $className();
1501  } else {
1502  addWarningMsg("hook class not implement DomainHook");
1503  }
1504  }
1505  }
1506  }
1507  return $this->hookObject;
1508  }
1509  /**
1510  * delete all user folder not used
1511  * domain unlock all documents which are not in a domain folder
1512  */
1513  public function cleanAll()
1514  {
1515  /** @noinspection PhpIncludeInspection */
1516  include_once ("FDL/Class.SearchDoc.php");
1517  $users = $this->getUserMembersInfo();
1518  $userIds = implode(',', array_keys($users));
1519  $sql = sprintf("update doc set lockdomainid = null where lockdomainid = %d and locked > 0 and locked not in (%s)", $this->id, $userIds);
1520 
1521  $err = $this->exec_query($sql);
1522  $fuid = array();
1523  foreach ($users as $u) {
1524  $fuid[] = $u["docid"];
1525  }
1526  if (count($fuid) > 0) {
1527  $userFids = "'" . implode("','", $fuid) . "'";
1528  $searchDoc = new SearchDoc($this->dbaccess, "OFFLINEFOLDER");
1529  $searchDoc->only = true;
1530  $searchDoc->addFilter("off_domain = '%d'", $this->id);
1531  $searchDoc->addFilter(sprintf("off_user not in (%s)", $userFids));
1532  $searchDoc->setObjectReturn();
1533  $searchDoc->search();
1534  while ($doc = $searchDoc->nextDoc()) {
1535  $doc->delete();
1536  }
1537  }
1538 
1539  return $err;
1540  }
1541  /*
1542  * @begin-method-ignore
1543  * this part will be deleted when construct document class until end-method-ignore
1544  */
1545 }
1546 /*
1547  * @end-method-ignore
1548 */
1549 
getReservedDocumentIds($userId=0)
insertUserCollection(DocumentList $collection, $userId, $reserve=true, &$documentstatus=array())
insertUserDocument($documentId, $userId=0, $reserve=true, &$documentstatus=array())
setManagePrivilege($userId, $hasManagePrivilege)
clearSharedFolder($unlock=true)
updateReport($userId, &$report)
insertSharedDocument($documentId, $reservedBy=null)
addExtraData(Doc &$doc, $key, $value)
insertShareCollection(DocumentList $collection, $reservedBy=0, &$documentstatus=array())
clearUserFolder($userId=0, $unlock=true)
removeUserDocument($documentId, $userId)
removeSharedDocument($documentId)
setReservation($documentId, $reservedBy)
generateUserFolder($userFolderID, $member, Dir $usersFolder)
addFollowingStates(Doc &$doc)
setFamilyMask($familyId, $includeSubFamily=true, $maskId)
addFamily($familyId, $includeSubFamily=true)
addMember($userId, $hasManagePrivilege=false)
getUserMembersInfo($useSystemId=true)
← centre documentaire © anakeen - published under CC License - Dynacase