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