dolibarr  21.0.0-alpha
modulebuilder.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2009-2010 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  * or see https://www.gnu.org/
18  */
19 
39 function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = '', $addfieldentry = array(), $delfieldentry = '')
40 {
41  global $db, $langs;
42 
43  if (empty($objectname)) {
44  return -6;
45  }
46  if (empty($readdir)) {
47  $readdir = $destdir;
48  }
49 
50  if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) {
51  dol_print_error(null, 'Bad parameter addfieldentry with a property arrayofkeyval defined but that is not an array.');
52  return -7;
53  }
54 
55  $error = 0;
56 
57  // Check parameters
58  if (is_array($addfieldentry) && count($addfieldentry) > 0) {
59  if (empty($addfieldentry['name'])) {
60  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Name")), null, 'errors');
61  return -2;
62  }
63  if (empty($addfieldentry['label'])) {
64  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Label")), null, 'errors');
65  return -2;
66  }
67  if (!preg_match('/^(integer|price|sellist|varchar|double|text|html|duration)/', $addfieldentry['type'])
68  && !preg_match('/^(boolean|smallint|real|date|datetime|timestamp|phone|mail|url|ip|password)$/', $addfieldentry['type'])) {
69  setEventMessages($langs->trans('BadValueForType', $addfieldentry['type']), null, 'errors');
70  return -2;
71  }
72  }
73 
74  $pathoffiletoeditsrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
75  $pathoffiletoedittarget = $destdir.'/class/'.strtolower($objectname).'.class.php'.($readdir != $destdir ? '.new' : '');
76  if (!dol_is_file($pathoffiletoeditsrc)) {
77  $langs->load("errors");
78  setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
79  return -3;
80  }
81 
82  //$pathoffiletoedittmp=$destdir.'/class/'.strtolower($objectname).'.class.php.tmp';
83  //dol_delete_file($pathoffiletoedittmp, 0, 1, 1);
84 
85  try {
86  include_once $pathoffiletoeditsrc;
87  if (class_exists($objectname)) {
88  $object = new $objectname($db);
89  } else {
90  return -4;
91  }
92  '@phan-var-force CommonObject $object';
93 
94  // Backup old file
95  dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
96 
97  // Edit class files
98  $contentclass = file_get_contents(dol_osencode($pathoffiletoeditsrc));
99 
100  // Update ->fields (to add or remove entries defined into $addfieldentry)
101  if (count($object->fields)) {
102  if (is_array($addfieldentry) && count($addfieldentry)) {
103  $name = $addfieldentry['name'];
104  unset($addfieldentry['name']);
105 
106  $object->fields[$name] = $addfieldentry;
107  }
108  if (!empty($delfieldentry)) {
109  $name = $delfieldentry;
110  unset($object->fields[$name]);
111  }
112  }
113 
114  dol_sort_array($object->fields, 'position');
115 
116  $i = 0;
117  $texttoinsert = '// BEGIN MODULEBUILDER PROPERTIES'."\n";
118  $texttoinsert .= "\t".''."\n";
121  $texttoinsert .= "\t".'public $fields=array('."\n";
122 
123  if (count($object->fields)) {
124  foreach ($object->fields as $key => $val) {
125  $i++;
126  $texttoinsert .= "\t\t".'"'.$key.'" => array(';
127  $texttoinsert .= '"type"=>"'.dol_escape_php($val['type']).'",';
128  $texttoinsert .= ' "label"=>"'.dol_escape_php($val['label']).'",';
129  if (!empty($val['picto'])) {
130  $texttoinsert .= ' "picto"=>"'.dol_escape_php($val['picto']).'",';
131  }
132  $texttoinsert .= ' "enabled"=>"'.($val['enabled'] !== '' ? dol_escape_php($val['enabled']) : 1).'",';
133  $texttoinsert .= " 'position'=>".($val['position'] !== '' ? (int) $val['position'] : 50).",";
134  $texttoinsert .= " 'notnull'=>".(empty($val['notnull']) ? 0 : (int) $val['notnull']).",";
135  $texttoinsert .= ' "visible"=>"'.($val['visible'] !== '' ? dol_escape_js($val['visible']) : -1).'",';
136  if (!empty($val['noteditable'])) {
137  $texttoinsert .= ' "noteditable"=>"'.dol_escape_php($val['noteditable']).'",';
138  }
139  if (!empty($val['alwayseditable'])) {
140  $texttoinsert .= ' "alwayseditable"=>"'.dol_escape_php($val['alwayseditable']).'",';
141  }
142  if (array_key_exists('default', $val) && (!empty($val['default']) || $val['default'] === '0')) {
143  $texttoinsert .= ' "default"=>"'.dol_escape_php($val['default']).'",';
144  }
145  if (!empty($val['index'])) {
146  $texttoinsert .= ' "index"=>"'.(int) $val['index'].'",';
147  }
148  if (!empty($val['foreignkey'])) {
149  $texttoinsert .= ' "foreignkey"=>"'.(int) $val['foreignkey'].'",';
150  }
151  if (!empty($val['searchall'])) {
152  $texttoinsert .= ' "searchall"=>"'.(int) $val['searchall'].'",';
153  }
154  if (!empty($val['isameasure'])) {
155  $texttoinsert .= ' "isameasure"=>"'.(int) $val['isameasure'].'",';
156  }
157  if (!empty($val['css'])) {
158  $texttoinsert .= ' "css"=>"'.dol_escape_php($val['css']).'",';
159  }
160  if (!empty($val['cssview'])) {
161  $texttoinsert .= ' "cssview"=>"'.dol_escape_php($val['cssview']).'",';
162  }
163  if (!empty($val['csslist'])) {
164  $texttoinsert .= ' "csslist"=>"'.dol_escape_php($val['csslist']).'",';
165  }
166  if (!empty($val['help'])) {
167  $texttoinsert .= ' "help"=>"'.dol_escape_php($val['help']).'",';
168  }
169  if (!empty($val['showoncombobox'])) {
170  $texttoinsert .= ' "showoncombobox"=>"'.(int) $val['showoncombobox'].'",';
171  }
172  if (!empty($val['disabled'])) {
173  $texttoinsert .= ' "disabled"=>"'.(int) $val['disabled'].'",';
174  }
175  if (!empty($val['autofocusoncreate'])) {
176  $texttoinsert .= ' "autofocusoncreate"=>"'.(int) $val['autofocusoncreate'].'",';
177  }
178  if (!empty($val['arrayofkeyval'])) {
179  $texttoinsert .= ' "arrayofkeyval"=>array(';
180  $i = 0;
181  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
182  if ($i) {
183  $texttoinsert .= ", ";
184  }
185  $texttoinsert .= '"'.dol_escape_php($key2).'" => "'.dol_escape_php($val2).'"';
186  $i++;
187  }
188  $texttoinsert .= '),';
189  }
190  if (!empty($val['validate'])) {
191  $texttoinsert .= ' "validate"=>"'.(int) $val['validate'].'",';
192  }
193  if (!empty($val['comment'])) {
194  $texttoinsert .= ' "comment"=>"'.dol_escape_php($val['comment']).'"';
195  }
196 
197  $texttoinsert .= "),\n";
198  //print $texttoinsert;
199  }
200  }
201 
202  $texttoinsert .= "\t".');'."\n";
203  //print ($texttoinsert);exit;
204 
205  if (count($object->fields)) {
206  //$typetotypephp=array('integer'=>'integer', 'duration'=>'integer', 'varchar'=>'string');
207 
208  foreach ($object->fields as $key => $val) {
209  $i++;
210  //$typephp=$typetotypephp[$val['type']];
211  $texttoinsert .= "\t".'public $'.$key.";";
212  //if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
213  //if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
214  //$texttoinsert.= ($val['notnull']?' NOT NULL':'');
215  //if ($i < count($object->fields)) $texttoinsert.=";";
216  $texttoinsert .= "\n";
217  }
218  }
219 
220  $texttoinsert .= "\t".'// END MODULEBUILDER PROPERTIES';
221 
222  //print($texttoinsert);
223 
224  $contentclass = preg_replace('/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims', $texttoinsert, $contentclass);
225  //print $contentclass;
226 
227  dol_mkdir(dirname($pathoffiletoedittarget));
228 
229  //file_put_contents($pathoffiletoedittmp, $contentclass);
230  $result = file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass);
231 
232  if ($result) {
233  dolChmod($pathoffiletoedittarget, $newmask);
234  } else {
235  $error++;
236  }
237 
238  return $error ? -1 : $object;
239  } catch (Exception $e) {
240  print $e->getMessage();
241  return -5;
242  }
243 }
244 
258 function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external')
259 {
260  global $db, $langs;
261 
262  $error = 0;
263 
264  if (empty($objectname)) {
265  return -1;
266  }
267  if (empty($readdir)) {
268  $readdir = $destdir;
269  }
270 
271  $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
272 
273  // Edit .sql file
274  if ($moduletype == 'internal') {
275  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
276  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
277  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'-'.strtolower($module).'.sql';
278  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
279  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
280  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
281  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'.sql';
282  }
283  }
284  }
285  } else {
286  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
287  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
288  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'-'.strtolower($module).'.sql';
289  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
290  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
291  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
292  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'.sql';
293  }
294  }
295  }
296  }
297 
298  // Complete path to be full path
299  $pathoffiletoedittarget = $destdir.$pathoffiletoeditsrc.($readdir != $destdir ? '.new' : '');
300  $pathoffiletoeditsrc = $readdir.$pathoffiletoeditsrc;
301 
302  if (!dol_is_file($pathoffiletoeditsrc)) {
303  $langs->load("errors");
304  setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
305  return -1;
306  }
307 
308  // Load object from myobject.class.php
309  try {
310  if (!is_object($object)) {
311  include_once $pathoffiletoclasssrc;
312  if (class_exists($objectname)) {
313  $object = new $objectname($db);
314  } else {
315  return -1;
316  }
317  }
318  } catch (Exception $e) {
319  print $e->getMessage();
320  }
321 
322  // Backup old file
323  dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
324 
325  $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc));
326 
327  $i = 0;
328  $texttoinsert = '-- BEGIN MODULEBUILDER FIELDS'."\n";
329  if (count($object->fields)) {
330  foreach ($object->fields as $key => $val) {
331  $i++;
332 
333  $type = $val['type'];
334  $type = preg_replace('/:.*$/', '', $type); // For case type = 'integer:Societe:societe/class/societe.class.php'
335 
336  if ($type == 'html') {
337  $type = 'text'; // html modulebuilder type is a text type in database
338  } elseif ($type == 'price') {
339  $type = 'double'; // html modulebuilder type is a text type in database
340  } elseif (in_array($type, array('link', 'sellist', 'duration'))) {
341  $type = 'integer';
342  } elseif ($type == 'mail') {
343  $type = 'varchar(128)';
344  } elseif ($type == 'phone') {
345  $type = 'varchar(20)';
346  } elseif ($type == 'ip') {
347  $type = 'varchar(32)';
348  }
349 
350  $texttoinsert .= "\t".$key." ".$type;
351  if ($key == 'rowid') {
352  $texttoinsert .= ' AUTO_INCREMENT PRIMARY KEY';
353  } elseif ($type == 'timestamp') {
354  $texttoinsert .= ' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP';
355  }
356  if ($key == 'entity') {
357  $texttoinsert .= ' DEFAULT 1';
358  } else {
359  if (!empty($val['default'])) {
360  if (preg_match('/^null$/i', $val['default'])) {
361  $texttoinsert .= " DEFAULT NULL";
362  } elseif (preg_match('/varchar/', $type)) {
363  $texttoinsert .= " DEFAULT '".$db->escape($val['default'])."'";
364  } else {
365  $texttoinsert .= (($val['default'] > 0) ? ' DEFAULT '.$val['default'] : '');
366  }
367  }
368  }
369  $texttoinsert .= ((!empty($val['notnull']) && $val['notnull'] > 0) ? ' NOT NULL' : '');
370  if ($i < count($object->fields)) {
371  $texttoinsert .= ", ";
372  }
373  $texttoinsert .= "\n";
374  }
375  }
376  $texttoinsert .= "\t".'-- END MODULEBUILDER FIELDS';
377 
378  $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql);
379 
380  $result = file_put_contents($pathoffiletoedittarget, $contentsql);
381  if ($result) {
382  dolChmod($pathoffiletoedittarget, $newmask);
383  } else {
384  $error++;
385  setEventMessages($langs->trans("ErrorFailToCreateFile", $pathoffiletoedittarget), null, 'errors');
386  }
387 
388  // Edit .key.sql file
389  $pathoffiletoeditsrc = preg_replace('/\.sql$/', '.key.sql', $pathoffiletoeditsrc);
390  $pathoffiletoedittarget = preg_replace('/\.sql$/', '.key.sql', $pathoffiletoedittarget);
391  $pathoffiletoedittarget = preg_replace('/\.sql.new$/', '.key.sql.new', $pathoffiletoedittarget);
392 
393  $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc));
394 
395  $i = 0;
396  $texttoinsert = '-- BEGIN MODULEBUILDER INDEXES'."\n";
397  if (count($object->fields)) {
398  foreach ($object->fields as $key => $val) {
399  $i++;
400  if (!empty($val['index'])) {
401  $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
402  $texttoinsert .= "\n";
403  }
404  if (!empty($val['foreignkey'])) {
405  $tmp = explode('.', $val['foreignkey']);
406  if (!empty($tmp[0]) && !empty($tmp[1])) {
407  $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD CONSTRAINT llx_".strtolower($module).'_'.strtolower($objectname)."_".$key." FOREIGN KEY (".$key.") REFERENCES llx_".preg_replace('/^llx_/', '', $tmp[0])."(".$tmp[1].");";
408  $texttoinsert .= "\n";
409  }
410  }
411  }
412  }
413  $texttoinsert .= '-- END MODULEBUILDER INDEXES';
414 
415  $contentsql = preg_replace('/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsql);
416 
417  dol_mkdir(dirname($pathoffiletoedittarget));
418 
419  $result2 = file_put_contents($pathoffiletoedittarget, $contentsql);
420  if ($result2) {
421  dolChmod($pathoffiletoedittarget, $newmask);
422  } else {
423  $error++;
424  setEventMessages($langs->trans("ErrorFailToCreateFile", $pathoffiletoedittarget), null, 'errors');
425  }
426 
427  return $error ? -1 : 1;
428 }
429 
436 function dolGetListOfObjectClasses($destdir)
437 {
438  $objects = array();
439  $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
440  foreach ($listofobject as $fileobj) {
441  if (preg_match('/^api_/', $fileobj['name'])) {
442  continue;
443  }
444  if (preg_match('/^actions_/', $fileobj['name'])) {
445  continue;
446  }
447 
448  $tmpcontent = file_get_contents($fileobj['fullname']);
449  $reg = array();
450  if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
451  $objectnameloop = $reg[1];
452  $objects[$fileobj['fullname']] = $objectnameloop;
453  }
454  }
455  if (count($objects) > 0) {
456  return $objects;
457  }
458 
459  return -1;
460 }
461 
469 function checkExistComment($file, $number)
470 {
471  if (!file_exists($file)) {
472  return -1;
473  }
474 
475  $content = file_get_contents($file);
476  if ($number === 0) {
477  $ret = 0;
478  if (strpos($content, '/* BEGIN MODULEBUILDER TOPMENU MYOBJECT */') !== false
479  || strpos($content, '/* BEGIN MODULEBUILDER TOPMENU */') !== false) {
480  $ret++;
481  }
482  if (strpos($content, '/* END MODULEBUILDER TOPMENU MYOBJECT */') !== false
483  || strpos($content, '/* END MODULEBUILDER TOPMENU */') !== false) {
484  $ret++;
485  }
486  if (strpos($content, '/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */') !== false) {
487  $ret++;
488  }
489  if (strpos($content, '/* END MODULEBUILDER LEFTMENU MYOBJECT */') !== false) {
490  $ret++;
491  }
492 
493  if ($ret == 4) {
494  return 1;
495  }
496  } elseif ($number === 1) {
497  if (strpos($content, '/* BEGIN MODULEBUILDER PERMISSIONS */') !== false && strpos($content, '/* END MODULEBUILDER PERMISSIONS */') !== false) {
498  return 1;
499  }
500  } elseif ($number == 2) {
501  if (strpos($content, '/* BEGIN MODULEBUILDER DICTIONARIES */') !== false && strpos($content, '/* END MODULEBUILDER DICTIONARIES */') !== false) {
502  return 1;
503  }
504  }
505  return -1;
506 }
513 function deletePerms($file)
514 {
515  $start = "/* BEGIN MODULEBUILDER PERMISSIONS */";
516  $end = "/* END MODULEBUILDER PERMISSIONS */";
517  $i = 1;
518  $array = array();
519  $lines = file($file);
520  // Search for start and end lines
521  foreach ($lines as $i => $line) {
522  if (strpos($line, $start) !== false) {
523  $start_line = $i + 1;
524 
525  // Copy lines until the end on array
526  while (($line = $lines[++$i]) !== false) {
527  if (strpos($line, $end) !== false) {
528  $end_line = $i + 1;
529  break;
530  }
531  $array[] = $line;
532  }
533  break;
534  }
535  }
536  $allContent = implode("", $array);
537  dolReplaceInFile($file, array($allContent => ''));
538 }
539 
546 function compareFirstValue($a, $b)
547 {
548  return strcmp($a[0], $b[0]);
549 }
561 function reWriteAllPermissions($file, $permissions, $key, $right, $objectname, $module, $action)
562 {
563  $error = 0;
564  $rights = array();
565  if ($action == 0) {
566  // delete right from permissions array
567  array_splice($permissions, array_search($permissions[$key], $permissions), 1);
568  } elseif ($action == 1) {
569  array_push($permissions, $right);
570  } elseif ($action == 2 && !empty($right)) {
571  // update right from permissions array
572  array_splice($permissions, array_search($permissions[$key], $permissions), 1, $right);
573  } elseif ($action == -1 && !empty($objectname)) {
574  // when delete object
575  $key = null;
576  $right = null;
577  foreach ($permissions as $perms) {
578  if ($perms[4] === strtolower($objectname)) {
579  array_splice($permissions, array_search($perms, $permissions), 1);
580  }
581  }
582  } elseif ($action == -2 && !empty($objectname) && !empty($module)) {
583  $key = null;
584  $right = null;
585  $objectOfRights = array();
586  //check if object already declared in rights file
587  foreach ($permissions as $right) {
588  $objectOfRights[] = $right[4];
589  }
590  if (in_array(strtolower($objectname), $objectOfRights)) {
591  $error++;
592  } else {
593  $permsToadd = array();
594  $perms = array(
595  'read' => 'Read '.$objectname.' object of '.ucfirst($module),
596  'write' => 'Create/Update '.$objectname.' object of '.ucfirst($module),
597  'delete' => 'Delete '.$objectname.' object of '.ucfirst($module)
598  );
599  $i = 0;
600  foreach ($perms as $index => $value) {
601  $permsToadd[$i][0] = '';
602  $permsToadd[$i][1] = $value;
603  $permsToadd[$i][4] = strtolower($objectname);
604  $permsToadd[$i][5] = $index;
605  array_push($permissions, $permsToadd[$i]);
606  $i++;
607  }
608  }
609  } else {
610  $error++;
611  }
612  '@phan-var-force array<int,string[]> $permissions';
613  if (!$error) {
614  // prepare permissions array
615  $count_perms = count($permissions);
616  foreach (array_keys($permissions) as $i) {
617  $permissions[$i][0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', \$r + 1)";
618  $permissions[$i][1] = "\$this->rights[\$r][1] = '".$permissions[$i][1]."'";
619  $permissions[$i][4] = "\$this->rights[\$r][4] = '".$permissions[$i][4]."'";
620  $permissions[$i][5] = "\$this->rights[\$r][5] = '".$permissions[$i][5]."';\n\t\t";
621  }
622  // for group permissions by object
623  $perms_grouped = array();
624  foreach ($permissions as $perms) {
625  $object = $perms[4];
626  if (!isset($perms_grouped[$object])) {
627  $perms_grouped[$object] = [];
628  }
629  $perms_grouped[$object][] = $perms;
630  }
631  //$perms_grouped = array_values($perms_grouped);
632  $permissions = $perms_grouped;
633 
634 
635  // parcourir les objects
636  $o = 0;
637  foreach ($permissions as &$object) {
638  // récupérer la permission de l'objet
639  $p = 1;
640  foreach ($object as &$obj) {
641  if (str_contains($obj[5], 'read')) {
642  $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 0 + 1)";
643  } elseif (str_contains($obj[5], 'write')) {
644  $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 1 + 1)";
645  } elseif (str_contains($obj[5], 'delete')) {
646  $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 2 + 1)";
647  } else {
648  $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + ".$p." + 1)";
649  $p++;
650  }
651  }
652  usort($object, 'compareFirstValue');
653  $o++;
654  }
655 
656  //convert to string
657  foreach ($permissions as $perms) {
658  foreach ($perms as $per) {
659  $rights[] = implode(";\n\t\t", $per);
660  $rights[] = "\$r++;\n\t\t";
661  }
662  }
663  $rights_str = implode("", $rights);
664  // delete all permissions from file
665  deletePerms($file);
666  // rewrite all permissions again
667  dolReplaceInFile($file, array('/* BEGIN MODULEBUILDER PERMISSIONS */' => '/* BEGIN MODULEBUILDER PERMISSIONS */'."\n\t\t".$rights_str));
668  return 1;
669  } else {
670  return -1;
671  }
672 }
673 
680 function parsePropertyString($string)
681 {
682  $string = str_replace("'", '', $string);
683 
684  // Uses a regular expression to capture keys and values
685  preg_match_all('/\s*([^\s=>]+)\s*=>\s*([^,]+),?/', $string, $matches, PREG_SET_ORDER);
686  $propertyArray = [];
687 
688  foreach ($matches as $match) {
689  $key = trim($match[1]);
690  $value = trim($match[2]);
691 
692  if (strpos($value, 'array(') === 0) {
693  $nestedArray = substr($value, 6);
694  $nestedArray = parsePropertyString($nestedArray);
695  $value = $nestedArray;
696  } elseif (strpos($value, '"Id")') !== false) {
697  $value = str_replace(')', '', $value);
698  } else {
699  if (is_numeric($value)) {
700  if (strpos($value, '.') !== false) {
701  $value = (float) $value;
702  } else {
703  $value = (int) $value;
704  }
705  } else {
706  if ($value === 'true') {
707  $value = true;
708  } elseif ($value === 'false') {
709  $value = false;
710  }
711  }
712  }
713  $propertyArray[$key] = $value;
714  }
715 
716  return $propertyArray;
717 }
718 
726 function writePropsInAsciiDoc($file, $objectname, $destfile)
727 {
728 
729  // stock all properties in array
730  $attributesUnique = array('type','label', 'enabled', 'position', 'notnull', 'visible', 'noteditable', 'index', 'default' , 'foreignkey', 'arrayofkeyval', 'alwayseditable','validate', 'searchall','comment', 'isameasure', 'css', 'cssview','csslist', 'help', 'showoncombobox','picto' );
731 
732  $start = "public \$fields=array(";
733  $end = ");";
734  $i = 1;
735  $keys = array();
736  $lines = file($file);
737  // Search for start and end lines
738  foreach ($lines as $i => $line) {
739  if (strpos($line, $start) !== false) {
740  // Copy lines until the end on array
741  while (($line = $lines[++$i]) !== false) {
742  if (strpos($line, $end) !== false) {
743  break;
744  }
745  $keys[] = $line;
746  }
747  break;
748  }
749  }
750  // write the begin of table with specifics options
751  $table = "== DATA SPECIFICATIONS\n";
752  $table .= "=== Table of fields with properties for object *$objectname* : \n";
753  $table .= "[options='header',grid=rows,frame=topbot,width=100%,caption=Organisation]\n";
754  $table .= "|===\n";
755  $table .= "|code";
756  // write all properties in the header of the table
757  foreach ($attributesUnique as $attUnique) {
758  $table .= "|".$attUnique;
759  }
760  $table .= "\n";
761  $valuesModif = array();
762  foreach ($keys as $string) {
763  $string = trim($string, "'");
764  $string = rtrim($string, ",");
765 
766  $array = parsePropertyString($string);
767 
768  // Iterate through the array to merge all key to one array
769  $code = '';
770  foreach ($array as $key => $value) {
771  if (is_array($value)) {
772  $code = $key;
773  continue;
774  } else {
775  $array[$code][$key] = $value;
776  unset($array[$key]);
777  }
778  }
779  // check if is array after parsing the string
780  if (!is_array($array)) {
781  return -1;
782  }
783  $field = array_keys($array);
784  if ($field[0] === '') {
785  $field[0] = 'label';
786  }
787  $values = array_values($array)[0];
788 
789  // check each field has all properties and add it if missed
790  foreach ($attributesUnique as $attUnique) {
791  if ($attUnique == 'type' && $field[0] === 'label') {
792  $values[$attUnique] = 'varchar(255)';
793  }
794  if (!array_key_exists($attUnique, $values)) {
795  $valuesModif[$attUnique] = '';
796  } else {
797  $valuesModif[$attUnique] = $values[$attUnique];
798  }
799  }
800  $table .= "|*" . $field[0] . "*|";
801  $table .= implode("|", $valuesModif) . "\n";
802  }
803 
804  // end table
805  $table .= "|===\n";
806  $table .= "__ end table for object $objectname\n";
807 
808  //write in file @phan-suppress-next-line PhanPluginSuspiciousParamPosition
809  $writeInFile = dolReplaceInFile($destfile, array('== DATA SPECIFICATIONS' => $table));
810  if ($writeInFile < 0) {
811  return -1;
812  }
813  return 1;
814 }
815 
816 
824 function deletePropsAndPermsFromDoc($file, $objectname)
825 {
826  if (dol_is_file($file)) {
827  $start = "== Table of fields and their properties for object *".ucfirst($objectname)."* : ";
828  $end = "__ end table for object ".ucfirst($objectname);
829 
830  $str = file_get_contents($file);
831 
832  $search = '/' . preg_quote($start, '/') . '(.*?)' . preg_quote($end, '/') . '/s';
833  $new_contents = preg_replace($search, '', $str);
834  file_put_contents($file, $new_contents);
835 
836  //perms If Exist
837  $perms = "|*".strtolower($objectname)."*|";
838  $search_pattern_perms = '/' . preg_quote($perms, '/') . '.*?\n/';
839  $new_contents = preg_replace($search_pattern_perms, '', $new_contents);
840  file_put_contents($file, $new_contents);
841  }
842 }
843 
844 
845 
856 function getFromFile($file, $start, $end, $excludestart = '', $includese = 0)
857 {
858  $keys = array();
859 
860  //$lines = file(dol_osencode($file));
861  $fhandle = fopen(dol_osencode($file), 'r');
862  if ($fhandle) {
863  // Search for start and end lines
864  //foreach ($lines as $i => $line) {
865  while ($line = fgets($fhandle)) {
866  if (strpos($line, $start) !== false && (empty($excludestart) || strpos($line, $excludestart) === false)) {
867  if ($includese) {
868  $keys[] = $line;
869  }
870  // Copy lines until we reach the end
871  while (($line = fgets($fhandle)) !== false) {
872  if (strpos($line, $end) !== false) {
873  if ($includese) {
874  $keys[] = $line;
875  }
876  break;
877  }
878  $keys[] = $line;
879  }
880  break;
881  }
882  }
883  }
884  fclose($fhandle);
885 
886  $content = implode("", $keys);
887  return $content;
888 }
889 
896 function writePermsInAsciiDoc($file, $destfile)
897 {
898  global $langs;
899  //search and get all permissions in string
900  $start = '/* BEGIN MODULEBUILDER PERMISSIONS */';
901  $end = '/* END MODULEBUILDER PERMISSIONS */';
902  $content = getFromFile($file, $start, $end);
903  if (empty($content)) {
904  return -1;
905  }
906  //prepare table
907  $string = "[options='header',grid=rows,width=60%,caption=Organisation]\n";
908  $string .= "|===\n";
909  // header for table
910  $header = array($langs->trans('Objects'),$langs->trans('Permission'));
911  foreach ($header as $h) {
912  $string .= "|".$h;
913  }
914  $string .= "\n";
915  //content table
916  $array = explode(";", $content);
917  $permissions = array_filter($array);
918  // delete occurrences "$r++" and ID
919  $permissions = str_replace('$r++', '1', $permissions);
920 
921  $permsN = array();
922  foreach ($permissions as $i => $element) {
923  if ($element == 1) {
924  unset($permissions[$i]);
925  }
926  if (str_contains($element, '$this->numero')) {
927  unset($permissions[$i]);
928  }
929  if (str_contains($element, '$this->rights[$r][5]')) {
930  unset($permissions[$i]);
931  }
932  }
933  // cleaning the string on each element
934  foreach ($permissions as $key => $element) {
935  $element = str_replace(" '", '', $element);
936  $element = trim($element, "'");
937  $permsN[] = substr($element, strpos($element, "=") + 1);
938  }
939  array_pop($permsN);
940 
941  // Group permissions by Object and add it to string
942  $final_array = [];
943  $index = 0;
944  while ($index < count($permsN)) {
945  $temp_array = [$permsN[$index], $permsN[$index + 1]];
946  $final_array[] = $temp_array;
947  $index += 2;
948  }
949 
950  $result = array();
951  foreach ($final_array as $subarray) {
952  // found object
953  $key = $subarray[1];
954  // add sub array to object
955  $result[$key][] = $subarray;
956  }
957  foreach ($result as $i => $pems) {
958  $string .= "|*".$i."*|";
959  foreach ($pems as $tab) {
960  $string .= $tab[0]." , ";
961  }
962  $string .= "\n";
963  }
964  // end table
965  $string .= "\n|===\n";
966  // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
967  $write = dolReplaceInFile($destfile, array('__DATA_PERMISSIONS__' => $string));
968  if ($write < 0) {
969  return -1;
970  }
971  return 1;
972 }
973 
983 function addObjectsToApiFile($srcfile, $file, $objects, $modulename)
984 {
985  global $langs, $user;
986 
987  if (!file_exists($file)) {
988  return -1;
989  }
990 
991  $now = dol_now();
992  $content = file($file); // $content is an array
993 
994  $includeClass = "dol_include_once\‍(\'\/\w+\/class\/\w+\.class\.php\'\‍);";
995  $props = 'public\s+\$\w+;';
996  $varcommented = '@var\s+\w+\s+\$\w+\s+{@type\s+\w+}';
997  $constructObj = '\$this->\w+\s+=\s+new\s+\w+\‍(\$this->db\‍);';
998 
999  // add properties and declare them in constructor
1000  foreach ($content as $lineNumber => &$lineContent) {
1001  if (preg_match('/'.$varcommented.'/', $lineContent)) {
1002  $lineContent = '';
1003  foreach ($objects as $objectname) {
1004  $lineContent .= "\t * @var ".$objectname." \$".strtolower($objectname)." {@type ".$objectname."}". PHP_EOL;
1005  }
1006  //var_dump($lineContent);exit;
1007  } elseif (preg_match('/'.$props.'/', $lineContent)) {
1008  $lineContent = '';
1009  foreach ($objects as $objectname) {
1010  $lineContent .= "\tpublic \$".strtolower($objectname).";". PHP_EOL;
1011  }
1012  } elseif (preg_match('/'.$constructObj.'/', $lineContent)) {
1013  $lineContent = '';
1014  foreach ($objects as $objectname) {
1015  $lineContent .= "\t\t\$this->".strtolower($objectname)." = new ".$objectname."(\$this->db);". PHP_EOL;
1016  }
1017  } elseif (preg_match('/'.$includeClass.'/', $lineContent)) {
1018  $lineContent = '';
1019  foreach ($objects as $objectname) {
1020  $lineContent .= "dol_include_once('/".strtolower($modulename)."/class/".strtolower($objectname).".class.php');". PHP_EOL;
1021  }
1022  }
1023  }
1024 
1025  $allContent = implode("", $content);
1026  file_put_contents($file, $allContent);
1027 
1028  // Add methods for each object
1029  $allContent = getFromFile($srcfile, '/* BEGIN MODULEBUILDER API MYOBJECT */', '/* END MODULEBUILDER API MYOBJECT */');
1030  foreach ($objects as $objectname) {
1031  $arrayreplacement = array(
1032  'mymodule' => strtolower($modulename),
1033  'MyModule' => $modulename,
1034  'MYMODULE' => strtoupper($modulename),
1035  'My module' => $modulename,
1036  'my module' => $modulename,
1037  'Mon module' => $modulename,
1038  'mon module' => $modulename,
1039  'htdocs/modulebuilder/template' => strtolower($modulename),
1040  'myobject' => strtolower($objectname),
1041  'MyObject' => $objectname,
1042  'MYOBJECT' => strtoupper($objectname),
1043  '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
1044  );
1045  $contentReplaced = make_substitutions($allContent, $arrayreplacement, null);
1046  //$contentReplaced = str_replace(["myobject","MyObject"], [strtolower($object),$object], $allContent);
1047 
1048  dolReplaceInFile($file, array(
1049  '/* BEGIN MODULEBUILDER API MYOBJECT */' => '/* BEGIN MODULEBUILDER API '.strtoupper($objectname).' */'.$contentReplaced."\t".'/* END MODULEBUILDER API '.strtoupper($objectname).' */'."\n\n\n\t".'/* BEGIN MODULEBUILDER API MYOBJECT */'
1050  ));
1051  }
1052 
1053  // Remove the block $allContent found in src file
1054  // TODO Replace with a replacement of all text including into /* BEGIN MODULEBUILDER API MYOBJECT */ and /* END MODULEBUILDER API MYOBJECT */
1055  dolReplaceInFile($file, array($allContent => ''));
1056 
1057  return 1;
1058 }
1059 
1068 function removeObjectFromApiFile($file, $objects, $objectname)
1069 {
1070  if (!file_exists($file)) {
1071  return -1;
1072  }
1073 
1074  $content = file($file); // $content is an array
1075 
1076  $includeClass = "dol_include_once\‍(\'\/\w+\/class\/".strtolower($objectname)."\.class\.php\'\‍);";
1077  $props = 'public\s+\$'.strtolower($objectname);
1078  $varcommented = '@var\s+\w+\s+\$'.strtolower($objectname).'\s+{@type\s+\w+}';
1079  $constructObj = '\$this->'.strtolower($objectname).'\s+=\s+new\s+\w+\‍(\$this->db\‍);';
1080 
1081  // add properties and declare them in constructor
1082  foreach ($content as $lineNumber => &$lineContent) {
1083  if (preg_match('/'.$varcommented.'/i', $lineContent)) {
1084  $lineContent = '';
1085  } elseif (preg_match('/'.$props.'/i', $lineContent)) {
1086  $lineContent = '';
1087  } elseif (preg_match('/'.$constructObj.'/i', $lineContent)) {
1088  $lineContent = '';
1089  } elseif (preg_match('/'.$includeClass.'/i', $lineContent)) {
1090  $lineContent = '';
1091  }
1092  }
1093 
1094  $allContent = implode("", $content);
1095  file_put_contents($file, $allContent);
1096 
1097  // for delete methods of object
1098  $begin = '/* BEGIN MODULEBUILDER API '.strtoupper($objectname).' */';
1099  $end = '/* END MODULEBUILDER API '.strtoupper($objectname).' */';
1100  $allContent = getFromFile($file, $begin, $end);
1101  $check = dolReplaceInFile($file, array($allContent => ''));
1102  if ($check) {
1103  dolReplaceInFile($file, array($begin => '', $end => ''));
1104  }
1105 
1106  return 1;
1107 }
1108 
1109 
1118 function reWriteAllMenus($file, $menus, $menuWantTo, $key, $action)
1119 {
1120  $errors = 0;
1121  $counter = 0;
1122  if (!file_exists($file)) {
1123  return -1;
1124  }
1125 
1126  if ($action == 0 && !empty($key)) {
1127  // delete menu manually
1128  array_splice($menus, array_search($menus[$key], $menus), 1);
1129  } elseif ($action == 1) {
1130  // add menu manually
1131  array_push($menus, $menuWantTo);
1132  } elseif ($action == 2 && !empty($key) && !empty($menuWantTo)) {
1133  // update right from permissions array
1134  $urlCounter = 0;
1135  // check if the values already exists
1136  foreach ($menus as $index => $menu) {
1137  if ($index !== $key) {
1138  if ($menu['type'] === $menuWantTo['type']) {
1139  if (strcasecmp(str_replace(' ', '', $menu['titre']), str_replace(' ', '', $menuWantTo['titre'])) === 0) {
1140  $counter++;
1141  }
1142  if (strcasecmp(str_replace(' ', '', $menu['url']), str_replace(' ', '', $menuWantTo['url'])) === 0) {
1143  $urlCounter++;
1144  }
1145  }
1146  }
1147  }
1148  if (!$counter && $urlCounter < 2) {
1149  $menus[$key] = $menuWantTo;
1150  } else {
1151  $errors++;
1152  }
1153  } elseif ($action == -1 && !empty($menuWantTo)) {
1154  // delete menus when delete Object
1155  foreach ($menus as $index => $menu) {
1156  if ((strpos(strtolower($menu['fk_menu']), strtolower($menuWantTo)) !== false) || (strpos(strtolower($menu['leftmenu']), strtolower($menuWantTo)) !== false)) {
1157  array_splice($menus, array_search($menu, $menus), 1);
1158  }
1159  }
1160  } else {
1161  $errors++;
1162  }
1163  if (!$errors) {
1164  // delete All LEFT Menus (except for commented template MYOBJECT)
1165  $beginMenu = '/* BEGIN MODULEBUILDER LEFTMENU';
1166  $excludeBeginMenu = '/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT';
1167  $endMenu = '/* END MODULEBUILDER LEFTMENU';
1168  $protection = 0;
1169  while ($protection <= 1000 && $allMenus = getFromFile($file, $beginMenu, $endMenu, $excludeBeginMenu, 1)) {
1170  $protection++;
1171  dolReplaceInFile($file, array($allMenus => ''));
1172  }
1173 
1174  // forge the menu code in a string
1175  $str_menu = "";
1176  foreach ($menus as $index => $menu) {
1177  $menu['position'] = "1000 + \$r";
1178  if ($menu['type'] === 'left') {
1179  $start = "\t\t".'/* BEGIN MODULEBUILDER LEFTMENU '.strtoupper(empty($menu['object']) ? $menu['titre'] : $menu['object']).' */';
1180  $end = "\t\t".'/* END MODULEBUILDER LEFTMENU '.strtoupper(empty($menu['object']) ? $menu['titre'] : $menu['object']).' */';
1181 
1182  $val_actuel = $menu;
1183  $next_val = empty($menus[$index + 1]) ? null : $menus[$index + 1];
1184  //var_dump(dol_escape_php($menu['perms'], 1)); exit;
1185 
1186  $str_menu .= $start."\n";
1187  $str_menu .= "\t\t\$this->menu[\$r++]=array(\n";
1188  $str_menu .= "\t\t\t 'fk_menu' => '".dol_escape_php($menu['fk_menu'], 1)."',\n";
1189  $str_menu .= "\t\t\t 'type' => '".dol_escape_php($menu['type'], 1)."',\n";
1190  $str_menu .= "\t\t\t 'titre' => '".dol_escape_php($menu['titre'], 1)."',\n";
1191  $str_menu .= "\t\t\t 'mainmenu' => '".dol_escape_php($menu['mainmenu'], 1)."',\n";
1192  $str_menu .= "\t\t\t 'leftmenu' => '".dol_escape_php($menu['leftmenu'], 1)."',\n";
1193  $str_menu .= "\t\t\t 'url' => '".dol_escape_php($menu['url'], 1)."',\n";
1194  $str_menu .= "\t\t\t 'langs' => '".dol_escape_php($menu['langs'], 1)."',\n";
1195  $str_menu .= "\t\t\t 'position' => ".((int) $menu['position']).",\n";
1196  $str_menu .= "\t\t\t 'enabled' => '".dol_escape_php($menu['enabled'], 1)."',\n";
1197  $str_menu .= "\t\t\t 'perms' => '".dol_escape_php($menu['perms'], 1)."',\n";
1198  $str_menu .= "\t\t\t 'target' => '".dol_escape_php($menu['target'], 1)."',\n";
1199  $str_menu .= "\t\t\t 'user' => ".((int) $menu['user']).",\n";
1200  $str_menu .= "\t\t\t 'object' => '".dol_escape_php($menu['object'], 1)."',\n";
1201  $str_menu .= "\t\t);\n";
1202 
1203  if (is_null($next_val) || $val_actuel['leftmenu'] !== $next_val['leftmenu']) {
1204  $str_menu .= $end."\n";
1205  }
1206  }
1207  }
1208 
1209  dolReplaceInFile($file, array('/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */' => $str_menu."\n\t\t/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */"));
1210  return 1;
1211  }
1212  return -1;
1213 }
1214 
1223 function updateDictionaryInFile($module, $file, $dicts)
1224 {
1225  $isEmpty = false;
1226  $dicData = "\t\t\$this->dictionaries=array(\n";
1227  $module = strtolower($module);
1228  foreach ($dicts as $key => $value) {
1229  if (empty($value)) {
1230  $isEmpty = true;
1231  $dicData = "\t\t\$this->dictionaries=array();";
1232  break;
1233  }
1234 
1235  $dicData .= "\t\t\t'$key'=>";
1236 
1237  if ($key === 'tabcond') {
1238  $conditions = array_map(
1243  function ($val) use ($module) {
1244  return is_bool($val) ? "isModEnabled('$module')" : $val;
1245  },
1246  $value
1247  );
1248  $dicData .= "array(" . implode(",", $conditions) . ")";
1249  } elseif ($key === 'tabhelp') {
1250  $helpItems = array();
1251  foreach ($value as $helpValue) {
1252  $helpItems[] = "array('code'=>\$langs->trans('".$helpValue['code']."'), 'field2' => 'field2tooltip')";
1253  }
1254  $dicData .= "array(" . implode(",", $helpItems) . ")";
1255  } else {
1256  if (is_array($value)) {
1257  $dicData .= "array(" . implode(
1258  ",",
1259  array_map(
1264  static function ($val) {
1265  return "'$val'";
1266  },
1267  $value
1268  )
1269  ) . ")";
1270  } else {
1271  $dicData .= "'$value'";
1272  }
1273  }
1274  $dicData .= ",\n";
1275  }
1276  $dicData .= (!$isEmpty ? "\t\t);" : '');
1277 
1278  $stringDic = getFromFile($file, '/* BEGIN MODULEBUILDER DICTIONARIES */', '/* END MODULEBUILDER DICTIONARIES */');
1279  $writeInfile = dolReplaceInFile($file, array($stringDic => $dicData."\n"));
1280 
1281  return $writeInfile;
1282 }
1283 
1296 function createNewDictionnary($modulename, $file, $namedic, $dictionnaires = null)
1297 {
1298  global $db, $langs;
1299 
1300  if (empty($namedic)) {
1301  setEventMessages($langs->trans("ErrorEmptyNameDic"), null, 'errors');
1302  return -1;
1303  }
1304  if (!file_exists($file)) {
1305  return -1;
1306  }
1307  $modulename = strtolower($modulename);
1308 
1309  if (empty($dictionnaires)) {
1310  $dictionnaires = array('langs' => '', 'tabname' => array(), 'tablib' => array(), 'tabsql' => array(), 'tabsqlsort' => array(), 'tabfield' => array(), 'tabfieldvalue' => array(), 'tabfieldinsert' => array(), 'tabrowid' => array(), 'tabcond' => array(), 'tabhelp' => array());
1311  }
1312 
1313  $columns = array(
1314  'rowid' => array('type' => 'integer', 'value' => 11, 'extra' => 'AUTO_INCREMENT'),
1315  'code' => array('type' => 'varchar', 'value' => 255, 'null' => 'NOT NULL'),
1316  'label' => array('type' => 'varchar', 'value' => 255, 'null' => 'NOT NULL'),
1317  'position' => array('type' => 'integer', 'value' => 11, 'null' => 'NULL'),
1318  'use_default' => array('type' => 'varchar', 'value' => 11, 'default' => '1'),
1319  'active' => array('type' => 'integer', 'value' => 3)
1320  );
1321 
1322  $primaryKey = 'rowid';
1323  foreach ($columns as $key => $value) {
1324  if ($key === 'rowid') {
1325  $primaryKey = 'rowid';
1326  break;
1327  }
1328  if (!array_key_exists('rowid', $columns)) {
1329  $primaryKey = array_key_first($columns);
1330  break;
1331  }
1332  }
1333 
1334  // check if tablename exist in Database and create it if not
1335  $checkTable = $db->DDLDescTable(MAIN_DB_PREFIX.strtolower($namedic));
1336  if ($checkTable && $db->num_rows($checkTable) > 0) {
1337  setEventMessages($langs->trans("ErrorTableExist", $namedic), null, 'errors');
1338  return -1;
1339  } else {
1340  $_results = $db->DDLCreateTable(MAIN_DB_PREFIX.strtolower($namedic), $columns, $primaryKey, "");
1341  if ($_results < 0) {
1342  dol_print_error($db);
1343  $langs->load("errors");
1344  setEventMessages($langs->trans("ErrorTableNotFound", $namedic), null, 'errors');
1345  }
1346  }
1347 
1348  // rewrite dictionary if
1349  $dictionnaires['langs'] = $modulename.'@'.$modulename;
1350  $dictionnaires['tabname'][] = strtolower($namedic);
1351  $dictionnaires['tablib'][] = ucfirst(substr($namedic, 2));
1352  $dictionnaires['tabsql'][] = 'SELECT t.rowid as rowid, t.code, t.label, t.active FROM '.MAIN_DB_PREFIX.strtolower($namedic).' as t';
1353  $dictionnaires['tabsqlsort'][] = (array_key_exists('label', $columns) ? 'label ASC' : '');
1354  $dictionnaires['tabfield'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1355  $dictionnaires['tabfieldvalue'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1356  $dictionnaires['tabfieldinsert'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1357  $dictionnaires['tabrowid'][] = $primaryKey;
1358  $dictionnaires['tabcond'][] = isModEnabled('$modulename'); // @phan-suppress-current-line UnknownModuleName
1359  $dictionnaires['tabhelp'][] = (array_key_exists('code', $columns) ? array('code' => $langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip') : '');
1360 
1361  // Build the dictionary string
1362  $writeInfile = updateDictionaryInFile($modulename, $file, $dictionnaires);
1363  if ($writeInfile > 0) {
1364  setEventMessages($langs->trans("DictionariesCreated", ucfirst(substr($namedic, 2))), null);
1365  }
1366 
1367  return -1;
1368 }
1369 
1377 function writeApiUrlsInDoc($file_api, $file_doc)
1378 {
1379  $error = 0;
1380  if (!dol_is_file($file_api) || !dol_is_file($file_doc)) {
1381  $error++;
1382  }
1383  $string = getFromFile($file_api, '/*begin methods CRUD*/', '/*end methods CRUD*/');
1384  $extractUrls = explode("\n", $string);
1385 
1386  // extract urls from file
1387  $urlValues = [];
1388  foreach ($extractUrls as $key => $line) {
1389  $lineWithoutTabsSpaces = preg_replace('/^[\t\s]+/', '', $line);
1390  if (strpos($lineWithoutTabsSpaces, '* @url') === 0) {
1391  $urlValue = trim(substr($lineWithoutTabsSpaces, strlen('* @url')));
1392  $urlValues[] = $urlValue;
1393  }
1394  }
1395 
1396  // get urls by object
1397  $str = $_SERVER['HTTP_HOST'].'/api/index.php/';
1398  $groupedUrls = [];
1399  foreach ($urlValues as $url) {
1400  if (preg_match('/(?:GET|POST|PUT|DELETE) (\w+)s/', $url, $matches)) {
1401  $objectName = $matches[1];
1402  $url = $str.trim(strstr($url, ' '));
1403  $groupedUrls[$objectName][] = $url;
1404  }
1405  }
1406  if (empty($groupedUrls)) {
1407  $error++;
1408  }
1409 
1410  // build format asciidoc for urls in table
1411  if (!$error) {
1412  $asciiDocTable = "[options=\"header\"]\n|===\n|Object | URLs\n"; // phpcs:ignore
1413  foreach ($groupedUrls as $objectName => $urls) {
1414  $urlsList = implode(" +\n*", $urls);
1415  $asciiDocTable .= "|$objectName | \n*$urlsList +\n";
1416  }
1417  $asciiDocTable .= "|===\n";
1418  $file_write = dolReplaceInFile($file_doc, array('__API_DOC__' => '__API_DOC__'."\n".$asciiDocTable));
1419  if ($file_write < 0) {
1420  return -1;
1421  }
1422  return 1;
1423  }
1424  return -1;
1425 }
1426 
1427 
1434 function countItemsInDirectory($path, $type = 1)
1435 {
1436  if (!is_dir($path)) {
1437  return false;
1438  }
1439 
1440  $allFilesAndDirs = scandir($path);
1441  $count = 0;
1442 
1443  foreach ($allFilesAndDirs as $item) {
1444  if ($item != '.' && $item != '..') {
1445  if ($type == 1 && is_file($path . DIRECTORY_SEPARATOR . $item) && strpos($item, '.back') === false) {
1446  $count++;
1447  } elseif ($type == 2 && is_dir($path . DIRECTORY_SEPARATOR . $item)) {
1448  $count++;
1449  }
1450  }
1451  }
1452  return $count;
1453 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
dol_copy($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=0)
Copy a file to another file.
Definition: files.lib.php:767
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:519
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:63
dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask='0', $indexdatabase=0, $arrayreplacementisregex=0)
Make replacement of strings into a file.
Definition: files.lib.php:677
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_now($mode='auto')
Return date for now.
dol_escape_php($stringtoescape, $stringforquotes=2)
Returns text escaped for inclusion into a php string, build with double quotes " or '.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
isModEnabled($module)
Is Dolibarr module enabled.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
div float
Unit price before taxes.
Definition: style.css.php:963
updateDictionaryInFile($module, $file, $dicts)
Updates a dictionary in a module descriptor file.
deletePropsAndPermsFromDoc($file, $objectname)
Delete property and permissions from documentation ascii file if we delete an object.
createNewDictionnary($modulename, $file, $namedic, $dictionnaires=null)
Creates a new dictionary table.
countItemsInDirectory($path, $type=1)
count directories or files in modulebuilder folder
writePermsInAsciiDoc($file, $destfile)
Write all permissions of each object in AsciiDoc format.
reWriteAllMenus($file, $menus, $menuWantTo, $key, $action)
parsePropertyString($string)
Converts a formatted properties string into an associative array.
rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='', $object=null, $moduletype='external')
Save data into a memory area shared by all users, all sessions on server.
writeApiUrlsInDoc($file_api, $file_doc)
Generate Urls and add them to documentation module.
getFromFile($file, $start, $end, $excludestart='', $includese=0)
Search a string and return all lines needed from file.
dolGetListOfObjectClasses($destdir)
Get list of existing objects from a directory.
deletePerms($file)
Delete all permissions.
writePropsInAsciiDoc($file, $objectname, $destfile)
Write all properties of the object in AsciiDoc format.
compareFirstValue($a, $b)
Compare two value.
removeObjectFromApiFile($file, $objects, $objectname)
Remove Object variables and methods from API_Module File.
rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='', $addfieldentry=array(), $delfieldentry='')
Regenerate files .class.php.
reWriteAllPermissions($file, $permissions, $key, $right, $objectname, $module, $action)
Rewriting all permissions after any actions.
checkExistComment($file, $number)
Function to check if comment BEGIN and END exists in modMyModule class.
addObjectsToApiFile($srcfile, $file, $objects, $modulename)
Add Object in ModuleApi File.