dolibarr 21.0.0-beta
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 == 'chkbxlst') {
352 $type = 'varchar(128)';
353 } elseif ($type == 'mail') {
354 $type = 'varchar(128)';
355 } elseif (strpos($type, 'stars(') === 0) {
356 $type = 'integer';
357 } elseif ($type == 'phone') {
358 $type = 'varchar(20)';
359 } elseif ($type == 'ip') {
360 $type = 'varchar(32)';
361 }
362
363 $texttoinsert .= "\t".$key." ".$type;
364 if ($key == 'rowid') {
365 $texttoinsert .= ' AUTO_INCREMENT PRIMARY KEY';
366 } elseif ($type == 'timestamp') {
367 $texttoinsert .= ' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP';
368 }
369 if ($key == 'entity') {
370 $texttoinsert .= ' DEFAULT 1';
371 } else {
372 if (!empty($val['default'])) {
373 if (preg_match('/^null$/i', $val['default'])) {
374 $texttoinsert .= " DEFAULT NULL";
375 } elseif (preg_match('/varchar/', $type)) {
376 $texttoinsert .= " DEFAULT '".$db->escape($val['default'])."'";
377 } else {
378 $texttoinsert .= (($val['default'] > 0) ? ' DEFAULT '.$val['default'] : '');
379 }
380 }
381 }
382 $texttoinsert .= ((!empty($val['notnull']) && $val['notnull'] > 0) ? ' NOT NULL' : '');
383 if ($i < count($object->fields)) {
384 $texttoinsert .= ", ";
385 }
386 $texttoinsert .= "\n";
387 }
388 }
389 $texttoinsert .= "\t".'-- END MODULEBUILDER FIELDS';
390
391 $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql);
392
393 $result = file_put_contents($pathoffiletoedittarget, $contentsql);
394 if ($result) {
395 dolChmod($pathoffiletoedittarget, $newmask);
396 } else {
397 $error++;
398 setEventMessages($langs->trans("ErrorFailToCreateFile", $pathoffiletoedittarget), null, 'errors');
399 }
400
401 // Edit .key.sql file
402 $pathoffiletoeditsrc = preg_replace('/\.sql$/', '.key.sql', $pathoffiletoeditsrc);
403 $pathoffiletoedittarget = preg_replace('/\.sql$/', '.key.sql', $pathoffiletoedittarget);
404 $pathoffiletoedittarget = preg_replace('/\.sql.new$/', '.key.sql.new', $pathoffiletoedittarget);
405
406 $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc));
407
408 $i = 0;
409 $texttoinsert = '-- BEGIN MODULEBUILDER INDEXES'."\n";
410 if (count($object->fields)) {
411 foreach ($object->fields as $key => $val) {
412 $i++;
413 if (!empty($val['index'])) {
414 $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
415 $texttoinsert .= "\n";
416 }
417 if (!empty($val['foreignkey'])) {
418 $tmp = explode('.', $val['foreignkey']);
419 if (!empty($tmp[0]) && !empty($tmp[1])) {
420 $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].");";
421 $texttoinsert .= "\n";
422 }
423 }
424 }
425 }
426 $texttoinsert .= '-- END MODULEBUILDER INDEXES';
427
428 $contentsql = preg_replace('/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsql);
429
430 dol_mkdir(dirname($pathoffiletoedittarget));
431
432 $result2 = file_put_contents($pathoffiletoedittarget, $contentsql);
433 if ($result2) {
434 dolChmod($pathoffiletoedittarget, $newmask);
435 } else {
436 $error++;
437 setEventMessages($langs->trans("ErrorFailToCreateFile", $pathoffiletoedittarget), null, 'errors');
438 }
439
440 return $error ? -1 : 1;
441}
442
450{
451 $objects = array();
452 $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
453 foreach ($listofobject as $fileobj) {
454 if (preg_match('/^api_/', $fileobj['name'])) {
455 continue;
456 }
457 if (preg_match('/^actions_/', $fileobj['name'])) {
458 continue;
459 }
460
461 $tmpcontent = file_get_contents($fileobj['fullname']);
462 $reg = array();
463 if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
464 $objectnameloop = $reg[1];
465 $objects[$fileobj['fullname']] = $objectnameloop;
466 }
467 }
468 if (count($objects) > 0) {
469 return $objects;
470 }
471
472 return -1;
473}
474
482function checkExistComment($file, $number)
483{
484 if (!file_exists($file)) {
485 return -1;
486 }
487
488 $content = file_get_contents($file);
489 if ($number === 0) {
490 $ret = 0;
491 if (strpos($content, '/* BEGIN MODULEBUILDER TOPMENU MYOBJECT */') !== false
492 || strpos($content, '/* BEGIN MODULEBUILDER TOPMENU */') !== false) {
493 $ret++;
494 }
495 if (strpos($content, '/* END MODULEBUILDER TOPMENU MYOBJECT */') !== false
496 || strpos($content, '/* END MODULEBUILDER TOPMENU */') !== false) {
497 $ret++;
498 }
499 if (strpos($content, '/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */') !== false) {
500 $ret++;
501 }
502 if (strpos($content, '/* END MODULEBUILDER LEFTMENU MYOBJECT */') !== false) {
503 $ret++;
504 }
505
506 if ($ret == 4) {
507 return 1;
508 }
509 } elseif ($number === 1) {
510 if (strpos($content, '/* BEGIN MODULEBUILDER PERMISSIONS */') !== false && strpos($content, '/* END MODULEBUILDER PERMISSIONS */') !== false) {
511 return 1;
512 }
513 } elseif ($number == 2) {
514 if (strpos($content, '/* BEGIN MODULEBUILDER DICTIONARIES */') !== false && strpos($content, '/* END MODULEBUILDER DICTIONARIES */') !== false) {
515 return 1;
516 }
517 }
518 return -1;
519}
526function deletePerms($file)
527{
528 $start = "/* BEGIN MODULEBUILDER PERMISSIONS */";
529 $end = "/* END MODULEBUILDER PERMISSIONS */";
530 $i = 1;
531 $array = array();
532 $lines = file($file);
533 // Search for start and end lines
534 foreach ($lines as $i => $line) {
535 if (strpos($line, $start) !== false) {
536 $start_line = $i + 1;
537
538 // Copy lines until the end on array
539 while (($line = $lines[++$i]) !== false) {
540 if (strpos($line, $end) !== false) {
541 $end_line = $i + 1;
542 break;
543 }
544 $array[] = $line;
545 }
546 break;
547 }
548 }
549 $allContent = implode("", $array);
550 dolReplaceInFile($file, array($allContent => ''));
551}
552
559function compareFirstValue($a, $b)
560{
561 return strcmp($a[0], $b[0]);
562}
574function reWriteAllPermissions($file, $permissions, $key, $right, $objectname, $module, $action)
575{
576 $error = 0;
577 $rights = array();
578 if ($action == 0 && $key !== null) {
579 // delete right from permissions array
580 array_splice($permissions, array_search($permissions[$key], $permissions), 1);
581 } elseif ($action == 1) {
582 array_push($permissions, $right);
583 } elseif ($action == 2 && !empty($right) && $key !== null) {
584 // update right from permissions array
585 array_splice($permissions, array_search($permissions[$key], $permissions), 1, $right);
586 } elseif ($action == -1 && !empty($objectname)) {
587 // when delete object
588 $key = null;
589 $right = null;
590 foreach ($permissions as $perms) {
591 if ($perms[4] === strtolower($objectname)) {
592 array_splice($permissions, array_search($perms, $permissions), 1);
593 }
594 }
595 } elseif ($action == -2 && !empty($objectname) && !empty($module)) {
596 $key = null;
597 $right = null;
598 $objectOfRights = array();
599 //check if object already declared in rights file
600 foreach ($permissions as $right) {
601 $objectOfRights[] = $right[4];
602 }
603 if (in_array(strtolower($objectname), $objectOfRights)) {
604 $error++;
605 } else {
606 $permsToadd = array();
607 $perms = array(
608 'read' => 'Read '.$objectname.' object of '.ucfirst($module),
609 'write' => 'Create/Update '.$objectname.' object of '.ucfirst($module),
610 'delete' => 'Delete '.$objectname.' object of '.ucfirst($module)
611 );
612 $i = 0;
613 foreach ($perms as $index => $value) {
614 $permsToadd[$i][0] = '';
615 $permsToadd[$i][1] = $value;
616 $permsToadd[$i][4] = strtolower($objectname);
617 $permsToadd[$i][5] = $index;
618 array_push($permissions, $permsToadd[$i]);
619 $i++;
620 }
621 }
622 } else {
623 $error++;
624 }
625 '@phan-var-force array<int,string[]> $permissions';
626 if (!$error) {
627 // prepare permissions array
628 $count_perms = count($permissions);
629 foreach (array_keys($permissions) as $i) {
630 $permissions[$i][0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', \$r + 1)";
631 $permissions[$i][1] = "\$this->rights[\$r][1] = '".$permissions[$i][1]."'";
632 $permissions[$i][4] = "\$this->rights[\$r][4] = '".$permissions[$i][4]."'";
633 $permissions[$i][5] = "\$this->rights[\$r][5] = '".$permissions[$i][5]."';\n\t\t";
634 }
635 // for group permissions by object
636 $perms_grouped = array();
637 foreach ($permissions as $perms) {
638 $object = $perms[4];
639 if (!isset($perms_grouped[$object])) {
640 $perms_grouped[$object] = array();
641 }
642 $perms_grouped[$object][] = $perms;
643 }
644 //$perms_grouped = array_values($perms_grouped);
645 $permissions = $perms_grouped;
646
647
648 // parcourir les objects
649 $o = 0;
650 foreach ($permissions as &$object) {
651 // récupérer la permission de l'objet
652 $p = 1;
653 foreach ($object as &$obj) {
654 if (str_contains($obj[5], 'read')) {
655 $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 0 + 1)";
656 } elseif (str_contains($obj[5], 'write')) {
657 $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 1 + 1)";
658 } elseif (str_contains($obj[5], 'delete')) {
659 $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 2 + 1)";
660 } else {
661 $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + ".$p." + 1)";
662 $p++;
663 }
664 }
665 usort($object, 'compareFirstValue');
666 $o++;
667 }
668
669 //convert to string
670 foreach ($permissions as $perms) {
671 foreach ($perms as $per) {
672 $rights[] = implode(";\n\t\t", $per)."\$r++;\n";
673 }
674 }
675 $rights_str = implode("\t\t", $rights);
676 // delete all permissions from file
677 deletePerms($file);
678 // rewrite all permissions again
679 dolReplaceInFile($file, array('/* BEGIN MODULEBUILDER PERMISSIONS */' => '/* BEGIN MODULEBUILDER PERMISSIONS */'."\n\t\t".$rights_str));
680 return 1;
681 } else {
682 return -1;
683 }
684}
685
692function parsePropertyString($string)
693{
694 $string = str_replace("'", '', $string);
695
696 // Uses a regular expression to capture keys and values
697 preg_match_all('/\s*([^\s=>]+)\s*=>\s*([^,]+),?/', $string, $matches, PREG_SET_ORDER);
698 $propertyArray = array();
699
700 foreach ($matches as $match) {
701 $key = trim($match[1]);
702 $value = trim($match[2]);
703
704 if (strpos($value, 'array(') === 0) {
705 $nestedArray = substr($value, 6);
706 $nestedArray = parsePropertyString($nestedArray);
707 $value = $nestedArray;
708 } elseif (strpos($value, '"Id")') !== false) {
709 $value = str_replace(')', '', $value);
710 } else {
711 if (is_numeric($value)) {
712 if (strpos($value, '.') !== false) {
713 $value = (float) $value;
714 } else {
715 $value = (int) $value;
716 }
717 } else {
718 if ($value === 'true') {
719 $value = true;
720 } elseif ($value === 'false') {
721 $value = false;
722 }
723 }
724 }
725 $propertyArray[$key] = $value;
726 }
727
728 return $propertyArray;
729}
730
738function writePropsInAsciiDoc($file, $objectname, $destfile)
739{
740
741 // stock all properties in array
742 $attributesUnique = array('type','label', 'enabled', 'position', 'notnull', 'visible', 'noteditable', 'index', 'default' , 'foreignkey', 'arrayofkeyval', 'alwayseditable','validate', 'searchall','comment', 'isameasure', 'css', 'cssview','csslist', 'help', 'showoncombobox','picto' );
743
744 $start = "public \$fields = array(";
745 $end = ");";
746 $i = 1;
747 $keys = array();
748 $lines = file($file);
749 // Search for start and end lines
750 foreach ($lines as $i => $line) {
751 if (strpos($line, $start) !== false) {
752 // Copy lines until the end on array
753 while (($line = $lines[++$i]) !== false) {
754 if (strpos($line, $end) !== false) {
755 break;
756 }
757 $keys[] = $line;
758 }
759 break;
760 }
761 }
762 // write the begin of table with specifics options
763 $table = "== DATA SPECIFICATIONS\n";
764 $table .= "=== Table of fields with properties for object *$objectname* : \n";
765 $table .= "[options='header',grid=rows,frame=topbot,width=100%,caption=Organisation]\n";
766 $table .= "|===\n";
767 $table .= "|code";
768 // write all properties in the header of the table
769 foreach ($attributesUnique as $attUnique) {
770 $table .= "|".$attUnique;
771 }
772 $table .= "\n";
773 $valuesModif = array();
774 foreach ($keys as $string) {
775 $string = trim($string, "'");
776 $string = rtrim($string, ",");
777
778 $array = parsePropertyString($string);
779
780 // Iterate through the array to merge all key to one array
781 $code = '';
782 foreach ($array as $key => $value) {
783 if (is_array($value)) {
784 $code = $key;
785 continue;
786 } else {
787 $array[$code][$key] = $value;
788 unset($array[$key]);
789 }
790 }
791 // check if is array after parsing the string
792 if (!is_array($array)) {
793 return -1;
794 }
795 $field = array_keys($array);
796 if ($field[0] === '') {
797 $field[0] = 'label';
798 }
799 $values = array_values($array)[0];
800
801 // check each field has all properties and add it if missed
802 foreach ($attributesUnique as $attUnique) {
803 if ($attUnique == 'type' && $field[0] === 'label') {
804 $values[$attUnique] = 'varchar(255)';
805 }
806 if (!array_key_exists($attUnique, $values)) {
807 $valuesModif[$attUnique] = '';
808 } else {
809 $valuesModif[$attUnique] = $values[$attUnique];
810 }
811 }
812 $table .= "|*" . $field[0] . "*|";
813 $table .= implode("|", $valuesModif) . "\n";
814 }
815
816 // end table
817 $table .= "|===\n";
818 $table .= "__ end table for object $objectname\n";
819
820 //write in file @phan-suppress-next-line PhanPluginSuspiciousParamPosition
821 $writeInFile = dolReplaceInFile($destfile, array('== DATA SPECIFICATIONS' => $table));
822 if ($writeInFile < 0) {
823 return -1;
824 }
825 return 1;
826}
827
828
836function deletePropsAndPermsFromDoc($file, $objectname)
837{
838 if (dol_is_file($file)) {
839 $start = "== Table of fields and their properties for object *".ucfirst($objectname)."* : ";
840 $end = "__ end table for object ".ucfirst($objectname);
841
842 $str = file_get_contents($file);
843
844 $search = '/' . preg_quote($start, '/') . '(.*?)' . preg_quote($end, '/') . '/s';
845 $new_contents = preg_replace($search, '', $str);
846 file_put_contents($file, $new_contents);
847
848 //perms If Exist
849 $perms = "|*".strtolower($objectname)."*|";
850 $search_pattern_perms = '/' . preg_quote($perms, '/') . '.*?\n/';
851 $new_contents = preg_replace($search_pattern_perms, '', $new_contents);
852 file_put_contents($file, $new_contents);
853 }
854}
855
856
857
868function getFromFile($file, $start, $end, $excludestart = '', $includese = 0)
869{
870 $keys = array();
871
872 //$lines = file(dol_osencode($file));
873 $fhandle = fopen(dol_osencode($file), 'r');
874 if ($fhandle) {
875 // Search for start and end lines
876 //foreach ($lines as $i => $line) {
877 while ($line = fgets($fhandle)) {
878 if (strpos($line, $start) !== false && (empty($excludestart) || strpos($line, $excludestart) === false)) {
879 if ($includese) {
880 $keys[] = $line;
881 }
882 // Copy lines until we reach the end
883 while (($line = fgets($fhandle)) !== false) {
884 if (strpos($line, $end) !== false) {
885 if ($includese) {
886 $keys[] = $line;
887 }
888 break;
889 }
890 $keys[] = $line;
891 }
892 break;
893 }
894 }
895 }
896 fclose($fhandle);
897
898 $content = implode("", $keys);
899 return $content;
900}
901
908function writePermsInAsciiDoc($file, $destfile)
909{
910 global $langs;
911 //search and get all permissions in string
912 $start = '/* BEGIN MODULEBUILDER PERMISSIONS */';
913 $end = '/* END MODULEBUILDER PERMISSIONS */';
914 $content = getFromFile($file, $start, $end);
915 if (empty($content)) {
916 return -1;
917 }
918 //prepare table
919 $string = "[options='header',grid=rows,width=60%,caption=Organisation]\n";
920 $string .= "|===\n";
921 // header for table
922 $header = array($langs->trans('Objects'),$langs->trans('Permission'));
923 foreach ($header as $h) {
924 $string .= "|".$h;
925 }
926 $string .= "\n";
927 //content table
928 $array = explode(";", $content);
929 $permissions = array_filter($array);
930 // delete occurrences "$r++" and ID
931 $permissions = str_replace('$r++', '1', $permissions);
932
933 $permsN = array();
934 foreach ($permissions as $i => $element) {
935 if ($element == 1) {
936 unset($permissions[$i]);
937 }
938 if (str_contains($element, '$this->numero')) {
939 unset($permissions[$i]);
940 }
941 if (str_contains($element, '$this->rights[$r][5]')) {
942 unset($permissions[$i]);
943 }
944 }
945 // cleaning the string on each element
946 foreach ($permissions as $key => $element) {
947 $element = str_replace(" '", '', $element);
948 $element = trim($element, "'");
949 $permsN[] = substr($element, strpos($element, "=") + 1);
950 }
951 array_pop($permsN);
952
953 // Group permissions by Object and add it to string
954 $final_array = array();
955 $index = 0;
956 while ($index < count($permsN)) {
957 $temp_array = array($permsN[$index], $permsN[$index + 1]);
958 $final_array[] = $temp_array;
959 $index += 2;
960 }
961
962 $result = array();
963 foreach ($final_array as $subarray) {
964 // found object
965 $key = $subarray[1];
966 // add sub array to object
967 $result[$key][] = $subarray;
968 }
969 foreach ($result as $i => $pems) {
970 $string .= "|*".$i."*|";
971 foreach ($pems as $tab) {
972 $string .= $tab[0]." , ";
973 }
974 $string .= "\n";
975 }
976 // end table
977 $string .= "\n|===\n";
978 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
979 $write = dolReplaceInFile($destfile, array('__DATA_PERMISSIONS__' => $string));
980 if ($write < 0) {
981 return -1;
982 }
983 return 1;
984}
985
995function addObjectsToApiFile($srcfile, $file, $objects, $modulename)
996{
997 global $langs, $user;
998
999 if (!file_exists($file)) {
1000 return -1;
1001 }
1002
1003 $now = dol_now();
1004 $content = file($file); // $content is an array
1005
1006 $includeClass = "dol_include_once\‍(\'\/\w+\/class\/\w+\.class\.php\'\‍);";
1007 $props = 'public\s+\$\w+;';
1008 $varcommented = '@var\s+\w+\s+\$\w+\s+{@type\s+\w+}';
1009 $constructObj = '\$this->\w+\s+=\s+new\s+\w+\‍(\$this->db\‍);';
1010
1011 // add properties and declare them in constructor
1012 foreach ($content as $lineNumber => &$lineContent) {
1013 if (preg_match('/'.$varcommented.'/', $lineContent)) {
1014 $lineContent = '';
1015 foreach ($objects as $objectname) {
1016 $lineContent .= "\t * @var ".$objectname." \$".strtolower($objectname)." {@type ".$objectname."}". PHP_EOL;
1017 }
1018 //var_dump($lineContent);exit;
1019 } elseif (preg_match('/'.$props.'/', $lineContent)) {
1020 $lineContent = '';
1021 foreach ($objects as $objectname) {
1022 $lineContent .= "\t/*".PHP_EOL."\t * @var mixed TODO: set type".PHP_EOL."\t */".PHP_EOL."\tpublic \$".strtolower($objectname).";". PHP_EOL;
1023 }
1024 } elseif (preg_match('/'.$constructObj.'/', $lineContent)) {
1025 $lineContent = '';
1026 foreach ($objects as $objectname) {
1027 $lineContent .= "\t\t\$this->".strtolower($objectname)." = new ".$objectname."(\$this->db);". PHP_EOL;
1028 }
1029 } elseif (preg_match('/'.$includeClass.'/', $lineContent)) {
1030 $lineContent = '';
1031 foreach ($objects as $objectname) {
1032 $lineContent .= "dol_include_once('/".strtolower($modulename)."/class/".strtolower($objectname).".class.php');". PHP_EOL;
1033 }
1034 }
1035 }
1036
1037 $allContent = implode("", $content);
1038 file_put_contents($file, $allContent);
1039
1040 // Add methods for each object
1041 $allContent = getFromFile($srcfile, '/* BEGIN MODULEBUILDER API MYOBJECT */', '/* END MODULEBUILDER API MYOBJECT */');
1042 foreach ($objects as $objectname) {
1043 $arrayreplacement = array(
1044 'mymodule' => strtolower($modulename),
1045 'MyModule' => $modulename,
1046 'MYMODULE' => strtoupper($modulename),
1047 'My module' => $modulename,
1048 'my module' => $modulename,
1049 'Mon module' => $modulename,
1050 'mon module' => $modulename,
1051 'htdocs/modulebuilder/template' => strtolower($modulename),
1052 'myobject' => strtolower($objectname),
1053 'MyObject' => $objectname,
1054 'MYOBJECT' => strtoupper($objectname),
1055 '---Replace with your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
1056 );
1057 $contentReplaced = make_substitutions($allContent, $arrayreplacement, null);
1058 //$contentReplaced = str_replace(["myobject","MyObject"], [strtolower($object),$object], $allContent);
1059
1060 dolReplaceInFile($file, array(
1061 '/* BEGIN MODULEBUILDER API MYOBJECT */' => '/* BEGIN MODULEBUILDER API '.strtoupper($objectname).' */'.$contentReplaced."\t".'/* END MODULEBUILDER API '.strtoupper($objectname).' */'."\n\n\n\t".'/* BEGIN MODULEBUILDER API MYOBJECT */'
1062 ));
1063 }
1064
1065 // Remove the block $allContent found in src file
1066 // TODO Replace with a replacement of all text including into /* BEGIN MODULEBUILDER API MYOBJECT */ and /* END MODULEBUILDER API MYOBJECT */
1067 dolReplaceInFile($file, array($allContent => ''));
1068
1069 return 1;
1070}
1071
1080function removeObjectFromApiFile($file, $objects, $objectname)
1081{
1082 if (!file_exists($file)) {
1083 return -1;
1084 }
1085
1086 $content = file($file); // $content is an array
1087
1088 $includeClass = "dol_include_once\‍(\'\/\w+\/class\/".strtolower($objectname)."\.class\.php\'\‍);";
1089 $props = 'public\s+\$'.strtolower($objectname);
1090 $varcommented = '@var\s+\w+\s+\$'.strtolower($objectname).'\s+{@type\s+\w+}';
1091 $constructObj = '\$this->'.strtolower($objectname).'\s+=\s+new\s+\w+\‍(\$this->db\‍);';
1092
1093 // add properties and declare them in constructor
1094 foreach ($content as $lineNumber => &$lineContent) {
1095 if (preg_match('/'.$varcommented.'/i', $lineContent)) {
1096 $lineContent = '';
1097 } elseif (preg_match('/'.$props.'/i', $lineContent)) {
1098 $lineContent = '';
1099 } elseif (preg_match('/'.$constructObj.'/i', $lineContent)) {
1100 $lineContent = '';
1101 } elseif (preg_match('/'.$includeClass.'/i', $lineContent)) {
1102 $lineContent = '';
1103 }
1104 }
1105
1106 $allContent = implode("", $content);
1107 file_put_contents($file, $allContent);
1108
1109 // for delete methods of object
1110 $begin = '/* BEGIN MODULEBUILDER API '.strtoupper($objectname).' */';
1111 $end = '/* END MODULEBUILDER API '.strtoupper($objectname).' */';
1112 $allContent = getFromFile($file, $begin, $end);
1113 $check = dolReplaceInFile($file, array($allContent => ''));
1114 if ($check) {
1115 dolReplaceInFile($file, array($begin => '', $end => ''));
1116 }
1117
1118 return 1;
1119}
1120
1121
1130function reWriteAllMenus($file, $menus, $menuWantTo, $key, $action)
1131{
1132 $errors = 0;
1133 $counter = 0;
1134 if (!file_exists($file)) {
1135 return -1;
1136 }
1137
1138 if ($action == 0 && !empty($key)) {
1139 // delete menu manually
1140 array_splice($menus, array_search($menus[$key], $menus), 1);
1141 } elseif ($action == 1) {
1142 // add menu manually
1143 array_push($menus, $menuWantTo);
1144 } elseif ($action == 2 && !empty($key) && !empty($menuWantTo)) {
1145 // update right from permissions array
1146 $urlCounter = 0;
1147 // check if the values already exists
1148 foreach ($menus as $index => $menu) {
1149 if ($index !== $key) {
1150 if ($menu['type'] === $menuWantTo['type']) {
1151 if (strcasecmp(str_replace(' ', '', $menu['titre']), str_replace(' ', '', $menuWantTo['titre'])) === 0) {
1152 $counter++;
1153 }
1154 if (strcasecmp(str_replace(' ', '', $menu['url']), str_replace(' ', '', $menuWantTo['url'])) === 0) {
1155 $urlCounter++;
1156 }
1157 }
1158 }
1159 }
1160 if (!$counter && $urlCounter < 2) {
1161 $menus[$key] = $menuWantTo;
1162 } else {
1163 $errors++;
1164 }
1165 } elseif ($action == -1 && !empty($menuWantTo) && is_string($menuWantTo)) {
1166 // delete menus when delete Object
1167 foreach ($menus as $index => $menu) {
1168 if ((strpos(strtolower($menu['fk_menu']), strtolower($menuWantTo)) !== false) || (strpos(strtolower($menu['leftmenu']), strtolower($menuWantTo)) !== false)) {
1169 array_splice($menus, array_search($menu, $menus), 1);
1170 }
1171 }
1172 } else {
1173 $errors++;
1174 }
1175 if (!$errors) {
1176 // delete All LEFT Menus (except for commented template MYOBJECT)
1177 $beginMenu = '/* BEGIN MODULEBUILDER LEFTMENU';
1178 $excludeBeginMenu = '/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT';
1179 $endMenu = '/* END MODULEBUILDER LEFTMENU';
1180 $protection = 0;
1181 while ($protection <= 1000 && $allMenus = getFromFile($file, $beginMenu, $endMenu, $excludeBeginMenu, 1)) {
1182 $protection++;
1183 dolReplaceInFile($file, array($allMenus => ''));
1184 }
1185
1186 // forge the menu code in a string
1187 $str_menu = "";
1188 foreach ($menus as $index => $menu) {
1189 $menu['position'] = "1000 + \$r";
1190 if ($menu['type'] === 'left') {
1191 $start = "\t\t".'/* BEGIN MODULEBUILDER LEFTMENU '.strtoupper(empty($menu['object']) ? $menu['titre'] : $menu['object']).' */';
1192 $end = "\t\t".'/* END MODULEBUILDER LEFTMENU '.strtoupper(empty($menu['object']) ? $menu['titre'] : $menu['object']).' */';
1193
1194 $val_actuel = $menu;
1195 $next_val = empty($menus[$index + 1]) ? null : $menus[$index + 1];
1196 //var_dump(dol_escape_php($menu['perms'], 1)); exit;
1197
1198 $str_menu .= $start."\n";
1199 $str_menu .= "\t\t\$this->menu[\$r++] = array(\n";
1200 $str_menu .= "\t\t\t'fk_menu' => '".dol_escape_php($menu['fk_menu'], 1)."',\n";
1201 $str_menu .= "\t\t\t'type' => '".dol_escape_php($menu['type'], 1)."',\n";
1202 $str_menu .= "\t\t\t'titre' => '".dol_escape_php($menu['titre'], 1)."',\n";
1203 $str_menu .= "\t\t\t'mainmenu' => '".dol_escape_php($menu['mainmenu'], 1)."',\n";
1204 $str_menu .= "\t\t\t'leftmenu' => '".dol_escape_php($menu['leftmenu'], 1)."',\n";
1205 $str_menu .= "\t\t\t'url' => '".dol_escape_php($menu['url'], 1)."',\n";
1206 $str_menu .= "\t\t\t'langs' => '".dol_escape_php($menu['langs'], 1)."',\n";
1207 $str_menu .= "\t\t\t'position' => ".((int) $menu['position']).",\n";
1208 $str_menu .= "\t\t\t'enabled' => '".dol_escape_php((string) $menu['enabled'], 1)."',\n";
1209 $str_menu .= "\t\t\t'perms' => '".dol_escape_php($menu['perms'], 1)."',\n";
1210 $str_menu .= "\t\t\t'target' => '".dol_escape_php($menu['target'], 1)."',\n";
1211 $str_menu .= "\t\t\t'user' => ".((int) $menu['user']).",\n";
1212 $str_menu .= "\t\t\t'object' => '".dol_escape_php($menu['object'], 1)."',\n";
1213 $str_menu .= "\t\t);\n";
1214
1215 if (is_null($next_val) || $val_actuel['leftmenu'] !== $next_val['leftmenu']) {
1216 $str_menu .= $end."\n";
1217 }
1218 }
1219 }
1220
1221 dolReplaceInFile($file, array('/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */' => $str_menu."\n\t\t/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */"));
1222 return 1;
1223 }
1224 return -1;
1225}
1226
1235function updateDictionaryInFile($module, $file, $dicts)
1236{
1237 $isEmpty = false;
1238 $dicData = "\t\t\$this->dictionaries = array(\n";
1239 $module = strtolower($module);
1240 foreach ($dicts as $key => $value) {
1241 if (empty($value)) {
1242 $isEmpty = true;
1243 $dicData = "\t\t\$this->dictionaries = array();";
1244 break;
1245 }
1246
1247 $dicData .= "\t\t\t'$key' => ";
1248
1249 if ($key === 'tabcond') {
1250 $conditions = array_map(
1255 static function ($val) use ($module) {
1256 return is_bool($val) ? "isModEnabled('$module')" : $val;
1257 },
1258 $value
1259 );
1260 $dicData .= "array(" . implode(", ", $conditions) . ")";
1261 } elseif ($key === 'tabhelp') {
1262 $helpItems = array();
1263 foreach ($value as $helpValue) {
1264 $helpItems[] = "array('code' => \$langs->trans('".$helpValue['code']."'), 'field2' => 'field2tooltip')";
1265 }
1266 $dicData .= "array(" . implode(",", $helpItems) . ")";
1267 } else {
1268 if (is_array($value)) {
1269 $dicData .= "array(" . implode(
1270 ",",
1271 array_map(
1276 static function ($val) {
1277 return "'$val'";
1278 },
1279 $value
1280 )
1281 ) . ")";
1282 } else {
1283 $dicData .= "'$value'";
1284 }
1285 }
1286 $dicData .= ",\n";
1287 }
1288 $dicData .= (!$isEmpty ? "\t\t);" : '');
1289
1290 $stringDic = getFromFile($file, '/* BEGIN MODULEBUILDER DICTIONARIES */', '/* END MODULEBUILDER DICTIONARIES */');
1291 $writeInfile = dolReplaceInFile($file, array($stringDic => $dicData."\n"));
1292
1293 return $writeInfile;
1294}
1295
1308function createNewDictionnary($modulename, $file, $namedic, $dictionnaires = null)
1309{
1310 global $db, $langs;
1311
1312 if (empty($namedic)) {
1313 setEventMessages($langs->trans("ErrorEmptyNameDic"), null, 'errors');
1314 return -1;
1315 }
1316 if (!file_exists($file)) {
1317 return -1;
1318 }
1319 $modulename = strtolower($modulename);
1320
1321 if (empty($dictionnaires)) {
1322 $dictionnaires = array('langs' => '', 'tabname' => array(), 'tablib' => array(), 'tabsql' => array(), 'tabsqlsort' => array(), 'tabfield' => array(), 'tabfieldvalue' => array(), 'tabfieldinsert' => array(), 'tabrowid' => array(), 'tabcond' => array(), 'tabhelp' => array());
1323 }
1324
1325 $columns = array(
1326 'rowid' => array('type' => 'integer', 'value' => 11, 'extra' => 'AUTO_INCREMENT'),
1327 'code' => array('type' => 'varchar', 'value' => 255, 'null' => 'NOT NULL'),
1328 'label' => array('type' => 'varchar', 'value' => 255, 'null' => 'NOT NULL'),
1329 'position' => array('type' => 'integer', 'value' => 11, 'null' => 'NULL'),
1330 'use_default' => array('type' => 'varchar', 'value' => 11, 'default' => '1'),
1331 'active' => array('type' => 'integer', 'value' => 3)
1332 );
1333
1334 $primaryKey = 'rowid';
1335 foreach ($columns as $key => $value) {
1336 if ($key === 'rowid') {
1337 $primaryKey = 'rowid';
1338 break;
1339 }
1340 if (!array_key_exists('rowid', $columns)) {
1341 $primaryKey = array_key_first($columns);
1342 break;
1343 }
1344 }
1345
1346 // check if tablename exist in Database and create it if not
1347 $checkTable = $db->DDLDescTable(MAIN_DB_PREFIX.strtolower($namedic));
1348 if ($checkTable && $db->num_rows($checkTable) > 0) {
1349 setEventMessages($langs->trans("ErrorTableExist", $namedic), null, 'errors');
1350 return -1;
1351 } else {
1352 $_results = $db->DDLCreateTable(MAIN_DB_PREFIX.strtolower($namedic), $columns, $primaryKey, "");
1353 if ($_results < 0) {
1354 dol_print_error($db);
1355 $langs->load("errors");
1356 setEventMessages($langs->trans("ErrorTableNotFound", $namedic), null, 'errors');
1357 }
1358 }
1359
1360 // rewrite dictionary if
1361 $dictionnaires['langs'] = $modulename.'@'.$modulename;
1362 $dictionnaires['tabname'][] = strtolower($namedic);
1363 $dictionnaires['tablib'][] = ucfirst(substr($namedic, 2));
1364 $dictionnaires['tabsql'][] = 'SELECT t.rowid as rowid, t.code, t.label, t.active FROM '.MAIN_DB_PREFIX.strtolower($namedic).' as t';
1365 $dictionnaires['tabsqlsort'][] = (array_key_exists('label', $columns) ? 'label ASC' : '');
1366 $dictionnaires['tabfield'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1367 $dictionnaires['tabfieldvalue'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1368 $dictionnaires['tabfieldinsert'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1369 $dictionnaires['tabrowid'][] = $primaryKey;
1370 $dictionnaires['tabcond'][] = isModEnabled('$modulename'); // @phan-suppress-current-line UnknownModuleName
1371 $dictionnaires['tabhelp'][] = (array_key_exists('code', $columns) ? array('code' => $langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip') : '');
1372
1373 // Build the dictionary string
1374 $writeInfile = updateDictionaryInFile($modulename, $file, $dictionnaires);
1375 if ($writeInfile > 0) {
1376 setEventMessages($langs->trans("DictionariesCreated", ucfirst(substr($namedic, 2))), null);
1377 }
1378
1379 return -1;
1380}
1381
1389function writeApiUrlsInDoc($file_api, $file_doc)
1390{
1391 $error = 0;
1392 if (!dol_is_file($file_api) || !dol_is_file($file_doc)) {
1393 $error++;
1394 }
1395 $string = getFromFile($file_api, '/*begin methods CRUD*/', '/*end methods CRUD*/');
1396 $extractUrls = explode("\n", $string);
1397
1398 // extract urls from file
1399 $urlValues = array();
1400 foreach ($extractUrls as $key => $line) {
1401 $lineWithoutTabsSpaces = preg_replace('/^[\t\s]+/', '', $line);
1402 if (strpos($lineWithoutTabsSpaces, '* @url') === 0) {
1403 $urlValue = trim(substr($lineWithoutTabsSpaces, strlen('* @url')));
1404 $urlValues[] = $urlValue;
1405 }
1406 }
1407
1408 // get urls by object
1409 $str = $_SERVER['HTTP_HOST'].'/api/index.php/';
1410 $groupedUrls = array();
1411 foreach ($urlValues as $url) {
1412 if (preg_match('/(?:GET|POST|PUT|DELETE) (\w+)s/', $url, $matches)) {
1413 $objectName = $matches[1];
1414 $url = $str.trim(strstr($url, ' '));
1415 $groupedUrls[$objectName][] = $url;
1416 }
1417 }
1418 if (empty($groupedUrls)) {
1419 $error++;
1420 }
1421
1422 // build format asciidoc for urls in table
1423 if (!$error) {
1424 $asciiDocTable = "[options=\"header\"]\n|===\n|Object | URLs\n"; // phpcs:ignore
1425 foreach ($groupedUrls as $objectName => $urls) {
1426 $urlsList = implode(" +\n*", $urls);
1427 $asciiDocTable .= "|$objectName | \n*$urlsList +\n";
1428 }
1429 $asciiDocTable .= "|===\n";
1430 $file_write = dolReplaceInFile($file_doc, array('__API_DOC__' => '__API_DOC__'."\n".$asciiDocTable));
1431 if ($file_write < 0) {
1432 return -1;
1433 }
1434 return 1;
1435 }
1436 return -1;
1437}
1438
1439
1446function countItemsInDirectory($path, $type = 1)
1447{
1448 if (!is_dir($path)) {
1449 return false;
1450 }
1451
1452 $allFilesAndDirs = scandir($path);
1453 $count = 0;
1454
1455 foreach ($allFilesAndDirs as $item) {
1456 if ($item != '.' && $item != '..') {
1457 if ($type == 1 && is_file($path . DIRECTORY_SEPARATOR . $item) && strpos($item, '.back') === false) {
1458 $count++;
1459 } elseif ($type == 2 && is_dir($path . DIRECTORY_SEPARATOR . $item)) {
1460 $count++;
1461 }
1462 }
1463 }
1464 return $count;
1465}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
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.