Core  3.2
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Class.DocAttribute.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @package FDL
5 */
6 /**
7  * Document Attributes
8  *
9  * @author Anakeen
10  * @version $Id: Class.DocAttribute.php,v 1.47 2008/12/11 10:06:51 eric Exp $
11  * @package FDL
12  */
13 /**
14  */
15 /**
16  *
17  * Generic attribute class
18  *
19  * @author Anakeen
20  */
22 {
23  const hiddenFieldId = Adoc::HIDDENFIELD;
24  public $id;
25  public $docid;
26  public $labelText;
27  public $visibility; // W, R, H, O, M, I
28  public $mvisibility; ///mask visibility
29  public $options;
30  public $docname;
31  public $type; // text, longtext, date, file, ...
32  public $usefor; // = Q if parameters.
33  public $ordered; // order to place attributes
34  public $format; // subtypepublic
35  public $isNormal = null;
36  /**
37  * @var FieldSetAttribute field set object
38  */
39  public $fieldSet;
40  /**
41  * @var array
42  */
43  public $_topt = null;
44  /**
45  * Construct a basic attribute
46  *
47  * @param string $id logical name of the attr
48  * @param string $docid
49  * @param string $label
50  */
51  function __construct($id, $docid, $label)
52  {
53  $this->id = $id;
54  $this->docid = $docid;
55  $this->labelText = $label;
56  }
57  /**
58  * Return attribute label
59  *
60  * @return string
61  */
62  function getLabel()
63  {
64  $r = $this->docname . '#' . $this->id;
65  $i = _($r);
66  if ($i != $r) return $i;
67  return $this->labelText;
68  }
69  /**
70  * Return value of option $x
71  *
72  * @param string $x option name
73  * @param string $def default value
74  *
75  * @return string
76  */
77  function getOption($x, $def = "")
78  {
79  if (!isset($this->_topt)) {
80  $topt = explode("|", $this->options);
81  $this->_topt = array();
82  foreach ($topt as $k => $v) {
83  if ($v) {
84  $v = explode("=", $v, 2);
85  $this->_topt[$v[0]] = isset($v[1]) ? $v[1] : null;
86  }
87  }
88  }
89  $r = $this->docname . '#' . $this->id . '#' . $x;
90  $i = _($r);
91  if ($i != $r) return $i;
92 
93  $v = (isset($this->_topt[$x]) && $this->_topt[$x] !== '') ? $this->_topt[$x] : $def;
94  return $v;
95  }
96  /**
97  * Return all value of options
98  *
99  * @return array
100  */
101  function getOptions()
102  {
103  if (!isset($this->_topt)) {
104  $this->getOption('a');
105  }
106  return $this->_topt;
107  }
108  /**
109  * Temporary change option
110  *
111  * @param string $x name
112  * @param string $v value
113  *
114  * @return void
115  */
116  function setOption($x, $v)
117  {
118  if (!isset($this->_topt)) {
119  $this->getOption($x);
120  }
121  $this->_topt[$x] = $v;
122  }
123  /**
124  * temporary change visibility
125  * @param string $vis new visibility : R|H|W|O|I
126  * @return void
127  */
128  function setVisibility($vis)
129  {
130  $this->mvisibility = $vis;
131  }
132  /**
133  * test if attribute is not a auto created attribute
134  *
135  * @return boolean
136  */
137  function isReal()
138  {
139  return $this->getOption("autocreated") != "yes";
140  }
141  /**
142  * Escape value with xml entities
143  *
144  * @param string $s value
145  * @param bool $quot to encode also quote "
146  * @return string
147  */
148  static function encodeXml($s, $quot = false)
149  {
150  if ($quot) {
151  return str_replace(array(
152  '&',
153  '<',
154  '>',
155  '"'
156  ) , array(
157  '&amp;',
158  '&lt;',
159  '&gt;',
160  '&quot;'
161  ) , $s);
162  } else {
163  return str_replace(array(
164  '&',
165  '<',
166  '>'
167  ) , array(
168  '&amp;',
169  '&lt;',
170  '&gt;'
171  ) , $s);
172  }
173  }
174  /**
175  * to see if an attribute is n item of an array
176  *
177  * @return boolean
178  */
179  function inArray()
180  {
181  return false;
182  }
183  /**
184  * verify if accept multiple value
185  *
186  * @return boolean
187  */
188  function isMultiple()
189  {
190  return ($this->inArray() || ($this->getOption('multiple') === 'yes'));
191  }
192  /**
193  * verify if attribute is multiple value and if is also in array multiple^2
194  *
195  * @return boolean
196  */
197  function isMultipleInArray()
198  {
199  return ($this->inArray() && ($this->getOption('multiple') === 'yes'));
200  }
201  /**
202  * Get tab ancestor
203  * false if not found
204  *
205  * @return FieldSetAttribute|bool
206  */
207  function getTab()
208  {
209  if ($this->type == 'tab') {
210  return $this;
211  }
212  if (is_object($this->fieldSet) && method_exists($this->fieldSet, 'getTab') && ($this->fieldSet->id != Adoc::HIDDENFIELD)) {
213  return $this->fieldSet->getTab();
214  }
215  return false;
216  }
217  /**
218  * Export values as xml fragment
219  *
220  * @param array $la array of DocAttribute
221  * @return string
222  */
223  function getXmlSchema($la)
224  {
225  return sprintf("<!-- no Schema %s (%s)-->", $this->id, $this->type);
226  }
227  /**
228  * export values as xml fragment
229  *
230  * @param Doc $doc working doc
231  * @param bool|\exportOptionAttribute $opt
232  * @deprecated use \Dcp\ExportXmlDocument class instead
233  *
234  * @return string
235  */
236  function getXmlValue(Doc & $doc, $opt = false)
237  {
238  return sprintf("<!-- no value %s (%s)-->", $this->id, $this->type);
239  }
240  /**
241  * Get human readable textual value
242  * Fallback method
243  *
244  * @param Doc $doc current Doc
245  * @param int $index index if multiple
246  * @param array $configuration value
247  *
248  * @return string
249  */
250  public function getTextualValue(Doc $doc, $index = - 1, Array $configuration = array())
251  {
252  return null;
253  }
254  /**
255  * Generate XML schema layout
256  *
257  * @param Layout $play
258  */
259  function common_getXmlSchema(&$play)
260  {
261 
262  $lay = new Layout(getLayoutFile("FDL", "infoattribute_schema.xml"));
263  $lay->set("aname", $this->id);
264  $lay->set("label", $this->encodeXml($this->labelText));
265  $lay->set("type", $this->type);
266  $lay->set("visibility", $this->visibility);
267  $lay->set("isTitle", false);
268  $lay->set("phpfile", false);
269  $lay->set("phpfunc", false);
270 
271  $lay->set("computed", false);
272  $lay->set("link", '');
273  $lay->set("elink", '');
274  $lay->set("default", false);
275  $lay->set("constraint", '');
276  $tops = $this->getOptions();
277  $t = array();
278  foreach ($tops as $k => $v) {
279  if ($k) $t[] = array(
280  "key" => $k,
281  "val" => $this->encodeXml($v)
282  );
283  }
284  $lay->setBlockData("options", $t);
285 
286  $play->set("minOccurs", "0");
287  $play->set("isnillable", "true");
288  $play->set("maxOccurs", "1");
289  $play->set("aname", $this->id);
290  $play->set("appinfos", $lay->gen());
291  }
292 }
293 /**
294  * NormalAttribute Class
295  * Non structural attribute (all attribute except frame and tab)
296  *
297  * @author Anakeen
298  *
299  */
301 {
302  const _cEnum = "_CACHE_ENUM";
303  const _cEnumLabel = "_CACHE_ENUMLABEL";
304  const _cParent = "_CACHE_PARENT";
305  /**
306  * @var bool
307  */
308  public $needed; // Y / N
309  public $format; // C format
310  public $eformat; // format for edition : list,vcheck,hcheck
311  public $repeat; // true if is a repeatable attribute
312  public $isNormal = true;
313  /**
314  * @var bool
315  */
316  public $isInTitle;
317  /**
318  * @var bool
319  */
321  public $link; // hypertext link
322  public $phpfile;
323  public $phpfunc;
324  public $elink; // extra link
325  public $phpconstraint; // special constraint set
326 
327  /**
328  * @var bool special use for application interface
329  */
330  public $isAlone = false;
331  /**
332  * @var $enum array use for enum attributes
333  */
334  public $enum;
335  /**
336  * @var $enumlabel array use for enum attributes
337  */
338  public $enumlabel;
339  /**
340  * Array of separator by level of multiplicity for textual export
341  * @var array
342  */
344  0 => "\n",
345  1 => ", "
346  );
347  /**
348  * @var array
349  */
350  private static $_cache = array();
351  protected $originalPhpfile;
352  protected $originalPhpfunc;
353  /**
354  * Normal Attribute constructor : non structural attribute
355  *
356  * @param int $id id of the attribute
357  * @param int $docid id of the family
358  * @param string $label default translate key
359  * @param string $type kind of attribute
360  * @param string $format format option
361  * @param string $repeat is repeteable attr
362  * @param int $order display order
363  * @param string $link link option
364  * @param string $visibility visibility option
365  * @param bool $needed is mandotary attribute
366  * @param bool $isInTitle is used to compute title
367  * @param bool $isInAbstract is used in abstract view
368  * @param FieldSetAttribute &$fieldSet parent attribute
369  * @param string $phpfile php file used with the phpfunc
370  * @param string $phpfunc helpers function
371  * @param string $elink eling option
372  * @param string $phpconstraint class php function
373  * @param string $usefor Attribute or Parameter
374  * @param string $eformat eformat option
375  * @param string $options option string
376  * @param string $docname
377  */
379  {
380  $this->id = $id;
381  $this->docid = $docid;
382  $this->labelText = $label;
383  $this->type = $type;
384  $this->format = $format;
385  $this->eformat = $eformat;
386  $this->ordered = $order;
387  $this->link = $link;
388  $this->visibility = $visibility;
389  $this->needed = $needed;
390  $this->isInTitle = $isInTitle;
391  $this->isInAbstract = $isInAbstract;
392  $this->fieldSet = & $fieldSet;
393  $this->phpfile = $phpfile;
394  $this->phpfunc = $phpfunc;
395  $this->elink = $elink;
396  $this->phpconstraint = $phpconstraint;
397  $this->usefor = $usefor;
398  $this->repeat = $repeat;
399  $this->options = $options;
400  $this->docname = $docname;
401  }
402  /**
403  * temporary change need
404  * @param bool $need true means needed, false not needed
405  * @return void
406  */
407  function setNeeded($need)
408  {
409  $this->needed = $need;
410  }
411  /**
412  * Parse htmltext and replace id by logicalname for links
413  *
414  * @param string $value Formated value of attribute
415  * @return string Value transformed
416  */
418  {
419  if ($this->type == "htmltext") {
420  $value = preg_replace_callback('/(data-initid=")([0-9]+)/', function ($matches)
421  {
422  $name = getNameFromId(getDbAccess() , $matches[2]);
423  return $matches[1] . ($name ? $name : $matches[2]);
424  }
425  , $value);
426  }
427  return $value;
428  }
429  /**
430  * Generate the xml schema fragment
431  *
432  * @param array $la array of DocAttribute
433  *
434  * @return string
435  */
436  function getXmlSchema($la)
437  {
438  switch ($this->type) {
439  case 'text':
440  return $this->text_getXmlSchema($la);
441  case 'longtext':
442  case 'htmltext':
443  return $this->longtext_getXmlSchema($la);
444  case 'int':
445  case 'integer':
446  return $this->int_getXmlSchema($la);
447  case 'float':
448  case 'money':
449  return $this->float_getXmlSchema($la);
450  case 'image':
451  case 'file':
452  return $this->file_getXmlSchema($la);
453  case 'enum':
454  return $this->enum_getXmlSchema($la);
455  case 'thesaurus':
456  case 'docid':
457  case 'account':
458  return $this->docid_getXmlSchema($la);
459  case 'date':
460  return $this->date_getXmlSchema($la);
461  case 'timestamp':
462  return $this->timestamp_getXmlSchema($la);
463  case 'time':
464  return $this->time_getXmlSchema($la);
465  case 'array':
466  return $this->array_getXmlSchema($la);
467  case 'color':
468  return $this->color_getXmlSchema($la);
469  default:
470  return sprintf("<!-- no Schema %s (type %s)-->", $this->id, $this->type);
471  }
472  }
473  /**
474  * Generate XML schema layout
475  *
476  * @param Layout $play
477  */
478  function common_getXmlSchema(&$play)
479  {
480 
481  $lay = new Layout(getLayoutFile("FDL", "infoattribute_schema.xml"));
482  $lay->set("aname", $this->id);
483  $lay->set("label", $this->encodeXml($this->labelText));
484  $lay->set("type", $this->type);
485  $lay->set("visibility", $this->visibility);
486  $lay->set("isTitle", $this->isInTitle);
487  $lay->set("phpfile", $this->phpfile);
488  $lay->set("phpfunc", $this->phpfunc);
489 
490  if (($this->type == "enum") && (!$this->phpfile) || ($this->phpfile == "-")) {
491  $lay->set("phpfile", false);
492  $lay->set("phpfunc", false);
493  }
494  $lay->set("computed", ((!$this->phpfile) && (substr($this->phpfunc, 0, 2) == "::")));
495  $lay->set("link", $this->encodeXml($this->link));
496  $lay->set("elink", $this->encodeXml($this->elink));
497  $lay->set("default", false); // TODO : need detect default value
498  $lay->set("constraint", $this->phpconstraint);
499  $tops = $this->getOptions();
500  $t = array();
501  foreach ($tops as $k => $v) {
502  if ($k) $t[] = array(
503  "key" => $k,
504  "val" => $this->encodeXml($v)
505  );
506  }
507  $lay->setBlockData("options", $t);
508 
509  $play->set("minOccurs", $this->needed ? "1" : "0");
510  $play->set("isnillable", $this->needed ? "false" : "true");
511  $play->set("maxOccurs", (($this->getOption('multiple') == 'yes') ? "unbounded" : "1"));
512  $play->set("aname", $this->id);
513  $play->set("appinfos", $lay->gen());
514  }
515  /**
516  * export values as xml fragment
517  *
518  * @param Doc $doc working doc
519  * @param bool|\exportOptionAttribute $opt
520  * @deprecated use \Dcp\ExportXmlDocument class intead
521  *
522  * @return string
523  */
524  function getXmlValue(Doc & $doc, $opt = false)
525  {
526  if ($opt->index > - 1) $v = $doc->getMultipleRawValues($this->id, null, $opt->index);
527  else $v = $doc->getRawValue($this->id, null);
528  //if (! $v) return sprintf("<!-- no value %s -->",$this->id);
529  if ($this->getOption("autotitle") == "yes") {
530  return sprintf("<!--autotitle %s %s -->", $this->id, $v);
531  }
532  if (($v === null) && ($this->type != 'array')) {
533  if (($this->type == 'file') || ($this->type == 'image')) return sprintf('<%s mime="" title="" xsi:nil="true"/>', $this->id);
534  else return sprintf('<%s xsi:nil="true"/>', $this->id);
535  }
536  switch ($this->type) {
537  case 'timestamp':
538  case 'date':
539  $v = stringDateToIso($v);
540  return sprintf("<%s>%s</%s>", $this->id, $v, $this->id);
541  case 'array':
542  $la = $doc->getAttributes();
543  $xmlvalues = array();
544  $av = $doc->getArrayRawValues($this->id);
545  $axml = array();
546  foreach ($av as $k => $col) {
547  $xmlvalues = array();
548  foreach ($col as $aid => $aval) {
549  $oa = $doc->getAttribute($aid);
550  if (empty($opt->exportAttributes[$doc->fromid]) || in_array($aid, $opt->exportAttributes[$doc->fromid])) {
551  $opt->index = $k;
552  $xmlvalues[] = $oa->getXmlValue($doc, $opt);
553  }
554  }
555  $axml[] = sprintf("<%s>%s</%s>", $this->id, implode("\n", $xmlvalues) , $this->id);
556  }
557  $opt->index = - 1; // restore initial index
558  return implode("\n", $axml);
559  case 'image':
560  case 'file':
561 
562  if (preg_match(PREGEXPFILE, $v, $reg)) {
563  if ($opt->withIdentifier) {
564  $vid = $reg[2];
565  } else {
566  $vid = '';
567  }
568  $mime = $reg[1];
569  $name = $reg[3];
570  $base = getParam("CORE_EXTERNURL");
571  $href = $base . str_replace('&', '&amp;', $doc->getFileLink($this->id));
572  if ($opt->withFile) {
573  $path = $doc->vault_filename_fromvalue($v, true);
574 
575  if (is_file($path)) {
576  if ($opt->outFile) {
577  return sprintf('<%s vid="%s" mime="%s" title="%s">[FILE64:%s]</%s>', $this->id, $vid, $mime, $name, $path, $this->id);
578  } else {
579  return sprintf('<%s vid="%s" mime="%s" title="%s">%s</%s>', $this->id, $vid, $mime, $name, base64_encode(file_get_contents($path)) , $this->id);
580  }
581  } else {
582  return sprintf('<!-- file not found --><%s vid="%s" mime="%s" title="%s"/>', $this->id, $vid, $mime, $name, $this->id);
583  }
584  } else {
585  return sprintf('<%s vid="%s" mime="%s" href="%s" title="%s"/>', $this->id, $vid, $mime, $href, $this->encodeXml($name));
586  }
587  } else {
588  return sprintf("<%s>%s</%s>", $this->id, $v, $this->id);
589  }
590  case 'thesaurus':
591  case 'account':
592  case 'docid':
593  if (!$v) {
594  return sprintf('<%s xsi:nil="true"/>', $this->id);
595  } else {
596  $info = getTDoc($doc->dbaccess, $v, array() , array(
597  "title",
598  "name",
599  "id",
600  "initid",
601  "locked"
602  ));
603 
604  if ($info) {
605  $docid = $info["id"];
606  $latestTitle = ($this->getOption("docrev", "latest") == "latest");
607  if ($latestTitle) {
608  $docid = $info["initid"];
609  if ($info["locked"] == - 1) {
610  $info["title"] = $doc->getLastTitle($docid);
611  }
612  }
613  if ($info["name"]) {
614  if ($opt->withIdentifier) {
615  return sprintf('<%s id="%s" name="%s">%s</%s>', $this->id, $docid, $info["name"], $this->encodeXml($info["title"]) , $this->id);
616  } else {
617  return sprintf('<%s name="%s">%s</%s>', $this->id, $info["name"], $this->encodeXml($info["title"]) , $this->id);
618  }
619  } else {
620  if ($opt->withIdentifier) {
621  return sprintf('<%s id="%s">%s</%s>', $this->id, $docid, $this->encodeXml($info["title"]) , $this->id);
622  } else {
623 
624  return sprintf('<%s>%s</%s>', $this->id, $this->encodeXml($info["title"]) , $this->id);
625  }
626  }
627  } else {
628  if ((strpos($v, '<BR>') === false) && (strpos($v, "\n") === false)) {
629  return sprintf('<%s id="%s">%s</%s>', $this->id, $v, _("unreferenced document") , $this->id);
630  } else {
631 
632  $tids = explode("\n", str_replace('<BR>', "\n", $v));
633  $mName = array();
634  $mId = array();
635  $foundName = false;
636  foreach ($tids as $id) {
637  $lName = getNameFromId($doc->dbaccess, $id);
638  $mName[] = $lName;
639  $mId[] = $id;
640  if ($lName) $foundName = true;
641  }
642  $sIds = '';
643  if ($opt->withIdentifier) {
644  $sIds = sprintf('id="%s"', implode(',', $mId));
645  }
646  $sName = '';
647  if ($foundName) {
648 
649  $sName = sprintf('name="%s"', implode(',', $mName));
650  }
651  return sprintf('<%s %s %s>%s</%s>', $this->id, $sName, $sIds, _("multiple document") , $this->id);
652  }
653  }
654  }
655  default:
656  return sprintf("<%s>%s</%s>", $this->id, $this->encodeXml($v) , $this->id);
657  }
658  }
659  /**
660  * custom textual XML schema
661  *
662  * @return string
663  */
664  function text_getXmlSchema()
665  {
666  $lay = new Layout(getLayoutFile("FDL", "textattribute_schema.xml"));
667  $this->common_getXmlSchema($lay);
668 
669  $lay->set("maxlength", false);
670  $lay->set("pattern", false);
671  return $lay->gen();
672  }
673  /**
674  * enum XML schema
675  *
676  * @return string
677  */
678  function enum_getXmlSchema()
679  {
680  $lay = new Layout(getLayoutFile("FDL", "enumattribute_schema.xml"));
681  $this->common_getXmlSchema($lay);
682 
683  $la = $this->getEnum();
684  $te = array();
685  foreach ($la as $k => $v) {
686  $te[] = array(
687  "key" => $k,
688  "val" => $this->encodeXml($v)
689  );
690  }
691  $lay->setBlockData("enums", $te);
692  return $lay->gen();
693  }
694  /**
695  * docid XML schema
696  *
697  * @return string
698  */
700  {
701  $lay = new Layout(getLayoutFile("FDL", "docidattribute_schema.xml"));
702  $this->common_getXmlSchema($lay);
703 
704  $lay->set("famid", $this->format);
705  return $lay->gen();
706  }
707  /**
708  * date XML schema
709  *
710  * @return string
711  */
712  function date_getXmlSchema()
713  {
714  $lay = new Layout(getLayoutFile("FDL", "dateattribute_schema.xml"));
715  $this->common_getXmlSchema($lay);
716  return $lay->gen();
717  }
718  /**
719  * timeStamp XML schema
720  *
721  * @return string
722  */
724  {
725  $lay = new Layout(getLayoutFile("FDL", "timestampattribute_schema.xml"));
726  $this->common_getXmlSchema($lay);
727  return $lay->gen();
728  }
729  /**
730  * Color XML schema
731  *
732  * @return string
733  */
735  {
736  $lay = new Layout(getLayoutFile("FDL", "colorattribute_schema.xml"));
737  $this->common_getXmlSchema($lay);
738  return $lay->gen();
739  }
740  /**
741  * int XML schema
742  *
743  * @return string
744  */
745  function int_getXmlSchema()
746  {
747  $lay = new Layout(getLayoutFile("FDL", "intattribute_schema.xml"));
748  $this->common_getXmlSchema($lay);
749  return $lay->gen();
750  }
751  /**
752  * longText XML schema
753  *
754  * @return string
755  */
757  {
758  $lay = new Layout(getLayoutFile("FDL", "longtextattribute_schema.xml"));
759  $this->common_getXmlSchema($lay);
760  return $lay->gen();
761  }
762  /**
763  * Float XML schema
764  *
765  * @return string
766  */
768  {
769  $lay = new Layout(getLayoutFile("FDL", "floatattribute_schema.xml"));
770  $this->common_getXmlSchema($lay);
771  return $lay->gen();
772  }
773  /**
774  * Time XML schema
775  *
776  * @return string
777  */
778  function time_getXmlSchema()
779  {
780  $lay = new Layout(getLayoutFile("FDL", "timeattribute_schema.xml"));
781  $this->common_getXmlSchema($lay);
782  return $lay->gen();
783  }
784  /**
785  * File XML schema
786  *
787  * @return string
788  */
789  function file_getXmlSchema()
790  {
791  $lay = new Layout(getLayoutFile("FDL", "fileattribute_schema.xml"));
792  $this->common_getXmlSchema($lay);
793  return $lay->gen();
794  }
795  /**
796  * Array XML schema
797  * @param BasicAttribute[] &$la
798  *
799  * @return string
800  */
802  {
803  $lay = new Layout(getLayoutFile("FDL", "arrayattribute_schema.xml"));
804  $this->common_getXmlSchema($lay);
805  $lay->set("minOccurs", "0");
806  $lay->set("maxOccurs", "unbounded");
807  $tax = array();
808  foreach ($la as $k => $v) {
809  if ($v->fieldSet && $v->fieldSet->id == $this->id) {
810  $tax[] = array(
811  "axs" => $v->getXmlSchema($la)
812  );
813  }
814  }
815  $lay->setBlockData("ATTR", $tax);
816  return $lay->gen();
817  }
818  /**
819  * Get the textual value of an attribute
820  *
821  * @param Doc $doc current Doc
822  * @param int $index index if multiple
823  * @param array $configuration value config array :
824  * dateFormat => 'US' 'ISO',
825  * decimalSeparator => '.',
826  * longtextMultipleBrToCr => ' '
827  * multipleSeparator => array(0 => 'arrayLine', 1 => 'multiple')
828  *
829  * (defaultValue : dateFormat : 'US', decimalSeparator : '.', multiple => array(0 => "\n", 1 => ", "))
830  *
831  * @return string
832  */
833  public function getTextualValue(Doc $doc, $index = - 1, Array $configuration = array())
834  {
835  $decimalSeparator = isset($configuration['decimalSeparator']) ? $configuration['decimalSeparator'] : '.';
836 
837  if (in_array($this->type, array(
838  "int",
839  "double",
840  "money"
841  ))) {
842  return $this->getNumberValue($doc, $index, $decimalSeparator);
843  }
844  $value = $doc->getRawValue($this->id);
845  $fc = new \FormatCollection();
846  $stripHtmlTags = isset($configuration['stripHtmlTags']) ? $configuration['stripHtmlTags'] : false;
847  $fc->stripHtmlTags($stripHtmlTags);
848 
849  $fc->setDecimalSeparator($decimalSeparator);
850  $fc->setDateStyle(\DateAttributeValue::defaultStyle);
851  $dateFormat = isset($configuration['dateFormat']) ? $configuration['dateFormat'] : 'US';
852 
853  if ($dateFormat == 'US') {
854  $fc->setDateStyle(\DateAttributeValue::isoWTStyle);
855  } elseif ($dateFormat == "ISO") {
856  $fc->setDateStyle(\DateAttributeValue::isoStyle);
857  } elseif ($dateFormat == 'FR') {
858  $fc->setDateStyle(\DateAttributeValue::frenchStyle);
859  } else {
860  $fc->setDateStyle(\DateAttributeValue::defaultStyle);
861  }
862  if (isset($configuration['longtextMultipleBrToCr'])) {
863  $fc->setLongtextMultipleBrToCr($configuration['longtextMultipleBrToCr']);
864  } else {
865  $fc->setLongtextMultipleBrToCr(" "); // long text are in a single line
866 
867  }
868  $info = $fc->getInfo($this, $value, $doc);
869  if (empty($info)) {
870  return '';
871  }
872  return \FormatCollection::getDisplayValue($info, $this, $index, $configuration);
873  }
874 
875  public function getNumberValue(Doc $doc, $index = - 1, $decimalSeparator = ".")
876  {
877 
878  if ($index >= 0) {
879  $numberValue = $doc->getMultipleRawValues($this->id, "", $index);
880  if ($this->format) {
881  $numberValue = sprintf($this->format, $numberValue);
882  }
883  } elseif ($this->isMultiple() && $this->format) {
884  $cellValues = $doc->getMultipleRawValues($this->id);
885  foreach ($cellValues as & $cell) {
886  $cell = sprintf($this->format, $cell);
887  }
888  $numberValue = implode("\n", $cellValues);
889  } else {
890  $numberValue = $doc->getRawValue($this->id);
891  if ($this->format) {
892  $numberValue = sprintf($this->format, $numberValue);
893  }
894  }
895 
896  if (!empty($decimalSeparator)) {
897  $numberValue = str_replace(".", $decimalSeparator, $numberValue);
898  }
899  return $numberValue;
900  }
901  /**
902  * to see if an attribute is n item of an array
903  *
904  * @return boolean
905  */
906  function inArray()
907  {
908  return ($this->fieldSet && $this->fieldSet->type === "array");
909  }
910  /**
911  * Return array of enumeration definition
912  * the array's keys are the enum key and the values are the labels
913  *
914  * @param bool $returnDisabled if false disabled enum are not returned
915  * @return array
916  */
917  function getEnum($returnDisabled = true)
918  {
919  $cached = self::_cacheFetch(self::_cEnum, array(
920  $this->docid,
921  $this->id
922  ) , null, $returnDisabled);
923  if ($cached !== null) {
924  return $cached;
925  }
926 
927  if (($this->type == "enum") || ($this->type == "enumlist")) {
928  // set the enum array
929  $this->enum = array();
930  $this->enumlabel = array();
931  $br = $this->docname . '#' . $this->id . '#'; // id i18n prefix
932  if ($this->originalPhpfile && $this->originalPhpfunc) {
933  $this->phpfile = $this->originalPhpfile;
934  $this->phpfunc = $this->originalPhpfunc;
935  }
936  if (($this->phpfile != "") && ($this->phpfile != "-")) {
937  // for dynamic specification of kind attributes
938  if (!include_once ("EXTERNALS/$this->phpfile")) {
939  /*
940  * @var Action $action
941  */
942  global $action;
943  $action->exitError(sprintf(_("the external pluggin file %s cannot be read") , $this->phpfile));
944  }
945  if (preg_match('/(.*)\((.*)\)/', $this->phpfunc, $reg)) {
946  $args = explode(",", $reg[2]);
947  if (preg_match('/linkenum\((.*),(.*)\)/', $this->phpfunc, $dreg)) {
948  $br = $dreg[1] . '#' . strtolower($dreg[2]) . '#';
949  }
950  if (function_exists($reg[1])) {
951  $this->originalPhpfile = $this->phpfile;
952  $this->originalPhpfunc = $this->phpfunc;
953  $this->phpfile = "";
954  $this->phpfunc = call_user_func_array($reg[1], $args);
955 
956  EnumAttributeTools::flatEnumNotationToEnumArray($this->phpfunc, $this->enum, $this->enumlabel, $br);
957  } else {
958  AddWarningMsg(sprintf(_("function [%s] not exists") , $this->phpfunc));
959  $this->phpfunc = "";
960  }
961  } else {
962  AddWarningMsg(sprintf(_("invalid syntax for [%s] for enum attribute [%s]") , $this->phpfunc, $this->id));
963  }
964  self::_cacheStore(self::_cEnum, array(
965  $this->docid,
966  $this->id
967  ) , $this->enum);
968  self::_cacheStore(self::_cEnumLabel, array(
969  $this->docid,
970  $this->id
971  ) , $this->enumlabel);
972  } else {
973  // static enum
974  $famId = $this->_getRecursiveParentFamHavingAttribute($this->docid, $this->id);
975 
976  $cached = self::_cacheFetch(self::_cEnum, array(
977  $famId,
978  $this->id
979  ) , null, $returnDisabled);
980  if ($cached !== null) {
981  return $cached;
982  }
983 
984  $sql = sprintf("select * from docenum where famid=%d and attrid='%s' order by eorder", $famId, pg_escape_string($this->id));
985 
986  simpleQuery('', $sql, $enums);
987 
988  foreach ($enums as $k => $item) {
989  $enums[$k]["keyPath"] = str_replace('.', '\\.', $item["key"]);
990  }
991  foreach ($enums as $item) {
992  $enumKey = $item["key"];
993  $enumPath = $item["keyPath"];
994  $translatedEnumValue = _($br . $enumKey);
995  if ($translatedEnumValue != $br . $enumKey) {
996  $enumLabel = $translatedEnumValue;
997  } else {
998  $enumLabel = $item["label"];
999  }
1000  if ($item["parentkey"] !== null) {
1001  $this->enum[$this->getCompleteEnumKey($enumKey, $enums) ] = $enumLabel;
1002  $enumCompleteLabel = $this->getCompleteEnumlabel($enumKey, $enums, $br);
1003  $this->enumlabel[$enumKey] = $enumCompleteLabel;
1004  } else {
1005  $this->enum[$enumPath] = $enumLabel;
1006  $this->enumlabel[$enumKey] = $enumLabel;
1007  }
1008  }
1009  self::_cacheStore(self::_cEnum, array(
1010  $famId,
1011  $this->id
1012  ) , $this->enum);
1013  self::_cacheStore(self::_cEnumLabel, array(
1014  $famId,
1015  $this->id
1016  ) , $this->enumlabel);
1017  }
1018  }
1019  if (!$returnDisabled) {
1020  return self::_cacheFetch(self::_cEnum, array(
1021  $this->docid,
1022  $this->id
1023  ) , null, $returnDisabled);
1024  }
1025  return $this->enum;
1026  }
1027 
1028  private function getCompleteEnumKey($key, array & $enums)
1029  {
1030  foreach ($enums as $item) {
1031  if ($item["key"] === $key) {
1032  if ($item["parentkey"] !== null) {
1033 
1034  return sprintf("%s.%s", $this->getCompleteEnumKey($item["parentkey"], $enums) , $item["keyPath"]);
1035  } else {
1036  return $item["keyPath"];
1037  }
1038  }
1039  }
1040  return '';
1041  }
1042  private function getCompleteEnumLabel($key, array & $enums, $prefix)
1043  {
1044  foreach ($enums as $item) {
1045  if ($item["key"] === $key) {
1046  $translatedEnumValue = _($prefix . $key);
1047  if ($translatedEnumValue != $prefix . $key) {
1048  $label = $translatedEnumValue;
1049  } else {
1050  $label = $item["label"];
1051  }
1052  if ($item["parentkey"] !== null) {
1053 
1054  return sprintf("%s/%s", $this->getCompleteEnumLabel($item["parentkey"], $enums, $prefix) , $label);
1055  } else {
1056  return $label;
1057  }
1058  }
1059  }
1060  return '';
1061  }
1062  /**
1063  * reset Enum cache
1064  */
1065  public static function resetEnum()
1066  {
1067  self::_cacheFlush(self::_cEnum);
1068  self::_cacheFlush(self::_cEnumLabel);
1069  self::_cacheFlush(self::_cParent);
1070  }
1071  /**
1072  * return array of enumeration definition
1073  * the array'skeys are the enum single key and the values are the complete labels
1074  *
1075  * @param string $enumid the key of enumerate (if no parameter all labels are returned
1076  * @param bool $returnDisabled if false disabled enum are not returned
1077  * @return array|string|null
1078  */
1079  function getEnumLabel($enumid = null, $returnDisabled = true)
1080  {
1081  $implode = false;
1082  $this->getEnum($returnDisabled);
1083 
1084  $cached = self::_cacheFetch(self::_cEnumLabel, array(
1085  $this->docid,
1086  $this->id
1087  ) , null, $returnDisabled);
1088  if ($cached === null) {
1089  $famId = $this->_getRecursiveParentFamHavingAttribute($this->docid, $this->id);
1090  if ($famId !== $this->docid) {
1091  $cached = self::_cacheFetch(self::_cEnumLabel, array(
1092  $famId,
1093  $this->id
1094  ) , null, $returnDisabled);
1095  }
1096  }
1097  if ($cached !== null) {
1098  if ($enumid === null) {
1099  return $cached;
1100  }
1101  if (strstr($enumid, "\n")) {
1102  $enumid = explode("\n", $enumid);
1103  $implode = true;
1104  }
1105  if (is_array($enumid)) {
1106  $tv = array();
1107  foreach ($enumid as $v) {
1108  $tv[] = (isset($cached[$v])) ? $cached[$v] : $v;
1109  }
1110  if ($implode) {
1111  return implode("\n", $tv);
1112  }
1113  return $tv;
1114  } else {
1115  return (array_key_exists($enumid, $cached)) ? $cached[$enumid] : $enumid;
1116  }
1117  }
1118 
1119  return null;
1120  }
1121  /**
1122  * add new item in enum list items
1123  *
1124  * @param string $dbaccess dbaccess string
1125  * @param string $key database key
1126  * @param string $label human label
1127  *
1128  * @return string error message (empty means ok)
1129  */
1130  function addEnum($dbaccess, $key, $label)
1131  {
1132  $err = '';
1133  if ($key == "") return "";
1134 
1135  $famId = $this->docid;
1136  $attrId = $this->id;
1137 
1138  $a = new DocAttr($dbaccess, array(
1139  $famId,
1140  $attrId
1141  ));
1142  if (!$a->isAffected()) {
1143  /* Search attribute in parents */
1144  $a = $this->_getDocAttrFromParents($dbaccess, $famId, $attrId);
1145  if ($a === false) {
1146  $err = sprintf(_("unknow attribute %s (family %s)") , $attrId, $famId);
1147  return $err;
1148  }
1149  }
1150  if ($a->isAffected()) {
1151  $famId = $a->docid;
1152  $oe = new DocEnum($dbaccess, array(
1153  $famId,
1154  $attrId,
1155  $key
1156  ));
1157  $this->getEnum();
1158 
1159  $key = str_replace(array(
1160  '|'
1161  ) , array(
1162  '_'
1163  ) , $key);
1164  $label = str_replace(array(
1165  '|'
1166  ) , array(
1167  '_'
1168  ) , $label);
1169  if (!$oe->isAffected()) {
1170  $oe->attrid = $attrId;
1171  $oe->famid = $famId;
1172  $oe->key = $key;
1173  $oe->label = $label;
1174  /* Store enum in database */
1175  $err = $oe->add();
1176  if ($err == '') {
1177  /* Update cache */
1178  $cachedEnum = self::_cacheFetch(self::_cEnum, array(
1179  $famId,
1180  $this->id
1181  ) , array());
1182  $cachedEnumLabel = self::_cacheFetch(self::_cEnumLabel, array(
1183  $famId,
1184  $this->id
1185  ) , array());
1186  $cachedEnum[$key] = $label;
1187  $cachedEnumLabel[$key] = $label;
1188  self::_cacheStore(self::_cEnum, array(
1189  $famId,
1190  $this->id
1191  ) , $cachedEnum);
1192  self::_cacheStore(self::_cEnumLabel, array(
1193  $famId,
1194  $this->id
1195  ) , $cachedEnumLabel);
1196  }
1197  }
1198  } else {
1199  $err = sprintf(_("unknow attribute %s (family %s)") , $attrId, $famId);
1200  }
1201  return $err;
1202  }
1203  private function _getRecursiveParentFamHavingAttribute($famId, $attrId)
1204  {
1205  $cached = self::_cacheFetch(self::_cParent, array(
1206  $famId,
1207  $attrId
1208  ));
1209  if ($cached !== null) {
1210  return $cached;
1211  }
1212  $sql = <<<'SQL'
1213 WITH RECURSIVE parent_attr(fromid, docid, id) AS (
1214  SELECT
1215  docfam.fromid,
1216  docattr.docid,
1217  docattr.id
1218  FROM
1219  docattr,
1220  docfam
1221  WHERE
1222  docattr.docid = docfam.id
1223  AND
1224  docattr.docid = %d
1225 
1226  UNION
1227 
1228  SELECT
1229  docfam.fromid,
1230  docattr.docid,
1231  docattr.id
1232  FROM
1233  docattr,
1234  docfam,
1235  parent_attr
1236  WHERE
1237  docattr.docid = parent_attr.fromid
1238  AND
1239  parent_attr.fromid = docfam.id
1240 )
1241 SELECT docid FROM parent_attr WHERE id = '%s' LIMIT 1;
1242 SQL;
1243  $sql = sprintf($sql, pg_escape_string($famId) , pg_escape_string($attrId));
1244  $parentFamId = false;
1245  simpleQuery('', $sql, $parentFamId, true, true);
1246  if ($parentFamId !== false) {
1247  self::_cacheStore(self::_cParent, array(
1248  $famId,
1249  $attrId
1250  ) , $parentFamId);
1251  }
1252  return $parentFamId;
1253  }
1254  private function _getDocAttrFromParents($dbaccess, $famId, $attrId)
1255  {
1256  $parentFamId = $this->_getRecursiveParentFamHavingAttribute($famId, $attrId);
1257  if ($parentFamId === false) {
1258  return false;
1259  }
1260  $a = new DocAttr($dbaccess, $parentFamId, $attrId);
1261  return $a;
1262  }
1263  /**
1264  * Test if an enum key exists
1265  *
1266  * @param string $key enumKey
1267  * @param bool $completeKey if true test complete key with path else without path
1268  * @return bool
1269  */
1270  function existEnum($key, $completeKey = true)
1271  {
1272  if ($key == "") {
1273  return false;
1274  }
1275 
1276  if ($completeKey) {
1277  $enumKeys = $this->getEnum();
1278  } else {
1279  $enumKeys = $this->getEnumLabel();
1280  }
1281  return isset($enumKeys[$key]);
1282  }
1283  /**
1284  * Construct a string key
1285  *
1286  * @param mixed $k key
1287  * @return string
1288  */
1289  private static function _cacheKey($k)
1290  {
1291  if (is_scalar($k)) {
1292  return $k;
1293  } else if (is_array($k)) {
1294  return implode(':', $k);
1295  }
1296  return serialize($k);
1297  }
1298  /**
1299  * Check if an entry exists for the given key
1300  *
1301  * @param string $cacheId cache Id
1302  * @param string $k key
1303  * @return bool true if it exists, false if it does not exists
1304  */
1305  private static function _cacheExists($cacheId, $k)
1306  {
1307  $k = self::_cacheKey($k);
1308  return isset(self::$_cache[$cacheId][$k]);
1309  }
1310  /**
1311  * Add (or update) a key/value
1312  *
1313  * @param string $cacheId cache Id
1314  * @param string $k key
1315  * @param mixed $v value
1316  * @return bool true on success, false on failure
1317  */
1318  private static function _cacheStore($cacheId, $k, $v)
1319  {
1320  $k = self::_cacheKey($k);
1321  self::$_cache[$cacheId][$k] = $v;
1322  return true;
1323  }
1324  /**
1325  * Fetch the key's value
1326  *
1327  * @param string $cacheId cache Id
1328  * @param string $k key
1329  * @param mixed $onCacheMiss value returned on cache miss (default is null)
1330  * @param bool $returnDisabled if false unreturn disabled enums
1331  * @return null|mixed null on failure, mixed value on success
1332  */
1333  private static function _cacheFetch($cacheId, $k, $onCacheMiss = null, $returnDisabled = true)
1334  {
1335  if (self::_cacheExists($cacheId, $k)) {
1336  $ks = self::_cacheKey($k);
1337  if (!$returnDisabled) {
1338  $famId = $k[0];
1339  $attrid = $k[1];
1340  $disabledKeys = DocEnum::getDisabledKeys($famId, $attrid);
1341  if (!empty($disabledKeys)) {
1342  $cached = self::$_cache[$cacheId][$ks];
1343  foreach ($disabledKeys as $dKey) {
1344  unset($cached[$dKey]);
1345  }
1346  return $cached;
1347  }
1348  }
1349 
1350  return self::$_cache[$cacheId][$ks];
1351  }
1352  return $onCacheMiss;
1353  }
1354  /**
1355  * Remove a key and it's value from the cache
1356  *
1357  * @param string $cacheId cache Id
1358  * @param string $k key
1359  * @return bool true on success, false on failure
1360  */
1361  private static function _cacheRemove($cacheId, $k)
1362  {
1363  if (self::_cacheExists($cacheId, $k)) {
1364  $k = self::_cacheKey($k);
1365  unset(self::$_cache[$cacheId][$k]);
1366  }
1367  return true;
1368  }
1369  /**
1370  * Flush the cache contents
1371  *
1372  * @param string|null $cacheId cache Id or null (default) to flush all caches
1373  * @return void
1374  */
1375  private static function _cacheFlush($cacheId = null)
1376  {
1377  if ($cacheId === null) {
1378  self::$_cache = array();
1379  } else {
1380  self::$_cache[$cacheId] = array();
1381  }
1382  }
1383 }
1384 /**
1385  * Structural attribute (attribute that contain other attribute : tab, frame)
1386  *
1387  * @author Anakeen
1388  *
1389  */
1390 class FieldSetAttribute extends BasicAttribute
1391 {
1392  /**
1393  * Constructor
1394  *
1395  * @param string $id $docid famid
1396  * @param string $docid
1397  * @param string $label default translation key
1398  * @param string $visibility visibility option
1399  * @param string $usefor Attr or Param usage
1400  * @param string $type kind of
1401  * @param FieldSetAttribute $fieldSet parent field
1402  * @param string $options option string
1403  * @param string $docname
1404  */
1405  function __construct($id, $docid, $label, $visibility = "", $usefor = "", $type = "frame", &$fieldSet = null, $options = "", $docname = "")
1406  {
1407  $this->id = $id;
1408  $this->docid = $docid;
1409  $this->labelText = $label;
1410  $this->visibility = $visibility;
1411  $this->usefor = $usefor;
1412  $this->type = $type;
1413  $this->fieldSet = & $fieldSet;
1414  $this->options = $options;
1415  $this->docname = $docname;
1416  }
1417  /**
1418  * Generate the xml schema fragment
1419  *
1420  * @param BasicAttribute[] $la
1421  *
1422  * @return string
1423  */
1424  function getXmlSchema($la)
1425  {
1426  $lay = new Layout(getLayoutFile("FDL", "fieldattribute_schema.xml"));
1427  $lay->set("aname", $this->id);
1428  $this->common_getXmlSchema($lay);
1429 
1430  $lay->set("minOccurs", "0");
1431  $lay->set("maxOccurs", "1");
1432  $lay->set("notop", ($this->fieldSet->id != '' && $this->fieldSet->id != Adoc::HIDDENFIELD));
1433  $tax = array();
1434  foreach ($la as $k => $v) {
1435  if ($v->fieldSet && $v->fieldSet->id == $this->id) {
1436  $tax[] = array(
1437  "axs" => $v->getXmlSchema($la)
1438  );
1439  }
1440  }
1441 
1442  $lay->setBlockData("ATTR", $tax);
1443  return $lay->gen();
1444  }
1445  /**
1446  * export values as xml fragment
1447  *
1448  * @param Doc $doc working doc
1449  * @param exportOptionAttribute $opt
1450  * @deprecated use \Dcp\ExportXmlDocument class instead
1451  *
1452  * @return string
1453  */
1454  function getXmlValue(Doc & $doc, $opt = false)
1455  {
1456  $la = $doc->getAttributes();
1457  $xmlvalues = array();
1458  foreach ($la as $k => $v) {
1459  /*
1460  * @var NormalAttribute $v
1461  */
1462  if ($v->fieldSet && $v->fieldSet->id == $this->id && (empty($opt->exportAttributes[$doc->fromid]) || in_array($v->id, $opt->exportAttributes[$doc->fromid]))) {
1463  $value = $v->getXmlValue($doc, $opt);
1464  if ($v->type == "htmltext" && $opt !== false) {
1465  $value = $v->prepareHtmltextForExport($value);
1466  if ($opt->withFile) {
1467  $value = preg_replace_callback('/(&lt;img.*?)src="(((?=.*docid=(.*?)&)(?=.*attrid=(.*?)&)(?=.*index=(-?[0-9]+)))|(file\/(.*?)\/[0-9]+\/(.*?)\/(-?[0-9]+))).*?"/', function ($matches) use ($opt)
1468  {
1469  if (isset($matches[7])) {
1470  $docid = $matches[8];
1471  $attrid = $matches[9];
1472  $index = $matches[10] == "-1" ? 0 : $matches[10];
1473  } else {
1474  $docid = $matches[4];
1475  $index = $matches[6] == "-1" ? 0 : $matches[6];
1476  $attrid = $matches[5];
1477  }
1478  $doc = new_Doc(getDbAccess() , $docid);
1479  $attr = $doc->getAttribute($attrid);
1480  $tfiles = $doc->vault_properties($attr);
1481  $f = $tfiles[$index];
1482  if (is_file($f["path"])) {
1483  if ($opt->outFile) {
1484  return sprintf('%s title="%s" src="data:%s;base64,[FILE64:%s]"', "\n" . $matches[1], unaccent($f["name"]) , $f["mime_s"], $f["path"]);
1485  } else {
1486  return sprintf('%s title="%s" src="data:%s;base64,%s"', "\n" . $matches[1], unaccent($f["name"]) , $f["mime_s"], base64_encode(file_get_contents($f["path"])));
1487  }
1488  } else {
1489  return sprintf('%s title="%s" src="data:%s;base64,file not found"', "\n" . $matches[1], unaccent($f["name"]) , $f["mime_s"]);
1490  }
1491  }
1493  }
1494  }
1495  $xmlvalues[] = $value;
1496  }
1497  }
1498  if ($opt->flat) return implode("\n", $xmlvalues);
1499  else return sprintf("<%s>%s</%s>", $this->id, implode("\n", $xmlvalues) , $this->id);
1500  }
1501 }
1502 
1503 class MenuAttribute extends BasicAttribute
1504 {
1505  public $link; // hypertext link
1506  public $precond; // pre-condition to activate menu
1507  function __construct($id, $docid, $label, $order, $link, $visibility = "", $precond = "", $options = "", $docname = "")
1508  {
1509  $this->id = $id;
1510  $this->docid = $docid;
1511  $this->labelText = $label;
1512  $this->ordered = $order;
1513  $this->link = $link;
1514  $this->visibility = $visibility;
1515  $this->options = $options;
1516  $this->precond = $precond;
1517  $this->type = "menu";
1518  $this->docname = $docname;
1519  }
1520 }
1521 
1522 class ActionAttribute extends BasicAttribute
1523 {
1524 
1525  public $wapplication; // the what application name
1526  public $waction; // the what action name
1527  public $precond; // pre-condition to activate action
1528  function __construct($id, $docid, $label, $order, $visibility = "", $wapplication = "", $waction = "", $precond = "", $options = "", $docname = "")
1529  {
1530  $this->id = $id;
1531  $this->docid = $docid;
1532  $this->labelText = $label;
1533  $this->visibility = $visibility;
1534  $this->ordered = $order;
1535  $this->waction = $waction;
1536  $this->wapplication = $wapplication;
1537  $this->options = $options;
1538  $this->precond = $precond;
1539  $this->type = "action";
1540  $this->docname = $docname;
1541  }
1542  function getLink($docid)
1543  {
1544  $l = getParam("CORE_STANDURL");
1545  $batch = ($this->getOption("batchfolder") == "yes");
1546  if ($batch) {
1547  $l.= "&app=FREEDOM&action=BATCHEXEC&sapp=" . $this->wapplication;
1548  $l.= "&saction=" . $this->waction;
1549  $l.= "&id=" . $docid;
1550  } else {
1551  $l.= "&app=" . $this->wapplication;
1552  $l.= "&action=" . $this->waction;
1553  if (!stristr($this->waction, "&id=")) $l.= "&id=" . $docid;
1554  }
1555  return $l;
1556  }
1558 
1560 {
1561  /**
1562  * @var array
1563  */
1564  public $exportAttributes;
1565  /**
1566  * @var bool
1567  */
1568  public $flat;
1569  /**
1570  * @var bool
1571  */
1572  public $withIdentifier;
1573  /**
1574  * @var bool
1575  */
1576  public $withFile;
1577  /**
1578  * @var string
1579  */
1580  public $outFile;
1581  /**
1582  * @var int
1583  */
1584  public $index;
1585 }
1586 
1587 class EnumAttributeTools
1588 {
1589  /**
1590  * convert enum flat notation to an array of item (key/label).
1591  * @param string $phpfunc the flat notation
1592  * @param array $theEnum [out] the enum array converted
1593  * @param array $theEnumlabel [out] the enum array converted - with complete labels in case of levels
1594  * @param string $locale the prefix key for locale values (if empty no locale are set)
1595  * @return array
1596  */
1597  public static function flatEnumNotationToEnumArray($phpfunc, array & $theEnum, array & $theEnumlabel = array() , $locale = '')
1598  {
1599 
1600  if (!$phpfunc) return array();
1601  if (preg_match('/^\[[a-z]*\](.*)/', $phpfunc, $reg)) {
1602  //delete old enum format syntax
1603  $phpfunc = $reg[1];
1604  }
1605  // set the enum array
1606  $theEnum = array();
1607  $theEnumlabel = array();
1608 
1609  $sphpfunc = str_replace("\\.", "-dot-", $phpfunc); // to replace dot & comma separators
1610  $sphpfunc = str_replace("\\,", "-comma-", $sphpfunc);
1611  if ($sphpfunc == "-") $sphpfunc = ""; // it is recorded
1612  if ($sphpfunc != "") {
1613  $tenum = explode(",", $sphpfunc);
1614  foreach ($tenum as $k => $v) {
1615  list($enumKey, $enumValue) = explode("|", $v, 2);
1616  $treeKeys = explode(".", $enumKey);
1617  $enumKey = trim($enumKey);
1618  if (strlen($enumKey) == 0) $enumKey = " ";
1619  $enumValue = trim($enumValue);
1620 
1621  $n = count($treeKeys);
1622  if ($n <= 1) {
1623  $enumValue = str_replace(array(
1624  '-dot-',
1625  '-comma-'
1626  ) , array(
1627  '\.',
1628  ','
1629  ) , $enumValue);
1630 
1631  if ($locale) {
1632  $translatedEnumValue = _($locale . $enumKey);
1633  if ($translatedEnumValue != $locale . $enumKey) {
1634  $enumValue = $translatedEnumValue;
1635  }
1636  }
1637 
1638  $theEnum[str_replace(array(
1639  '-dot-',
1640  '-comma-'
1641  ) , array(
1642  '\.',
1643  ','
1644  ) , $enumKey) ] = $enumValue;
1645  $theEnumlabel[str_replace(array(
1646  '-dot-',
1647  '-comma-'
1648  ) , array(
1649  '.',
1650  ','
1651  ) , $enumKey) ] = $enumValue;
1652  } else {
1653  $enumlabelKey = '';
1654  $tmpKey = '';
1655  $previousKey = '';
1656  foreach ($treeKeys as $i => $treeKey) {
1657  $enumlabelKey = $treeKey;
1658 
1659  if ($i < $n - 1) {
1660  if ($i > 0) {
1661  $tmpKey.= '.';
1662  }
1663  $tmpKey.= $treeKey;
1664  }
1665  }
1666  $tmpKey = str_replace(array(
1667  '-dot-',
1668  '-comma-'
1669  ) , array(
1670  '\.',
1671  ','
1672  ) , $tmpKey);
1673 
1674  if ($locale) {
1675  $translatedEnumValue = _($locale . $enumlabelKey);
1676  if ($translatedEnumValue != $locale . $enumlabelKey) {
1677  $enumValue = $translatedEnumValue;
1678  }
1679  }
1680  $enumlabelValue = $theEnum[$tmpKey] . '/' . $enumValue;
1681  $enumlabelValue = str_replace(array(
1682  '-dot-',
1683  '-comma-'
1684  ) , array(
1685  '\.',
1686  ','
1687  ) , $enumlabelValue);
1688  $theEnum[str_replace(array(
1689  '-dot-',
1690  '-comma-'
1691  ) , array(
1692  '\.',
1693  ','
1694  ) , $enumKey) ] = $enumValue;
1695  $theEnumlabel[str_replace(array(
1696  '-dot-',
1697  '-comma-'
1698  ) , array(
1699  '.',
1700  ','
1701  ) , $enumlabelKey) ] = $enumlabelValue;
1702  }
1703  }
1704  }
1705 
1706  return $theEnum;
1707  }
1708 
1709  private static function getEnumHierarchy($key, $parents)
1710  {
1711  if (isset($parents[$key])) {
1712  return array_merge(self::getEnumHierarchy($parents[$key], $parents) , array(
1713  $key
1714  ));
1715  } else {
1716  return array(
1717  $key
1718  );
1719  }
1720  }
1721  /**
1722  * return flat notation from docenum database table
1723  * @param int $famid family identifier
1724  * @param string $attrid attribute identifier
1725  * @return string ftat enum
1726  */
1727  public static function getFlatEnumNotation($famid, $attrid)
1728  {
1729  $sql = sprintf("select * from docenum where famid='%s' and attrid='%s' and (disabled is null or not disabled) order by eorder", pg_escape_string($famid) , pg_escape_string($attrid));
1730  simpleQuery('', $sql, $results);
1731  $tItems = array();
1732  $hierarchy = array();
1733  foreach ($results as $item) {
1734  if ($item["parentkey"] !== null) {
1735  $hierarchy[$item["key"]] = $item["parentkey"];
1736  }
1737  }
1738  foreach ($results as $item) {
1739  $key = $item["key"];
1740  $label = $item["label"];
1741  if ($item["parentkey"] !== null) {
1742  $parents = self::getEnumHierarchy($key, $hierarchy);
1743  foreach ($parents as & $pKey) {
1744  $pKey = str_replace(".", '-dot-', $pKey);
1745  }
1746  $key = implode('.', $parents);
1747  $key = str_replace('-dot-', '\\.', $key);
1748  } else {
1749  $key = str_replace('.', '\\.', $key);
1750  }
1751  $tItems[] = sprintf("%s|%s", str_replace(',', '\\,', $key) , str_replace(',', '\\,', $label));
1752  }
1753  return implode(",", $tItems);
1754  }
1755 }
1756 ?>
Layout is a template generator.
vault_properties(NormalAttribute $attr)
Definition: Class.Doc.php:8224
if(substr($wsh, 0, 1)!= '/') $args
$s type
Definition: dav.php:73
static encodeXml($s, $quot=false)
if($_POST["login"]=="")
Definition: chgpasswd.php:19
getTDoc($dbaccess, $id, $sqlfilters=array(), $result=array())
global $action
getXmlValue(Doc &$doc, $opt=false)
getLastTitle($id="-1", $def="")
Definition: Class.Doc.php:8702
& getAttribute($idAttr, &$oa=null, $useMask=true)
Definition: Class.Doc.php:2152
stringDateToIso($date, $format=false, $withT=false)
Definition: Lib.Util.php:246
print< H1 > Check Database< i > $dbaccess</i ></H1 > $a
Definition: checklist.php:45
__construct($id, $docid, $label, $visibility="", $usefor="", $type="frame", &$fieldSet=null, $options="", $docname="")
getEnum($returnDisabled=true)
__construct($id, $docid, $label, $order, $link, $visibility="", $precond="", $options="", $docname="")
const PREGEXPFILE
Definition: Class.Doc.php:54
$locale
static getDisabledKeys($famId, $attrid)
if($famId) $s
getEnumLabel($enumid=null, $returnDisabled=true)
getArrayRawValues($idAttr, $index=-1)
Definition: Class.Doc.php:3292
if($app->id > 0) return false
print docid
Definition: migrEnum.php:33
static flatEnumNotationToEnumArray($phpfunc, array &$theEnum, array &$theEnumlabel=array(), $locale= '')
getLayoutFile($app, $layfile)
Definition: Lib.Common.php:258
__construct($id, $docid, $label, $order, $visibility="", $wapplication="", $waction="", $precond="", $options="", $docname="")
$path
Definition: dav.php:39
getMultipleRawValues($idAttr, $def="", $index=-1)
Definition: Class.Doc.php:3240
static getFlatEnumNotation($famid, $attrid)
getParam($name, $def="")
must be in core or global type
Definition: Lib.Common.php:193
addEnum($dbaccess, $key, $label)
__construct($id, $docid, $label, $type, $format, $repeat, $order, $link, $visibility, $needed, $isInTitle, $isInAbstract, &$fieldSet, $phpfile, $phpfunc, $elink, $phpconstraint="", $usefor="", $eformat="", $options="", $docname="")
getFileLink($attrid, $index=-1, $cache=false, $inline=false, $otherValue= '', $info=null)
Definition: Class.Doc.php:6293
$oe
Definition: migrEnum.php:37
getTextualValue(Doc $doc, $index=-1, Array $configuration=array())
existEnum($key, $completeKey=true)
getDbAccess()
Definition: Lib.Common.php:368
getTextualValue(Doc $doc, $index=-1, Array $configuration=array())
new_Doc($dbaccess, $id= '', $latest=false)
getNameFromId($dbaccess, $id)
getNumberValue(Doc $doc, $index=-1, $decimalSeparator=".")
& getAttributes($useMask=true)
Definition: Class.Doc.php:2174
$dbaccess
Definition: checkVault.php:17
$info
Definition: geticon.php:30
unaccent($s)
Definition: Lib.Util.php:569
simpleQuery($dbaccess, $query, &$result=array(), $singlecolumn=false, $singleresult=false, $useStrict=null)
Definition: Lib.Common.php:484
if($file) if($subject==""&&$file) if($subject=="") $err
__construct($id, $docid, $label)
getRawValue($idAttr, $def="")
Definition: Class.Doc.php:3117
getXmlValue(Doc &$doc, $opt=false)
$value
getOption($x, $def="")
prepareHtmltextForExport($value)
vault_filename_fromvalue($fileid, $path=false)
Definition: Class.Doc.php:8188
getXmlValue(Doc &$doc, $opt=false)
$options
mask visibility
← centre documentaire © anakeen