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