dolibarr 22.0.5
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 $count_perms = count($permissions);
632 foreach (array_keys($permissions) as $i) {
633 $permissions[$i][0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', \$r + 1)";
634 $permissions[$i][1] = "\$this->rights[\$r][1] = '".$permissions[$i][1]."'";
635 $permissions[$i][4] = "\$this->rights[\$r][4] = '".$permissions[$i][4]."'";
636 $permissions[$i][5] = "\$this->rights[\$r][5] = '".$permissions[$i][5]."';\n\t\t";
637 }
638 // for group permissions by object
639 $perms_grouped = array();
640 foreach ($permissions as $perms) {
641 $object = $perms[4];
642 if (!isset($perms_grouped[$object])) {
643 $perms_grouped[$object] = array();
644 }
645 $perms_grouped[$object][] = $perms;
646 }
647 //$perms_grouped = array_values($perms_grouped);
648 $permissions = $perms_grouped;
649
650
651 // parcourir les objects
652 $o = 0;
653 foreach ($permissions as &$object) {
654 // récupérer la permission de l'objet
655 $p = 1;
656 foreach ($object as &$obj) {
657 if (str_contains($obj[5], 'read')) {
658 $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 0 + 1)";
659 } elseif (str_contains($obj[5], 'write')) {
660 $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 1 + 1)";
661 } elseif (str_contains($obj[5], 'delete')) {
662 $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + 2 + 1)";
663 } else {
664 $obj[0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', (".$o." * 10) + ".$p." + 1)";
665 $p++;
666 }
667 }
668 usort($object, 'compareFirstValue');
669 $o++;
670 }
671
672 //convert to string
673 foreach ($permissions as $perms) {
674 foreach ($perms as $per) {
675 $rights[] = implode(";\n\t\t", $per)."\$r++;\n";
676 }
677 }
678 $rights_str = implode("\t\t", $rights);
679 // delete all permissions from file
680 deletePerms($file);
681 // rewrite all permissions again
682 dolReplaceInFile($file, array('/* BEGIN MODULEBUILDER PERMISSIONS */' => '/* BEGIN MODULEBUILDER PERMISSIONS */'."\n\t\t".$rights_str));
683 return 1;
684 } else {
685 return -1;
686 }
687}
688
695function parsePropertyString($string)
696{
697 $string = str_replace("'", '', $string);
698
699 // Uses a regular expression to capture keys and values
700 preg_match_all('/\s*([^\s=>]+)\s*=>\s*([^,]+),?/', $string, $matches, PREG_SET_ORDER);
701 $propertyArray = array();
702
703 foreach ($matches as $match) {
704 $key = trim($match[1]);
705 $value = trim($match[2]);
706
707 if (strpos($value, 'array(') === 0) {
708 $nestedArray = substr($value, 6);
709 $nestedArray = parsePropertyString($nestedArray);
710 $value = $nestedArray;
711 } elseif (strpos($value, '"Id")') !== false) {
712 $value = str_replace(')', '', $value);
713 } else {
714 if (is_numeric($value)) {
715 if (strpos($value, '.') !== false) {
716 $value = (float) $value;
717 } else {
718 $value = (int) $value;
719 }
720 } else {
721 if ($value === 'true') {
722 $value = true;
723 } elseif ($value === 'false') {
724 $value = false;
725 }
726 }
727 }
728 $propertyArray[$key] = $value;
729 }
730
731 return $propertyArray;
732}
733
741function writePropsInAsciiDoc($file, $objectname, $destfile)
742{
743
744 // stock all properties in array
745 $attributesUnique = array('type','label', 'enabled', 'position', 'notnull', 'visible', 'noteditable', 'index', 'default' , 'foreignkey', 'arrayofkeyval', 'alwayseditable','validate', 'searchall','comment', 'isameasure', 'css', 'cssview','csslist', 'help', 'showoncombobox','picto' );
746
747 $start = "public \$fields = array(";
748 $end = ");";
749 $i = 1;
750 $keys = array();
751 $lines = file($file);
752 // Search for start and end lines
753 foreach ($lines as $i => $line) {
754 if (strpos($line, $start) !== false) {
755 // Copy lines until the end on array
756 while (($line = $lines[++$i]) !== false) {
757 if (strpos($line, $end) !== false) {
758 break;
759 }
760 $keys[] = $line;
761 }
762 break;
763 }
764 }
765 // write the begin of table with specifics options
766 $table = "== DATA SPECIFICATIONS\n";
767 $table .= "=== Table of fields with properties for object *$objectname* : \n";
768 $table .= "[options='header',grid=rows,frame=topbot,width=100%,caption=Organisation]\n";
769 $table .= "|===\n";
770 $table .= "|code";
771 // write all properties in the header of the table
772 foreach ($attributesUnique as $attUnique) {
773 $table .= "|".$attUnique;
774 }
775 $table .= "\n";
776 $valuesModif = array();
777 foreach ($keys as $string) {
778 $string = trim($string, "'");
779 $string = rtrim($string, ",");
780
781 $array = parsePropertyString($string);
782
783 // Iterate through the array to merge all key to one array
784 $code = '';
785 foreach ($array as $key => $value) {
786 if (is_array($value)) {
787 $code = $key;
788 continue;
789 } else {
790 $array[$code][$key] = $value;
791 unset($array[$key]);
792 }
793 }
794 // check if is array after parsing the string
795 if (!is_array($array)) {
796 return -1;
797 }
798 $field = array_keys($array);
799 if ($field[0] === '') {
800 $field[0] = 'label';
801 }
802 $values = array_values($array)[0];
803
804 // check each field has all properties and add it if missed
805 foreach ($attributesUnique as $attUnique) {
806 if ($attUnique == 'type' && $field[0] === 'label') {
807 $values[$attUnique] = 'varchar(255)';
808 }
809 if (!array_key_exists($attUnique, $values)) {
810 $valuesModif[$attUnique] = '';
811 } else {
812 $valuesModif[$attUnique] = $values[$attUnique];
813 }
814 }
815 $table .= "|*" . $field[0] . "*|";
816 $table .= implode("|", $valuesModif) . "\n";
817 }
818
819 // end table
820 $table .= "|===\n";
821 $table .= "__ end table for object $objectname\n";
822
823 //write in file @phan-suppress-next-line PhanPluginSuspiciousParamPosition
824 $writeInFile = dolReplaceInFile($destfile, array('== DATA SPECIFICATIONS' => $table));
825 if ($writeInFile < 0) {
826 return -1;
827 }
828 return 1;
829}
830
831
839function deletePropsAndPermsFromDoc($file, $objectname)
840{
841 if (dol_is_file($file)) {
842 $start = "== Table of fields and their properties for object *".ucfirst($objectname)."* : ";
843 $end = "__ end table for object ".ucfirst($objectname);
844
845 $str = file_get_contents($file);
846
847 $search = '/' . preg_quote($start, '/') . '(.*?)' . preg_quote($end, '/') . '/s';
848 $new_contents = preg_replace($search, '', $str);
849 file_put_contents($file, $new_contents);
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 }
857}
858
859
860
871function getFromFile($file, $start, $end, $excludestart = '', $includese = 0)
872{
873 $keys = array();
874
875 //$lines = file(dol_osencode($file));
876 $fhandle = fopen(dol_osencode($file), 'r');
877 if ($fhandle) {
878 // Search for start and end lines
879 //foreach ($lines as $i => $line) {
880 while ($line = fgets($fhandle)) {
881 if (strpos($line, $start) !== false && (empty($excludestart) || strpos($line, $excludestart) === false)) {
882 if ($includese) {
883 $keys[] = $line;
884 }
885 // Copy lines until we reach the end
886 while (($line = fgets($fhandle)) !== false) {
887 if (strpos($line, $end) !== false) {
888 if ($includese) {
889 $keys[] = $line;
890 }
891 break;
892 }
893 $keys[] = $line;
894 }
895 break;
896 }
897 }
898 }
899 fclose($fhandle);
900
901 $content = implode("", $keys);
902 return $content;
903}
904
911function writePermsInAsciiDoc($file, $destfile)
912{
913 global $langs;
914 //search and get all permissions in string
915 $start = '/* BEGIN MODULEBUILDER PERMISSIONS */';
916 $end = '/* END MODULEBUILDER PERMISSIONS */';
917 $content = getFromFile($file, $start, $end);
918 if (empty($content)) {
919 return -1;
920 }
921 //prepare table
922 $string = "[options='header',grid=rows,width=60%,caption=Organisation]\n";
923 $string .= "|===\n";
924 // header for table
925 $header = array($langs->trans('Objects'),$langs->trans('Permission'));
926 foreach ($header as $h) {
927 $string .= "|".$h;
928 }
929 $string .= "\n";
930 //content table
931 $array = explode(";", $content);
932 $permissions = array_filter($array);
933 // delete occurrences "$r++" and ID
934 $permissions = str_replace('$r++', '1', $permissions);
935
936 $permsN = array();
937 foreach ($permissions as $i => $element) {
938 if ($element == 1) {
939 unset($permissions[$i]);
940 }
941 if (str_contains($element, '$this->numero')) {
942 unset($permissions[$i]);
943 }
944 if (str_contains($element, '$this->rights[$r][5]')) {
945 unset($permissions[$i]);
946 }
947 }
948 // cleaning the string on each element
949 foreach ($permissions as $key => $element) {
950 $element = str_replace(" '", '', $element);
951 $element = trim($element, "'");
952 $permsN[] = substr($element, strpos($element, "=") + 1);
953 }
954 array_pop($permsN);
955
956 // Group permissions by Object and add it to string
957 $final_array = array();
958 $index = 0;
959 while ($index < count($permsN)) {
960 $temp_array = array($permsN[$index], $permsN[$index + 1]);
961 $final_array[] = $temp_array;
962 $index += 2;
963 }
964
965 $result = array();
966 foreach ($final_array as $subarray) {
967 // found object
968 $key = $subarray[1];
969 // add sub array to object
970 $result[$key][] = $subarray;
971 }
972 foreach ($result as $i => $pems) {
973 $string .= "|*".$i."*|";
974 foreach ($pems as $tab) {
975 $string .= $tab[0]." , ";
976 }
977 $string .= "\n";
978 }
979 // end table
980 $string .= "\n|===\n";
981 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
982 $write = dolReplaceInFile($destfile, array('__DATA_PERMISSIONS__' => $string));
983 if ($write < 0) {
984 return -1;
985 }
986 return 1;
987}
988
998function addObjectsToApiFile($srcfile, $file, $objects, $modulename)
999{
1000 global $langs, $user;
1001
1002 if (!file_exists($file)) {
1003 return -1;
1004 }
1005
1006 $now = dol_now();
1007 $content = file($file); // $content is an array
1008
1009 $includeClass = "dol_include_once\‍(\'\/\w+\/class\/\w+\.class\.php\'\‍);";
1010 $props = 'public\s+\$\w+;';
1011 $varcommented = '@var\s+\w+\s+\$\w+\s+{@type\s+\w+}';
1012 $constructObj = '\$this->\w+\s+=\s+new\s+\w+\‍(\$this->db\‍);';
1013
1014 // add properties and declare them in constructor
1015 foreach ($content as $lineNumber => &$lineContent) {
1016 if (preg_match('/'.$varcommented.'/', $lineContent)) {
1017 $lineContent = '';
1018 foreach ($objects as $objectname) {
1019 $lineContent .= "\t * @var ".$objectname." \$".strtolower($objectname)." {@type ".$objectname."}". PHP_EOL;
1020 }
1021 //var_dump($lineContent);exit;
1022 } elseif (preg_match('/'.$props.'/', $lineContent)) {
1023 $lineContent = '';
1024 foreach ($objects as $objectname) {
1025 $lineContent .= "\t/*".PHP_EOL."\t * @var mixed TODO: set type".PHP_EOL."\t */".PHP_EOL."\tpublic \$".strtolower($objectname).";". PHP_EOL;
1026 }
1027 } elseif (preg_match('/'.$constructObj.'/', $lineContent)) {
1028 $lineContent = '';
1029 foreach ($objects as $objectname) {
1030 $lineContent .= "\t\t\$this->".strtolower($objectname)." = new ".$objectname."(\$this->db);". PHP_EOL;
1031 }
1032 } elseif (preg_match('/'.$includeClass.'/', $lineContent)) {
1033 $lineContent = '';
1034 foreach ($objects as $objectname) {
1035 $lineContent .= "dol_include_once('/".strtolower($modulename)."/class/".strtolower($objectname).".class.php');". PHP_EOL;
1036 }
1037 }
1038 }
1039
1040 $allContent = implode("", $content);
1041 file_put_contents($file, $allContent);
1042
1043 // Add methods for each object
1044 $allContent = getFromFile($srcfile, '/* BEGIN MODULEBUILDER API MYOBJECT */', '/* END MODULEBUILDER API MYOBJECT */');
1045 foreach ($objects as $objectname) {
1046 $arrayreplacement = array(
1047 'mymodule' => strtolower($modulename),
1048 'MyModule' => $modulename,
1049 'MYMODULE' => strtoupper($modulename),
1050 'My module' => $modulename,
1051 'my module' => $modulename,
1052 'Mon module' => $modulename,
1053 'mon module' => $modulename,
1054 'htdocs/modulebuilder/template' => strtolower($modulename),
1055 'myobject' => strtolower($objectname),
1056 'MyObject' => $objectname,
1057 'MYOBJECT' => strtoupper($objectname),
1058 '---Replace with your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
1059 );
1060 $contentReplaced = make_substitutions($allContent, $arrayreplacement, null);
1061 //$contentReplaced = str_replace(["myobject","MyObject"], [strtolower($object),$object], $allContent);
1062
1063 dolReplaceInFile($file, array(
1064 '/* BEGIN MODULEBUILDER API MYOBJECT */' => '/* BEGIN MODULEBUILDER API '.strtoupper($objectname).' */'.$contentReplaced."\t".'/* END MODULEBUILDER API '.strtoupper($objectname).' */'."\n\n\n\t".'/* BEGIN MODULEBUILDER API MYOBJECT */'
1065 ));
1066 }
1067
1068 // Remove the block $allContent found in src file
1069 // TODO Replace with a replacement of all text including into /* BEGIN MODULEBUILDER API MYOBJECT */ and /* END MODULEBUILDER API MYOBJECT */
1070 dolReplaceInFile($file, array($allContent => ''));
1071
1072 return 1;
1073}
1074
1083function removeObjectFromApiFile($file, $objects, $objectname)
1084{
1085 if (!file_exists($file)) {
1086 return -1;
1087 }
1088
1089 $content = file($file); // $content is an array
1090
1091 $includeClass = "dol_include_once\‍(\'\/\w+\/class\/".strtolower($objectname)."\.class\.php\'\‍);";
1092 $props = 'public\s+\$'.strtolower($objectname);
1093 $varcommented = '@var\s+\w+\s+\$'.strtolower($objectname).'\s+{@type\s+\w+}';
1094 $constructObj = '\$this->'.strtolower($objectname).'\s+=\s+new\s+\w+\‍(\$this->db\‍);';
1095
1096 // add properties and declare them in constructor
1097 foreach ($content as $lineNumber => &$lineContent) {
1098 if (preg_match('/'.$varcommented.'/i', $lineContent)) {
1099 $lineContent = '';
1100 } elseif (preg_match('/'.$props.'/i', $lineContent)) {
1101 $lineContent = '';
1102 } elseif (preg_match('/'.$constructObj.'/i', $lineContent)) {
1103 $lineContent = '';
1104 } elseif (preg_match('/'.$includeClass.'/i', $lineContent)) {
1105 $lineContent = '';
1106 }
1107 }
1108
1109 $allContent = implode("", $content);
1110 file_put_contents($file, $allContent);
1111
1112 // for delete methods of object
1113 $begin = '/* BEGIN MODULEBUILDER API '.strtoupper($objectname).' */';
1114 $end = '/* END MODULEBUILDER API '.strtoupper($objectname).' */';
1115 $allContent = getFromFile($file, $begin, $end);
1116 $check = dolReplaceInFile($file, array($allContent => ''));
1117 if ($check) {
1118 dolReplaceInFile($file, array($begin => '', $end => ''));
1119 }
1120
1121 return 1;
1122}
1123
1124
1133function reWriteAllMenus($file, $menus, $menuWantTo, $key, $action)
1134{
1135 $errors = 0;
1136 $counter = 0;
1137 if (!file_exists($file)) {
1138 return -1;
1139 }
1140
1141 if ($action == 0 && !empty($key)) {
1142 // delete menu manually
1143 array_splice($menus, array_search($menus[$key], $menus), 1);
1144 } elseif ($action == 1) {
1145 // add menu manually
1146 array_push($menus, $menuWantTo);
1147 } elseif ($action == 2 && !empty($key) && !empty($menuWantTo)) {
1148 // update right from permissions array
1149 $urlCounter = 0;
1150 // check if the values already exists
1151 foreach ($menus as $index => $menu) {
1152 if ($index !== $key) {
1153 if ($menu['type'] === $menuWantTo['type']) {
1154 if (strcasecmp(str_replace(' ', '', $menu['titre']), str_replace(' ', '', $menuWantTo['titre'])) === 0) {
1155 $counter++;
1156 }
1157 if (strcasecmp(str_replace(' ', '', $menu['url']), str_replace(' ', '', $menuWantTo['url'])) === 0) {
1158 $urlCounter++;
1159 }
1160 }
1161 }
1162 }
1163 if (!$counter && $urlCounter < 2) {
1164 $menus[$key] = $menuWantTo;
1165 } else {
1166 $errors++;
1167 }
1168 } elseif ($action == -1 && !empty($menuWantTo) && is_string($menuWantTo)) {
1169 // delete menus when delete Object
1170 foreach ($menus as $index => $menu) {
1171 if ((strpos(strtolower($menu['fk_menu']), strtolower($menuWantTo)) !== false) || (strpos(strtolower($menu['leftmenu']), strtolower($menuWantTo)) !== false)) {
1172 array_splice($menus, array_search($menu, $menus), 1);
1173 }
1174 }
1175 } else {
1176 $errors++;
1177 }
1178 if (!$errors) {
1179 // delete All LEFT Menus (except for commented template MYOBJECT)
1180 $beginMenu = '/* BEGIN MODULEBUILDER LEFTMENU';
1181 $excludeBeginMenu = '/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT';
1182 $endMenu = '/* END MODULEBUILDER LEFTMENU';
1183 $protection = 0;
1184 while ($protection <= 1000 && $allMenus = getFromFile($file, $beginMenu, $endMenu, $excludeBeginMenu, 1)) {
1185 $protection++;
1186 dolReplaceInFile($file, array($allMenus => ''));
1187 }
1188
1189 // forge the menu code in a string
1190 $str_menu = "";
1191 foreach ($menus as $index => $menu) {
1192 $menu['position'] = "1000 + \$r";
1193 if ($menu['type'] === 'left') {
1194 $start = "\t\t".'/* BEGIN MODULEBUILDER LEFTMENU '.strtoupper(empty($menu['object']) ? $menu['titre'] : $menu['object']).' */';
1195 $end = "\t\t".'/* END MODULEBUILDER LEFTMENU '.strtoupper(empty($menu['object']) ? $menu['titre'] : $menu['object']).' */';
1196
1197 $val_actuel = $menu;
1198 $next_val = empty($menus[$index + 1]) ? null : $menus[$index + 1];
1199 //var_dump(dol_escape_php($menu['perms'], 1)); exit;
1200
1201 $str_menu .= $start."\n";
1202 $str_menu .= "\t\t\$this->menu[\$r++] = array(\n";
1203 $str_menu .= "\t\t\t'fk_menu' => '".dol_escape_php($menu['fk_menu'], 1)."',\n";
1204 $str_menu .= "\t\t\t'type' => '".dol_escape_php($menu['type'], 1)."',\n";
1205 $str_menu .= "\t\t\t'titre' => '".dol_escape_php($menu['titre'], 1)."',\n";
1206 $str_menu .= "\t\t\t'mainmenu' => '".dol_escape_php($menu['mainmenu'], 1)."',\n";
1207 $str_menu .= "\t\t\t'leftmenu' => '".dol_escape_php($menu['leftmenu'], 1)."',\n";
1208 $str_menu .= "\t\t\t'url' => '".dol_escape_php($menu['url'], 1)."',\n";
1209 $str_menu .= "\t\t\t'langs' => '".dol_escape_php($menu['langs'], 1)."',\n";
1210 $str_menu .= "\t\t\t'position' => ".((int) $menu['position']).",\n";
1211 $str_menu .= "\t\t\t'enabled' => '".dol_escape_php((string) $menu['enabled'], 1)."',\n";
1212 $str_menu .= "\t\t\t'perms' => '".dol_escape_php($menu['perms'], 1)."',\n";
1213 $str_menu .= "\t\t\t'target' => '".dol_escape_php($menu['target'], 1)."',\n";
1214 $str_menu .= "\t\t\t'user' => ".((int) $menu['user']).",\n";
1215 $str_menu .= "\t\t\t'object' => '".dol_escape_php($menu['object'], 1)."',\n";
1216 $str_menu .= "\t\t);\n";
1217
1218 if (is_null($next_val) || $val_actuel['leftmenu'] !== $next_val['leftmenu']) {
1219 $str_menu .= $end."\n";
1220 }
1221 }
1222 }
1223
1224 dolReplaceInFile($file, array('/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */' => $str_menu."\n\t\t/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */"));
1225 return 1;
1226 }
1227 return -1;
1228}
1229
1238function updateDictionaryInFile($module, $file, $dicts)
1239{
1240 $isEmpty = false;
1241 $dicData = "\t\t\$this->dictionaries = array(\n";
1242 $module = strtolower($module);
1243 foreach ($dicts as $key => $value) {
1244 if (empty($value)) {
1245 $isEmpty = true;
1246 $dicData = "\t\t\$this->dictionaries = array();";
1247 break;
1248 }
1249
1250 $dicData .= "\t\t\t'$key' => ";
1251
1252 if ($key === 'tabcond') {
1253 $conditions = array_map(
1258 static function ($val) use ($module) {
1259 return is_bool($val) ? "isModEnabled('$module')" : $val;
1260 },
1261 $value
1262 );
1263 $dicData .= "array(" . implode(", ", $conditions) . ")";
1264 } elseif ($key === 'tabhelp') {
1265 $helpItems = array();
1266 foreach ($value as $helpValue) {
1267 $helpItems[] = "array('code' => \$langs->trans('".$helpValue['code']."'), 'field2' => 'field2tooltip')";
1268 }
1269 $dicData .= "array(" . implode(",", $helpItems) . ")";
1270 } else {
1271 if (is_array($value)) {
1272 $dicData .= "array(" . implode(
1273 ",",
1274 array_map(
1279 static function ($val) {
1280 return "'$val'";
1281 },
1282 $value
1283 )
1284 ) . ")";
1285 } else {
1286 $dicData .= "'$value'";
1287 }
1288 }
1289 $dicData .= ",\n";
1290 }
1291 $dicData .= (!$isEmpty ? "\t\t);" : '');
1292
1293 $stringDic = getFromFile($file, '/* BEGIN MODULEBUILDER DICTIONARIES */', '/* END MODULEBUILDER DICTIONARIES */');
1294 $writeInfile = dolReplaceInFile($file, array($stringDic => $dicData."\n"));
1295
1296 return $writeInfile;
1297}
1298
1311function createNewDictionnary($modulename, $file, $namedic, $dictionnaires = null)
1312{
1313 global $db, $langs;
1314
1315 if (empty($namedic)) {
1316 setEventMessages($langs->trans("ErrorEmptyNameDic"), null, 'errors');
1317 return -1;
1318 }
1319 if (!file_exists($file)) {
1320 return -1;
1321 }
1322 $modulename = strtolower($modulename);
1323
1324 if (empty($dictionnaires)) {
1325 $dictionnaires = array('langs' => '', 'tabname' => array(), 'tablib' => array(), 'tabsql' => array(), 'tabsqlsort' => array(), 'tabfield' => array(), 'tabfieldvalue' => array(), 'tabfieldinsert' => array(), 'tabrowid' => array(), 'tabcond' => array(), 'tabhelp' => array());
1326 }
1327
1328 $columns = array(
1329 'rowid' => array('type' => 'integer', 'value' => 11, 'extra' => 'AUTO_INCREMENT'),
1330 'code' => array('type' => 'varchar', 'value' => 255, 'null' => 'NOT NULL'),
1331 'label' => array('type' => 'varchar', 'value' => 255, 'null' => 'NOT NULL'),
1332 'position' => array('type' => 'integer', 'value' => 11, 'null' => 'NULL'),
1333 'use_default' => array('type' => 'varchar', 'value' => 11, 'default' => '1'),
1334 'active' => array('type' => 'integer', 'value' => 3)
1335 );
1336
1337 $primaryKey = 'rowid';
1338 foreach ($columns as $key => $value) {
1339 if ($key === 'rowid') {
1340 $primaryKey = 'rowid';
1341 break;
1342 }
1343 if (!array_key_exists('rowid', $columns)) {
1344 $primaryKey = array_key_first($columns);
1345 break;
1346 }
1347 }
1348
1349 // check if tablename exist in Database and create it if not
1350 $checkTable = $db->DDLDescTable(MAIN_DB_PREFIX.strtolower($namedic));
1351 if ($checkTable && $db->num_rows($checkTable) > 0) {
1352 setEventMessages($langs->trans("ErrorTableExist", $namedic), null, 'errors');
1353 return -1;
1354 } else {
1355 $_results = $db->DDLCreateTable(MAIN_DB_PREFIX.strtolower($namedic), $columns, $primaryKey, "");
1356 if ($_results < 0) {
1357 dol_print_error($db);
1358 $langs->load("errors");
1359 setEventMessages($langs->trans("ErrorTableNotFound", $namedic), null, 'errors');
1360 }
1361 }
1362
1363 // rewrite dictionary if
1364 $dictionnaires['langs'] = $modulename.'@'.$modulename;
1365 $dictionnaires['tabname'][] = strtolower($namedic);
1366 $dictionnaires['tablib'][] = ucfirst(substr($namedic, 2));
1367 $dictionnaires['tabsql'][] = 'SELECT t.rowid as rowid, t.code, t.label, t.active FROM '.MAIN_DB_PREFIX.strtolower($namedic).' as t';
1368 $dictionnaires['tabsqlsort'][] = (array_key_exists('label', $columns) ? 'label ASC' : '');
1369 $dictionnaires['tabfield'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1370 $dictionnaires['tabfieldvalue'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1371 $dictionnaires['tabfieldinsert'][] = (array_key_exists('code', $columns) && array_key_exists('label', $columns) ? 'code,label' : '');
1372 $dictionnaires['tabrowid'][] = $primaryKey;
1373 $dictionnaires['tabcond'][] = isModEnabled('$modulename'); // @phan-suppress-current-line UnknownModuleName
1374 $dictionnaires['tabhelp'][] = (array_key_exists('code', $columns) ? array('code' => $langs->trans('CodeTooltipHelp'), 'field2' => 'field2tooltip') : '');
1375
1376 // Build the dictionary string
1377 $writeInfile = updateDictionaryInFile($modulename, $file, $dictionnaires);
1378 if ($writeInfile > 0) {
1379 setEventMessages($langs->trans("DictionariesCreated", ucfirst(substr($namedic, 2))), null);
1380 }
1381
1382 return -1;
1383}
1384
1392function writeApiUrlsInDoc($file_api, $file_doc)
1393{
1394 $error = 0;
1395 if (!dol_is_file($file_api) || !dol_is_file($file_doc)) {
1396 $error++;
1397 }
1398 $string = getFromFile($file_api, '/*begin methods CRUD*/', '/*end methods CRUD*/');
1399 $extractUrls = explode("\n", $string);
1400
1401 // extract urls from file
1402 $urlValues = array();
1403 foreach ($extractUrls as $key => $line) {
1404 $lineWithoutTabsSpaces = preg_replace('/^[\t\s]+/', '', $line);
1405 if (strpos($lineWithoutTabsSpaces, '* @url') === 0) {
1406 $urlValue = trim(substr($lineWithoutTabsSpaces, strlen('* @url')));
1407 $urlValues[] = $urlValue;
1408 }
1409 }
1410
1411 // get urls by object
1412 $str = $_SERVER['HTTP_HOST'].'/api/index.php/';
1413 $groupedUrls = array();
1414 foreach ($urlValues as $url) {
1415 if (preg_match('/(?:GET|POST|PUT|DELETE) (\w+)s/', $url, $matches)) {
1416 $objectName = $matches[1];
1417 $url = $str.trim(strstr($url, ' '));
1418 $groupedUrls[$objectName][] = $url;
1419 }
1420 }
1421 if (empty($groupedUrls)) {
1422 $error++;
1423 }
1424
1425 // build format asciidoc for urls in table
1426 if (!$error) {
1427 $asciiDocTable = "[options=\"header\"]\n|===\n|Object | URLs\n"; // phpcs:ignore
1428 foreach ($groupedUrls as $objectName => $urls) {
1429 $urlsList = implode(" +\n*", $urls);
1430 $asciiDocTable .= "|$objectName | \n*$urlsList +\n";
1431 }
1432 $asciiDocTable .= "|===\n";
1433 $file_write = dolReplaceInFile($file_doc, array('__API_DOC__' => '__API_DOC__'."\n".$asciiDocTable));
1434 if ($file_write < 0) {
1435 return -1;
1436 }
1437 return 1;
1438 }
1439 return -1;
1440}
1441
1442
1449function countItemsInDirectory($path, $type = 1)
1450{
1451 if (!is_dir($path)) {
1452 return false;
1453 }
1454
1455 $allFilesAndDirs = scandir($path);
1456 $count = 0;
1457
1458 foreach ($allFilesAndDirs as $item) {
1459 if ($item != '.' && $item != '..') {
1460 if ($type == 1 && is_file($path . DIRECTORY_SEPARATOR . $item) && strpos($item, '.back') === false) {
1461 $count++;
1462 } elseif ($type == 2 && is_dir($path . DIRECTORY_SEPARATOR . $item)) {
1463 $count++;
1464 }
1465 }
1466 }
1467 return $count;
1468}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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.