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