Platform  3.1
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Class.DocWait.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 require_once "Class.DbObj.php";
9 /**
10  * Waiting document
11  *
12  * @brief Temporary saving
13  * @class DocWait
14  * @package FDL
15  */
16 class DocWait extends DbObj
17 {
18  /**
19  * database field
20  *
21  * @var array
22  */
23  public $fields = array(
24  "refererid", // doc id
25  "refererinitid", // doc initid
26  "localid", // temporary id in case of creation
27  "title", // doc title
28  "fromid", // family
29  "values", // values of document (serialized object)
30  "orivalues", // original values of document (serialized object)
31  "uid", // user id
32  "domain", // domain id
33  "status", // status code
34  "statusmessage", // status message
35  "transaction", // transaction id
36  "date",
37  "extradata"
38  );
39  /**
40  * identificator of referer document
41  *
42  * @var integer
43  */
44  public $refererid;
45  /**
46  * temporary identificator use before creation
47  *
48  * @var integer
49  */
50  public $localid;
51  /**
52  * identificator system of the user
53  *
54  * @var integer
55  */
56  public $uid;
57  /**
58  * document title
59  *
60  * @var string
61  */
62  public $title;
63  /**
64  * date record
65  *
66  * @var date
67  */
68  public $date;
69  /**
70  * document status : ok|constraint|obsolete
71  *
72  * @var string
73  */
74  public $status;
75  /**
76  * document status message
77  *
78  * @var string
79  */
81  /**
82  * arg of code
83  *
84  * @var text serialize object
85  */
86  public $arg;
87  /**
88  * fields primary key
89  *
90  * @var array fields primary key
91  */
92  public $id_fields = array(
93  "refererinitid",
94  "uid"
95  );
96  /**
97  * database table name
98  *
99  * @var array
100  */
101  public $dbtable = "docwait";
102  /**
103  * sql create table
104  *
105  * @var array
106  */
107  public $sqlcreate = "
108 create table docwait ( refererid int not null,
109  refererinitid int not null,
110  localid text,
111  fromid int,
112  title text,
113  uid int not null,
114  values text,
115  orivalues text,
116  date timestamp default now(),
117  domain int,
118  transaction int,
119  statusmessage text,
120  status text,
121  extradata text );
122 create index i_docwait on docwait(transaction);
123 create unique index iu_docwait on docwait(refererinitid, uid);
124 create sequence seq_waittransaction start 1;
125 ";
126  /**#@+
127  * constant for waiting status"
128  */
129  const newDocument = "new";
130  const upToDate = "uptodate";
131  const modified = "modified";
132  const conflict = "conflict";
133  const constraint = "constraint";
134  const invalid = "invalid";
135  const recording = "recording";
136  /**
137  * referer document
138  *
139  * @var Doc
140  */
141  private $refererDoc = null;
142  /**
143  * referer document identificator
144  *
145  * @var integer
146  */
147  private $refererDocId = null;
148  /**
149  * waiting document
150  *
151  * @var Doc
152  */
153  private $waitingDoc = null;
154  /**
155  * save waiting document
156  *
157  * @param mixed &$info informations for save
158  *
159  * @return string error message
160  */
161  public function save(&$info = null)
162  {
163  $err = '';
164  $this->status = $this->computeStatus();
165  if ($this->status == self::conflict) $err = $this->statusmessage;
166  else {
167  $wdoc = $this->getWaitingDocument();
168  $wdoc->doctype = $wdoc->defDoctype; // become consistent
169  if ($this->localid) {
170  // create it
171  $err = $wdoc->add();
172  if (!$err) {
173  if ($this->localid) {
174  $this->refererid = $wdoc->id;
175  $this->refererinitid = $wdoc->initid;
176  // change primary key
177  //$this->exec_query(sprintf("delete from docwait where localid='%s'", pg_escape_string($this->localid)));
178  $this->exec_query(sprintf("update docwait set refererid=%d, refererinitid=%d, localid='' where localid='%s'", $this->refererid, $this->refererinitid, pg_escape_string($this->localid)));
179  }
180  }
181  }
182  if (!$err) {
183  $info = null;
184  $err = $wdoc->save($info);
185  }
186  if ($err) {
187  $this->status = self::constraint;
188  $this->statusmessage = ($info->error) ? $info->label . ' : ' . $info->error : $err;
189  // $this->statusmessage=json_encode($info->error);
190  $this->modify();
191  } else {
192  $this->resetWaitingDocument();
193  }
194  }
195  // error_log("try create $err".$this->localid."::".$wdoc->id);
196  //print "save [$this->status]" . $this->title;
197  return $err;
198  }
199  /**
200  * get waiting document from database
201  *
202  * @return string error message
203  */
204  public function resetWaitingDocument()
205  {
206  $doc = $this->getRefererDocument(true);
207  $err = '';
208  if ($doc) {
209  $this->refererinitid = $doc->initid;
210  $this->refererid = $doc->id;
211  $this->orivalues = serialize($doc->getValues());
212  $this->status = self::upToDate;
213  $this->statusmessage = '';
214  $this->transaction = 0;
215  $this->date = date('Y-m-d H:i:s.u');
216  $err = $this->modify();
217  }
218  return $err;
219  }
220  /**
221  * get write attribute of a doc
222  *
223  * @param Doc &$doc the doc
224  *
225  * @return array of docAttribute
226  */
227  private function getWriteAttribute(Doc & $doc)
228  {
229  $attrs = $doc->getNormalAttributes();
230  $wattr = array();
231  foreach ($attrs as $aid => $oa) {
232  if (($oa->mvisibility == 'W') || ($oa->mvisibility == 'O') || $oa->getOption("writted") == "yes") {
233  $wattr[$aid] = $oa;
234  }
235  }
236  return $wattr;
237  }
238  /**
239  * complete
240  *
241  * @return void
242  */
243  public function complete()
244  {
245  $this->refererDoc = null;
246  $this->waitingDoc = null;
247  }
248  /**
249  * the referer (null if new document)
250  *
251  * @param boolean $reset set to true to force update from database
252  *
253  * @return Doc the referer
254  */
255  public function getRefererDocument($reset = false)
256  {
257  if ($reset) $this->refererDoc = null;
258  if ($this->refererid <= 0) return null;
259  if (!$this->refererDoc) {
260  $this->refererDoc = new_doc($this->dbaccess, $this->refererid, true);
261  $this->refererDocId = $this->refererDoc->id;
262  if ($this->waitingDoc) {
263  $this->values = serialize($this->waitingDoc->getValues());
264  $this->waitingDoc = null;
265  }
266  } else {
267  if (($this->refererDoc->id != $this->refererDocId) || ($fix = $this->refererDoc->isFixed()) || ($fix === null)) {
268  $this->refererDoc = new_doc($this->dbaccess, $this->refererid, true);
269  $this->refererDocId = $this->refererDoc->id;
270  if ($this->waitingDoc) {
271  $this->values = serialize($this->waitingDoc->getValues());
272  $this->waitingDoc = null;
273  }
274  }
275  }
276  return $this->refererDoc;
277  }
278  /**
279  * the referer with new values, document ready to update original
280  *
281  * @return Doc the document
282  */
283  public function getWaitingDocument()
284  {
285  $cdoc = $this->getRefererDocument(); // refresh referer if needed
286  if (!$this->waitingDoc) {
287  if (!$cdoc) {
288  $cdoc = createDoc($this->dbaccess, $this->fromid, false, false);
289  }
290  $this->waitingDoc = clone $cdoc;
291  $waitValues = unserialize($this->values);
292  foreach ($waitValues as $aid => $v) {
293  if ($v == '') $v = ' ';
294  $this->waitingDoc->setValue($aid, $v);
295  }
296  $this->waitingDoc->doctype = 'I';
297  }
298  return $this->waitingDoc;
299  }
300  /**
301  * verify if waiting document status is valid
302  *
303  * @return boolean true if valid
304  */
305  public function isValid()
306  {
307  return ($this->status == self::newDocument || $this->status == self::modified || $this->status == self::upToDate);
308  }
309  /**
310  * verify if origin values are same as current alive values
311  *
312  * @param integer $mask identificator to use specific mask to detect W attributes
313  *
314  * @brief restrict to W/O visibilities values
315  * @return integer ths status code
316  */
317  public function computeStatus($mask = 0)
318  {
319  if ($this->status != self::invalid) {
320  if ($this->refererid) {
321  $originValues = unserialize($this->orivalues);
322  $currentDoc = $this->getRefererDocument();
323  if ($currentDoc->isAlive()) {
324  $err = $currentDoc->canEdit(false);
325  if ($err) {
326  $this->statusmessage = $err;
327  $this->status = self::conflict;
328  } else {
329  if ($currentDoc->locked != $currentDoc->getSystemUserId()) {
330  $this->statusmessage = sprintf('document "%s" [%d] not locked', $currentDoc->getTitle() , $currentDoc->id);
331  $this->status = self::conflict;
332  } else {
333  if ($mask) $currentDoc->ApplyMask($mask);
334  $attrs = $this->getWriteAttribute($currentDoc);
335  $this->status = self::upToDate;
336  $this->statusmessage = '';
337  /*print_r2(array(
338  "cur" => $currentDoc->getValues(),
339  "wai" => $this->getWaitingDocument()->getValues(),
340  "ori" => $originValues
341  ));
342  */
343  $waitingDoc = $this->getWaitingDocument();
344  foreach ($attrs as $aid => $oa) {
345  $ovalue = $originValues[$oa->id];
346  $cvalue = $currentDoc->getValue($oa->id);
347  if ($ovalue != $cvalue) {
348  $this->status = self::conflict;
349  $this->statusmessage.= sprintf(_("conflict %s [%s]: referer=%s, modified=%s") , $oa->getLabel() , $oa->id, $cvalue, $ovalue) . "\n";
350  }
351  }
352  $this->statusmessage = substr($this->statusmessage, 0, -1);
353  }
354  }
355  } else {
356  $this->statusmessage = sprintf("document with id %d does not exists", $this->refererid);
357  $this->status = self::conflict;
358  }
359  } else {
360  $this->status = self::newDocument;
361  }
362  $this->modify();
363  }
364  return $this->status;
365  }
366  /**
367  * get extrat data of waiting document
368  *
369  * @return string the data
370  */
371  public function getExtraData()
372  {
373  return ($this->extradata) ? json_decode($this->extradata) : null;
374  }
375 }
376 ?>
← centre documentaire © anakeen - published under CC License - Dynacase