26require_once DOL_DOCUMENT_ROOT .
'/core/lib/functions.lib.php';
27require_once DOL_DOCUMENT_ROOT .
'/modulebuilder/class/NamingContract.class.php';
49 $identifier = $prefix.$module.
'_'.$table.
'_'.$key;
60 return $prefix.$module.
'_'.$table.
'_'.$key;
80 if (empty($objectname)) {
83 if (empty($readdir)) {
87 if (!empty($addfieldentry[
'arrayofkeyval']) && !is_array($addfieldentry[
'arrayofkeyval'])) {
88 dol_print_error(
null,
'Bad parameter addfieldentry with a property arrayofkeyval defined but that is not an array.');
95 if (is_array($addfieldentry) && count($addfieldentry) > 0) {
96 if (empty($addfieldentry[
'name'])) {
97 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
"Name")),
null,
'errors');
100 if (empty($addfieldentry[
'label'])) {
101 setEventMessages($langs->trans(
'ErrorFieldRequired', $langs->transnoentitiesnoconv(
"Label")),
null,
'errors');
104 if (!preg_match(
'/^(integer|price|sellist|varchar|double|text|html|duration|stars)/', $addfieldentry[
'type'])
105 && !preg_match(
'/^(boolean|smallint|real|date|datetime|timestamp|phone|email|url|ip|password)$/', $addfieldentry[
'type'])) {
106 setEventMessages($langs->trans(
'BadValueForType', $addfieldentry[
'type']),
null,
'errors');
111 if (preg_match(
'/^stars\((.+)\)$/', $addfieldentry[
'type'], $matches)) {
112 if (!preg_match(
'/^[0-9]+$/', $matches[1]) || $matches[1] < 1 || $matches[1] > 10) {
113 setEventMessages($langs->trans(
'BadValueForType', $addfieldentry[
'type']),
null,
'errors');
119 $pathoffiletoeditsrc = $readdir.
'/class/'.
dol_strtolower($objectname).
'.class.php';
120 $pathoffiletoedittarget = $destdir.
'/class/'.
dol_strtolower($objectname).
'.class.php'.($readdir != $destdir ?
'.new' :
'');
122 $langs->load(
"errors");
123 setEventMessages($langs->trans(
"ErrorFileNotFound", $pathoffiletoeditsrc),
null,
'errors');
131 include_once $pathoffiletoeditsrc;
132 if (class_exists($objectname)) {
133 $object =
new $objectname($db);
137 '@phan-var-force CommonObject $object';
140 dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.
'.back', $newmask, 1);
143 $contentclass = file_get_contents(
dol_osencode($pathoffiletoeditsrc));
147 if (is_array($addfieldentry) && count($addfieldentry)) {
148 $name = $addfieldentry[
'name'];
149 unset($addfieldentry[
'name']);
151 $object->fields[$name] = $addfieldentry;
153 if (!empty($delfieldentry)) {
154 $name = $delfieldentry;
162 $texttoinsert =
'// BEGIN MODULEBUILDER PROPERTIES'.
"\n";
163 $texttoinsert .=
"\t".
'
167 $texttoinsert .=
"\t".
'public $fields = array('.
"\n";
170 foreach (
$object->fields as $key => $val) {
172 $texttoinsert .=
"\t\t".
'"'.$key.
'" => array(';
173 $texttoinsert .=
'"type" => "'.dol_escape_php($val[
'type']).
'",';
174 $texttoinsert .=
' "label" => "'.dol_escape_php($val[
'label']).
'",';
175 if (!empty($val[
'picto'])) {
176 $texttoinsert .=
' "picto" => "'.dol_escape_php($val[
'picto']).
'",';
178 $texttoinsert .=
' "enabled" => "'.dol_escape_php($val[
'enabled'] !==
'' ? $val[
'enabled'] :
'1').
'",';
179 $texttoinsert .=
" 'position' => ".($val[
'position'] !==
'' ? (int) $val[
'position'] : 50).
",";
180 $texttoinsert .=
" 'notnull' => ".(empty($val[
'notnull']) ? 0 : (int) $val[
'notnull']).
",";
181 $texttoinsert .=
' "visible" => "'.dol_escape_php($val[
'visible'] !==
'' ? $val[
'visible'] :
'-1').
'",';
182 if (!empty($val[
'noteditable'])) {
183 $texttoinsert .=
' "noteditable" => "'.dol_escape_php((
string) $val[
'noteditable']).
'",';
185 if (!empty($val[
'alwayseditable'])) {
186 $texttoinsert .=
' "alwayseditable" => "'.dol_escape_php((
string) $val[
'alwayseditable']).
'",';
188 if (array_key_exists(
'default', $val) && (!empty($val[
'default']) || $val[
'default'] ===
'0')) {
189 $texttoinsert .=
' "default" => "'.dol_escape_php($val[
'default']).
'",';
191 if (!empty($val[
'index'])) {
192 $texttoinsert .=
' "index" => "'.(int) $val[
'index'].
'",';
194 if (!empty($val[
'foreignkey'])) {
195 $texttoinsert .=
' "foreignkey" => "'.dol_escape_php($val[
'foreignkey']).
'",';
197 if (!empty($val[
'searchall'])) {
198 $texttoinsert .=
' "searchall" => "'.(int) $val[
'searchall'].
'",';
200 if (!empty($val[
'isameasure'])) {
201 $texttoinsert .=
' "isameasure" => "'.(int) $val[
'isameasure'].
'",';
203 if (!empty($val[
'css'])) {
204 $texttoinsert .=
' "css" => "'.dol_escape_php($val[
'css']).
'",';
206 if (!empty($val[
'cssview'])) {
207 $texttoinsert .=
' "cssview" => "'.dol_escape_php($val[
'cssview']).
'",';
209 if (!empty($val[
'csslist'])) {
210 $texttoinsert .=
' "csslist" => "'.dol_escape_php($val[
'csslist']).
'",';
212 if (!empty($val[
'help'])) {
213 $texttoinsert .=
' "help" => "'.dol_escape_php($val[
'help']).
'",';
215 if (!empty($val[
'showoncombobox'])) {
216 $texttoinsert .=
' "showoncombobox" => "'.(int) $val[
'showoncombobox'].
'",';
218 if (!empty($val[
'disabled'])) {
219 $texttoinsert .=
' "disabled" => "'.(int) $val[
'disabled'].
'",';
221 if (!empty($val[
'autofocusoncreate'])) {
222 $texttoinsert .=
' "autofocusoncreate" => "'.(int) $val[
'autofocusoncreate'].
'",';
224 if (!empty($val[
'arrayofkeyval'])) {
225 $texttoinsert .=
' "arrayofkeyval" => array(';
227 foreach ($val[
'arrayofkeyval'] as $key2 => $val2) {
229 $texttoinsert .=
", ";
231 $texttoinsert .=
'"'.dol_escape_php($key2).
'" => "'.
dol_escape_php($val2).
'"';
234 $texttoinsert .=
'),';
236 if (!empty($val[
'validate'])) {
237 $texttoinsert .=
' "validate" => "'.(int) $val[
'validate'].
'",';
239 if (!empty($val[
'comment'])) {
240 $texttoinsert .=
' "comment" => "'.dol_escape_php($val[
'comment']).
'"';
243 $texttoinsert .=
"),\n";
248 $texttoinsert .=
"\t".
');'.
"\n";
254 foreach (
$object->fields as $key => $val) {
257 $texttoinsert .=
"\t".
'public $'.$key.
";";
262 $texttoinsert .=
"\n";
266 $texttoinsert .=
"\t".
'// END MODULEBUILDER PROPERTIES';
270 $contentclass = preg_replace(
'/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims', $texttoinsert, $contentclass);
273 dol_mkdir(dirname($pathoffiletoedittarget));
276 $result = file_put_contents(
dol_osencode($pathoffiletoedittarget), $contentclass);
279 dolChmod($pathoffiletoedittarget, $newmask);
286 print $e->getMessage();
310 if (empty($objectname)) {
313 if (empty($readdir)) {
317 $pathoffiletoclasssrc = $readdir.
'/class/'.
dol_strtolower($objectname).
'.class.php';
320 if ($moduletype ==
'internal') {
321 $pathoffiletoeditsrc =
'/../install/mysql/tables/llx_'.dol_strtolower(
$module).
'_'.
dol_strtolower($objectname).
'.sql';
322 if (!
dol_is_file($readdir.$pathoffiletoeditsrc)) {
324 if (!
dol_is_file($readdir.$pathoffiletoeditsrc)) {
326 if (!
dol_is_file($readdir.$pathoffiletoeditsrc)) {
327 $pathoffiletoeditsrc =
'/../install/mysql/tables/llx_'.dol_strtolower(
$module).
'.sql';
333 if (!
dol_is_file($readdir.$pathoffiletoeditsrc)) {
335 if (!
dol_is_file($readdir.$pathoffiletoeditsrc)) {
337 if (!
dol_is_file($readdir.$pathoffiletoeditsrc)) {
338 $pathoffiletoeditsrc =
'/sql/llx_'.dol_strtolower(
$module).
'.sql';
345 $pathoffiletoedittarget = $destdir.$pathoffiletoeditsrc.($readdir != $destdir ?
'.new' :
'');
346 $pathoffiletoeditsrc = $readdir.$pathoffiletoeditsrc;
349 $langs->load(
"errors");
350 setEventMessages($langs->trans(
"ErrorFileNotFound", $pathoffiletoeditsrc),
null,
'errors');
357 include_once $pathoffiletoclasssrc;
358 if (class_exists($objectname)) {
359 $object =
new $objectname($db);
365 print $e->getMessage();
369 dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.
'.back', $newmask, 1);
371 $contentsqlfile = file_get_contents(
dol_osencode($pathoffiletoeditsrc));
374 $texttoinsert =
'-- BEGIN MODULEBUILDER FIELDS'.
"\n";
376 foreach (
$object->fields as $key => $val) {
379 $type = $val[
'type'];
380 $type = preg_replace(
'/:.*$/',
'', $type);
382 if ($type ==
'html') {
384 } elseif ($type ==
'price') {
386 } elseif (in_array($type, array(
'link',
'sellist',
'duration'))) {
388 } elseif ($type ==
'chkbxlst') {
389 $type =
'varchar(128)';
390 } elseif ($type ==
'mail' || $type ==
'email') {
391 $type =
'varchar(128)';
392 } elseif (strpos($type,
'stars(') === 0) {
394 } elseif ($type ==
'phone') {
395 $type =
'varchar(20)';
396 } elseif ($type ==
'ip') {
397 $type =
'varchar(32)';
398 } elseif ($type ==
'url') {
399 $type =
'varchar(255)';
402 $texttoinsert .=
"\t".$key.
" ".$type;
403 if ($key ==
'rowid') {
404 $texttoinsert .=
' AUTO_INCREMENT PRIMARY KEY';
405 } elseif ($type ==
'timestamp') {
406 $texttoinsert .=
' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP';
408 if ($key ==
'entity') {
409 $texttoinsert .=
' DEFAULT 1';
411 if (!empty($val[
'default'])) {
412 if (preg_match(
'/^null$/i', $val[
'default'])) {
413 $texttoinsert .=
" DEFAULT NULL";
414 } elseif (preg_match(
'/varchar/', $type)) {
415 $texttoinsert .=
" DEFAULT '".$db->escape($val[
'default']).
"'";
417 $texttoinsert .= (($val[
'default'] > 0) ?
' DEFAULT '.$val[
'default'] :
'');
421 $texttoinsert .= ((!empty($val[
'notnull']) && $val[
'notnull'] > 0) ?
' NOT NULL' :
'');
422 if ($i < count(
$object->fields)) {
423 $texttoinsert .=
", ";
425 $texttoinsert .=
"\n";
428 $texttoinsert .=
"\t".
'-- END MODULEBUILDER FIELDS';
430 $contentsqlfile = preg_replace(
'/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsqlfile);
432 $result = file_put_contents($pathoffiletoedittarget, $contentsqlfile);
434 dolChmod($pathoffiletoedittarget, $newmask);
437 setEventMessages($langs->trans(
"ErrorFailToCreateFile", $pathoffiletoedittarget),
null,
'errors');
441 $pathoffiletoeditsrc = preg_replace(
'/\.sql$/',
'.key.sql', $pathoffiletoeditsrc);
442 $pathoffiletoedittarget = preg_replace(
'/\.sql$/',
'.key.sql', $pathoffiletoedittarget);
443 $pathoffiletoedittarget = preg_replace(
'/\.sql.new$/',
'.key.sql.new', $pathoffiletoedittarget);
445 $contentsqlfile = file_get_contents(
dol_osencode($pathoffiletoeditsrc));
448 $texttoinsert =
'-- BEGIN MODULEBUILDER INDEXES'.
"\n";
450 foreach (
$object->fields as $key => $val) {
452 if (!empty($val[
'index'])) {
454 $texttoinsert .=
"ALTER TABLE llx_".dol_strtolower(
$module).
'_'.
dol_strtolower($objectname).
" ADD ".($key ==
'ref' ?
"UNIQUE INDEX " :
"INDEX ").$indexname.
" (".$key.($key ==
'ref' && array_key_exists(
'entity',
$object->fields) ?
", entity" :
"").
");";
455 $texttoinsert .=
"\n";
457 if (!empty($val[
'foreignkey'])) {
458 $tmp = explode(
'.', $val[
'foreignkey']);
459 if (!empty($tmp[0]) && !empty($tmp[1])) {
461 $texttoinsert .=
"ALTER TABLE llx_".dol_strtolower(
$module).
'_'.
dol_strtolower($objectname).
" ADD CONSTRAINT ".$constraintname.
" FOREIGN KEY (".$key.
") REFERENCES llx_".preg_replace(
'/^llx_/',
'', $tmp[0]).
"(".$tmp[1].
");";
462 $texttoinsert .=
"\n";
467 $texttoinsert .=
'-- END MODULEBUILDER INDEXES';
469 $contentsqlfile = preg_replace(
'/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsqlfile);
471 dol_mkdir(dirname($pathoffiletoedittarget));
473 $result2 = file_put_contents($pathoffiletoedittarget, $contentsqlfile);
475 dolChmod($pathoffiletoedittarget, $newmask);
478 setEventMessages($langs->trans(
"ErrorFailToCreateFile", $pathoffiletoedittarget),
null,
'errors');
481 return $error ? -1 : 1;
493 $listofobject =
dol_dir_list($destdir.
'/class',
'files', 0,
'\.class\.php$');
494 foreach ($listofobject as $fileobj) {
495 if (preg_match(
'/^api_/', $fileobj[
'name'])) {
498 if (preg_match(
'/^actions_/', $fileobj[
'name'])) {
502 $tmpcontent = file_get_contents($fileobj[
'fullname']);
504 if (preg_match(
'/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
505 $objectnameloop = $reg[1];
506 $objects[$fileobj[
'fullname']] = $objectnameloop;
509 if (count($objects) > 0) {
525 if (!file_exists($file)) {
529 $content = file_get_contents($file);
532 if (strpos($content,
'/* BEGIN MODULEBUILDER TOPMENU MYOBJECT */') !==
false
533 || strpos($content,
'/* BEGIN MODULEBUILDER TOPMENU */') !==
false) {
536 if (strpos($content,
'/* END MODULEBUILDER TOPMENU MYOBJECT */') !==
false
537 || strpos($content,
'/* END MODULEBUILDER TOPMENU */') !==
false) {
540 if (strpos($content,
'/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */') !==
false) {
543 if (strpos($content,
'/* END MODULEBUILDER LEFTMENU MYOBJECT */') !==
false) {
550 } elseif ($number === 1) {
551 if (strpos($content,
'/* BEGIN MODULEBUILDER PERMISSIONS */') !==
false && strpos($content,
'/* END MODULEBUILDER PERMISSIONS */') !==
false) {
554 } elseif ($number == 2) {
555 if (strpos($content,
'/* BEGIN MODULEBUILDER DICTIONARIES */') !==
false && strpos($content,
'/* END MODULEBUILDER DICTIONARIES */') !==
false) {
569 require_once DOL_DOCUMENT_ROOT.
'/modulebuilder/class/PermissionsBlock.class.php';
573 }
catch (\RuntimeException $e) {
574 dol_syslog(
'deletePerms '.$e->getMessage(), LOG_WARNING);
578 return $block->write(
'') < 0 ? -1 : 1;
599 require_once DOL_DOCUMENT_ROOT.
'/modulebuilder/class/RightsSyncService.class.php';
602 $objectname = (string) $objectname;
603 $permissions = is_array($permissions) ? $permissions : array();
604 $right = is_array($right) ? $right : array();
609 $module = (string) preg_replace(
'/^mod|\.class\.php$/',
'', basename($file));
613 switch ((
int) $action) {
625 (
string) ($right[4] ??
''),
626 (
string) ($right[1] ??
''),
627 (
string) ($right[5] ??
'')
636 (
string) ($right[4] ??
''),
637 (
string) ($right[1] ??
''),
638 (
string) ($right[5] ??
'')
645 dol_syslog(
'reWriteAllPermissions got an unknown action: '.$action, LOG_WARNING);
648 }
catch (\InvalidArgumentException $e) {
649 dol_syslog(
'reWriteAllPermissions '.$e->getMessage(), LOG_WARNING);
656 if ($report->skipped > 0) {
660 return $report->toLegacyReturnCode();
671 $string = str_replace(
"'",
'', $string);
674 preg_match_all(
'/\s*([^\s=>]+)\s*=>\s*([^,]+),?/', $string, $matches, PREG_SET_ORDER);
675 $propertyArray = array();
677 foreach ($matches as $match) {
678 $key = trim($match[1]);
679 $value = trim($match[2]);
681 if (strpos($value,
'array(') === 0) {
684 $value = $nestedArray;
685 } elseif (strpos($value,
'"Id")') !==
false) {
686 $value = str_replace(
')',
'', $value);
688 if (is_numeric($value)) {
689 if (strpos($value,
'.') !==
false) {
690 $value = (float) $value;
692 $value = (int) $value;
695 if ($value ===
'true') {
697 } elseif ($value ===
'false') {
702 $propertyArray[$key] = $value;
705 return $propertyArray;
719 $attributesUnique = array(
'type',
'label',
'enabled',
'position',
'notnull',
'visible',
'noteditable',
'index',
'default' ,
'foreignkey',
'arrayofkeyval',
'alwayseditable',
'validate',
'searchall',
'comment',
'isameasure',
'css',
'cssview',
'csslist',
'help',
'showoncombobox',
'picto' );
721 $start =
"public \$fields = array(";
725 $lines = file($file);
727 foreach ($lines as $i => $line) {
728 if (strpos($line, $start) !==
false) {
730 while (($line = $lines[++$i]) !==
false) {
731 if (strpos($line, $end) !==
false) {
740 $table =
"== DATA SPECIFICATIONS\n";
741 $table .=
"=== Table of fields with properties for object *$objectname* : \n";
742 $table .=
"[options='header',grid=rows,frame=topbot,width=100%,caption=Organisation]\n";
746 foreach ($attributesUnique as $attUnique) {
747 $table .=
"|".$attUnique;
750 $valuesModif = array();
751 foreach ($keys as $string) {
752 $string = trim($string,
"'");
753 $string = rtrim($string,
",");
759 foreach ($array as $key => $value) {
760 if (is_array($value)) {
764 $array[$code][$key] = $value;
769 if (!is_array($array)) {
772 $field = array_keys($array);
773 if ($field[0] ===
'') {
776 $values = array_values($array)[0];
779 foreach ($attributesUnique as $attUnique) {
780 if ($attUnique ==
'type' && $field[0] ===
'label') {
781 $values[$attUnique] =
'varchar(255)';
783 if (!array_key_exists($attUnique, $values)) {
784 $valuesModif[$attUnique] =
'';
786 $valuesModif[$attUnique] = $values[$attUnique];
789 $table .=
"|*" . $field[0] .
"*|";
790 $table .= implode(
"|", $valuesModif) .
"\n";
795 $table .=
"__ end table for object $objectname\n";
798 $writeInFile =
dolReplaceInFile($destfile, array(
'== DATA SPECIFICATIONS' => $table));
799 if ($writeInFile < 0) {
816 $start =
"== Table of fields and their properties for object *".dol_ucfirst($objectname).
"* : ";
817 $end =
"__ end table for object ".dol_ucfirst($objectname);
819 $str = file_get_contents($file);
821 $search =
'/' . preg_quote($start,
'/') .
'(.*?)' . preg_quote($end,
'/') .
'/s';
822 $new_contents = preg_replace($search,
'', $str);
823 file_put_contents($file, $new_contents);
827 $perms =
"|*".dol_strtolower($objectname).
"*|";
828 $search_pattern_perms =
'/' . preg_quote($perms,
'/') .
'.*?\n/';
829 $new_contents = preg_replace($search_pattern_perms,
'', $new_contents);
830 file_put_contents($file, $new_contents);
847function getFromFile($file, $start, $end, $excludestart =
'', $includese = 0)
856 while ($line = fgets($fhandle)) {
857 if (strpos($line, $start) !==
false && (empty($excludestart) || strpos($line, $excludestart) ===
false)) {
862 while (($line = fgets($fhandle)) !==
false) {
863 if (strpos($line, $end) !==
false) {
877 $content = implode(
"", $keys);
891 $start =
'/* BEGIN MODULEBUILDER PERMISSIONS */';
892 $end =
'/* END MODULEBUILDER PERMISSIONS */';
894 if (empty($content)) {
898 $string =
"[options='header',grid=rows,width=60%,caption=Organisation]\n";
901 $header = array($langs->trans(
'Objects'),$langs->trans(
'Permission'));
902 foreach ($header as $h) {
907 $array = explode(
";", $content);
908 $permissions = array_filter($array);
910 $permissions = str_replace(
'$r++',
'1', $permissions);
913 foreach ($permissions as $i => $element) {
915 unset($permissions[$i]);
917 if (str_contains($element,
'$this->numero')) {
918 unset($permissions[$i]);
920 if (str_contains($element,
'$this->rights[$r][5]')) {
921 unset($permissions[$i]);
925 foreach ($permissions as $key => $element) {
926 $element = str_replace(
" '",
'', $element);
927 $element = trim($element,
"'");
928 $permsN[] =
dol_substr($element, strpos($element,
"=") + 1);
933 $final_array = array();
935 while ($index < count($permsN)) {
936 $temp_array = array($permsN[$index], $permsN[$index + 1]);
937 $final_array[] = $temp_array;
942 foreach ($final_array as $subarray) {
946 $result[$key][] = $subarray;
948 foreach ($result as $i => $pems) {
949 $string .=
"|*".$i.
"*|";
950 foreach ($pems as $tab) {
951 $string .= $tab[0].
" , ";
956 $string .=
"\n|===\n";
958 $write =
dolReplaceInFile($destfile, array(
'__DATA_PERMISSIONS__' => $string));
976 global $langs, $user;
978 if (!file_exists($file)) {
983 $content = file($file);
985 $includeClass =
"dol_include_once\(\'\/\w+\/class\/\w+\.class\.php\'\);";
986 $props =
'public\s+\$\w+;';
987 $varcommented =
'@var\s+\w+\s+\$\w+\s+{@type\s+\w+}';
988 $constructObj =
'\$this->\w+\s+=\s+new\s+\w+\(\$this->db\);';
991 foreach ($content as $lineNumber => &$lineContent) {
992 if (preg_match(
'/'.$varcommented.
'/', $lineContent)) {
994 foreach ($objects as $objectname) {
995 $lineContent .=
"\t * @var ".$objectname.
" \$".
dol_strtolower($objectname).
" {@type ".$objectname.
"}". PHP_EOL;
998 } elseif (preg_match(
'/'.$props.
'/', $lineContent)) {
1000 foreach ($objects as $objectname) {
1001 $lineContent .=
"\t/*".PHP_EOL.
"\t * @var mixed TODO: set type".PHP_EOL.
"\t */".PHP_EOL.
"\tpublic \$".
dol_strtolower($objectname).
";". PHP_EOL;
1003 } elseif (preg_match(
'/'.$constructObj.
'/', $lineContent)) {
1005 foreach ($objects as $objectname) {
1006 $lineContent .=
"\t\t\$this->".dol_strtolower($objectname).
" = new ".$objectname.
"(\$this->db);". PHP_EOL;
1008 } elseif (preg_match(
'/'.$includeClass.
'/', $lineContent)) {
1010 foreach ($objects as $objectname) {
1011 $lineContent .=
"dol_include_once('/".dol_strtolower($modulename).
"/class/".
dol_strtolower($objectname).
".class.php');". PHP_EOL;
1016 $allContent = implode(
"", $content);
1017 file_put_contents($file, $allContent);
1021 $allContent =
getFromFile($srcfile,
'/* BEGIN MODULEBUILDER API MYOBJECT */',
'/* END MODULEBUILDER API MYOBJECT */');
1022 foreach ($objects as $objectname) {
1024 dol_syslog(
'addObjectsToApiFile: skipping object "' . $objectname .
'" — name collides with module "' . $modulename .
'"', LOG_WARNING);
1029 'htdocs/modulebuilder/template' => $nc->moduleNameLower,
1030 '---Replace with your own copyright and developer email---' =>
dol_print_date($now,
'%Y') .
' ' . $user->getFullName($langs) . ($user->email ?
' <' . $user->email .
'>' :
''),
1032 $fullMap = array_merge($nc->getSubstitutionMap(), $extraMap);
1033 $contentReplaced = str_replace(array_keys($fullMap), array_values($fullMap), $allContent);
1036 '/* BEGIN MODULEBUILDER API MYOBJECT */' =>
'/* BEGIN MODULEBUILDER API '.
dol_strtoupper($objectname).
' */'.$contentReplaced.
"\t".
'/* END MODULEBUILDER API '.dol_strtoupper($objectname).
' */'.
"\n\n\n\t".
'/* BEGIN MODULEBUILDER API MYOBJECT */'
1057 if (!file_exists($file)) {
1061 $content = file($file);
1063 $includeClass =
"dol_include_once\(\'\/\w+\/class\/".dol_strtolower($objectname).
"\.class\.php\'\);";
1064 $props =
'public\s+\$'.dol_strtolower($objectname);
1065 $varcommented =
'@var\s+\w+\s+\$'.dol_strtolower($objectname).
'\s+{@type\s+\w+}';
1066 $constructObj =
'\$this->'.dol_strtolower($objectname).
'\s+=\s+new\s+\w+\(\$this->db\);';
1069 foreach ($content as $lineNumber => &$lineContent) {
1070 if (preg_match(
'/'.$varcommented.
'/i', $lineContent)) {
1072 } elseif (preg_match(
'/'.$props.
'/i', $lineContent)) {
1074 } elseif (preg_match(
'/'.$constructObj.
'/i', $lineContent)) {
1076 } elseif (preg_match(
'/'.$includeClass.
'/i', $lineContent)) {
1081 $allContent = implode(
"", $content);
1082 file_put_contents($file, $allContent);
1086 $begin =
'/* BEGIN MODULEBUILDER API '.dol_strtoupper($objectname).
' */';
1087 $end =
'/* END MODULEBUILDER API '.dol_strtoupper($objectname).
' */';
1110 if (!file_exists($file)) {
1114 if ($action == 0 && !empty($key)) {
1116 array_splice($menus, array_search($menus[$key], $menus), 1);
1117 } elseif ($action == 1) {
1119 array_push($menus, $menuWantTo);
1120 } elseif ($action == 2 && !empty($key) && !empty($menuWantTo)) {
1124 foreach ($menus as $index => $menu) {
1125 if ($index !== $key) {
1126 if ($menu[
'type'] === $menuWantTo[
'type']) {
1127 if (strcasecmp(str_replace(
' ',
'', $menu[
'titre']), str_replace(
' ',
'', $menuWantTo[
'titre'])) === 0) {
1130 if (strcasecmp(str_replace(
' ',
'', $menu[
'url']), str_replace(
' ',
'', $menuWantTo[
'url'])) === 0) {
1136 if (!$counter && $urlCounter < 2) {
1137 $menus[$key] = $menuWantTo;
1141 } elseif ($action == -1 && !empty($menuWantTo) && is_string($menuWantTo)) {
1143 foreach ($menus as $index => $menu) {
1145 array_splice($menus, array_search($menu, $menus), 1);
1153 $beginMenu =
'/* BEGIN MODULEBUILDER LEFTMENU';
1154 $excludeBeginMenu =
'/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT';
1155 $endMenu =
'/* END MODULEBUILDER LEFTMENU';
1157 while ($protection <= 1000 && $allMenus =
getFromFile($file, $beginMenu, $endMenu, $excludeBeginMenu, 1)) {
1164 foreach ($menus as $index => $menu) {
1165 $menu[
'position'] =
"1000 + \$r";
1166 if ($menu[
'type'] ===
'left') {
1167 $start =
"\t\t".
'/* BEGIN MODULEBUILDER LEFTMENU '.
dol_strtoupper(empty($menu[
'object']) ? $menu[
'titre'] : $menu[
'object']).
' */';
1168 $end =
"\t\t".
'/* END MODULEBUILDER LEFTMENU '.
dol_strtoupper(empty($menu[
'object']) ? $menu[
'titre'] : $menu[
'object']).
' */';
1170 $val_actuel = $menu;
1171 $next_val = empty($menus[$index + 1]) ? null : $menus[$index + 1];
1174 $str_menu .= $start.
"\n";
1175 $str_menu .=
"\t\t\$this->menu[\$r++] = array(\n";
1176 $str_menu .=
"\t\t\t'fk_menu' => '".dol_escape_php($menu[
'fk_menu'], 1).
"',\n";
1177 $str_menu .=
"\t\t\t'type' => '".dol_escape_php($menu[
'type'], 1).
"',\n";
1178 $str_menu .=
"\t\t\t'titre' => '".dol_escape_php($menu[
'titre'], 1).
"',\n";
1179 $str_menu .=
"\t\t\t'mainmenu' => '".dol_escape_php($menu[
'mainmenu'], 1).
"',\n";
1180 $str_menu .=
"\t\t\t'leftmenu' => '".dol_escape_php($menu[
'leftmenu'], 1).
"',\n";
1181 $str_menu .=
"\t\t\t'url' => '".dol_escape_php($menu[
'url'], 1).
"',\n";
1182 $str_menu .=
"\t\t\t'langs' => '".dol_escape_php($menu[
'langs'], 1).
"',\n";
1183 $str_menu .=
"\t\t\t'position' => ".((int) $menu[
'position']).
",\n";
1184 $str_menu .=
"\t\t\t'enabled' => '".dol_escape_php((
string) $menu[
'enabled'], 1).
"',\n";
1185 $str_menu .=
"\t\t\t'perms' => '".dol_escape_php($menu[
'perms'], 1).
"',\n";
1186 $str_menu .=
"\t\t\t'target' => '".dol_escape_php($menu[
'target'], 1).
"',\n";
1187 $str_menu .=
"\t\t\t'user' => ".((int) $menu[
'user']).
",\n";
1188 $str_menu .=
"\t\t\t'object' => '".dol_escape_php($menu[
'object'], 1).
"',\n";
1189 $str_menu .=
"\t\t);\n";
1191 if (is_null($next_val) || $val_actuel[
'leftmenu'] !== $next_val[
'leftmenu']) {
1192 $str_menu .= $end.
"\n";
1197 dolReplaceInFile($file, array(
'/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */' => $str_menu.
"\n\t\t/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */"));
1214 $dicData =
"\t\t\$this->dictionaries = array(\n";
1216 foreach ($dicts as $key => $value) {
1217 if (empty($value)) {
1219 $dicData =
"\t\t\$this->dictionaries = array();";
1223 $dicData .=
"\t\t\t'$key' => ";
1225 if ($key ===
'tabcond') {
1226 $conditions = array_map(
1231 static function ($val) use (
$module) {
1232 return is_bool($val) ?
"isModEnabled('$module')" : $val;
1236 $dicData .=
"array(" . implode(
", ", $conditions) .
")";
1237 } elseif ($key ===
'tabhelp') {
1238 $helpItems = array();
1239 foreach ($value as $helpValue) {
1240 $helpItems[] =
"array('code' => \$langs->trans('".$helpValue[
'code'].
"'), 'field2' => 'field2tooltip')";
1242 $dicData .=
"array(" . implode(
",", $helpItems) .
")";
1244 if (is_array($value)) {
1245 $dicData .=
"array(" . implode(
1252 static function ($val) {
1259 $dicData .=
"'$value'";
1264 $dicData .= (!$isEmpty ?
"\t\t);" :
'');
1266 $stringDic =
getFromFile($file,
'/* BEGIN MODULEBUILDER DICTIONARIES */',
'/* END MODULEBUILDER DICTIONARIES */');
1267 $writeInfile =
dolReplaceInFile($file, array($stringDic => $dicData.
"\n"));
1269 return $writeInfile;
1288 if (empty($namedic)) {
1289 setEventMessages($langs->trans(
"ErrorEmptyNameDic"),
null,
'errors');
1292 if (!file_exists($file)) {
1297 if (empty($dictionnaires)) {
1298 $dictionnaires = array(
'langs' =>
'',
'tabname' => array(),
'tablib' => array(),
'tabsql' => array(),
'tabsqlsort' => array(),
'tabfield' => array(),
'tabfieldvalue' => array(),
'tabfieldinsert' => array(),
'tabrowid' => array(),
'tabcond' => array(),
'tabhelp' => array());
1302 'rowid' => array(
'type' =>
'integer',
'value' => 11,
'extra' =>
'AUTO_INCREMENT'),
1303 'code' => array(
'type' =>
'varchar',
'value' => 255,
'null' =>
'NOT NULL'),
1304 'label' => array(
'type' =>
'varchar',
'value' => 255,
'null' =>
'NOT NULL'),
1305 'position' => array(
'type' =>
'integer',
'value' => 11,
'null' =>
'NULL'),
1306 'use_default' => array(
'type' =>
'varchar',
'value' => 11,
'default' =>
'1'),
1307 'active' => array(
'type' =>
'integer',
'value' => 3)
1310 $primaryKey =
'rowid';
1311 foreach ($columns as $key => $value) {
1312 if ($key ===
'rowid') {
1313 $primaryKey =
'rowid';
1316 if (!array_key_exists(
'rowid', $columns)) {
1317 $primaryKey = array_key_first($columns);
1323 $checkTable = $db->DDLDescTable(MAIN_DB_PREFIX.dol_strtolower($namedic));
1324 if ($checkTable && $db->num_rows($checkTable) > 0) {
1325 setEventMessages($langs->trans(
"ErrorTableExist", $namedic),
null,
'errors');
1328 $_results = $db->DDLCreateTable(MAIN_DB_PREFIX.dol_strtolower($namedic), $columns, $primaryKey,
"");
1329 if ($_results < 0) {
1330 dol_print_error($db);
1331 $langs->load(
"errors");
1332 setEventMessages($langs->trans(
"ErrorTableNotFound", $namedic),
null,
'errors');
1337 $dictionnaires[
'langs'] = $modulename.
'@'.$modulename;
1340 $dictionnaires[
'tabsql'][] =
'SELECT t.rowid as rowid, t.code, t.label, t.active FROM '.MAIN_DB_PREFIX.dol_strtolower($namedic).
' as t';
1341 $dictionnaires[
'tabsqlsort'][] = (array_key_exists(
'label', $columns) ?
'label ASC' :
'');
1342 $dictionnaires[
'tabfield'][] = (array_key_exists(
'code', $columns) && array_key_exists(
'label', $columns) ?
'code,label' :
'');
1343 $dictionnaires[
'tabfieldvalue'][] = (array_key_exists(
'code', $columns) && array_key_exists(
'label', $columns) ?
'code,label' :
'');
1344 $dictionnaires[
'tabfieldinsert'][] = (array_key_exists(
'code', $columns) && array_key_exists(
'label', $columns) ?
'code,label' :
'');
1345 $dictionnaires[
'tabrowid'][] = $primaryKey;
1346 $dictionnaires[
'tabcond'][] =
isModEnabled(
'$modulename');
1347 $dictionnaires[
'tabhelp'][] = (array_key_exists(
'code', $columns) ? array(
'code' => $langs->trans(
'CodeTooltipHelp'),
'field2' =>
'field2tooltip') :
'');
1351 if ($writeInfile > 0) {
1371 $string =
getFromFile($file_api,
'/*begin methods CRUD*/',
'/*end methods CRUD*/');
1372 $extractUrls = explode(
"\n", $string);
1375 $urlValues = array();
1376 foreach ($extractUrls as $key => $line) {
1377 $lineWithoutTabsSpaces = preg_replace(
'/^[\t\s]+/',
'', $line);
1378 if (strpos($lineWithoutTabsSpaces,
'* @url') === 0) {
1380 $urlValues[] = $urlValue;
1385 $str = $_SERVER[
'HTTP_HOST'].
'/api/index.php/';
1386 $groupedUrls = array();
1387 foreach ($urlValues as $url) {
1388 if (preg_match(
'/(?:GET|POST|PUT|DELETE) (\w+)s/', $url, $matches)) {
1389 $objectName = $matches[1];
1390 $url = $str.trim(strstr($url,
' '));
1391 $groupedUrls[$objectName][] = $url;
1394 if (empty($groupedUrls)) {
1400 $asciiDocTable =
"[options=\"header\"]\n|===\n|Object | URLs\n";
1401 foreach ($groupedUrls as $objectName => $urls) {
1402 $urlsList = implode(
" +\n*", $urls);
1403 $asciiDocTable .=
"|$objectName | \n*$urlsList +\n";
1405 $asciiDocTable .=
"|===\n";
1406 $file_write =
dolReplaceInFile($file_doc, array(
'__API_DOC__' =>
'__API_DOC__'.
"\n".$asciiDocTable));
1407 if ($file_write < 0) {
1428 $allFilesAndDirs = scandir($path);
1431 foreach ($allFilesAndDirs as $item) {
1432 if ($item !=
'.' && $item !=
'..') {
1433 if ($type == 1 &&
dol_is_file($path . DIRECTORY_SEPARATOR . $item) && strpos($item,
'.back') ===
false) {
1435 } elseif ($type == 2 &&
dol_is_dir($path . DIRECTORY_SEPARATOR . $item)) {
1453 'contact' => array(
'file' =>
'myobject_contact.php',
'var' =>
'showtabofpagecontact',
'marker' =>
'CONTACT',
'label' =>
'Contacts'),
1454 'note' => array(
'file' =>
'myobject_note.php',
'var' =>
'showtabofpagenote',
'marker' =>
'NOTE',
'label' =>
'Notes'),
1455 'document' => array(
'file' =>
'myobject_document.php',
'var' =>
'showtabofpagedocument',
'marker' =>
'DOCUMENT',
'label' =>
'Documents'),
1456 'agenda' => array(
'file' =>
'myobject_agenda.php',
'var' =>
'showtabofpageagenda',
'marker' =>
'AGENDA',
'label' =>
'Events'),
1474 'sendmail' => array(
'marker' =>
'SENDMAIL',
'label' =>
'SendMail',
'default' => 1,
'mode' =>
'remove'),
1475 'clone' => array(
'marker' =>
'CLONE',
'label' =>
'ToClone',
'default' => 1,
'mode' =>
'remove'),
1476 'validate' => array(
'marker' =>
'VALIDATE',
'label' =>
'Validate',
'default' => 1,
'mode' =>
'remove'),
1477 'setdraft' => array(
'marker' =>
'SETDRAFT',
'label' =>
'SetToDraft',
'default' => 1,
'mode' =>
'remove'),
1478 'statuschange' => array(
'marker' =>
'STATUSCHANGE',
'label' =>
'CancelAndReopen',
'default' => 0,
'mode' =>
'activate'),
1479 'delete' => array(
'marker' =>
'DELETE',
'label' =>
'Delete',
'default' => 1,
'mode' =>
'remove'),
1492 $defaults = array();
1493 foreach ($map as $key => $meta) {
1494 if (!isset($meta[
'default']) || !empty($meta[
'default'])) {
1511 $quotedmarker = preg_quote($marker,
'/');
1513 return '/\h*\/\/ BEGIN MODULEBUILDER ACTION '.$quotedmarker.
'.*?\/\/ END MODULEBUILDER ACTION '.$quotedmarker.
'\h*\R(?:\h*\R)?/s';
1525 $quotedmarker = preg_quote($marker,
'/');
1528 '/\h*\/\* BEGIN COMMENTED '.$quotedmarker.
'\h*\R/',
1529 '/\h*END COMMENTED '.$quotedmarker.
'\h*\*\/\h*\R/',
1543 return '/\/\/BEGIN MODULEBUILDER LINES.*?\/\/END MODULEBUILDER LINES\s*/s';
1557 if (!is_array($requested) || empty($requested)) {
1560 foreach (array_keys($map) as $key) {
1561 if (in_array($key, $requested,
true)) {
1593 if (!file_exists($file)) {
1596 $content = file_get_contents($file);
1597 if ($content ===
false) {
1602 $foundmarkers = array();
1603 preg_match_all(
'/\/\*\s*(?:BEGIN|END) MODULEBUILDER [^*]*\*\//', $content, $foundmarkers);
1604 $sentinels = array();
1605 foreach (array_values(array_unique($foundmarkers[0])) as $index => $marker) {
1606 $key =
"\0MODULEBUILDERMARKER".$index.
"\0";
1607 $sentinels[$key] = $marker;
1608 $content = str_replace($marker, $key, $content);
1611 $content = str_replace(array_keys($arrayreplacement), array_values($arrayreplacement), $content);
1614 if (!empty($sentinels)) {
1615 $content = strtr($content, $sentinels);
1618 if (file_put_contents($file, $content) ===
false) {
if(! $sortfield) if(! $sortorder) $object
Syncs rights straight into the mod<Module>.class.php descriptor file.
Immutable value object holding all case variants of a module/object pair.
static fromFile(string $file)
Read a descriptor and locate its permissions block.
static forObjectDeletion(string $module, string $descriptorFile, array $permissions, string $objectName)
Drop every right attached to an object being deleted.
static forRightDeletion(string $module, string $descriptorFile, array $permissions, int $rightKey)
Remove one right, addressed by its index in the rights array.
static forRightUpdate(string $module, string $descriptorFile, array $permissions, int $rightKey, string $objectName, string $label, string $crud)
Replace one right, addressed by its index in the rights array.
static forRightAddition(string $module, string $descriptorFile, array $permissions, string $objectName, string $label, string $crud)
Append one right to the descriptor.
static forObjectCreation(string $module, string $descriptorFile, array $permissions, string $objectName)
Declare the three CRUD rights of a newly generated object.
if(! $sortfield) if(! $sortorder) $module
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.
dol_is_dir($folder)
Test if filename is a directory.
dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask='0', $indexdatabase=0, $arrayreplacementisregex=0)
Make replacement of strings into a file.
dol_now($mode='gmt')
Return date for now.
dol_ucfirst($string, $encoding="UTF-8")
Convert first character of the first word of a string to upper.
dol_strtolower($string, $encoding="UTF-8")
Convert a string to lower.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_escape_php($stringtoescape, $stringforquotes=2)
Returns text escaped for inclusion into a php string, build with double quotes " or '.
dol_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...
dol_strtoupper($string, $encoding="UTF-8")
Convert a string to upper.
dol_substr($string, $start, $length=null, $stringencoding='', $trunconbytes=0)
Make a substring.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
getModuleBuilderDefaultEnabledKeys($map)
Return the keys enabled by default in a ModuleBuilder generation map.
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.
filterEnabledTabs($requested, $map)
Filter a list of requested tab keys against the known optional tabs map.
getModuleBuilderCardActionUncommentPatterns($marker)
Build the regular expressions removing the comment fence of a card action generated in 'activate' mod...
createNewDictionnary($modulename, $file, $namedic, $dictionnaires=null)
Create a new dictionary table.
filterEnabledKeys($requested, $map)
Filter a list of requested keys against a known map of generable elements.
countItemsInDirectory($path, $type=1)
count directories or files in modulebuilder folder
getModuleBuilderCardActionBlockPattern($marker)
Build the regular expression matching every block of a card action in the object card template.
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 declared in the permissions section of a module descriptor.
getModuleBuilderLinesBlockPattern()
Return the regular expression matching a block of object lines code in the templates,...
writePropsInAsciiDoc($file, $objectname, $destfile)
Write all properties of the object in AsciiDoc format.
dolModuleBuilderSqlIdentifier(string $prefix, string $module, string $table, string $key)
Build the name of an index or of a foreign key constraint for a table generated by the module builder...
removeObjectFromApiFile($file, $objects, $objectname)
Remove Object variables and methods from API_Module File.
getModuleBuilderObjectCardActions()
Return the map of optional action buttons that can be generated on the card page of a ModuleBuilder o...
dolReplaceInFilePreservingModuleBuilderMarkers($file, $arrayreplacement)
Apply substitutions to a module descriptor file while preserving the MODULEBUILDER comment markers.
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.
getModuleBuilderObjectTabs()
Return the map of optional tabs that can be generated for a ModuleBuilder object.
addObjectsToApiFile($srcfile, $file, $objects, $modulename)
Add Object in ModuleApi File.