dolibarr 21.0.3
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2023 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2018-2019 Nicolas ZABOURI <info@inovea-conseil.com>
4 * Copyright (C) 2023 Alexandre Janniaux <alexandre.janniaux@gmail.com>
5 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 *
21 * You can also make a direct call the page with parameter like this:
22 * htdocs/modulebuilder/index.php?module=Inventory@/pathtodolibarr/htdocs/product
23 */
24
33if (!defined('NOSCANPOSTFORINJECTION')) {
34 define('NOSCANPOSTFORINJECTION', '1'); // Do not check anti SQL+XSS injection attack test
35}
36
37// Load Dolibarr environment
38require '../main.inc.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
42require_once DOL_DOCUMENT_ROOT.'/core/lib/modulebuilder.lib.php';
43require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
44require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php';
45
58// Load translation files required by the page
59$langs->loadLangs(array("admin", "modulebuilder", "exports", "other", "cron", "errors"));
60
61// GET Parameters
62$action = GETPOST('action', 'aZ09');
63$confirm = GETPOST('confirm', 'alpha');
64$cancel = GETPOST('cancel', 'alpha');
65
66$sortfield = GETPOST('sortfield', 'alpha');
67$sortorder = GETPOST('sortorder', 'aZ09');
68
69$module = GETPOST('module', 'alpha');
70$tab = GETPOST('tab', 'aZ09');
71$tabobj = GETPOST('tabobj', 'alpha');
72$tabdic = GETPOST('tabdic', 'alpha');
73$propertykey = GETPOST('propertykey', 'alpha');
74if (empty($module)) {
75 $module = 'initmodule';
76}
77if (empty($tab)) {
78 $tab = 'description';
79}
80if (empty($tabobj)) {
81 $tabobj = 'newobjectifnoobj';
82}
83if (empty($tabdic)) {
84 $tabdic = 'newdicifnodic';
85}
86$file = GETPOST('file', 'alpha');
87$find = GETPOST('find', 'alpha');
88
89$modulename = dol_sanitizeFileName(GETPOST('modulename', 'alpha'));
90$objectname = dol_sanitizeFileName(GETPOST('objectname', 'alpha'));
91$dicname = dol_sanitizeFileName(GETPOST('dicname', 'alpha'));
92$editorname = GETPOST('editorname', 'alpha');
93$editorurl = GETPOST('editorurl', 'alpha');
94$version = GETPOST('version', 'alpha');
95$family = GETPOST('family', 'alpha');
96$picto = GETPOST('idpicto', 'alpha');
97$idmodule = GETPOST('idmodule', 'alpha');
98$format = ''; // Prevent undefined in css tab
99
100// Security check
101if (!isModEnabled('modulebuilder')) {
102 accessforbidden('Module ModuleBuilder not enabled');
103}
104if (!$user->hasRight("modulebuilder", "run")) {
105 accessforbidden('ModuleBuilderNotAllowed');
106}
107
108// Dir for custom dirs
109$tmp = explode(',', $dolibarr_main_document_root_alt);
110$dirins = $tmp[0];
111$dirread = $dirins;
112$forceddirread = 0;
113
114$tmpdir = explode('@', $module);
115if (!empty($tmpdir[1])) {
116 $module = $tmpdir[0];
117 $dirread = $tmpdir[1];
118 $forceddirread = 1;
119}
120if (GETPOST('dirins', 'alpha')) {
121 $dirread = $dirins = GETPOST('dirins', 'alpha');
122 $forceddirread = 1;
123}
124
125$FILEFLAG = 'modulebuilder.txt';
126
127$now = dol_now();
128$newmask = 0;
129if (empty($newmask) && getDolGlobalString('MAIN_UMASK')) {
130 $newmask = getDolGlobalString('MAIN_UMASK');
131}
132if (empty($newmask)) { // This should no happen
133 $newmask = '0664';
134}
135
136$result = restrictedArea($user, 'modulebuilder', 0);
137
138$error = 0;
139$param = '';
140
141$form = new Form($db);
142
143// Define $listofmodules
144$dirsrootforscan = array($dirread);
145
146// Add also the core modules into the list of modules to show/edit
147if ($dirread != DOL_DOCUMENT_ROOT && (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2 || getDolGlobalString('MODULEBUILDER_ADD_DOCUMENT_ROOT'))) {
148 $dirsrootforscan[] = DOL_DOCUMENT_ROOT;
149}
150
151// Search modules to edit
152$textforlistofdirs = '<!-- Directory scanned -->'."\n";
153$listofmodules = array();
154'@phan-var-force array<string,array{modulenamewithcase:string,moduledescriptorrelpath:string,moduledescriptorfullpath:string,moduledescriptorrootpath,moduletype?:string}> $listofmodules';
155$i = 0;
156foreach ($dirsrootforscan as $tmpdirread) {
157 $moduletype = 'external';
158 if ($tmpdirread == DOL_DOCUMENT_ROOT) {
159 $moduletype = 'internal';
160 }
161
162 $dirsincustom = dol_dir_list($tmpdirread, 'directories');
163 if (is_array($dirsincustom) && count($dirsincustom) > 0) {
164 foreach ($dirsincustom as $dircustomcursor) {
165 $fullname = $dircustomcursor['fullname'];
166 if (dol_is_file($fullname.'/'.$FILEFLAG)) {
167 // Get real name of module (MyModule instead of mymodule)
168 $dirtoscanrel = basename($fullname).'/core/modules/';
169
170 $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$');
171 if (empty($descriptorfiles)) { // If descriptor not found into module dir, we look into main module dir.
172 $dirtoscanrel = 'core/modules/';
173 $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$');
174 }
175 $modulenamewithcase = '';
176 $moduledescriptorrelpath = '';
177 $moduledescriptorfullpath = '';
178
179 foreach ($descriptorfiles as $descriptorcursor) {
180 $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']);
181 $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase);
182 $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name'];
183 $moduledescriptorfullpath = $descriptorcursor['fullname'];
184 //var_dump($descriptorcursor);
185 }
186 if ($modulenamewithcase) {
187 $listofmodules[$dircustomcursor['name']] = array(
188 'modulenamewithcase' => $modulenamewithcase,
189 'moduledescriptorrelpath' => $moduledescriptorrelpath,
190 'moduledescriptorfullpath' => $moduledescriptorfullpath,
191 'moduledescriptorrootpath' => $tmpdirread,
192 'moduletype' => $moduletype
193 );
194 }
195 //var_dump($listofmodules);
196 }
197 }
198 }
199
200 if ($forceddirread && empty($listofmodules)) { // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir
201 $listofmodules[strtolower($module)] = array(
202 'modulenamewithcase' => $module,
203 'moduledescriptorrelpath' => 'notyetimplemented',
204 'moduledescriptorfullpath' => 'notyetimplemented',
205 'moduledescriptorrootpath' => 'notyetimplemented',
206 );
207 }
208
209 // Show description of content
210 $newdircustom = $dirins;
211 if (empty($newdircustom)) {
212 $newdircustom = img_warning();
213 }
214 // If dirread was forced to somewhere else, by using URL
215 // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product
216 if (empty($i)) {
217 $textforlistofdirs .= $langs->trans("DirScanned").' : ';
218 } else {
219 $textforlistofdirs .= ', ';
220 }
221 $textforlistofdirs .= '<strong class="wordbreakimp">'.$tmpdirread.'</strong>';
222 if ($tmpdirread == DOL_DOCUMENT_ROOT) {
223 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
224 $textforlistofdirs .= $form->textwithpicto('', $langs->trans("ConstantIsOn", "MAIN_FEATURES_LEVEL"));
225 }
226 if (getDolGlobalString('MODULEBUILDER_ADD_DOCUMENT_ROOT')) {
227 $textforlistofdirs .= $form->textwithpicto('', $langs->trans("ConstantIsOn", "MODULEBUILDER_ADD_DOCUMENT_ROOT"));
228 }
229 }
230 $i++;
231}
232
239{
240 $error = error_get_last();
241 if ($error && ($error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR))) {
242 // Handle the fatal error
243 echo "Fatal error occurred: {$error['message']} in {$error['file']} on line {$error['line']}";
244 // If a header was already send, we suppose it is the llx_Header() so we call the llxFooter()
245 if (headers_sent()) {
246 llxFooter();
247 }
248 }
249}
250register_shutdown_function("moduleBuilderShutdownFunction");
251
252
262function getLicenceHeader($user, $langs, $now)
263{
264 $licInfo = $user->getFullName($langs);
265 $emailTabs = str_repeat("\t", (int) (max(0, (31 - mb_strlen($licInfo)) / 4)));
266 $licInfo .= ($user->email ? $emailTabs.'<'.$user->email.'>' : '');
267 $licInfo = dol_print_date($now, '%Y')."\t\t".$licInfo;
268 return $licInfo;
269}
270
271/*
272 * Actions
273 */
274
275if ($dirins && $action == 'initmodule' && $modulename && $user->hasRight("modulebuilder", "run")) {
276 $modulename = ucfirst($modulename); // Force first letter in uppercase
277 $destdir = '/not_set/';
278
279 if (preg_match('/[^a-z0-9_]/i', $modulename)) {
280 $error++;
281 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
282 }
283
284 if (!$error) {
285 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
286 $destdir = $dirins.'/'.strtolower($modulename);
287
288 $arrayreplacement = array(
289 'mymodule' => strtolower($modulename),
290 'MyModule' => $modulename
291 );
292 $result = dolCopyDir($srcdir, $destdir, '0', 0, $arrayreplacement);
293 //dol_mkdir($destfile);
294 if ($result <= 0) {
295 if ($result < 0) {
296 $error++;
297 $langs->load("errors");
298 setEventMessages($langs->trans("ErrorFailToCopyDir", $srcdir, $destdir), null, 'errors');
299 } else {
300 // $result == 0
301 setEventMessages($langs->trans("AllFilesDidAlreadyExist", $srcdir, $destdir), null, 'warnings');
302 }
303 }
304
305 // Copy last 'html.formsetup.class.php' to backport folder
306 if (getDolGlobalInt('MODULEBUILDER_SUPPORT_COMPATIBILITY_V16')) {
307 $tryToCopyFromSetupClass = true;
308 $backportDest = $destdir .'/backport/v16/core/class';
309 $backportFileSrc = DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php';
310 $backportFileDest = $backportDest.'/html.formsetup.class.php';
311 $result = dol_mkdir($backportDest);
312
313 if ($result < 0) {
314 $error++;
315 $langs->load("errors");
316 setEventMessages($langs->trans("ErrorFailToCreateDir", $backportDest), null, 'errors');
317 $tryToCopyFromSetupClass = false;
318 }
319
320 if ($tryToCopyFromSetupClass) {
321 $result = dol_copy($backportFileSrc, $backportFileDest);
322 if ($result <= 0) {
323 if ($result < 0) {
324 $error++;
325 $langs->load("errors");
326 setEventMessages($langs->trans("ErrorFailToCopyFile", $backportFileSrc, $backportFileDest), null, 'errors');
327 } else {
328 setEventMessages($langs->trans("FileDidAlreadyExist", $backportFileDest), null, 'warnings');
329 }
330 }
331 }
332 }
333
334 if (getDolGlobalString('MODULEBUILDER_USE_ABOUT')) {
335 dol_delete_file($destdir.'/admin/about.php');
336 }
337
338 // Delete dir and files that can be generated in sub tabs later if we need them (we want a minimal module first)
339 dol_delete_dir_recursive($destdir.'/ajax');
340 dol_delete_dir_recursive($destdir.'/build/doxygen');
341 dol_delete_dir_recursive($destdir.'/core/modules/mailings');
342 dol_delete_dir_recursive($destdir.'/core/modules/'.strtolower($modulename));
343 dol_delete_dir_recursive($destdir.'/core/tpl');
344 dol_delete_dir_recursive($destdir.'/core/triggers');
345 dol_delete_dir_recursive($destdir.'/doc');
346 //dol_delete_dir_recursive($destdir.'/.tx');
347 dol_delete_dir_recursive($destdir.'/core/boxes');
348
349 dol_delete_file($destdir.'/admin/myobject_extrafields.php');
350
351 dol_delete_file($destdir.'/class/actions_'.strtolower($modulename).'.class.php');
352 dol_delete_file($destdir.'/class/api_'.strtolower($modulename).'.class.php');
353
354 dol_delete_file($destdir.'/css/'.strtolower($modulename).'.css.php');
355
356 dol_delete_file($destdir.'/js/'.strtolower($modulename).'.js.php');
357
358 dol_delete_file($destdir.'/scripts/'.strtolower($modulename).'.php');
359
360 dol_delete_file($destdir.'/sql/data.sql');
361 dol_delete_file($destdir.'/sql/update_x.x.x-y.y.y.sql');
362
363 // Delete some files related to Object (because the previous dolCopyDir has copied everything)
364 dol_delete_file($destdir.'/myobject_card.php');
365 dol_delete_file($destdir.'/myobject_contact.php');
366 dol_delete_file($destdir.'/myobject_note.php');
367 dol_delete_file($destdir.'/myobject_document.php');
368 dol_delete_file($destdir.'/myobject_agenda.php');
369 dol_delete_file($destdir.'/myobject_list.php');
370 dol_delete_file($destdir.'/lib/'.strtolower($modulename).'_myobject.lib.php');
371 dol_delete_file($destdir.'/test/phpunit/functional/'.$modulename.'FunctionalTest.php');
372 dol_delete_file($destdir.'/test/phpunit/MyObjectTest.php');
373 dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject.sql');
374 dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject_extrafields.sql');
375 dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject.key.sql');
376 dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject_extrafields.key.sql');
377 dol_delete_file($destdir.'/class/myobject.class.php');
378
379 dol_delete_dir($destdir.'/class', 1);
380 dol_delete_dir($destdir.'/css', 1);
381 dol_delete_dir($destdir.'/js', 1);
382 dol_delete_dir($destdir.'/scripts', 1);
383 dol_delete_dir($destdir.'/sql', 1);
384 dol_delete_dir($destdir.'/test/phpunit/functionnal', 1);
385 dol_delete_dir($destdir.'/test/phpunit', 1);
386 dol_delete_dir($destdir.'/test', 1);
387 }
388
389 // Edit PHP files
390 if (!$error) {
391 $listofphpfilestoedit = dol_dir_list($destdir, 'files', 1, '\.(php|MD|js|sql|txt|xml|lang)$', '', 'fullname', SORT_ASC, 0, 1);
392
393 $licInfo = getLicenceHeader($user, $langs, $now);
394 foreach ($listofphpfilestoedit as $phpfileval) {
395 //var_dump($phpfileval['fullname']);
396 $arrayreplacement = array(
397 'mymodule' => strtolower($modulename),
398 'MyModule' => $modulename,
399 'MYMODULE' => strtoupper($modulename),
400 'My module' => $modulename,
401 'my module' => $modulename,
402 'Mon module' => $modulename,
403 'mon module' => $modulename,
404 'htdocs/modulebuilder/template' => strtolower($modulename),
405 '---Put here your own copyright and developer email---' => $licInfo,
406 '---Replace with your own copyright and developer email---' => $licInfo,
407 'Editor name' => $editorname,
408 'https://www.example.com' => $editorurl,
409 '$this->version = \'1.0\'' => '$this->version = \''.$version.'\'',
410 '$this->picto = \'generic\';' => (empty($picto)) ? '$this->picto = \'generic\'' : '$this->picto = \''.$picto.'\';',
411 "modulefamily" => $family,
412 '500000' => $idmodule
413 );
414
415 if (getDolGlobalString('MODULEBUILDER_SPECIFIC_AUTHOR')) {
416 $arrayreplacement['---Replace with your own copyright and developer email---'] = dol_print_date($now, '%Y')."\t\t" . getDolGlobalString('MODULEBUILDER_SPECIFIC_AUTHOR');
417 }
418
419 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
420 $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement);
421 //var_dump($result);
422 if ($result < 0) {
423 setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
424 }
425 }
426
427 if (getDolGlobalString('MODULEBUILDER_SPECIFIC_README')) {
428 setEventMessages($langs->trans("ContentOfREADMECustomized"), null, 'warnings');
429 dol_delete_file($destdir.'/README.md');
430 file_put_contents($destdir.'/README.md', $conf->global->MODULEBUILDER_SPECIFIC_README);
431 }
432 // for create file to add properties
433 // file_put_contents($destdir.'/'.strtolower($modulename).'propertycard.php','');
434 // $srcFileCard = DOL_DOCUMENT_ROOT.'/modulebuilder/card.php';
435 // $destFileCard = $dirins.'/'.strtolower($modulename).'/template/card.php';
436 // dol_copy($srcFileCard, $destdir.'/'.strtolower($modulename).'propertycard.php', '0',1, $arrayreplacement);
437 }
438
439 if (!$error) {
440 setEventMessages($langs->trans('ModuleInitialized', $destdir), null);
441 $module = $modulename;
442
443 clearstatcache(true);
444 if (function_exists('opcache_invalidate')) {
445 opcache_reset(); // remove the include cache hell !
446 }
447
448 header("Location: ".$_SERVER["PHP_SELF"].'?module='.$modulename);
449 exit;
450 }
451}
452
453$destdir = '/not_set/'; // Initialize (for static analysis)
454$destfile = '/not_set/'; // Initialize (for static analysis)
455$srcfile = '/not_set/'; // Initialize (for static analysis)
456
457// init API, PHPUnit
458if ($dirins && in_array($action, array('initapi', 'initphpunit', 'initpagecontact', 'initpagedocument', 'initpagenote', 'initpageagenda')) && !empty($module) && $user->hasRight("modulebuilder", "run")) {
459 $modulename = ucfirst($module); // Force first letter in uppercase
460 $objectname = $tabobj;
461 $varnametoupdate = '';
462 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
463 $destdir = $dirins.'/'.strtolower($module);
464
465 // Get list of existing objects
466 $objects = dolGetListOfObjectClasses($destdir);
467
468
469 if ($action == 'initapi') { // Test on permission already done
470 if (file_exists($dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php')) {
471 $result = dol_copy(DOL_DOCUMENT_ROOT.'/modulebuilder/template/class/api_mymodule.class.php', $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php', '0', 1);
472 }
473 dol_mkdir($dirins.'/'.strtolower($module).'/class');
474 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
475 $srcfile = $srcdir.'/class/api_mymodule.class.php';
476 $destfile = $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php';
477 } elseif ($action == 'initphpunit') { // Test on permission already done
478 dol_mkdir($dirins.'/'.strtolower($module).'/test/phpunit');
479 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
480 $srcfile = $srcdir.'/test/phpunit/MyObjectTest.php';
481 $destfile = $dirins.'/'.strtolower($module).'/test/phpunit/'.strtolower($objectname).'Test.php';
482 } elseif ($action == 'initpagecontact') { // Test on permission already done
483 dol_mkdir($dirins.'/'.strtolower($module));
484 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
485 $srcfile = $srcdir.'/myobject_contact.php';
486 $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_contact.php';
487 $varnametoupdate = 'showtabofpagecontact';
488 } elseif ($action == 'initpagedocument') { // Test on permission already done
489 dol_mkdir($dirins.'/'.strtolower($module));
490 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
491 $srcfile = $srcdir.'/myobject_document.php';
492 $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_document.php';
493 $varnametoupdate = 'showtabofpagedocument';
494 } elseif ($action == 'initpagenote') { // Test on permission already done
495 dol_mkdir($dirins.'/'.strtolower($module));
496 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
497 $srcfile = $srcdir.'/myobject_note.php';
498 $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_note.php';
499 $varnametoupdate = 'showtabofpagenote';
500 } elseif ($action == 'initpageagenda') { // Test on permission already done
501 dol_mkdir($dirins.'/'.strtolower($module));
502 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
503 $srcfile = $srcdir.'/myobject_agenda.php';
504 $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_agenda.php';
505 $varnametoupdate = 'showtabofpageagenda';
506 }
507
508 if (!file_exists($destfile)) {
509 $result = dol_copy($srcfile, $destfile, '0', 0);
510 }
511
512 if ($result > 0) {
513 //var_dump($phpfileval['fullname']);
514 $arrayreplacement = array(
515 'mymodule' => strtolower($modulename),
516 'MyModule' => $modulename,
517 'MYMODULE' => strtoupper($modulename),
518 'My module' => $modulename,
519 'my module' => $modulename,
520 'Mon module' => $modulename,
521 'mon module' => $modulename,
522 'htdocs/modulebuilder/template' => strtolower($modulename),
523 'myobject' => strtolower($objectname),
524 'MyObject' => $objectname,
525 'MYOBJECT' => strtoupper($objectname),
526
527 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
528 );
529
530 if ($action == 'initapi') { // Test on permission already done
531 if (count($objects) >= 1) {
532 addObjectsToApiFile($srcfile, $destfile, $objects, $modulename);
533 }
534 } else {
535 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
536 dolReplaceInFile($destfile, $arrayreplacement);
537 }
538
539 if ($varnametoupdate) {
540 // Now we update the object file to set $$varnametoupdate to 1
541 $srcfile = $dirins.'/'.strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php';
542 $arrayreplacement = array('/\$'.preg_quote($varnametoupdate, '/').' = 0;/' => '$'.$varnametoupdate.' = 1;');
543 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
544 dolReplaceInFile($srcfile, $arrayreplacement, '', '0', 0, 1);
545 }
546 } else {
547 $langs->load("errors");
548 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
549 }
550}
551
552
553// init ExtraFields
554if ($dirins && $action == 'initsqlextrafields' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
555 $modulename = ucfirst($module); // Force first letter in uppercase
556 $objectname = $tabobj;
557
558 dol_mkdir($dirins.'/'.strtolower($module).'/sql');
559 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
560 $srcfile1 = $srcdir.'/sql/llx_mymodule_myobject_extrafields.sql';
561 $destfile1 = $dirins.'/'.strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql';
562 $result1 = dol_copy($srcfile1, $destfile1, '0', 0);
563 $srcfile2 = $srcdir.'/sql/llx_mymodule_myobject_extrafields.key.sql';
564 $destfile2 = $dirins.'/'.strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql';
565 $result2 = dol_copy($srcfile2, $destfile2, '0', 0);
566
567 if ($result1 > 0 && $result2 > 0) {
568 $modulename = ucfirst($module); // Force first letter in uppercase
569
570 //var_dump($phpfileval['fullname']);
571 $arrayreplacement = array(
572 'mymodule' => strtolower($modulename),
573 'MyModule' => $modulename,
574 'MYMODULE' => strtoupper($modulename),
575 'My module' => $modulename,
576 'my module' => $modulename,
577 'Mon module' => $modulename,
578 'mon module' => $modulename,
579 'htdocs/modulebuilder/template' => strtolower($modulename),
580 'My Object' => $objectname,
581 'MyObject' => $objectname,
582 'my object' => strtolower($objectname),
583 'myobject' => strtolower($objectname),
584 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
585 );
586
587 dolReplaceInFile($destfile1, $arrayreplacement);
588 dolReplaceInFile($destfile2, $arrayreplacement);
589 } else {
590 $langs->load("errors");
591 if ($result1 <= 0) {
592 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile1), null, 'errors');
593 }
594 if ($result2 <= 0) {
595 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile2), null, 'errors');
596 }
597 }
598
599 // Now we update the object file to set $this->isextrafieldmanaged to 1
600 $srcfile = $dirins.'/'.strtolower($module).'/class/'.strtolower($objectname).'.class.php';
601 $arrayreplacement = array('/\$this->isextrafieldmanaged = 0;/' => '$this->isextrafieldmanaged = 1;');
602 dolReplaceInFile($srcfile, $arrayreplacement, '', '0', 0, 1);
603}
604
605
606// init Hook
607if ($dirins && $action == 'inithook' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
608 dol_mkdir($dirins.'/'.strtolower($module).'/class');
609 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
610 $srcfile = $srcdir.'/class/actions_mymodule.class.php';
611 $destfile = $dirins.'/'.strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
612 $result = dol_copy($srcfile, $destfile, '0', 0);
613
614 if ($result > 0) {
615 $modulename = ucfirst($module); // Force first letter in uppercase
616
617 //var_dump($phpfileval['fullname']);
618 $arrayreplacement = array(
619 'mymodule' => strtolower($modulename),
620 'MyModule' => $modulename,
621 'MYMODULE' => strtoupper($modulename),
622 'My module' => $modulename,
623 'my module' => $modulename,
624 'Mon module' => $modulename,
625 'mon module' => $modulename,
626 'htdocs/modulebuilder/template' => strtolower($modulename),
627 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
628 );
629
630 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
631 dolReplaceInFile($destfile, $arrayreplacement);
632 } else {
633 $langs->load("errors");
634 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
635 }
636}
637
638
639// init Trigger
640if ($dirins && $action == 'inittrigger' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
641 dol_mkdir($dirins.'/'.strtolower($module).'/core/triggers');
642 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
643 $srcfile = $srcdir.'/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php';
644 $destfile = $dirins.'/'.strtolower($module).'/core/triggers/interface_99_mod'.$module.'_'.$module.'Triggers.class.php';
645 $result = dol_copy($srcfile, $destfile, '0', 0);
646
647 if ($result > 0) {
648 $modulename = ucfirst($module); // Force first letter in uppercase
649
650 //var_dump($phpfileval['fullname']);
651 $arrayreplacement = array(
652 'mymodule' => strtolower($modulename),
653 'MyModule' => $modulename,
654 'MYMODULE' => strtoupper($modulename),
655 'My module' => $modulename,
656 'my module' => $modulename,
657 'Mon module' => $modulename,
658 'mon module' => $modulename,
659 'htdocs/modulebuilder/template' => strtolower($modulename),
660 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
661 );
662
663 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
664 dolReplaceInFile($destfile, $arrayreplacement);
665 } else {
666 $langs->load("errors");
667 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
668 }
669}
670
671
672// init Widget
673if ($dirins && $action == 'initwidget' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
674 dol_mkdir($dirins.'/'.strtolower($module).'/core/boxes');
675 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
676 $srcfile = $srcdir.'/core/boxes/mymodulewidget1.php';
677 $destfile = $dirins.'/'.strtolower($module).'/core/boxes/'.strtolower($module).'widget1.php';
678 $result = dol_copy($srcfile, $destfile, '0', 0);
679
680 if ($result > 0) {
681 $modulename = ucfirst($module); // Force first letter in uppercase
682
683 //var_dump($phpfileval['fullname']);
684 $arrayreplacement = array(
685 'mymodule' => strtolower($modulename),
686 'MyModule' => $modulename,
687 'MYMODULE' => strtoupper($modulename),
688 'My module' => $modulename,
689 'my module' => $modulename,
690 'Mon module' => $modulename,
691 'mon module' => $modulename,
692 'htdocs/modulebuilder/template' => strtolower($modulename),
693 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
694 );
695
696 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
697 dolReplaceInFile($destfile, $arrayreplacement);
698 } else {
699 $langs->load("errors");
700 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
701 }
702}
703
704
705// init EmailSelector
706if ($dirins && $action == 'initemailing' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
707 dol_mkdir($dirins.'/'.strtolower($module).'/core/modules/mailings');
708 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
709 $srcfile = $srcdir.'/core/modules/mailings/mailing_mymodule_selector1.modules.php';
710 $destfile = $dirins.'/'.strtolower($module).'/core/modules/mailings/mailing_'.strtolower($module).'_selector1.modules.php';
711 $result = dol_copy($srcfile, $destfile, '0', 0);
712
713 if ($result > 0) {
714 $modulename = ucfirst($module); // Force first letter in uppercase
715
716 //var_dump($phpfileval['fullname']);
717 $arrayreplacement = array(
718 'mymodule' => strtolower($modulename),
719 'MyModule' => $modulename,
720 'MYMODULE' => strtoupper($modulename),
721 'My module' => $modulename,
722 'my module' => $modulename,
723 'Mon module' => $modulename,
724 'mon module' => $modulename,
725 'htdocs/modulebuilder/template' => strtolower($modulename),
726 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
727 );
728
729 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
730 dolReplaceInFile($destfile, $arrayreplacement);
731 } else {
732 $langs->load("errors");
733 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
734 }
735}
736
737
738// init CSS
739if ($dirins && $action == 'initcss' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
740 dol_mkdir($dirins.'/'.strtolower($module).'/css');
741 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
742 $srcfile = $srcdir.'/css/mymodule.css.php';
743 $destfile = $dirins.'/'.strtolower($module).'/css/'.strtolower($module).'.css.php';
744 $result = dol_copy($srcfile, $destfile, '0', 0);
745
746 if ($result > 0) {
747 $modulename = ucfirst($module); // Force first letter in uppercase
748
749 //var_dump($phpfileval['fullname']);
750 $arrayreplacement = array(
751 'mymodule' => strtolower($modulename),
752 'MyModule' => $modulename,
753 'MYMODULE' => strtoupper($modulename),
754 'My module' => $modulename,
755 'my module' => $modulename,
756 'Mon module' => $modulename,
757 'mon module' => $modulename,
758 'htdocs/modulebuilder/template' => strtolower($modulename),
759 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
760 );
761
762 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
763 dolReplaceInFile($destfile, $arrayreplacement);
764
765 // Update descriptor file to uncomment file
766 $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
767 $arrayreplacement = array('/\/\/\s*\''.preg_quote('/'.strtolower($module).'/css/'.strtolower($module).'.css.php', '/').'\'/' => '\'/'.strtolower($module).'/css/'.strtolower($module).'.css.php\'');
768 dolReplaceInFile($srcfile, $arrayreplacement, '', '0', 0, 1);
769 } else {
770 $langs->load("errors");
771 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
772 }
773}
774
775
776// init JS
777if ($dirins && $action == 'initjs' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
778 dol_mkdir($dirins.'/'.strtolower($module).'/js');
779 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
780 $srcfile = $srcdir.'/js/mymodule.js.php';
781 $destfile = $dirins.'/'.strtolower($module).'/js/'.strtolower($module).'.js.php';
782 $result = dol_copy($srcfile, $destfile, '0', 0);
783
784 if ($result > 0) {
785 $modulename = ucfirst($module); // Force first letter in uppercase
786
787 //var_dump($phpfileval['fullname']);
788 $arrayreplacement = array(
789 'mymodule' => strtolower($modulename),
790 'MyModule' => $modulename,
791 'MYMODULE' => strtoupper($modulename),
792 'My module' => $modulename,
793 'my module' => $modulename,
794 'Mon module' => $modulename,
795 'mon module' => $modulename,
796 'htdocs/modulebuilder/template' => strtolower($modulename),
797 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
798 );
799
800 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
801 dolReplaceInFile($destfile, $arrayreplacement);
802
803 // Update descriptor file to uncomment file
804 $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
805 $arrayreplacement = array('/\/\/\s*\''.preg_quote('/'.strtolower($module).'/js/'.strtolower($module).'.js.php', '/').'\'/' => '\'/'.strtolower($module).'/js/'.strtolower($module).'.js.php\'');
806 dolReplaceInFile($srcfile, $arrayreplacement, '', '0', 0, 1);
807 } else {
808 $langs->load("errors");
809 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
810 }
811}
812
813
814// init CLI
815if ($dirins && $action == 'initcli' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
816 dol_mkdir($dirins.'/'.strtolower($module).'/scripts');
817 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
818 $srcfile = $srcdir.'/scripts/mymodule.php';
819 $destfile = $dirins.'/'.strtolower($module).'/scripts/'.strtolower($module).'.php';
820 $result = dol_copy($srcfile, $destfile, '0', 0);
821
822 if ($result > 0) {
823 $modulename = ucfirst($module); // Force first letter in uppercase
824
825 //var_dump($phpfileval['fullname']);
826 $arrayreplacement = array(
827 'mymodule' => strtolower($modulename),
828 'MyModule' => $modulename,
829 'MYMODULE' => strtoupper($modulename),
830 'My module' => $modulename,
831 'my module' => $modulename,
832 'Mon module' => $modulename,
833 'mon module' => $modulename,
834 'htdocs/modulebuilder/template' => strtolower($modulename),
835 '__MYCOMPANY_NAME__' => $mysoc->name,
836 '__KEYWORDS__' => $modulename,
837 '__USER_FULLNAME__' => $user->getFullName($langs),
838 '__USER_EMAIL__' => $user->email,
839 '__YYYY-MM-DD__' => dol_print_date($now, 'dayrfc'),
840 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
841 );
842
843 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
844 dolReplaceInFile($destfile, $arrayreplacement);
845 } else {
846 $langs->load("errors");
847 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
848 }
849}
850
851
852$moduledescriptorfile = '/not_set/';
853
854// init Doc
855if ($dirins && $action == 'initdoc' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
856 dol_mkdir($dirins.'/'.strtolower($module).'/doc');
857 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
858 $srcfile = $srcdir.'/doc/Documentation.asciidoc';
859 $destfile = $dirins.'/'.strtolower($module).'/doc/Documentation.asciidoc';
860 $result = dol_copy($srcfile, $destfile, '0', 0);
861
862 if ($result > 0) {
863 $modulename = ucfirst($module); // Force first letter in uppercase
864 $modulelowercase = strtolower($module);
865
866 //var_dump($phpfileval['fullname']);
867 $arrayreplacement = array(
868 'mymodule' => strtolower($modulename),
869 'MyModule' => $modulename,
870 'MYMODULE' => strtoupper($modulename),
871 'My module' => $modulename,
872 'my module' => $modulename,
873 'Mon module' => $modulename,
874 'mon module' => $modulename,
875 'htdocs/modulebuilder/template' => strtolower($modulename),
876 '__MYCOMPANY_NAME__' => $mysoc->name,
877 '__KEYWORDS__' => $modulename,
878 '__USER_FULLNAME__' => $user->getFullName($langs),
879 '__USER_EMAIL__' => $user->email,
880 '__YYYY-MM-DD__' => dol_print_date($now, 'dayrfc'),
881 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
882 );
883
884 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
885 dolReplaceInFile($destfile, $arrayreplacement);
886
887 // add table of properties
888 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
889 $destdir = $dirins.'/'.strtolower($module);
890 $objects = dolGetListOfObjectClasses($destdir);
891 foreach ($objects as $path => $obj) {
892 writePropsInAsciiDoc($path, $obj, $destfile);
893 }
894
895 // add table of permissions
896 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
897 writePermsInAsciiDoc($moduledescriptorfile, $destfile);
898
899 // add api urls if file exist
900 if (file_exists($dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php')) {
901 $apiFile = $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php';
902 writeApiUrlsInDoc($apiFile, $destfile);
903 }
904
905 // add ChangeLog in Doc
906 if (file_exists($dirins.'/'.strtolower($module).'/ChangeLog.md')) {
907 $changeLog = $dirins.'/'.strtolower($module).'/ChangeLog.md';
908 $string = file_get_contents($changeLog);
909
910 $replace = explode("\n", $string);
911 $strreplace = array();
912 foreach ($replace as $line) {
913 if ($line === '') {
914 continue;
915 }
916 if (strpos($line, '##') !== false) {
917 $strreplace[$line] = str_replace('##', '', $line);
918 } else {
919 $strreplace[$line] = $line;
920 }
921 }
922 $stringLog = implode("\n", $strreplace);
923 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
924 dolReplaceInFile($destfile, array('//include::ChangeLog.md[]' => '','__CHANGELOG__' => $stringLog));
925 }
926
927 // Delete old documentation files
928 $FILENAMEDOC = $modulelowercase.'.html';
929 $FILENAMEDOCPDF = $modulelowercase.'.pdf';
930 $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC;
931 $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC;
932 $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF;
933 $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF;
934
935 dol_delete_file($outputfiledoc, 0, 0, 0, null, false, 0);
936 dol_delete_file($outputfiledocpdf, 0, 0, 0, null, false, 0);
937 } else {
938 $langs->load("errors");
939 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
940 }
941}
942
943
944// add Language
945if ($dirins && $action == 'addlanguage' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
946 $newlangcode = GETPOST('newlangcode', 'aZ09');
947
948 if ($newlangcode) {
949 $modulelowercase = strtolower($module);
950
951 // Dir for module
952 $diroflang = dol_buildpath($modulelowercase, 0);
953
954 if ($diroflang == $dolibarr_main_document_root.'/'.$modulelowercase) {
955 // This is not a custom module, we force diroflang to htdocs root
956 $diroflang = $dolibarr_main_document_root;
957
958 $srcfile = $diroflang.'/langs/en_US/'.$modulelowercase.'.lang';
959 $destfile = $diroflang.'/langs/'.$newlangcode.'/'.$modulelowercase.'.lang';
960
961 $result = dol_copy($srcfile, $destfile, '0', 0);
962 if ($result < 0) {
963 setEventMessages($langs->trans("ErrorFailToCopyFile", $srcfile, $destfile), null, 'errors');
964 }
965 } else {
966 $srcdir = $diroflang.'/langs/en_US';
967 $srcfile = $diroflang.'/langs/en_US/'.$modulelowercase.'.lang';
968 $destdir = $diroflang.'/langs/'.$newlangcode;
969
970 $arrayofreplacement = array();
971 if (!dol_is_dir($srcfile) || !dol_is_file($srcfile)) {
972 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template/langs/en_US';
973 $arrayofreplacement = array('mymodule' => $modulelowercase);
974 }
975 $result = dolCopyDir($srcdir, $destdir, '0', 0, $arrayofreplacement);
976 }
977 } else {
978 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Language")), null, 'errors');
979 }
980}
981
982
983// Remove/delete File
984if ($dirins && $action == 'confirm_removefile' && !empty($module) && $user->hasRight("modulebuilder", "run")) {
985 $objectname = $tabobj;
986 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
987 $destdir = $dirins.'/'.strtolower($module);
988
989 $relativefilename = dol_sanitizePathName(GETPOST('file', 'restricthtml'));
990
991 // Now we delete the file
992 if ($relativefilename) {
993 $dirnametodelete = dirname($relativefilename);
994 $filetodelete = $dirins.'/'.$relativefilename;
995 $dirtodelete = $dirins.'/'.$dirnametodelete;
996
997 // Get list of existing objects
998 $objects = dolGetListOfObjectClasses($destdir);
999
1000 $keyofobjecttodelete = array_search($objectname, $objects);
1001 if ($keyofobjecttodelete !== false) {
1002 unset($objects[$keyofobjecttodelete]);
1003 }
1004
1005 // Delete or modify the file
1006 if (strpos($relativefilename, 'api') !== false) {
1007 $file_api = $destdir.'/class/api_'.strtolower($module).'.class.php';
1008
1009 $removeFile = removeObjectFromApiFile($file_api, $objects, $objectname);
1010
1011 if (count($objects) == 0) {
1012 $result = dol_delete_file($filetodelete);
1013 }
1014
1015 if ($removeFile) {
1016 setEventMessages($langs->trans("ApiObjectDeleted"), null);
1017 }
1018 } else {
1019 $result = dol_delete_file($filetodelete);
1020 }
1021
1022 if (!$result) {
1023 setEventMessages($langs->trans("ErrorFailToDeleteFile", basename($filetodelete)), null, 'errors');
1024 } else {
1025 // If we delete a .sql file, we delete also the other .sql file
1026 if (preg_match('/\.sql$/', $relativefilename)) {
1027 if (preg_match('/\.key\.sql$/', $relativefilename)) {
1028 $relativefilename = preg_replace('/\.key\.sql$/', '.sql', $relativefilename);
1029 $filetodelete = $dirins.'/'.$relativefilename;
1030 $result = dol_delete_file($filetodelete);
1031 } elseif (preg_match('/\.sql$/', $relativefilename)) {
1032 $relativefilename = preg_replace('/\.sql$/', '.key.sql', $relativefilename);
1033 $filetodelete = $dirins.'/'.$relativefilename;
1034 $result = dol_delete_file($filetodelete);
1035 }
1036 }
1037
1038 if (dol_is_dir_empty($dirtodelete)) {
1039 dol_delete_dir($dirtodelete);
1040 }
1041
1042 // Update descriptor file to comment file
1043 if (in_array($tab, array('css', 'js'))) {
1044 $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
1045 $arrayreplacement = array('/^\s*\''.preg_quote('/'.$relativefilename, '/').'\',*/m' => ' // \'/'.$relativefilename.'\',');
1046 dolReplaceInFile($srcfile, $arrayreplacement, '', '0', 0, 1);
1047 }
1048
1049 if (preg_match('/_extrafields/', $relativefilename)) {
1050 // Now we update the object file to set $isextrafieldmanaged to 0
1051 $srcfile = $dirins.'/'.strtolower($module).'/class/'.strtolower($objectname).'.class.php';
1052 $arrayreplacement = array('/\$isextrafieldmanaged = 1;/' => '$isextrafieldmanaged = 0;');
1053 dolReplaceInFile($srcfile, $arrayreplacement, '', '0', 0, 1);
1054 }
1055
1056 // Now we update the lib file to set $showtabofpagexxx to 0
1057 $varnametoupdate = '';
1058 $reg = array();
1059 if (preg_match('/_([a-z]+)\.php$/', $relativefilename, $reg)) {
1060 $varnametoupdate = 'showtabofpage'.$reg[1];
1061 }
1062 if ($varnametoupdate) {
1063 $srcfile = $dirins.'/'.strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php';
1064 $arrayreplacement = array('/\$'.preg_quote($varnametoupdate, '/').' = 1;/' => '$'.preg_quote($varnametoupdate, '/').' = 0;');
1065 dolReplaceInFile($srcfile, $arrayreplacement, '', '0', 0, 1);
1066 }
1067 }
1068 }
1069}
1070
1071// Init an object
1072if ($dirins && $action == 'initobject' && $module && $objectname && $user->hasRight("modulebuilder", "run")) {
1073 $warning = 0;
1074
1075 $objectname = ucfirst($objectname);
1076
1077 $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
1078 $moduletype = $listofmodules[strtolower($module)]['moduletype'];
1079
1080 if (preg_match('/[^a-z0-9_]/i', $objectname)) {
1081 $error++;
1082 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
1083 $tabobj = 'newobject';
1084 }
1085 if (class_exists($objectname)) {
1086 // TODO Add a more efficient detection. Scan disk ?
1087 $error++;
1088 setEventMessages($langs->trans("AnObjectWithThisClassNameAlreadyExists"), null, 'errors');
1089 $tabobj = 'newobject';
1090 }
1091
1092 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
1093 $destdir = $dirins.'/'.strtolower($module);
1094
1095 // The dir was not created by init
1096 dol_mkdir($destdir.'/class');
1097 dol_mkdir($destdir.'/img');
1098 dol_mkdir($destdir.'/lib');
1099 dol_mkdir($destdir.'/scripts');
1100 dol_mkdir($destdir.'/sql');
1101 dol_mkdir($destdir.'/ajax');
1102
1103 // Scan dir class to find if an object with the same name already exists.
1104 if (!$error) {
1105 $dirlist = dol_dir_list($destdir.'/class', 'files', 0, '\.txt$');
1106 $alreadyfound = false;
1107 foreach ($dirlist as $key => $val) {
1108 $filefound = preg_replace('/\.txt$/', '', $val['name']);
1109 if (strtolower($objectname) == strtolower($filefound) && $objectname != $filefound) {
1110 $alreadyfound = true;
1111 $error++;
1112 setEventMessages($langs->trans("AnObjectAlreadyExistWithThisNameAndDiffCase"), null, 'errors');
1113 break;
1114 }
1115 }
1116 }
1117
1118 // If we must reuse an existing table for properties, define $stringforproperties
1119 // Generate class file from the table
1120 $stringforproperties = '';
1121 $tablename = GETPOST('initfromtablename', 'alpha');
1122 if ($tablename) {
1123 $_results = $db->DDLDescTable($tablename);
1124 if (empty($_results)) {
1125 $error++;
1126 $langs->load("errors");
1127 setEventMessages($langs->trans("ErrorTableNotFound", $tablename), null, 'errors');
1128 } else {
1156 /*public $fields=array(
1157 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'index' => 1, 'position' => 1, 'comment' => 'Id'),
1158 'ref' => array('type' => 'varchar(128)', 'label' => 'Ref', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'showoncombobox' => 1, 'index' => 1, 'position' => 10, 'searchall' => 1, 'comment' => 'Reference of object'),
1159 'entity' => array('type' => 'integer', 'label' => 'Entity', 'enabled' => 1, 'visible' => 0, 'default' => 1, 'notnull' => 1, 'index' => 1, 'position' => 20),
1160 'label' => array('type' => 'varchar(255)', 'label' => 'Label', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'searchall' => 1, 'css' => 'minwidth200', 'help' => 'Help text', 'alwayseditable' => '1'),
1161 'amount' => array('type' => 'double(24,8)', 'label' => 'Amount', 'enabled' => 1, 'visible' => 1, 'default' => 'null', 'position' => 40, 'searchall' => 0, 'isameasure' => 1, 'help' => 'Help text'),
1162 'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'visible' => 1, 'enabled' => 1, 'position' => 50, 'notnull' => -1, 'index' => 1, 'searchall' => 1, 'help' => 'LinkToThirdparty'),
1163 'description' => array('type' => 'text', 'label' => 'Descrption', 'enabled' => 1, 'visible' => 0, 'position' => 60),
1164 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 61),
1165 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 62),
1166 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 500),
1167 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 501),
1168 //'date_valid' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -2, 'position' => 502),
1169 'fk_user_creat' => array('type' => 'integer', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 510),
1170 'fk_user_modif' => array('type' => 'integer', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 511),
1171 //'fk_user_valid' => array('type' => 'integer', 'label' => 'UserValidation', 'enabled' => 1, 'visible' => -1, 'position' => 512),
1172 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'index' => 0, 'position' => 1000),
1173 'status' => array('type' => 'integer', 'label' => 'Status', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'default' => 0, 'index' => 1, 'position' => 1000, 'arrayofkeyval' => array(0 => 'Draft', 1 => 'Active', -1 => 'Cancel')),
1174 );*/
1175
1176 $stringforproperties = '// BEGIN MODULEBUILDER PROPERTIES'."\n";
1177 $stringforproperties .= 'public $fields = array('."\n";
1178 $i = 10;
1179 while ($obj = $db->fetch_object($_results)) {
1180 // fieldname
1181 $fieldname = $obj->Field;
1182 // type
1183 $type = $obj->Type;
1184 if ($type == 'int(11)') {
1185 $type = 'integer';
1186 }
1187 if ($type == 'float') {
1188 $type = 'real';
1189 }
1190 if (strstr($type, 'tinyint')) {
1191 $type = 'integer';
1192 }
1193 if ($obj->Field == 'fk_soc') {
1194 $type = 'integer:Societe:societe/class/societe.class.php';
1195 }
1196 if (preg_match('/^fk_proj/', $obj->Field)) {
1197 $type = 'integer:Project:projet/class/project.class.php:1:fk_statut=1';
1198 }
1199 if (preg_match('/^fk_prod/', $obj->Field)) {
1200 $type = 'integer:Product:product/class/product.class.php:1';
1201 }
1202 if ($obj->Field == 'fk_warehouse') {
1203 $type = 'integer:Entrepot:product/stock/class/entrepot.class.php';
1204 }
1205 if (preg_match('/^(fk_user|fk_commercial)/', $obj->Field)) {
1206 $type = 'integer:User:user/class/user.class.php';
1207 }
1208
1209 // notnull
1210 $notnull = ($obj->Null == 'YES' ? 0 : 1);
1211 if ($fieldname == 'fk_user_modif') {
1212 $notnull = -1;
1213 }
1214 // label
1215 $label = preg_replace('/_/', '', ucfirst($fieldname));
1216 if ($fieldname == 'rowid') {
1217 $label = 'TechnicalID';
1218 }
1219 if ($fieldname == 'import_key') {
1220 $label = 'ImportId';
1221 }
1222 if ($fieldname == 'fk_soc') {
1223 $label = 'ThirdParty';
1224 }
1225 if ($fieldname == 'tms') {
1226 $label = 'DateModification';
1227 }
1228 if ($fieldname == 'datec') {
1229 $label = 'DateCreation';
1230 }
1231 if ($fieldname == 'date_valid') {
1232 $label = 'DateValidation';
1233 }
1234 if ($fieldname == 'datev') {
1235 $label = 'DateValidation';
1236 }
1237 if ($fieldname == 'note_private') {
1238 $label = 'NotePublic';
1239 }
1240 if ($fieldname == 'note_public') {
1241 $label = 'NotePrivate';
1242 }
1243 if ($fieldname == 'fk_user_creat') {
1244 $label = 'UserAuthor';
1245 }
1246 if ($fieldname == 'fk_user_modif') {
1247 $label = 'UserModif';
1248 }
1249 if ($fieldname == 'fk_user_valid') {
1250 $label = 'UserValidation';
1251 }
1252 // visible
1253 $visible = -1;
1254 if (in_array($fieldname, array('ref', 'label'))) {
1255 $visible = 1;
1256 }
1257 if ($fieldname == 'entity') {
1258 $visible = -2;
1259 }
1260 if ($fieldname == 'entity') {
1261 $visible = -2;
1262 }
1263 if ($fieldname == 'import_key') {
1264 $visible = -2;
1265 }
1266 if ($fieldname == 'fk_user_creat') {
1267 $visible = -2;
1268 }
1269 if ($fieldname == 'fk_user_modif') {
1270 $visible = -2;
1271 }
1272 if (in_array($fieldname, array('ref_ext', 'model_pdf', 'note_public', 'note_private'))) {
1273 $visible = 0;
1274 }
1275 // enabled
1276 $enabled = 1;
1277 // default
1278 $default = '';
1279 if ($fieldname == 'entity') {
1280 $default = 1;
1281 }
1282 // position
1283 $position = $i;
1284 if (in_array($fieldname, array('status', 'statut', 'fk_status', 'fk_statut'))) {
1285 $position = 500;
1286 }
1287 if ($fieldname == 'import_key') {
1288 $position = 900;
1289 }
1290 // $alwayseditable
1291 $alwayseditable=0;
1292 if ($fieldname == 'label') {
1293 $alwayseditable = 1;
1294 } else {
1295 $alwayseditable = 0;
1296 }
1297 // index
1298 $index = 0;
1299 if ($fieldname == 'entity') {
1300 $index = 1;
1301 }
1302 // css, cssview, csslist
1303 $css = '';
1304 $cssview = '';
1305 $csslist = '';
1306 if (preg_match('/^fk_/', $fieldname)) {
1307 $css = 'maxwidth500 widthcentpercentminusxx';
1308 }
1309 if ($fieldname == 'label') {
1310 $css = 'minwidth300';
1311 $cssview = 'wordbreak';
1312 }
1313 if (in_array($fieldname, array('note_public', 'note_private'))) {
1314 $cssview = 'wordbreak';
1315 }
1316 if (in_array($fieldname, array('ref', 'label')) || preg_match('/integer:/', $type)) {
1317 $csslist = 'tdoverflowmax150';
1318 }
1319
1320 // type
1321 $picto = '';
1322 if (isset($obj->Picto)) {
1323 $picto = $obj->Picto;
1324 }
1325 if ($obj->Field == 'fk_soc') {
1326 $picto = 'company';
1327 }
1328 if (preg_match('/^fk_proj/', $obj->Field)) {
1329 $picto = 'project';
1330 }
1331
1332 // Build the property string
1333 $stringforproperties .= "'".$obj->Field."' => array('type' => '".$type."', 'label' => '".$label."',";
1334 if ($default != '') {
1335 $stringforproperties .= " 'default' => ".$default.",";
1336 }
1337 $stringforproperties .= " 'enabled' => ".$enabled.",";
1338 $stringforproperties .= " 'visible' => ".$visible;
1339 if ($notnull) {
1340 $stringforproperties .= ", 'notnull' => ".$notnull;
1341 }
1342 if ($alwayseditable) {
1343 $stringforproperties .= ", 'alwayseditable' => 1";
1344 }
1345 if ($fieldname == 'ref' || $fieldname == 'code') {
1346 $stringforproperties .= ", 'showoncombobox' => 1";
1347 }
1348 $stringforproperties .= ", 'position' => ".$position;
1349 if ($index) {
1350 $stringforproperties .= ", 'index' => ".$index;
1351 }
1352 if ($picto) {
1353 $stringforproperties .= ", 'picto' => '".$picto."'";
1354 }
1355 if ($css) {
1356 $stringforproperties .= ", 'css' => '".$css."'";
1357 }
1358 if ($cssview) {
1359 $stringforproperties .= ", 'cssview' => '".$cssview."'";
1360 }
1361 if ($csslist) {
1362 $stringforproperties .= ", 'csslist' => '".$csslist."'";
1363 }
1364 $stringforproperties .= "),\n";
1365 $i += 5;
1366 }
1367 $stringforproperties .= ');'."\n";
1368 $stringforproperties .= '// END MODULEBUILDER PROPERTIES'."\n";
1369 }
1370 }
1371
1372 $filetogenerate = array(); // For static analysis
1373 if (!$error) {
1374 // Copy some files
1375 $filetogenerate = array(
1376 'myobject_card.php' => strtolower($objectname).'_card.php',
1377 'myobject_note.php' => strtolower($objectname).'_note.php',
1378 'myobject_contact.php' => strtolower($objectname).'_contact.php',
1379 'myobject_document.php' => strtolower($objectname).'_document.php',
1380 'myobject_agenda.php' => strtolower($objectname).'_agenda.php',
1381 'myobject_list.php' => strtolower($objectname).'_list.php',
1382 'admin/myobject_extrafields.php' => 'admin/'.strtolower($objectname).'_extrafields.php',
1383 'lib/mymodule_myobject.lib.php' => 'lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php',
1384 //'test/phpunit/MyObjectTest.php' => 'test/phpunit/'.strtolower($objectname).'Test.php',
1385 'sql/llx_mymodule_myobject.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql',
1386 'sql/llx_mymodule_myobject.key.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql',
1387 'sql/llx_mymodule_myobject_extrafields.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql',
1388 'sql/llx_mymodule_myobject_extrafields.key.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql',
1389 //'scripts/mymodule.php' => 'scripts/'.strtolower($objectname).'.php',
1390 'class/myobject.class.php' => 'class/'.strtolower($objectname).'.class.php',
1391 //'class/api_mymodule.class.php' => 'class/api_'.strtolower($module).'.class.php',
1392 'ajax/myobject.php' => 'ajax/'.strtolower($objectname).'.php',
1393 );
1394
1395 if (GETPOST('includerefgeneration', 'aZ09')) {
1396 dol_mkdir($destdir.'/core/modules/'.strtolower($module));
1397
1398 $filetogenerate += array(
1399 'core/modules/mymodule/mod_myobject_advanced.php' => 'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_advanced.php',
1400 'core/modules/mymodule/mod_myobject_standard.php' => 'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_standard.php',
1401 'core/modules/mymodule/modules_myobject.php' => 'core/modules/'.strtolower($module).'/modules_'.strtolower($objectname).'.php',
1402 );
1403 }
1404 if (GETPOST('includedocgeneration', 'aZ09')) {
1405 dol_mkdir($destdir.'/core/modules/'.strtolower($module));
1406 dol_mkdir($destdir.'/core/modules/'.strtolower($module).'/doc');
1407
1408 $filetogenerate += array(
1409 'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php' => 'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php',
1410 'core/modules/mymodule/doc/pdf_standard_myobject.modules.php' => 'core/modules/'.strtolower($module).'/doc/pdf_standard_'.strtolower($objectname).'.modules.php'
1411 );
1412 }
1413 if (GETPOST('generatepermissions', 'aZ09')) {
1414 $firstobjectname = 'myobject';
1415 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1416 dol_include_once($pathtofile);
1417 $class = 'mod'.$module;
1418 $moduleobj = null;
1419 if (class_exists($class)) {
1420 try {
1421 $moduleobj = new $class($db);
1422 '@phan-var-force DolibarrModules $moduleobj';
1424 } catch (Exception $e) {
1425 $error++;
1426 dol_print_error($db, $e->getMessage());
1427 }
1428 }
1429 if (is_object($moduleobj)) {
1430 $rights = $moduleobj->rights;
1431 } else {
1432 $rights = [];
1433 }
1434 $moduledescriptorfile = $destdir.'/core/modules/mod'.$module.'.class.php';
1435 $checkComment = checkExistComment($moduledescriptorfile, 1);
1436 if ($checkComment < 0) {
1437 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
1438 } else {
1439 $generatePerms = reWriteAllPermissions($moduledescriptorfile, $rights, null, null, $objectname, $module, -2);
1440 if ($generatePerms < 0) {
1441 setEventMessages($langs->trans("WarningPermissionAlreadyExist", $langs->transnoentities($objectname)), null, 'warnings');
1442 }
1443 }
1444 }
1445
1446 if (!$error) {
1447 foreach ($filetogenerate as $srcfile => $destfile) {
1448 $result = dol_copy($srcdir.'/'.$srcfile, $destdir.'/'.$destfile, $newmask, 0);
1449 if ($result <= 0) {
1450 if ($result < 0) {
1451 $warning++;
1452 $langs->load("errors");
1453 setEventMessages($langs->trans("ErrorFailToCopyFile", $srcdir.'/'.$srcfile, $destdir.'/'.$destfile), null, 'errors');
1454 } else {
1455 // $result == 0
1456 setEventMessages($langs->trans("FileAlreadyExists", $destfile), null, 'warnings');
1457 }
1458 }
1459 $arrayreplacement = array(
1460 '/myobject\.class\.php/' => strtolower($objectname).'.class.php',
1461 '/myobject\.lib\.php/' => strtolower($objectname).'.lib.php',
1462 );
1463
1464 dolReplaceInFile($destdir.'/'.$destfile, $arrayreplacement, '', '0', 0, 1);
1465 }
1466 }
1467
1468 // Replace property section with $stringforproperties
1469 if (!$error && $stringforproperties) {
1470 //var_dump($stringforproperties);exit;
1471 $arrayreplacement = array(
1472 '/\/\/ BEGIN MODULEBUILDER PROPERTIES.*\/\/ END MODULEBUILDER PROPERTIES/ims' => $stringforproperties
1473 );
1474
1475 dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', '0', 0, 1);
1476 }
1477
1478 // Edit the class 'class/'.strtolower($objectname).'.class.php'
1479 if (GETPOST('includerefgeneration', 'aZ09')) {
1480 // Replace 'visible' => 1, 'noteditable' => 0, 'default' => ''
1481 $arrayreplacement = array(
1482 '/\'visible\'s*=>s*1,\s*\'noteditable\'s*=>s*0,\s*\'default\'s*=>s*\'\'/' => "'visible' => 4, 'noteditable' => 1, 'default' => '(PROV)'"
1483 );
1484 //var_dump($arrayreplacement);exit;
1485 //var_dump($destdir.'/class/'.strtolower($objectname).'.class.php');exit;
1486 dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', '0', 0, 1);
1487
1488 $arrayreplacement = array(
1489 '/\'models\' => 0,/' => '\'models\' => 1,'
1490 );
1491 dolReplaceInFile($destdir.'/core/modules/mod'.$module.'.class.php', $arrayreplacement, '', '0', 0, 1);
1492 }
1493
1494 // Edit the setup file and the card page
1495 if (GETPOST('includedocgeneration', 'aZ09')) {
1496 // Replace some var init into some files
1497 $arrayreplacement = array(
1498 '/\$includedocgeneration = 0;/' => '$includedocgeneration = 1;'
1499 );
1500 dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', '0', 0, 1);
1501 dolReplaceInFile($destdir.'/'.strtolower($objectname).'_card.php', $arrayreplacement, '', '0', 0, 1);
1502
1503 $arrayreplacement = array(
1504 '/\'models\' => 0,/' => '\'models\' => 1,'
1505 );
1506
1507 dolReplaceInFile($destdir.'/core/modules/mod'.$module.'.class.php', $arrayreplacement, '', '0', 0, 1);
1508 }
1509
1510 // TODO Update entries '$myTmpObjects['MyObject'] = array('includerefgeneration' => 0, 'includedocgeneration' => 0);'
1511
1512
1513 // Scan for object class files
1514 $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
1515
1516 $firstobjectname = '';
1517 $stringtoadd = '';
1518 foreach ($listofobject as $fileobj) {
1519 if (preg_match('/^api_/', $fileobj['name'])) {
1520 continue;
1521 }
1522 if (preg_match('/^actions_/', $fileobj['name'])) {
1523 continue;
1524 }
1525
1526 $tmpcontent = file_get_contents($fileobj['fullname']);
1527 $reg = array();
1528 if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
1529 $objectnameloop = $reg[1];
1530 if (empty($firstobjectname)) {
1531 $firstobjectname = $objectnameloop;
1532 }
1533 }
1534
1535 // Regenerate left menu entry in descriptor for $objectname
1536 $stringtoadd = "
1537 \$this->menu[\$r++] = array(
1538 'fk_menu' => 'fk_mainmenu=mymodule',
1539 'type' => 'left',
1540 'titre' => 'MyObject',
1541 'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'),
1542 'mainmenu' => 'mymodule',
1543 'leftmenu' => 'myobject',
1544 'url' => '/mymodule/myobject_list.php',
1545 'langs' => 'mymodule@mymodule',
1546 'position' => 1000 + \$r,
1547 'enabled' => 'isModEnabled(\"mymodule\")',
1548 'perms' => '".(GETPOST('generatepermissions') ? '$user->hasRight("mymodule", "myobject", "read")' : '1')."',
1549 'target' => '',
1550 'user' => 2,
1551 'object' => 'MyObject'
1552 );
1553 \$this->menu[\$r++] = array(
1554 'fk_menu' => 'fk_mainmenu=mymodule,fk_leftmenu=myobject',
1555 'type' => 'left',
1556 'titre' => 'List MyObject',
1557 'mainmenu' => 'mymodule',
1558 'leftmenu' => 'mymodule_myobject_list',
1559 'url' => '/mymodule/myobject_list.php',
1560 'langs' => 'mymodule@mymodule',
1561 'position' => 1000 + \$r,
1562 'enabled' => 'isModEnabled(\"mymodule\")',
1563 'perms' => '".(GETPOST('generatepermissions') ? '$user->hasRight("mymodule", "myobject", "read")' : '1')."',
1564 'target' => '',
1565 'user' => 2,
1566 'object' => 'MyObject'
1567 );
1568 \$this->menu[\$r++] = array(
1569 'fk_menu' => 'fk_mainmenu=mymodule,fk_leftmenu=myobject',
1570 'type' => 'left',
1571 'titre' => 'New MyObject',
1572 'mainmenu' => 'mymodule',
1573 'leftmenu' => 'mymodule_myobject_new',
1574 'url' => '/mymodule/myobject_card.php?action=create',
1575 'langs' => 'mymodule@mymodule',
1576 'position' => 1000 + \$r,
1577 'enabled' => 'isModEnabled(\"mymodule\")',
1578 'perms' => '".(GETPOST('generatepermissions') ? '$user->hasRight("mymodule", "myobject", "write")' : '1')."',
1579 'target' => '',
1580 'user' => 2,
1581 'object' => 'MyObject'
1582 );";
1583 $stringtoadd = preg_replace('/MyObject/', $objectname, $stringtoadd);
1584 $stringtoadd = preg_replace('/mymodule/', strtolower($module), $stringtoadd);
1585 $stringtoadd = preg_replace('/myobject/', strtolower($objectname), $stringtoadd);
1586
1587 $moduledescriptorfile = $destdir.'/core/modules/mod'.$module.'.class.php';
1588 }
1589 // TODO Allow a replace with regex using dolReplaceInFile with param arryreplacementisregex to 1
1590 // TODO Avoid duplicate addition
1591
1592 // load class and check if menu exist with same object name
1593 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1594 dol_include_once($pathtofile);
1595 $class = 'mod'.$module;
1596 $moduleobj = null;
1597 if (class_exists($class)) {
1598 try {
1599 $moduleobj = new $class($db);
1600 '@phan-var-force DolibarrModules $moduleobj';
1602 } catch (Exception $e) {
1603 $error++;
1604 dol_print_error($db, $e->getMessage());
1605 }
1606 }
1607 if (is_object($moduleobj)) {
1608 $menus = $moduleobj->menu;
1609 } else {
1610 $menus = array();
1611 }
1612 $counter = 0 ;
1613 foreach ($menus as $menu) {
1614 if ($menu['leftmenu'] == strtolower($objectname)) {
1615 $counter++;
1616 }
1617 }
1618 if (!$counter) {
1619 $checkComment = checkExistComment($moduledescriptorfile, 0);
1620 if ($checkComment < 0) {
1621 $warning++;
1622 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), basename($moduledescriptorfile)), null, 'warnings');
1623 } else {
1624 $arrayofreplacement = array('/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */' => '/* BEGIN MODULEBUILDER LEFTMENU '.strtoupper($objectname).' */'.$stringtoadd."\n\t\t".'/* END MODULEBUILDER LEFTMENU '.strtoupper($objectname).' */'."\n\t\t".'/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT */');
1625 dolReplaceInFile($moduledescriptorfile, $arrayofreplacement);
1626 }
1627 }
1628 // Add module descriptor to list of files to replace "MyObject' string with real name of object.
1629 $filetogenerate[] = 'core/modules/mod'.$module.'.class.php';
1630 }
1631
1632 if (!$error) {
1633 // Edit PHP files to make replacement
1634 foreach ($filetogenerate as $destfile) {
1635 $phpfileval['fullname'] = $destdir.'/'.$destfile;
1636
1637 //var_dump($phpfileval['fullname']);
1638 $arrayreplacement = array(
1639 'mymodule' => strtolower($module),
1640 'MyModule' => $module,
1641 'MYMODULE' => strtoupper($module),
1642 'My module' => $module,
1643 'my module' => $module,
1644 'mon module' => $module,
1645 'Mon module' => $module,
1646 'htdocs/modulebuilder/template/' => strtolower($modulename),
1647 'myobject' => strtolower($objectname),
1648 'MyObject' => $objectname,
1649 //'MYOBJECT' => strtoupper($objectname),
1650 '---Replace with your own copyright and developer email---' => getLicenceHeader($user, $langs, $now)
1651 );
1652
1653 if (getDolGlobalString('MODULEBUILDER_SPECIFIC_AUTHOR')) {
1654 $arrayreplacement['---Replace with your own copyright and developer email---'] = dol_print_date($now, '%Y').' ' . getDolGlobalString('MODULEBUILDER_SPECIFIC_AUTHOR');
1655 }
1656
1657 $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement);
1658 //var_dump($result);
1659 if ($result < 0) {
1660 setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
1661 }
1662 }
1663 }
1664
1665 if (!$error) {
1666 // Edit the class file to write properties
1667 $object = rebuildObjectClass($destdir, $module, $objectname, $newmask);
1668
1669 if (is_numeric($object) && $object <= 0) {
1670 $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
1671 setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
1672 $warning++;
1673 }
1674 // check if documentation was generate and add table of properties object
1675 $file = $destdir.'/class/'.strtolower($objectname).'.class.php';
1676 $destfile = $destdir.'/doc/Documentation.asciidoc';
1677
1678 if (file_exists($destfile)) {
1679 writePropsInAsciiDoc($file, $objectname, $destfile);
1680 }
1681 }
1682 if (!$error) {
1683 // Edit sql with new properties
1684 $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, '', $object);
1685
1686 if ($result <= 0) {
1687 setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null);
1688 $error++;
1689 }
1690 }
1691
1692 if (!$error) {
1693 setEventMessages($langs->trans('FilesForObjectInitialized', $objectname), null);
1694 $tabobj = $objectname;
1695 } else {
1696 $tabobj = 'newobject';
1697 }
1698
1699 // check if module is enabled
1700 if (isModEnabled(strtolower($module))) {
1701 $result = unActivateModule(strtolower($module));
1702 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
1703 if ($result) {
1704 setEventMessages($result, null, 'errors');
1705 }
1706 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
1707 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module);
1708 exit;
1709 }
1710}
1711
1712// Add a dictionary
1713if ($dirins && $action == 'initdic' && $module && empty($cancel) && $user->hasRight("modulebuilder", "run")) {
1714 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1715 $destdir = $dirins.'/'.strtolower($module);
1716 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
1717
1718 if (!GETPOST('dicname')) {
1719 $error++;
1720 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Table")), null, 'errors');
1721 }
1722 if (!GETPOST('label')) {
1723 $error++;
1724 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
1725 }
1726 if (!$error) {
1727 $newdicname = $dicname;
1728 if (!preg_match('/^c_/', $newdicname)) {
1729 $newdicname = 'c_'.$dicname;
1730 }
1731 dol_include_once($pathtofile);
1732 $class = 'mod'.$module;
1733
1734 if (class_exists($class)) {
1735 try {
1736 $moduleobj = new $class($db);
1737 '@phan-var-force DolibarrModules $moduleobj';
1739 } catch (Exception $e) {
1740 $error++;
1741 dol_print_error($db, $e->getMessage());
1742 }
1743 } else {
1744 $error++;
1745 $langs->load("errors");
1746 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
1747 exit;
1748 }
1749 $dictionaries = $moduleobj->dictionaries;
1750 $checkComment = checkExistComment($moduledescriptorfile, 2);
1751 if ($checkComment < 0) {
1752 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Dictionaries"), "mod".$module."class.php"), null, 'warnings');
1753 } else {
1754 createNewDictionnary($module, $moduledescriptorfile, $newdicname, $dictionaries);
1755 if (function_exists('opcache_invalidate')) {
1756 opcache_reset(); // remove the include cache hell !
1757 }
1758 clearstatcache(true);
1759 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : ''));
1760 exit;
1761 }
1762 }
1763}
1764
1765// Delete a SQL table
1766if ($dirins && ($action == 'droptable' || $action == 'droptableextrafields') && !empty($module) && !empty($tabobj) && $user->hasRight("modulebuilder", "run")) {
1767 $objectname = $tabobj;
1768
1769 $arrayoftables = array();
1770 if ($action == 'droptable') { // Test on permission already done
1771 $arrayoftables[] = MAIN_DB_PREFIX.strtolower($module).'_'.strtolower($tabobj);
1772 }
1773 if ($action == 'droptableextrafields') { // Test on permission already done
1774 $arrayoftables[] = MAIN_DB_PREFIX.strtolower($module).'_'.strtolower($tabobj).'_extrafields';
1775 }
1776
1777 foreach ($arrayoftables as $tabletodrop) {
1778 $nb = -1;
1779 $sql = "SELECT COUNT(*) as nb FROM ".$tabletodrop;
1780 $resql = $db->query($sql);
1781 if ($resql) {
1782 $obj = $db->fetch_object($resql);
1783 if ($obj) {
1784 $nb = $obj->nb;
1785 }
1786 } else {
1787 if ($db->lasterrno() == 'DB_ERROR_NOSUCHTABLE') {
1788 setEventMessages($langs->trans("TableDoesNotExists", $tabletodrop), null, 'warnings');
1789 } else {
1790 dol_print_error($db);
1791 }
1792 }
1793 if ($nb == 0) {
1794 $resql = $db->DDLDropTable($tabletodrop);
1795 //var_dump($resql);
1796 setEventMessages($langs->trans("TableDropped", $tabletodrop), null, 'mesgs');
1797 } elseif ($nb > 0) {
1798 setEventMessages($langs->trans("TableNotEmptyDropCanceled", $tabletodrop), null, 'warnings');
1799 }
1800 }
1801}
1802
1803if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && (!empty($tabobj) || !empty(GETPOST('obj'))) && $user->hasRight("modulebuilder", "run")) {
1804 $error = 0;
1805
1806 $objectname = (GETPOST('obj') ? GETPOST('obj') : $tabobj);
1807
1808 $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
1809 $moduletype = $listofmodules[strtolower($module)]['moduletype'];
1810
1811 $srcdir = $dirread.'/'.strtolower($module);
1812 $destdir = $dirins.'/'.strtolower($module);
1813 dol_mkdir($destdir);
1814
1815 $objects = dolGetListOfObjectClasses($destdir);
1816 if (!in_array($objectname, array_values($objects))) {
1817 $error++;
1818 setEventMessages($langs->trans("ErrorObjectNotFound", $langs->transnoentities($objectname)), null, 'errors');
1819 }
1820
1821 $addfieldentry = array();
1822
1823 // We click on add property
1824 if (!GETPOST('regenerateclasssql') && !GETPOST('regeneratemissing')) {
1825 if (!GETPOST('propname', 'aZ09')) {
1826 $error++;
1827 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Name")), null, 'errors');
1828 }
1829 if (!GETPOST('proplabel', 'alpha')) {
1830 $error++;
1831 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
1832 }
1833 if (!GETPOST('proptype', 'alpha')) {
1834 $error++;
1835 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors');
1836 }
1837
1838
1839 if (!$error && !GETPOST('regenerateclasssql') && !GETPOST('regeneratemissing')) {
1840 $addfieldentry = array(
1841 'name' => GETPOST('propname', 'aZ09'),
1842 'label' => GETPOST('proplabel', 'alpha'),
1843 'type' => strtolower(GETPOST('proptype', 'alpha')),
1844 'arrayofkeyval' => GETPOST('proparrayofkeyval', 'nohtml'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}'
1845 'visible' => GETPOST('propvisible', 'alphanohtml'),
1846 'enabled' => GETPOST('propenabled', 'alphanohtml'),
1847 'position' => GETPOSTINT('propposition'),
1848 'notnull' => GETPOSTINT('propnotnull'),
1849 'index' => GETPOSTINT('propindex'),
1850 'foreignkey' => GETPOST('propforeignkey', 'alpha'),
1851 'searchall' => GETPOSTINT('propsearchall'),
1852 'isameasure' => GETPOSTINT('propisameasure'),
1853 'comment' => GETPOST('propcomment', 'alpha'),
1854 'help' => GETPOST('prophelp', 'alpha'),
1855 'css' => GETPOST('propcss', 'alpha'), // Can be 'maxwidth500 widthcentpercentminusxx' for example
1856 'cssview' => GETPOST('propcssview', 'alpha'),
1857 'csslist' => GETPOST('propcsslist', 'alpha'),
1858 'default' => GETPOST('propdefault', 'restricthtml'),
1859 'noteditable' => GETPOSTINT('propnoteditable'),
1860 //'alwayseditable' => GETPOSTINT('propalwayseditable'),
1861 'validate' => GETPOSTINT('propvalidate')
1862 );
1863
1864 if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) {
1865 $tmpdecode = json_decode($addfieldentry['arrayofkeyval'], true);
1866 if ($tmpdecode) { // If string is already a json
1867 $addfieldentry['arrayofkeyval'] = $tmpdecode;
1868 } else { // If string is a list of lines with "key,value"
1869 $tmparray = dolExplodeIntoArray($addfieldentry['arrayofkeyval'], "\n", ",");
1870 $addfieldentry['arrayofkeyval'] = $tmparray;
1871 }
1872 }
1873 }
1874 }
1875
1876 /*if (GETPOST('regeneratemissing'))
1877 {
1878 setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings');
1879 $error++;
1880 }*/
1881
1882 $moduletype = $listofmodules[strtolower($module)]['moduletype'];
1883
1884 // Edit the class file to write properties
1885 if (!$error) {
1886 $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry, $moduletype);
1887
1888 if (is_numeric($object) && $object <= 0) {
1889 $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
1890 setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
1891 $error++;
1892 }
1893 }
1894
1895 // Edit sql with new properties
1896 if (!$error) {
1897 $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object, $moduletype);
1898
1899 if ($result <= 0) {
1900 setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null, 'errors');
1901 $error++;
1902 }
1903 }
1904
1905 if (!$error) {
1906 clearstatcache(true);
1907
1908 setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null);
1909
1910 setEventMessages($langs->trans('WarningDatabaseIsNotUpdated'), null);
1911
1912 // Make a redirect to reload all data
1913 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname.'&nocache='.time());
1914 exit;
1915 }
1916}
1917
1918if ($dirins && $action == 'confirm_deleteproperty' && $propertykey && $user->hasRight("modulebuilder", "run")) {
1919 $objectname = $tabobj;
1920
1921 $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
1922 $moduletype = $listofmodules[strtolower($module)]['moduletype'];
1923
1924 $srcdir = $dirread.'/'.strtolower($module);
1925 $destdir = $dirins.'/'.strtolower($module);
1926 dol_mkdir($destdir);
1927
1928 // Edit the class file to write properties
1929 if (!$error) {
1930 $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey);
1931
1932 if (is_numeric($object) && $object <= 0) {
1933 $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
1934 setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
1935 $error++;
1936 }
1937 }
1938
1939 // Edit sql with new properties
1940 if (!$error) {
1941 $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object);
1942
1943 if ($result <= 0) {
1944 setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null, 'errors');
1945 $error++;
1946 }
1947 }
1948
1949 if (!$error) {
1950 setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null);
1951
1952 clearstatcache(true);
1953
1954 // Make a redirect to reload all data
1955 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname);
1956 exit;
1957 }
1958}
1959
1960if ($dirins && $action == 'confirm_deletemodule' && $user->hasRight("modulebuilder", "run")) {
1961 if (preg_match('/[^a-z0-9_]/i', $module)) {
1962 $error++;
1963 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
1964 }
1965
1966 if (!$error) {
1967 $modulelowercase = strtolower($module);
1968
1969 // Dir for module
1970 $dir = $dirins.'/'.$modulelowercase;
1971
1972 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1973
1974 // Dir for module
1975 $dir = dol_buildpath($modulelowercase, 0);
1976
1977 // Zip file to build
1978 $FILENAMEZIP = '';
1979
1980 // Load module
1981 dol_include_once($pathtofile);
1982 $class = 'mod'.$module;
1983
1984 $moduleobj = null;
1985
1986 if (class_exists($class)) {
1987 try {
1988 $moduleobj = new $class($db);
1989 '@phan-var-force DolibarrModules $moduleobj';
1991 } catch (Exception $e) {
1992 $error++;
1993 dol_print_error($db, $e->getMessage());
1994 }
1995 } else {
1996 $error++;
1997 $langs->load("errors");
1998 setEventMessages($langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module), null, 'warnings');
1999 }
2000
2001 if ($moduleobj) {
2002 $moduleobj->remove();
2003 }
2004
2005 $result = dol_delete_dir_recursive($dir);
2006
2007 if ($result > 0) {
2008 setEventMessages($langs->trans("DirWasRemoved", $modulelowercase), null);
2009
2010 clearstatcache(true);
2011 if (function_exists('opcache_invalidate')) {
2012 opcache_reset(); // remove the include cache hell !
2013 }
2014
2015 header("Location: ".$_SERVER["PHP_SELF"].'?module=deletemodule');
2016 exit;
2017 } else {
2018 setEventMessages($langs->trans("PurgeNothingToDelete"), null, 'warnings');
2019 }
2020 }
2021
2022 $action = '';
2023 $module = 'deletemodule';
2024}
2025
2026if ($dirins && $action == 'confirm_deleteobject' && $objectname && $user->hasRight("modulebuilder", "run")) {
2027 if (preg_match('/[^a-z0-9_]/i', $objectname)) {
2028 $error++;
2029 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
2030 }
2031
2032 if (!$error) {
2033 $modulelowercase = strtolower($module);
2034 $objectlowercase = strtolower($objectname);
2035
2036 // Dir for module
2037 $dir = $dirins.'/'.$modulelowercase;
2038
2039 // Delete some files
2040 $filetodelete = array(
2041 'myobject_card.php' => strtolower($objectname).'_card.php',
2042 'myobject_note.php' => strtolower($objectname).'_note.php',
2043 'myobject_contact.php' => strtolower($objectname).'_contact.php',
2044 'myobject_document.php' => strtolower($objectname).'_document.php',
2045 'myobject_agenda.php' => strtolower($objectname).'_agenda.php',
2046 'myobject_list.php' => strtolower($objectname).'_list.php',
2047 'admin/myobject_extrafields.php' => 'admin/'.strtolower($objectname).'_extrafields.php',
2048 'lib/mymodule_myobject.lib.php' => 'lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php',
2049 'test/phpunit/MyObjectTest.php' => 'test/phpunit/'.strtolower($objectname).'Test.php',
2050 'sql/llx_mymodule_myobject.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql',
2051 'sql/llx_mymodule_myobject_extrafields.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql',
2052 'sql/llx_mymodule_myobject.key.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql',
2053 'sql/llx_mymodule_myobject_extrafields.key.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql',
2054 'scripts/myobject.php' => 'scripts/'.strtolower($objectname).'.php',
2055 'class/myobject.class.php' => 'class/'.strtolower($objectname).'.class.php',
2056 'class/api_myobject.class.php' => 'class/api_'.strtolower($module).'.class.php',
2057 'core/modules/mymodule/mod_myobject_advanced.php' => 'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_advanced.php',
2058 'core/modules/mymodule/mod_myobject_standard.php' => 'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_standard.php',
2059 'core/modules/mymodule/modules_myobject.php' => 'core/modules/'.strtolower($module).'/modules_'.strtolower($objectname).'.php',
2060 'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php' => 'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php',
2061 'core/modules/mymodule/doc/pdf_standard_myobject.modules.php' => 'core/modules/'.strtolower($module).'/doc/pdf_standard_'.strtolower($objectname).'.modules.php'
2062 );
2063
2064 //menu for the object selected
2065 // load class and check if menu,permission,documentation exist for this object
2066 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2067 dol_include_once($pathtofile);
2068 $class = 'mod'.$module;
2069 $moduleobj = null;
2070 if (class_exists($class)) {
2071 try {
2072 $moduleobj = new $class($db);
2073 '@phan-var-force DolibarrModules $moduleobj';
2075 } catch (Exception $e) {
2076 $error++;
2077 dol_print_error($db, $e->getMessage());
2078 }
2079 } else {
2080 $error++;
2081 $langs->load("errors");
2082 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
2083 exit;
2084 }
2085 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2086
2087 // delete menus linked to the object
2088 $menus = $moduleobj->menu;
2089 $rewriteMenu = checkExistComment($moduledescriptorfile, 0);
2090
2091 if ($rewriteMenu < 0) {
2092 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), "mod".$module."class.php"), null, 'warnings');
2093 } else {
2094 reWriteAllMenus($moduledescriptorfile, $menus, $objectname, null, -1);
2095 }
2096
2097 // regenerate permissions and delete them
2098 $permissions = $moduleobj->rights;
2099 $rewritePerms = checkExistComment($moduledescriptorfile, 1);
2100 if ($rewritePerms < 0) {
2101 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
2102 } else {
2103 reWriteAllPermissions($moduledescriptorfile, $permissions, null, null, $objectname, '', -1);
2104 }
2105 if ($rewritePerms && $rewriteMenu) {
2106 // check if documentation has been generated
2107 $file_doc = $dirins.'/'.strtolower($module).'/doc/Documentation.asciidoc';
2108 deletePropsAndPermsFromDoc($file_doc, $objectname);
2109
2110 clearstatcache(true);
2111 if (function_exists('opcache_invalidate')) {
2112 opcache_reset(); // remove the include cache hell !
2113 }
2114 $resultko = 0;
2115 foreach ($filetodelete as $tmpfiletodelete) {
2116 $resulttmp = dol_delete_file($dir.'/'.$tmpfiletodelete, 0, 0, 1);
2117 $resulttmp = dol_delete_file($dir.'/'.$tmpfiletodelete.'.back', 0, 0, 1);
2118 if (!$resulttmp) {
2119 $resultko++;
2120 }
2121 }
2122
2123 if ($resultko == 0) {
2124 setEventMessages($langs->trans("FilesDeleted"), null);
2125 } else {
2126 setEventMessages($langs->trans("ErrorSomeFilesCouldNotBeDeleted"), null, 'warnings');
2127 }
2128 }
2129 }
2130
2131 $action = '';
2132 if (! $error) {
2133 $tabobj = 'newobject';
2134 } else {
2135 $tabobj = 'deleteobject';
2136 }
2137
2138 // check if module is enabled
2139 if (isModEnabled(strtolower($module))) {
2140 $result = unActivateModule(strtolower($module));
2141 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
2142 if ($result) {
2143 setEventMessages($result, null, 'errors');
2144 }
2145 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2146 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&tabobj=deleteobject&module='.urlencode($module));
2147 exit;
2148 }
2149}
2150
2151if (($dirins && $action == 'confirm_deletedictionary' && $dicname) || ($dirins && $action == 'confirm_deletedictionary' && GETPOST('dictionnarykey')) && $user->hasRight("modulebuilder", "run")) {
2152 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2153 $destdir = $dirins.'/'.strtolower($module);
2154 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2155
2156 if (preg_match('/[^a-z0-9_]/i', $dicname)) {
2157 $error++;
2158 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
2159 }
2160
2161 if (!empty($dicname)) {
2162 $newdicname = $dicname;
2163 if (!preg_match('/^c_/', $newdicname)) {
2164 $newdicname = 'c_'.strtolower($dicname);
2165 }
2166 } else {
2167 $newdicname = null;
2168 }
2169
2170 dol_include_once($pathtofile);
2171 $class = 'mod'.$module;
2172
2173 if (class_exists($class)) {
2174 try {
2175 $moduleobj = new $class($db);
2176 '@phan-var-force DolibarrModules $moduleobj';
2178 } catch (Exception $e) {
2179 $error++;
2180 dol_print_error($db, $e->getMessage());
2181 }
2182 } else {
2183 $error++;
2184 $langs->load("errors");
2185 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
2186 exit;
2187 }
2188
2189 $dicts = $moduleobj->dictionaries;
2190 $checkComment = checkExistComment($moduledescriptorfile, 2);
2191 if ($checkComment < 0) {
2192 $error++;
2193 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Dictionaries"), "mod".$module."class.php"), null, 'warnings');
2194 }
2195
2196 if (!empty(GETPOST('dictionnarykey'))) {
2197 $newdicname = $dicts['tabname'][GETPOSTINT('dictionnarykey') - 1];
2198 }
2199
2200 // Lookup the table dicname
2201 $checkTable = false;
2202 if ($newdicname !== null) {
2203 $checkTable = $db->DDLDescTable(MAIN_DB_PREFIX.strtolower($newdicname));
2204 }
2205
2206 if (is_bool($checkTable) || $db->num_rows($checkTable) <= 0) { // @phpstan-ignore-line
2207 $error++;
2208 }
2209
2210 // search the key by name
2211 $keyToDelete = null;
2212 foreach ($dicts['tabname'] as $key => $table) {
2213 //var_dump($table." /////// ".$newdicname);exit;
2214 if (strtolower($table) === $newdicname) {
2215 $keyToDelete = $key;
2216 break;
2217 }
2218 }
2219 // delete all dicname's key values from the dictionary
2220 if ($keyToDelete !== null) {
2221 $keysToDelete = ['tabname', 'tablib', 'tabsql', 'tabsqlsort', 'tabfield', 'tabfieldvalue', 'tabfieldinsert', 'tabrowid', 'tabcond', 'tabhelp'];
2222 foreach ($keysToDelete as $key) {
2223 unset($dicts[$key][$keyToDelete]);
2224 }
2225 } else {
2226 $error++;
2227 setEventMessages($langs->trans("ErrorDictionaryNotFound", ucfirst($dicname)), null, 'errors');
2228 }
2229 if (!$error && $newdicname !== null) {
2230 // delete table
2231 $_results = $db->DDLDropTable(MAIN_DB_PREFIX.strtolower($newdicname));
2232 if ($_results < 0) {
2233 dol_print_error($db);
2234 $langs->load("errors");
2235 setEventMessages($langs->trans("ErrorTableNotFound", $newdicname), null, 'errors');
2236 }
2237 // rebuild file after update dictionaries
2238 $result = updateDictionaryInFile($module, $moduledescriptorfile, $dicts);
2239 if ($result > 0) {
2240 setEventMessages($langs->trans("DictionaryDeleted", ucfirst(substr($newdicname, 2))), null);
2241 }
2242 if (function_exists('opcache_invalidate')) {
2243 opcache_reset(); // remove the include cache hell !
2244 }
2245 clearstatcache(true);
2246 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : ''));
2247 exit;
2248 }
2249}
2250if ($dirins && $action == 'updatedictionary' && GETPOST('dictionnarykey') && $user->hasRight("modulebuilder", "run")) {
2251 $keydict = GETPOSTINT('dictionnarykey') - 1 ;
2252
2253 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2254 $destdir = $dirins.'/'.strtolower($module);
2255 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2256 dol_include_once($pathtofile);
2257 $class = 'mod'.$module;
2258
2259 if (class_exists($class)) {
2260 try {
2261 $moduleobj = new $class($db);
2262 '@phan-var-force DolibarrModules $moduleobj';
2264 } catch (Exception $e) {
2265 $error++;
2266 dol_print_error($db, $e->getMessage());
2267 }
2268 } else {
2269 $error++;
2270 $langs->load("errors");
2271 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
2272 exit;
2273 }
2274
2275 $dicts = $moduleobj->dictionaries;
2276 if (!empty(GETPOST('tablib')) && GETPOST('tablib') !== $dicts['tablib'][$keydict]) {
2277 $dicts['tablib'][$keydict] = ucfirst(strtolower(GETPOST('tablib')));
2278 $checkComment = checkExistComment($moduledescriptorfile, 2);
2279 if ($checkComment < 0) {
2280 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Dictionaries"), "mod".$module."class.php"), null, 'warnings');
2281 } else {
2282 $updateDict = updateDictionaryInFile($module, $moduledescriptorfile, $dicts);
2283 if ($updateDict > 0) {
2284 setEventMessages($langs->trans("DictionaryNameUpdated", ucfirst(GETPOST('tablib'))), null);
2285 }
2286 if (function_exists('opcache_invalidate')) {
2287 opcache_reset(); // remove the include cache hell !
2288 }
2289 clearstatcache(true);
2290 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : ''));
2291 exit;
2292 }
2293 }
2294 //var_dump(GETPOST('tablib'));exit;
2295}
2296if ($dirins && $action == 'generatedoc' && $user->hasRight("modulebuilder", "run")) {
2297 $modulelowercase = strtolower($module);
2298
2299 // Dir for module
2300 $dirofmodule = dol_buildpath($modulelowercase, 0).'/doc';
2301
2302 $FILENAMEDOC = strtolower($module).'.html';
2303
2304 $util = new Utils($db);
2305 $result = $util->generateDoc($module);
2306
2307 if ($result > 0) {
2308 setEventMessages($langs->trans("DocFileGeneratedInto", $dirofmodule), null);
2309 } else {
2310 setEventMessages($util->error, $util->errors, 'errors');
2311 }
2312}
2313
2314if ($dirins && $action == 'generatepackage' && $user->hasRight("modulebuilder", "run")) {
2315 $modulelowercase = strtolower($module);
2316
2317 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2318
2319 // Dir for module
2320 $dir = dol_buildpath($modulelowercase, 0);
2321
2322 // Zip file to build
2323 $FILENAMEZIP = '';
2324
2325 // Load module
2326 dol_include_once($pathtofile);
2327 $class = 'mod'.$module;
2328
2329 if (class_exists($class)) {
2330 try {
2331 $moduleobj = new $class($db);
2332 '@phan-var-force DolibarrModules $moduleobj';
2334 } catch (Exception $e) {
2335 $error++;
2336 dol_print_error($db, $e->getMessage());
2337 }
2338 } else {
2339 $error++;
2340 $langs->load("errors");
2341 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
2342 exit;
2343 }
2344
2345 $arrayversion = explode('.', $moduleobj->version, 3);
2346 if (count($arrayversion)) {
2347 $FILENAMEZIP = "module_".$modulelowercase.'-'.$arrayversion[0].(empty($arrayversion[1]) ? '.0' : '.'.$arrayversion[1]).(empty($arrayversion[2]) ? '' : '.'.$arrayversion[2]).'.zip';
2348
2349 $dirofmodule = dol_buildpath($modulelowercase, 0).'/bin';
2350 $outputfilezip = $dirofmodule.'/'.$FILENAMEZIP;
2351 if ($dirofmodule) {
2352 if (!dol_is_dir($dirofmodule)) {
2353 dol_mkdir($dirofmodule);
2354 }
2355 // Note: We exclude /bin/ to not include the already generated zip
2356 $result = dol_compress_dir($dir, $outputfilezip, 'zip', '/\/bin\/|\.git|\.old|\.back|\.ssh/', $modulelowercase);
2357 } else {
2358 $result = -1;
2359 }
2360
2361 if ($result > 0) {
2362 setEventMessages($langs->trans("ZipFileGeneratedInto", $outputfilezip), null);
2363 } else {
2364 $error++;
2365 $langs->load("errors");
2366 setEventMessages($langs->trans("ErrorFailToGenerateFile", $outputfilezip), null, 'errors');
2367 }
2368 } else {
2369 $error++;
2370 $langs->load("errors");
2371 setEventMessages($langs->trans("ErrorCheckVersionIsDefined"), null, 'errors');
2372 }
2373}
2374
2375// Add permission
2376if ($dirins && $action == 'addright' && !empty($module) && empty($cancel) && $user->hasRight("modulebuilder", "run")) {
2377 $error = 0;
2378
2379 // load class and check if right exist
2380 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2381 dol_include_once($pathtofile);
2382 $class = 'mod'.$module;
2383 $moduleobj = null;
2384 if (class_exists($class)) {
2385 try {
2386 $moduleobj = new $class($db);
2387 '@phan-var-force DolibarrModules $moduleobj';
2389 } catch (Exception $e) {
2390 $error++;
2391 dol_print_error($db, $e->getMessage());
2392 }
2393 }
2394
2395 // verify information entered
2396 if (!GETPOST('label', 'alpha')) {
2397 $error++;
2398 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
2399 }
2400 if (!GETPOST('permissionObj', 'alpha')) {
2401 $error++;
2402 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Rights")), null, 'errors');
2403 }
2404
2405 $id = GETPOST('id', 'alpha');
2406 $label = GETPOST('label', 'alpha');
2407 $objectForPerms = strtolower(GETPOST('permissionObj', 'alpha'));
2408 $crud = GETPOST('crud', 'alpha');
2409
2410 //check existing object permission
2411 $counter = 0;
2412 $permsForObject = array();
2413 if (is_object($moduleobj)) {
2414 $permissions = $moduleobj->rights;
2415 } else {
2416 $permissions = array();
2417 }
2418 $allObject = array();
2419
2420 $countPerms = count($permissions);
2421
2422 for ($i = 0; $i < $countPerms; $i++) {
2423 if ($permissions[$i][4] == $objectForPerms) {
2424 $counter++;
2425 if (count($permsForObject) < 3) {
2426 $permsForObject[] = $permissions[$i];
2427 }
2428 }
2429 $allObject[] = $permissions[$i][4];
2430 }
2431
2432 // check if label of object already exists
2433 $countPermsObj = count($permsForObject);
2434 for ($j = 0; $j < $countPermsObj; $j++) {
2435 if (in_array($crud, $permsForObject[$j])) {
2436 $error++;
2437 setEventMessages($langs->trans("ErrorExistingPermission", $langs->transnoentities($crud), $langs->transnoentities($objectForPerms)), null, 'errors');
2438 }
2439 }
2440
2441 $rightToAdd = array();
2442 if (!$error) {
2443 $key = $countPerms + 1;
2444 //prepare right to add
2445 $rightToAdd = array(
2446 0 => $id,
2447 1 => $label,
2448 4 => $objectForPerms,
2449 5 => $crud
2450 );
2451
2452 if (isModEnabled(strtolower($module))) {
2453 $result = unActivateModule(strtolower($module));
2454 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
2455 if ($result) {
2456 setEventMessages($result, null, 'errors');
2457 }
2458 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2459 }
2460 }
2461 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2462 //rewriting all permissions after add a right
2463 $rewrite = checkExistComment($moduledescriptorfile, 1);
2464 if ($rewrite < 0) {
2465 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
2466 } else {
2467 reWriteAllPermissions($moduledescriptorfile, $permissions, $key, $rightToAdd, '', '', 1);
2468 setEventMessages($langs->trans('PermissionAddedSuccesfuly'), null);
2469
2470 clearstatcache(true);
2471 if (function_exists('opcache_invalidate')) {
2472 opcache_reset(); // remove the include cache hell !
2473 }
2474 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
2475 exit;
2476 }
2477}
2478
2479
2480// Update permission
2481if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright') && empty($cancel) && $user->hasRight("modulebuilder", "run")) {
2482 $error = 0;
2483 // load class and check if right exist
2484 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2485 dol_include_once($pathtofile);
2486 $class = 'mod'.$module;
2487 $moduleobj = null;
2488 if (class_exists($class)) {
2489 try {
2490 $moduleobj = new $class($db);
2491 '@phan-var-force DolibarrModules $moduleobj';
2493 } catch (Exception $e) {
2494 $error++;
2495 dol_print_error($db, $e->getMessage());
2496 }
2497 }
2498 // verify information entered
2499 if (!GETPOST('label', 'alpha')) {
2500 $error++;
2501 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
2502 }
2503 if (!GETPOST('permissionObj', 'alpha')) {
2504 $error++;
2505 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Rights")), null, 'errors');
2506 }
2507
2508 $label = GETPOST('label', 'alpha');
2509 $objectForPerms = strtolower(GETPOST('permissionObj', 'alpha'));
2510 $crud = GETPOST('crud', 'alpha');
2511
2512
2513 if ($label == "Read objects of $module" && $crud != "read") {
2514 $crud = "read";
2515 // $label = "Read objects of $module";
2516 }
2517 if ($label == "Create/Update objects of $module" && $crud != "write") {
2518 $crud = "write";
2519 // $label = "Create/Update objects of $module";
2520 }
2521 if ($label == "Delete objects of $module" && $crud != "delete") {
2522 $crud = "delete";
2523 // $label = "Delete objects of $module";
2524 }
2525
2526 if (is_object($moduleobj)) {
2527 $permissions = $moduleobj->rights;
2528 } else {
2529 $permissions = [];
2530 }
2531 $key = GETPOSTINT('counter') - 1;
2532 //get permission want to delete from permissions array
2533 if (array_key_exists($key, $permissions)) {
2534 $x1 = $permissions[$key][1];
2535 $x2 = $permissions[$key][4];
2536 $x3 = $permissions[$key][5];
2537 } else {
2538 $x1 = null;
2539 $x2 = null;
2540 $x3 = null;
2541 }
2542 //check existing object permission
2543 $counter = 0;
2544 $permsForObject = array();
2545 // $permissions = $moduleobj->rights; // Already fetched above
2546 $firstRight = 0;
2547 $existRight = 0;
2548 $allObject = array();
2549
2550 $countPerms = count($permissions);
2551 for ($i = 0; $i < $countPerms; $i++) {
2552 if ($permissions[$i][4] == $objectForPerms) {
2553 $counter++;
2554 if (count($permsForObject) < 3) {
2555 $permsForObject[] = $permissions[$i];
2556 }
2557 }
2558 $allObject[] = $permissions[$i][4];
2559 }
2560
2561 if ($label != $x1 && $crud != $x3) {
2562 $countPermsObj = count($permsForObject);
2563 for ($j = 0; $j < $countPermsObj; $j++) {
2564 if (in_array($label, $permsForObject[$j])) {
2565 $error++;
2566 setEventMessages($langs->trans("ErrorExistingPermission", $langs->transnoentities($label), $langs->transnoentities($objectForPerms)), null, 'errors');
2567 }
2568 }
2569 }
2570
2571 if (!$error) {
2572 if (isModEnabled(strtolower($module))) {
2573 $result = unActivateModule(strtolower($module));
2574 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
2575 if ($result) {
2576 setEventMessages($result, null, 'errors');
2577 }
2578 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2579 }
2580
2581 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2582 // rewriting all permissions after update permission needed
2583 $rewrite = checkExistComment($moduledescriptorfile, 1);
2584 if ($rewrite < 0) {
2585 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
2586 } else {
2587 $rightUpdated = null; // I not set at this point
2588 reWriteAllPermissions($moduledescriptorfile, $permissions, $key, $rightUpdated, '', '', 2);
2589 setEventMessages($langs->trans('PermissionUpdatedSuccesfuly'), null);
2590 clearstatcache(true);
2591 if (function_exists('opcache_invalidate')) {
2592 opcache_reset(); // remove the include cache hell !
2593 }
2594 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
2595 exit;
2596 }
2597 }
2598}
2599// Delete permission
2600if ($dirins && $action == 'confirm_deleteright' && !empty($module) && GETPOSTINT('permskey') && $user->hasRight("modulebuilder", "run")) {
2601 $error = 0;
2602 // load class and check if right exist
2603 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2604 dol_include_once($pathtofile);
2605 $class = 'mod'.$module;
2606 $moduleobj = null;
2607 if (class_exists($class)) {
2608 try {
2609 $moduleobj = new $class($db);
2610 '@phan-var-force DolibarrModules $moduleobj';
2612 } catch (Exception $e) {
2613 $error++;
2614 dol_print_error($db, $e->getMessage());
2615 }
2616 }
2617
2618 $permissions = $moduleobj->rights;
2619 $key = GETPOSTINT('permskey') - 1;
2620
2621 if (!$error) {
2622 // check if module is enabled
2623 if (isModEnabled(strtolower($module))) {
2624 $result = unActivateModule(strtolower($module));
2625 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
2626 if ($result) {
2627 setEventMessages($result, null, 'errors');
2628 }
2629 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2630 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
2631 exit;
2632 }
2633
2634 // rewriting all permissions
2635 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2636 $rewrite = checkExistComment($moduledescriptorfile, 1);
2637 if ($rewrite < 0) {
2638 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
2639 } else {
2640 reWriteAllPermissions($moduledescriptorfile, $permissions, $key, null, '', '', 0);
2641 setEventMessages($langs->trans('PermissionDeletedSuccesfuly'), null);
2642
2643 clearstatcache(true);
2644 if (function_exists('opcache_invalidate')) {
2645 opcache_reset(); // remove the include cache hell !
2646 }
2647
2648 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
2649 exit;
2650 }
2651 }
2652}
2653// Save file
2654if ($action == 'savefile' && empty($cancel) && $user->hasRight("modulebuilder", "run")) {
2655 $relofcustom = basename($dirins);
2656
2657 if ($relofcustom) {
2658 // Check that relative path ($file) start with name 'custom'
2659 if (!preg_match('/^'.$relofcustom.'/', $file)) {
2660 $file = $relofcustom.'/'.$file;
2661 }
2662
2663 $pathoffile = dol_buildpath($file, 0);
2664 $pathoffilebackup = dol_buildpath($file.'.back', 0);
2665
2666 // Save old version
2667 if (dol_is_file($pathoffile)) {
2668 dol_copy($pathoffile, $pathoffilebackup, '0', 1);
2669 }
2670
2671 $check = 'restricthtml';
2672 $srclang = dol_mimetype($pathoffile, '', 3);
2673 if ($srclang == 'md') {
2674 $check = 'restricthtml';
2675 }
2676 if ($srclang == 'lang') {
2677 $check = 'restricthtml';
2678 }
2679 if ($srclang == 'php') {
2680 $check = 'none';
2681 }
2682
2683 $content = GETPOST('editfilecontent', $check);
2684
2685 // Save file on disk
2686 if ($content) {
2687 dol_delete_file($pathoffile);
2688 $result = file_put_contents($pathoffile, $content);
2689 if ($result) {
2690 dolChmod($pathoffile, $newmask);
2691
2692 setEventMessages($langs->trans("FileSaved"), null);
2693 } else {
2694 setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
2695 }
2696 } else {
2697 setEventMessages($langs->trans("ContentCantBeEmpty"), null, 'errors');
2698 //$action='editfile';
2699 $error++;
2700 }
2701 }
2702}
2703
2704// Enable module
2705if ($action == 'set' && $user->admin && $user->hasRight("modulebuilder", "run")) {
2706 $param = '';
2707 if ($module) {
2708 $param .= '&module='.urlencode($module);
2709 }
2710 if ($tab) {
2711 $param .= '&tab='.urlencode($tab);
2712 }
2713 if ($tabobj) {
2714 $param .= '&tabobj='.urlencode($tabobj);
2715 }
2716
2717 $value = GETPOST('value', 'alpha');
2718 $resarray = activateModule($value);
2719 if (!empty($resarray['errors'])) {
2720 setEventMessages('', $resarray['errors'], 'errors');
2721 } else {
2722 //var_dump($resarray);exit;
2723 if ($resarray['nbperms'] > 0) {
2724 $tmpsql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."user WHERE admin <> 1";
2725 $resqltmp = $db->query($tmpsql);
2726 if ($resqltmp) {
2727 $obj = $db->fetch_object($resqltmp);
2728 //var_dump($obj->nb);exit;
2729 if ($obj && $obj->nb > 1) {
2730 $msg = $langs->trans('ModuleEnabledAdminMustCheckRights');
2731 setEventMessages($msg, null, 'warnings');
2732 }
2733 } else {
2734 dol_print_error($db);
2735 }
2736 }
2737 }
2738 header("Location: ".$_SERVER["PHP_SELF"]."?".$param);
2739 exit;
2740}
2741
2742// Disable module
2743if ($action == 'reset' && $user->admin && $user->hasRight("modulebuilder", "run")) {
2744 $param = '';
2745 if ($module) {
2746 $param .= '&module='.urlencode($module);
2747 }
2748 if ($tab) {
2749 $param .= '&tab='.urlencode($tab);
2750 }
2751 if ($tabobj) {
2752 $param .= '&tabobj='.urlencode($tabobj);
2753 }
2754
2755 $value = GETPOST('value', 'alpha');
2756 $result = unActivateModule($value);
2757 if ($result) {
2758 setEventMessages($result, null, 'errors');
2759 }
2760 header("Location: ".$_SERVER["PHP_SELF"]."?".$param);
2761 exit;
2762}
2763
2764// delete menu
2765if ($dirins && $action == 'confirm_deletemenu' && GETPOSTINT('menukey') && $user->hasRight("modulebuilder", "run")) {
2766 // check if module is enabled
2767 if (isModEnabled(strtolower($module))) {
2768 $result = unActivateModule(strtolower($module));
2769 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
2770 if ($result) {
2771 setEventMessages($result, null, 'errors');
2772 }
2773 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2774 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2775 exit;
2776 }
2777 // load class and check if menu exist
2778 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2779 dol_include_once($pathtofile);
2780 $class = 'mod'.$module;
2781 $moduleobj = null;
2782 if (class_exists($class)) {
2783 try {
2784 $moduleobj = new $class($db);
2785 '@phan-var-force DolibarrModules $moduleobj';
2787 } catch (Exception $e) {
2788 $error++;
2789 dol_print_error($db, $e->getMessage());
2790 }
2791 }
2792 // get all objects and convert value to lower case for compare
2793 $dir = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
2794 $destdir = $dir.'/'.strtolower($module);
2795 $objects = dolGetListOfObjectClasses($destdir);
2796 $result = array_map('strtolower', $objects);
2797
2798 $menus = $moduleobj->menu;
2799 $key = GETPOSTINT('menukey');
2800 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2801
2802 $checkcomment = checkExistComment($moduledescriptorfile, 0);
2803 if ($checkcomment < 0) {
2804 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), "mod".$module."class.php"), null, 'warnings');
2805 } else {
2806 if ($menus[$key]['fk_menu'] === 'fk_mainmenu='.strtolower($module)) {
2807 if (in_array(strtolower($menus[$key]['leftmenu']), $result)) {
2808 reWriteAllMenus($moduledescriptorfile, $menus, $menus[$key]['leftmenu'], $key, -1);
2809 } else {
2810 reWriteAllMenus($moduledescriptorfile, $menus, null, $key, 0);
2811 }
2812 } else {
2813 reWriteAllMenus($moduledescriptorfile, $menus, null, $key, 0);
2814 }
2815
2816 clearstatcache(true);
2817 if (function_exists('opcache_invalidate')) {
2818 opcache_reset(); // remove the include cache hell !
2819 }
2820
2821 setEventMessages($langs->trans('MenuDeletedSuccessfuly'), null);
2822 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2823 exit;
2824 }
2825}
2826
2827// Add menu in module without initial object
2828if ($dirins && $action == 'addmenu' && empty($cancel) && $user->hasRight("modulebuilder", "run")) {
2829 // check if module is enabled
2830 if (isModEnabled(strtolower($module))) {
2831 $result = unActivateModule(strtolower($module));
2832 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
2833 if ($result) {
2834 setEventMessages($result, null, 'errors');
2835 }
2836 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2837 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2838 exit;
2839 }
2840 $error = 0;
2841
2842 // load class and check if right exist
2843 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2844 dol_include_once($pathtofile);
2845 $class = 'mod'.$module;
2846 $moduleobj = null;
2847 if (class_exists($class)) {
2848 try {
2849 $moduleobj = new $class($db);
2850 '@phan-var-force DolibarrModules $moduleobj';
2852 } catch (Exception $e) {
2853 $error++;
2854 dol_print_error($db, $e->getMessage());
2855 }
2856 }
2857 // get all menus
2858 $menus = $moduleobj->menu;
2859
2860 //verify fields required
2861 if (!GETPOST('type', 'alpha')) {
2862 $error++;
2863 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors');
2864 }
2865 if (!GETPOST('titre', 'alpha')) {
2866 $error++;
2867 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Title")), null, 'errors');
2868 }
2869 if (!GETPOST('user', 'alpha')) {
2870 $error++;
2871 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DetailUser")), null, 'errors');
2872 }
2873 if (!GETPOST('url', 'alpha')) {
2874 $error++;
2875 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Url")), null, 'errors');
2876 }
2877 if (!empty(GETPOST('target'))) {
2878 $targets = array('_blank','_self','_parent','_top','');
2879 if (!in_array(GETPOST('target'), $targets)) {
2880 $error++;
2881 setEventMessages($langs->trans("ErrorFieldValue", $langs->transnoentities("target")), null, 'errors');
2882 }
2883 }
2884
2885
2886 // check if title or url already exist in menus
2887
2888 foreach ($menus as $menu) {
2889 if (!empty(GETPOST('url')) && GETPOST('url') == $menu['url']) {
2890 $error++;
2891 setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentities("url")), null, 'errors');
2892 break;
2893 }
2894 if (strtolower(GETPOST('titre')) == strtolower($menu['titre'])) {
2895 $error++;
2896 setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentities("titre")), null, 'errors');
2897 break;
2898 }
2899 }
2900
2901 if (GETPOST('type', 'alpha') == 'left' && !empty(GETPOST('lefmenu', 'alpha'))) {
2902 if (!str_contains(GETPOST('leftmenu'), strtolower($module))) {
2903 $error++;
2904 setEventMessages($langs->trans("WarningFieldsMustContains", $langs->transnoentities("LeftmenuId")), null, 'errors');
2905 }
2906 }
2907 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
2908 $destdir = $dirins.'/'.strtolower($module);
2909 $objects = dolGetListOfObjectClasses($destdir);
2910
2911 if (GETPOST('type', 'alpha') == 'left') {
2912 if (empty(GETPOST('leftmenu')) && count($objects) > 0) {
2913 $error++;
2914 setEventMessages($langs->trans("ErrorCoherenceMenu", $langs->transnoentities("LeftmenuId"), $langs->transnoentities("type")), null, 'errors');
2915 }
2916 }
2917 if (GETPOST('type', 'alpha') == 'top') {
2918 $error++;
2919 setEventMessages($langs->trans("ErrorTypeMenu", $langs->transnoentities("type")), null, 'errors');
2920 }
2921
2922 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2923 if (!$error) {
2924 //stock forms in array
2925 $menuToAdd = array(
2926 'fk_menu' => GETPOST('fk_menu', 'alpha'),
2927 'type' => GETPOST('type', 'alpha'),
2928 'titre' => ucfirst(GETPOST('titre', 'alpha')),
2929 'prefix' => '',
2930 'mainmenu' => GETPOST('mainmenu', 'alpha'),
2931 'leftmenu' => GETPOST('leftmenu', 'alpha'),
2932 'url' => GETPOST('url', 'alpha'),
2933 'langs' => strtolower($module)."@".strtolower($module),
2934 'position' => '',
2935 'enabled' => GETPOST('enabled', 'alpha'),
2936 'perms' => '$user->hasRight("'.strtolower($module).'", "'.GETPOST('objects', 'alpha').'", "'.GETPOST('perms', 'alpha').'")',
2937 'target' => GETPOST('target', 'alpha'),
2938 'user' => GETPOSTINT('user'),
2939 );
2940
2941 if (GETPOST('type') == 'left') {
2942 unset($menuToAdd['prefix']);
2943 if (empty(GETPOST('fk_menu'))) {
2944 $menuToAdd['fk_menu'] = 'fk_mainmenu='.GETPOST('mainmenu', 'alpha');
2945 } else {
2946 $menuToAdd['fk_menu'] = 'fk_mainmenu='.GETPOST('mainmenu', 'alpha').',fk_leftmenu='.GETPOST('fk_menu');
2947 }
2948 }
2949 if (GETPOST('enabled') == '1') {
2950 $menuToAdd['enabled'] = 'isModEnabled("'.strtolower($module).'")';
2951 } else {
2952 $menuToAdd['enabled'] = "0";
2953 }
2954 if (empty(GETPOST('objects'))) {
2955 $menuToAdd['perms'] = '1';
2956 }
2957
2958 $checkcomment = checkExistComment($moduledescriptorfile, 0);
2959 if ($checkcomment < 0) {
2960 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), "mod".$module."class.php"), null, 'warnings');
2961 } else {
2962 // Write all menus
2963 $result = reWriteAllMenus($moduledescriptorfile, $menus, $menuToAdd, null, 1);
2964
2965 clearstatcache(true);
2966 if (function_exists('opcache_invalidate')) {
2967 opcache_reset();
2968 }
2969 /*if ($result < 0) {
2970 setEventMessages($langs->trans('ErrorMenuExistValue'), null, 'errors');
2971 header("Location: ".$_SERVER["PHP_SELF"].'?action=editmenu&token='.newToken().'&menukey='.urlencode($key+1).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.($key+1));
2972 exit;
2973 }*/
2974
2975 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2976 setEventMessages($langs->trans('MenuAddedSuccesfuly'), null);
2977 exit;
2978 }
2979 }
2980}
2981
2982// Modify a menu entry
2983if ($dirins && $action == "update_menu" && GETPOSTINT('menukey') && GETPOST('tabobj') && $user->hasRight("modulebuilder", "run")) {
2984 $objectname = GETPOST('tabobj');
2985 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
2986 $destdir = $dirins.'/'.strtolower($module);
2987 $objects = dolGetListOfObjectClasses($destdir);
2988
2989 if (empty($cancel)) {
2990 if (isModEnabled(strtolower($module))) {
2991 $result = unActivateModule(strtolower($module));
2992 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
2993 if ($result) {
2994 setEventMessages($result, null, 'errors');
2995 }
2996 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2997 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2998 exit;
2999 }
3000 $error = 0;
3001 // for loading class and the menu wants to modify
3002 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
3003 dol_include_once($pathtofile);
3004 $class = 'mod'.$module;
3005 $moduleobj = null;
3006 if (class_exists($class)) {
3007 try {
3008 $moduleobj = new $class($db);
3009 '@phan-var-force DolibarrModules $moduleobj';
3011 } catch (Exception $e) {
3012 $error++;
3013 dol_print_error($db, $e->getMessage());
3014 }
3015 }
3016 $menus = $moduleobj->menu;
3017 $key = GETPOSTINT('menukey') - 1;
3018
3019 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
3020 //stock forms in array
3021 $menuModify = array(
3022 'fk_menu' => GETPOST('fk_menu', 'alpha'),
3023 'type' => GETPOST('type', 'alpha'),
3024 'titre' => ucfirst(GETPOST('titre', 'alpha')),
3025 'prefix' => '',
3026 'mainmenu' => GETPOST('mainmenu', 'alpha'),
3027 'leftmenu' => $menus[$key]['leftmenu'],
3028 'url' => GETPOST('url', 'alpha'),
3029 'langs' => strtolower($module)."@".strtolower($module),
3030 'position' => '',
3031 'enabled' => GETPOST('enabled', 'alpha'),
3032 'perms' => GETPOST('perms', 'alpha'),
3033 'target' => GETPOST('target', 'alpha'),
3034 'user' => GETPOSTINT('user'),
3035 );
3036 if (!empty(GETPOST('fk_menu')) && GETPOST('fk_menu') != $menus[$key]['fk_menu']) {
3037 $menuModify['fk_menu'] = 'fk_mainmenu='.GETPOST('mainmenu').',fk_leftmenu='.GETPOST('fk_menu');
3038 } elseif (GETPOST('fk_menu') == $menus[$key]['fk_menu']) {
3039 $menuModify['fk_menu'] = $menus[$key]['fk_menu'];
3040 } else {
3041 $menuModify['fk_menu'] = 'fk_mainmenu='.GETPOST('mainmenu');
3042 }
3043 if ($menuModify['enabled'] === '') {
3044 $menuModify['enabled'] = '1';
3045 }
3046 if ($menuModify['perms'] === '') {
3047 $menuModify['perms'] = '1';
3048 }
3049
3050 if (GETPOST('type', 'alpha') == 'top') {
3051 $error++;
3052 setEventMessages($langs->trans("ErrorTypeMenu", $langs->transnoentities("type")), null, 'errors');
3053 }
3054
3055 if (!$error) {
3056 //update menu
3057 $checkComment = checkExistComment($moduledescriptorfile, 0);
3058
3059 if ($checkComment < 0) {
3060 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), "mod".$module."class.php"), null, 'warnings');
3061 } else {
3062 // Write all menus
3063 $result = reWriteAllMenus($moduledescriptorfile, $menus, $menuModify, $key, 2);
3064
3065 clearstatcache(true);
3066 if (function_exists('opcache_invalidate')) {
3067 opcache_reset();
3068 }
3069
3070 if ($result < 0) {
3071 setEventMessages($langs->trans('ErrorMenuExistValue'), null, 'errors');
3072 //var_dump($_SESSION);exit;
3073 header("Location: ".$_SERVER["PHP_SELF"].'?action=editmenu&token='.newToken().'&menukey='.urlencode((string) ($key + 1)).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)).'&tabobj='.($key + 1));
3074 exit;
3075 }
3076
3077 setEventMessages($langs->trans('MenuUpdatedSuccessfuly'), null);
3078 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
3079 exit;
3080 }
3081 }
3082 } else {
3083 $_POST['type'] = ''; // TODO Use a var here and later
3084 $_POST['titre'] = '';
3085 $_POST['fk_menu'] = '';
3086 $_POST['leftmenu'] = '';
3087 $_POST['url'] = '';
3088 }
3089}
3090
3091// update properties description of module
3092if ($dirins && $action == "update_props_module" && !empty(GETPOST('keydescription', 'alpha')) && empty($cancel) && $user->hasRight("modulebuilder", "run")) {
3093 if (isModEnabled(strtolower($module))) {
3094 $result = unActivateModule(strtolower($module));
3095 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
3096 if ($result) {
3097 setEventMessages($result, null, 'errors');
3098 }
3099 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
3100 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
3101 exit;
3102 }
3103 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
3104 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
3105 $modulelogfile = $dirins.'/'.strtolower($module).'/ChangeLog.md';
3106
3107 dol_include_once($pathtofile);
3108
3109 $class = 'mod'.$module;
3110 $moduleobj = null;
3111 if (class_exists($class)) {
3112 try {
3113 $moduleobj = new $class($db);
3114 '@phan-var-force DolibarrModules $moduleobj';
3116 } catch (Exception $e) {
3117 $error++;
3118 dol_print_error($db, $e->getMessage());
3119 }
3120 }
3121
3122 $keydescription = GETPOST('keydescription', 'alpha');
3123 switch ($keydescription) {
3124 case 'desc':
3125 $propertyToUpdate = 'description';
3126 break;
3127 case 'version':
3128 case 'family':
3129 case 'picto':
3130 case 'editor_name':
3131 case 'editor_url':
3132 $propertyToUpdate = $keydescription;
3133 break;
3134 default:
3135 $error = GETPOST('keydescription');
3136 break;
3137 }
3138
3139 if (isset($propertyToUpdate) && !empty(GETPOST('propsmodule'))) {
3140 $newValue = GETPOST('propsmodule');
3141 $lineToReplace = "\t\t\$this->$propertyToUpdate = ";
3142 $newLine = "\t\t\$this->$propertyToUpdate = '$newValue';\n";
3143
3144 //for change version in log file
3145 if ($propertyToUpdate === 'version') {
3146 dolReplaceInFile($modulelogfile, array("## ".$moduleobj->$propertyToUpdate => $newValue));
3147 }
3148
3149 $fileLines = file($moduledescriptorfile);
3150 foreach ($fileLines as &$line) {
3151 if (strpos($line, $lineToReplace) === 0) {
3152 dolReplaceInFile($moduledescriptorfile, array($line => $newLine));
3153 break;
3154 }
3155 }
3156
3157 clearstatcache(true);
3158 if (function_exists('opcache_invalidate')) {
3159 opcache_reset();
3160 }
3161 setEventMessages($langs->trans('PropertyModuleUpdated', $propertyToUpdate), null);
3162 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=description&module='.$module);
3163 exit;
3164 }
3165}
3166
3167
3168/*
3169 * View
3170 */
3171
3172$form = new Form($db);
3173$formadmin = new FormAdmin($db);
3174
3175// Set dir where external modules are installed
3176if (!dol_is_dir($dirins)) {
3177 dol_mkdir($dirins);
3178}
3179$dirins_ok = (dol_is_dir($dirins));
3180
3181$help_url = '';
3182$morejs = array(
3183 '/includes/ace/src/ace.js',
3184 '/includes/ace/src/ext-statusbar.js',
3185 '/includes/ace/src/ext-language_tools.js',
3186 //'/includes/ace/src/ext-chromevox.js'
3187);
3188$morecss = array();
3189
3190llxHeader('', $langs->trans("ModuleBuilder"), $help_url, '', 0, 0, $morejs, $morecss, '', 'classforhorizontalscrolloftabs');
3191
3192
3193$text = $langs->trans("ModuleBuilder");
3194
3195print load_fiche_titre($text, '', 'title_setup');
3196
3197print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'</span>';
3198print '<br class="hideonsmartphone">';
3199
3200//print $textforlistofdirs;
3201//print '<br>';
3202
3203
3204
3205$message = '';
3206if (!$dirins) {
3207 $message = info_admin($langs->trans("ConfFileMustContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT));
3208 $allowfromweb = -1;
3209} else {
3210 if ($dirins_ok) {
3211 if (!is_writable(dol_osencode($dirins))) {
3212 $langs->load("errors");
3213 $message = info_admin($langs->trans("ErrorFailedToWriteInDir", $dirins));
3214 $allowfromweb = 0;
3215 }
3216 } else {
3217 $message = info_admin($langs->trans("NotExistsDirect", $dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample"));
3218 $allowfromweb = 0;
3219 }
3220}
3221if ($message) {
3222 print $message;
3223}
3224
3225//print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'<br>';
3226$infomodulesfound = '<div style="padding: 12px 9px 12px">'.$form->textwithpicto('', $langs->trans("ModuleBuilderDesc3", count($listofmodules)).'<br><br>'.$langs->trans("ModuleBuilderDesc4", $FILEFLAG).'<br>'.$textforlistofdirs).'</div>';
3227
3228
3229
3230$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
3231$allowonlineinstall = true;
3232if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
3233 $allowonlineinstall = false;
3234}
3235if (empty($allowonlineinstall)) {
3236 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
3237 // Show clean message
3238 $message = info_admin($langs->trans('InstallModuleFromWebHasBeenDisabledContactUs'));
3239 } else {
3240 // Show technical message
3241 $message = info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock'), 0, 0, '1', 'warning');
3242 }
3243
3244 print $message;
3245
3246 llxFooter();
3247 exit(0);
3248}
3249
3250
3251// Load module descriptor
3252$error = 0;
3254
3255
3256if (!empty($module) && $module != 'initmodule' && $module != 'deletemodule') {
3257 $modulelowercase = strtolower($module);
3258 $loadclasserrormessage = '';
3259
3260 // Load module
3261 try {
3262 $fullpathdirtodescriptor = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
3263
3264 //throw(new Exception());
3265 dol_include_once($fullpathdirtodescriptor);
3266
3267 $class = 'mod'.$module;
3268 } catch (Throwable $e) { // This is called in PHP 7 only (includes Error and Exception)
3269 $loadclasserrormessage = $e->getMessage()."<br>\n";
3270 $loadclasserrormessage .= 'File: '.$e->getFile()."<br>\n";
3271 $loadclasserrormessage .= 'Line: '.$e->getLine()."<br>\n";
3272 }
3273
3274 $moduleobj = null;
3275 if (class_exists($class)) {
3276 try {
3277 $moduleobj = new $class($db);
3278 '@phan-var-force DolibarrModules $moduleobj';
3280 } catch (Exception $e) {
3281 $error++;
3282 print $e->getMessage();
3283 }
3284 } else {
3285 if (empty($forceddirread)) {
3286 $error++;
3287 }
3288 $langs->load("errors");
3289 print '<!-- ErrorFailedToLoadModuleDescriptorForXXX -->';
3290 print img_warning('').' '.$langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'<br>';
3291 print $loadclasserrormessage;
3292 }
3293}
3294
3295print '<br>';
3296
3297
3298// Tabs for all modules
3299$head = array();
3300$h = 0;
3301
3302$head[$h][0] = $_SERVER["PHP_SELF"].'?module=initmodule';
3303$head[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewModule").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
3304$head[$h][2] = 'initmodule';
3305$h++;
3306
3307$linktoenabledisable = '';
3308
3309if (is_array($listofmodules) && count($listofmodules) > 0) {
3310 // Define $linktoenabledisable
3311 $modulelowercase = strtolower($module);
3312
3313 $param = '';
3314 if ($tab) {
3315 $param .= '&tab='.urlencode($tab);
3316 }
3317 if ($module) {
3318 $param .= '&module='.urlencode($module);
3319 }
3320 if ($tabobj) {
3321 $param .= '&tabobj='.urlencode($tabobj);
3322 }
3323
3324 $urltomodulesetup = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?search_keyword='.urlencode($module).'">'.$langs->trans('Home').'-'.$langs->trans("Setup").'-'.$langs->trans("Modules").'</a>';
3325
3326 // Define $linktoenabledisable to show after module title
3327 if (isModEnabled($modulelowercase)) { // If module is already activated
3328 $linktoenabledisable .= '<a class="reposition asetresetmodule valignmiddle" href="'.$_SERVER["PHP_SELF"].'?id='.$moduleobj->numero.'&action=reset&token='.newToken().'&value=mod'.$module.$param.'">';
3329 $linktoenabledisable .= img_picto($langs->trans("Activated"), 'switch_on', '', 0, 0, 0, '', '', 1);
3330 $linktoenabledisable .= '</a>';
3331
3332 $linktoenabledisable .= $form->textwithpicto('', $langs->trans("Warning").' : '.$langs->trans("ModuleIsLive"), -1, 'warning');
3333
3334 $objMod = $moduleobj;
3335 $backtourlparam = '';
3336 $backtourlparam .= ($backtourlparam ? '&' : '?').'module='.$module; // No urlencode here, done later
3337 if ($tab) {
3338 $backtourlparam .= ($backtourlparam ? '&' : '?').'tab='.$tab; // No urlencode here, done later
3339 }
3340 $backtourl = $_SERVER["PHP_SELF"].$backtourlparam;
3341
3342 $regs = array();
3343 if (is_array($objMod->config_page_url)) {
3344 $i = 0;
3345 foreach ($objMod->config_page_url as $page) {
3346 $urlpage = $page;
3347 if ($i++) {
3348 $linktoenabledisable .= ' <a href="'.$urlpage.'" title="'.$langs->trans($page).'">'.img_picto(ucfirst($page), "setup").'</a>';
3349 // print '<a href="'.$page.'">'.ucfirst($page).'</a>&nbsp;';
3350 } else {
3351 if (preg_match('/^([^@]+)@([^@]+)$/i', $urlpage, $regs)) {
3352 $urltouse = dol_buildpath('/'.$regs[2].'/admin/'.$regs[1], 1);
3353 $linktoenabledisable .= ' <a href="'.$urltouse.(preg_match('/\?/', $urltouse) ? '&' : '?').'save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').'</a>';
3354 } else {
3355 // Case standard admin page (not a page provided by the
3356 // module but a page provided by dolibarr)
3357 $urltouse = DOL_URL_ROOT.'/admin/'.$urlpage;
3358 $linktoenabledisable .= ' <a href="'.$urltouse.(preg_match('/\?/', $urltouse) ? '&' : '?').'save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').'</a>';
3359 }
3360 }
3361 }
3362 } elseif (preg_match('/^([^@]+)@([^@]+)$/i', $objMod->config_page_url, $regs)) {
3363 $linktoenabledisable .= ' &nbsp; <a href="'.dol_buildpath('/'.$regs[2].'/admin/'.$regs[1], 1).'?save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').'</a>';
3364 }
3365 } else {
3366 if (is_object($moduleobj)) {
3367 $linktoenabledisable .= '<a class="reposition asetresetmodule valignmiddle" href="'.$_SERVER["PHP_SELF"].'?id='.$moduleobj->numero.'&action=set&token='.newToken().'&value=mod'.$module.$param.'">';
3368 $linktoenabledisable .= img_picto($langs->trans("ModuleIsNotActive", $urltomodulesetup), 'switch_off', 'style="padding-right: 8px"', 0, 0, 0, '', 'classfortooltip', 1);
3369 $linktoenabledisable .= "</a>\n";
3370 }
3371 }
3372
3373 // Loop to show tab of each module
3374 foreach ($listofmodules as $tmpmodule => $tmpmodulearray) {
3375 $head[$h][0] = $_SERVER["PHP_SELF"].'?module='.$tmpmodulearray['modulenamewithcase'].($forceddirread ? '@'.$dirread : '');
3376 $head[$h][1] = $tmpmodulearray['modulenamewithcase'];
3377 $head[$h][2] = $tmpmodulearray['modulenamewithcase'];
3378
3379 if ($tmpmodulearray['modulenamewithcase'] == $module) {
3380 $head[$h][4] = '<span class="inline-block">'.$linktoenabledisable.'</span>';
3381 }
3382
3383 $h++;
3384 }
3385}
3386
3387$head[$h][0] = $_SERVER["PHP_SELF"].'?module=deletemodule';
3388$head[$h][1] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("DangerZone");
3389$head[$h][2] = 'deletemodule';
3390$h++;
3391
3392
3393print dol_get_fiche_head($head, $module, '', -1, '', 0, $infomodulesfound, '', 8); // Modules
3394
3395if ($module == 'initmodule') {
3396 // New module
3397 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3398 print '<input type="hidden" name="token" value="'.newToken().'">';
3399 print '<input type="hidden" name="action" value="initmodule">';
3400 print '<input type="hidden" name="module" value="initmodule">';
3401
3402 //print '<span class="opacitymedium">'.$langs->trans("ModuleBuilderDesc2", 'conf/conf.php', $newdircustom).'</span><br>';
3403 print '<br>';
3404
3405 print '<div class="tagtable">';
3406
3407 print '<div class="tagtr"><div class="tagtd paddingright">';
3408 print '<span class="opacitymedium">'.$langs->trans("IdModule").'</span>';
3409 print '</div><div class="tagtd">';
3410 print '<input type="text" name="idmodule" class="width75" value="500000" placeholder="'.dol_escape_htmltag($langs->trans("IdModule")).'">';
3411 print '<span class="opacitymedium">';
3412 print ' &nbsp; (';
3413 print dolButtonToOpenUrlInDialogPopup('popup_modules_id', $langs->transnoentitiesnoconv("SeeIDsInUse"), $langs->transnoentitiesnoconv("SeeIDsInUse"), '/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', '', '');
3414 print ' - ';
3415 print '<a href="https://wiki.dolibarr.org/index.php/List_of_modules_id" target="_blank" rel="noopener noreferrer external">'.$langs->trans("SeeReservedIDsRangeHere").'</a>';
3416 print ')';
3417 print '</span>';
3418 print '</div></div>';
3419
3420 print '<div class="tagtr"><div class="tagtd paddingright">';
3421 print '<span class="opacitymedium fieldrequired">'.$langs->trans("ModuleName").'</span>';
3422 print '</div><div class="tagtd">';
3423 print '<input type="text" name="modulename" value="'.dol_escape_htmltag($modulename).'" autofocus>';
3424 print ' '.$form->textwithpicto('', $langs->trans("EnterNameOfModuleDesc"));
3425 print '</div></div>';
3426
3427 print '<div class="tagtr"><div class="tagtd paddingright">';
3428 print '<span class="opacitymedium">'.$langs->trans("Description").'</span>';
3429 print '</div><div class="tagtd">';
3430 print '<input type="text" name="description" value="" class="minwidth500"><br>';
3431 print '</div></div>';
3432
3433 print '<div class="tagtr"><div class="tagtd paddingright">';
3434 print '<span class="opacitymedium">'.$langs->trans("Version").'</span>';
3435 print '</div><div class="tagtd">';
3436 print '<input type="text" name="version" class="width75" value="'.(GETPOSTISSET('version') ? GETPOST('version') : getDolGlobalString('MODULEBUILDER_SPECIFIC_VERSION', '1.0')).'" placeholder="'.dol_escape_htmltag($langs->trans("Version")).'">';
3437 print '</div></div>';
3438
3439 print '<div class="tagtr"><div class="tagtd paddingright">';
3440 print '<span class="opacitymedium">'.$langs->trans("Family").'</span>';
3441 print '</div><div class="tagtd">';
3442 print '<select name="family" id="family" class="minwidth400">';
3443 $arrayoffamilies = array(
3444 'hr' => "ModuleFamilyHr",
3445 'crm' => "ModuleFamilyCrm",
3446 'srm' => "ModuleFamilySrm",
3447 'financial' => 'ModuleFamilyFinancial',
3448 'products' => 'ModuleFamilyProducts',
3449 'projects' => 'ModuleFamilyProjects',
3450 'ecm' => 'ModuleFamilyECM',
3451 'technic' => 'ModuleFamilyTechnic',
3452 'portal' => 'ModuleFamilyPortal',
3453 'interface' => 'ModuleFamilyInterface',
3454 'base' => 'ModuleFamilyBase',
3455 'other' => 'ModuleFamilyOther'
3456 );
3457 foreach ($arrayoffamilies as $key => $value) {
3458 print '<option value="hr"'.($key == getDolGlobalString('MODULEBUILDER_SPECIFIC_FAMILY', 'other') ? ' selected="selected"' : '').' data-html="'.dol_escape_htmltag($langs->trans($value).' <span class="opacitymedium">- '.$key.'</span>').'">'.$langs->trans($value).'</option>';
3459 }
3460 print '</select>';
3461 print ajax_combobox("family");
3462 print '</div></div>';
3463
3464 print '<div class="tagtr"><div class="tagtd paddingright">';
3465 print '<span class="opacitymedium">'.$langs->trans("Picto").'</span>';
3466 print '</div><div class="tagtd">';
3467 print '<input type="text" name="idpicto" value="'.(GETPOSTISSET('idpicto') ? GETPOST('idpicto') : getDolGlobalString('MODULEBUILDER_DEFAULTPICTO', 'fa-file')).'" placeholder="'.dol_escape_htmltag($langs->trans("Picto")).'">';
3468 print $form->textwithpicto('', $langs->trans("Example").': fa-file, fa-globe, ... any font awesome code.<br>Advanced syntax is fa-fakey[_faprefix[_facolor[_fasize]]]');
3469 print '</div></div>';
3470
3471 print '<div class="tagtr"><div class="tagtd paddingright">';
3472 print '<span class="opacitymedium">'.$langs->trans("EditorName").'</span>';
3473 print '</div><div class="tagtd">';
3474 print '<input type="text" name="editorname" value="'.(GETPOSTISSET('editorname') ? GETPOST('editorname') : getDolGlobalString('MODULEBUILDER_SPECIFIC_EDITOR_NAME', $mysoc->name)).'" placeholder="'.dol_escape_htmltag($langs->trans("EditorName")).'"><br>';
3475 print '</div></div>';
3476
3477 print '<div class="tagtr"><div class="tagtd paddingright">';
3478 print '<span class="opacitymedium">'.$langs->trans("EditorUrl").'</span>';
3479 print '</div><div class="tagtd">';
3480 print '<input type="text" name="editorurl" value="'.(GETPOSTISSET('editorurl') ? GETPOST('editorurl') : getDolGlobalString('MODULEBUILDER_SPECIFIC_EDITOR_URL', $mysoc->url)).'" placeholder="'.dol_escape_htmltag($langs->trans("EditorUrl")).'"><br>';
3481 print '</div></div>';
3482
3483 print '<br><input type="submit" class="button" name="create" value="'.dol_escape_htmltag($langs->trans("Create")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
3484 print '</form>';
3485} elseif ($module == 'deletemodule') {
3486 print '<!-- Form to init a module -->'."\n";
3487 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="delete">';
3488 print '<input type="hidden" name="token" value="'.newToken().'">';
3489 print '<input type="hidden" name="action" value="confirm_deletemodule">';
3490 print '<input type="hidden" name="module" value="deletemodule">';
3491
3492 print $langs->trans("EnterNameOfModuleToDeleteDesc").'<br><br>';
3493
3494 print '<input type="text" name="module" placeholder="'.dol_escape_htmltag($langs->trans("ModuleKey")).'" value="" autofocus>';
3495 print '<input type="submit" class="button smallpaddingimp" value="'.$langs->trans("Delete").'"'.($dirins ? '' : ' disabled="disabled"').'>';
3496 print '</form>';
3497} elseif (!empty($module) && isset($modulelowercase)) {
3498 // Tabs for module
3499 if (!$error) {
3500 $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
3501 $destdir = $dirread.'/'.strtolower($module);
3502 $objects = dolGetListOfObjectClasses($destdir);
3503 $diroflang = dol_buildpath($modulelowercase, 0)."/langs";
3504 $countLangs = countItemsInDirectory($diroflang, 2);
3505 $countDictionaries = (!empty($moduleobj->dictionaries) ? count($moduleobj->dictionaries['tabname']) : 0);
3506 $countRights = count($moduleobj->rights);
3507 $countMenus = count($moduleobj->menu);
3508 $countTriggers = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/triggers");
3509 $countWidgets = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/boxes");
3510 $countEmailingSelectors = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/modules/mailings");
3511 $countCss = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/css");
3512 $countJs = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/js");
3513 $countCLI = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/scripts");
3514 $hasDoc = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/doc");
3515 //var_dump($moduleobj->dictionaries);exit;
3516 $head2 = array();
3517 $h = 0;
3518
3519 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=description&module='.$module.($forceddirread ? '@'.$dirread : '');
3520 $head2[$h][1] = $langs->trans("Description");
3521 $head2[$h][2] = 'description';
3522 $h++;
3523
3524 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '');
3525 $head2[$h][1] = ((!is_array($objects) || count($objects) <= 0) ? $langs->trans("Objects") : $langs->trans("Objects").'<span class="marginleftonlyshort badge">'.count($objects)."</span>");
3526 $head2[$h][2] = 'objects';
3527 $h++;
3528
3529 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=languages&module='.$module.($forceddirread ? '@'.$dirread : '');
3530 $head2[$h][1] = ($countLangs <= 0 ? $langs->trans("Languages") : $langs->trans("Languages").'<span class="marginleftonlyshort badge">'.$countLangs."</span>");
3531 $head2[$h][2] = 'languages';
3532 $h++;
3533
3534 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '');
3535 $head2[$h][1] = ($countDictionaries == 0 ? $langs->trans("Dictionaries") : $langs->trans('Dictionaries').'<span class="marginleftonlyshort badge">'.$countDictionaries."</span>");
3536 $head2[$h][2] = 'dictionaries';
3537 $h++;
3538
3539 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=permissions&module='.$module.($forceddirread ? '@'.$dirread : '');
3540 $head2[$h][1] = ($countRights <= 0 ? $langs->trans("Permissions") : $langs->trans("Permissions").'<span class="marginleftonlyshort badge">'.$countRights."</span>");
3541 $head2[$h][2] = 'permissions';
3542 $h++;
3543
3544 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=tabs&module='.$module.($forceddirread ? '@'.$dirread : '');
3545 $head2[$h][1] = $langs->trans("Tabs");
3546 $head2[$h][2] = 'tabs';
3547 $h++;
3548
3549 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=menus&module='.$module.($forceddirread ? '@'.$dirread : '');
3550 $head2[$h][1] = ($countMenus <= 0 ? $langs->trans("Menus") : $langs->trans("Menus").'<span class="marginleftonlyshort badge">'.$countMenus."</span>");
3551 $head2[$h][2] = 'menus';
3552 $h++;
3553
3554 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=hooks&module='.$module.($forceddirread ? '@'.$dirread : '');
3555 $head2[$h][1] = $langs->trans("Hooks");
3556 $head2[$h][2] = 'hooks';
3557 $h++;
3558
3559 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=triggers&module='.$module.($forceddirread ? '@'.$dirread : '');
3560 $head2[$h][1] = ($countTriggers <= 0 ? $langs->trans("Triggers") : $langs->trans("Triggers").'<span class="marginleftonlyshort badge">'.$countTriggers."</span>");
3561 $head2[$h][2] = 'triggers';
3562 $h++;
3563
3564 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=widgets&module='.$module.($forceddirread ? '@'.$dirread : '');
3565 $head2[$h][1] = ($countWidgets <= 0 ? $langs->trans("Widgets") : $langs->trans("Widgets").'<span class="marginleftonlyshort badge">'.$countWidgets."</span>");
3566 $head2[$h][2] = 'widgets';
3567 $h++;
3568
3569 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=emailings&module='.$module.($forceddirread ? '@'.$dirread : '');
3570 $head2[$h][1] = ($countEmailingSelectors <= 0 ? $langs->trans("EmailingSelectors") : $langs->trans("EmailingSelectors").'<span class="marginleftonlyshort badge">'.$countEmailingSelectors."</span>");
3571 $head2[$h][2] = 'emailings';
3572 $h++;
3573
3574 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=exportimport&module='.$module.($forceddirread ? '@'.$dirread : '');
3575 $head2[$h][1] = $langs->trans("Export").'-'.$langs->trans("Import");
3576 $head2[$h][2] = 'exportimport';
3577 $h++;
3578
3579 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=css&module='.$module.($forceddirread ? '@'.$dirread : '');
3580 $head2[$h][1] = ($countCss <= 0 ? $langs->trans("CSS") : $langs->trans("CSS")." (".$countCss.")");
3581 $head2[$h][2] = 'css';
3582 $h++;
3583
3584 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=js&module='.$module.($forceddirread ? '@'.$dirread : '');
3585 $head2[$h][1] = ($countJs <= 0 ? $langs->trans("JS") : $langs->trans("JS").'<span class="marginleftonlyshort badge">'.$countJs."</span>");
3586 $head2[$h][2] = 'js';
3587 $h++;
3588
3589 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=cli&module='.$module.($forceddirread ? '@'.$dirread : '');
3590 $head2[$h][1] = ($countCLI <= 0 ? $langs->trans("CLI") : $langs->trans("CLI").'<span class="marginleftonlyshort badge">'.$countCLI."</span>");
3591 $head2[$h][2] = 'cli';
3592 $h++;
3593
3594 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=cron&module='.$module.($forceddirread ? '@'.$dirread : '');
3595 $head2[$h][1] = $langs->trans("CronList");
3596 $head2[$h][2] = 'cron';
3597 $h++;
3598
3599 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=specifications&module='.$module.($forceddirread ? '@'.$dirread : '');
3600 $head2[$h][1] = ($hasDoc <= 0 ? $langs->trans("Documentation") : $langs->trans("Documentation").'<span class="paddingleft badge">'.$hasDoc."</span>");
3601 $head2[$h][2] = 'specifications';
3602 $h++;
3603
3604 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=buildpackage&module='.$module.($forceddirread ? '@'.$dirread : '');
3605 $head2[$h][1] = $langs->trans("BuildPackage");
3606 $head2[$h][2] = 'buildpackage';
3607 $h++;
3608
3609 $MAXTABFOROBJECT = 15;
3610
3611 print '<!-- Section for a given module -->';
3612
3613 // Note module is inside $dirread
3614
3615 if ($tab == 'description') {
3616 print '<!-- tab=description -->'."\n";
3617 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
3618 $pathtofilereadme = $modulelowercase.'/README.md';
3619 $pathtochangelog = $modulelowercase.'/ChangeLog.md';
3620
3621 $realpathofmodule = realpath($dirread.'/'.$modulelowercase);
3622
3623 if ($action != 'editfile' || empty($file)) {
3624 $morehtmlright = '';
3625 if ($realpathofmodule != $dirread.'/'.$modulelowercase) {
3626 $morehtmlright = '<div style="padding: 12px 9px 12px">'.$form->textwithpicto('', '<span class="opacitymedium">'.$langs->trans("RealPathOfModule").' :</span> <strong class="wordbreak">'.$realpathofmodule.'</strong>').'</div>';
3627 }
3628
3629 print dol_get_fiche_head($head2, $tab, '', -1, '', 0, $morehtmlright, '', $MAXTABFOROBJECT, 'formodulesuffix'); // Description - level 2
3630
3631 print '<span class="opacitymedium">'.$langs->trans("ModuleBuilderDesc".$tab).'</span>';
3632 print '<br><br>';
3633
3634 print '<table>';
3635
3636 print '<tr><td>';
3637 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
3638 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=DESCRIPTION_FLAG">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
3639 print '</td></tr>';
3640
3641 // List of setup pages
3642 $listofsetuppages = dol_dir_list($realpathofmodule.'/admin', 'files', 0, '\.php$');
3643 foreach ($listofsetuppages as $setuppage) {
3644 //var_dump($setuppage);
3645 print '<tr><td>';
3646 print '<span class="fa fa-file"></span> ';
3647 if ($setuppage['relativename'] == 'about.php') {
3648 print $langs->trans("AboutFile");
3649 } else {
3650 print $langs->trans("SetupFile");
3651 }
3652 print ' : ';
3653 print '<strong class="wordbreak bold"><a href="'.dol_buildpath($modulelowercase.'/admin/'.$setuppage['relativename'], 1).'" target="_test">'.$modulelowercase.'/admin/'.$setuppage['relativename'].'</a></strong>';
3654 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($modulelowercase.'/admin/'.$setuppage['relativename']).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
3655 print '</td></tr>';
3656 }
3657
3658 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("ReadmeFile").' : <strong class="wordbreak">'.$pathtofilereadme.'</strong>';
3659 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=markdown&file='.urlencode($pathtofilereadme).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
3660 print '</td></tr>';
3661
3662 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("ChangeLog").' : <strong class="wordbreak">'.$pathtochangelog.'</strong>';
3663 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=markdown&file='.urlencode($pathtochangelog).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
3664 print '</td></tr>';
3665
3666 print '</table>';
3667 print '<br>';
3668
3669 print load_fiche_titre($form->textwithpicto($langs->trans("DescriptorFile"), $langs->transnoentitiesnoconv("File").' '.$pathtofile), '', '');
3670
3671 if (is_object($moduleobj)) {
3672 print '<div class="underbanner clearboth"></div>';
3673 print '<div class="fichecenter">';
3674 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3675 print '<input type="hidden" name="token" value="'.newToken().'">';
3676 print '<input type="hidden" name="action" value="update_props_module">';
3677 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
3678 print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
3679 print '<input type="hidden" name="keydescription" value="'.dol_escape_htmltag(GETPOST('keydescription', 'alpha')).'">';
3680 print '<table class="border centpercent">';
3681 print '<tr class="liste_titre"><td class="titlefield">';
3682 print $langs->trans("Parameter");
3683 print '</td><td>';
3684 print $langs->trans("Value");
3685 print '</td></tr>';
3686
3687 print '<tr><td>';
3688 print $langs->trans("IdModule");
3689 print '</td><td>';
3690 print $moduleobj->numero;
3691 print '<span class="opacitymedium">';
3692 print ' &nbsp; (';
3693 print dolButtonToOpenUrlInDialogPopup('popup_modules_id', $langs->transnoentitiesnoconv("SeeIDsInUse"), $langs->transnoentitiesnoconv("SeeIDsInUse"), '/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', '', '');
3694 print ' - <a href="https://wiki.dolibarr.org/index.php/List_of_modules_id" target="_blank" rel="noopener noreferrer external">'.$langs->trans("SeeReservedIDsRangeHere").'</a>)';
3695 print '</span>';
3696 print '</td></tr>';
3697
3698 print '<tr><td>';
3699 print $langs->trans("ModuleName");
3700 print '</td><td>';
3701 print $moduleobj->getName();
3702 print '</td></tr>';
3703
3704 print '<tr><td>';
3705 print $langs->trans("Description");
3706 print '</td><td>';
3707 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'desc') {
3708 print '<input class="minwidth500" name="propsmodule" value="'.dol_escape_htmltag($moduleobj->description).'">';
3709 print '<input class="reposition button smallpaddingimp" type="submit" name="modifydesc" value="'.$langs->trans("Modify").'"/>';
3710 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3711 } else {
3712 print $moduleobj->description;
3713 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=edit_moduledescription&token='.newToken().'&tab='.urlencode($tab).'&module='.urlencode($module).'&keydescription=desc">'.img_edit().'</a>';
3714
3715 $moduledescritpionautotrans = $moduleobj->getDesc();
3716 if ($moduledescritpionautotrans != "Module".$moduleobj->name."Desc") {
3717 // $moduledescritpionautotrans has been found into a translation file
3718 print ' '.$form->textwithpicto('', $langs->trans("ModuleTranslatedIntoLangForKeyInto", "Module".$moduleobj->name."Desc", $moduledescritpionautotrans));
3719 } elseif ($moduledescritpionautotrans != "Module".$moduleobj->numero."Desc") {
3720 // $moduledescritpionautotrans has been found into a translation file
3721 print ' '.$form->textwithpicto('', $langs->trans("ModuleTranslatedIntoLangForKeyInto", "Module".$moduleobj->numero."Desc", $moduledescritpionautotrans));
3722 }
3723 }
3724 print '</td></tr>';
3725
3726 print '<tr><td>';
3727 print $langs->trans("Version");
3728 print '</td><td>';
3729 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'version') {
3730 print '<input name="propsmodule" value="'.dol_escape_htmltag($moduleobj->getVersion()).'">';
3731 print '<input class="reposition button smallpaddingimp" type="submit" name="modifyversion" value="'.$langs->trans("Modify").'"/>';
3732 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3733 } else {
3734 print $moduleobj->getVersion();
3735 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=edit_moduledescription&token='.newToken().'&tab='.urlencode($tab).'&module='.urlencode($module).'&keydescription=version">'.img_edit().'</a>';
3736 }
3737 print '</td></tr>';
3738
3739 print '<tr><td>';
3740 print $langs->trans("Family");
3741 //print "<br>'crm','financial','hr','projects','products','ecm','technic','interface','other'";
3742 print '</td><td>';
3743 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'family') {
3744 print '<select name="propsmodule" id="family" class="minwidth400">';
3745 $arrayoffamilies = array(
3746 'hr' => "ModuleFamilyHr",
3747 'crm' => "ModuleFamilyCrm",
3748 'srm' => "ModuleFamilySrm",
3749 'financial' => 'ModuleFamilyFinancial',
3750 'products' => 'ModuleFamilyProducts',
3751 'projects' => 'ModuleFamilyProjects',
3752 'ecm' => 'ModuleFamilyECM',
3753 'technic' => 'ModuleFamilyTechnic',
3754 'portal' => 'ModuleFamilyPortal',
3755 'interface' => 'ModuleFamilyInterface',
3756 'base' => 'ModuleFamilyBase',
3757 'other' => 'ModuleFamilyOther'
3758 );
3759 print '<option value="'.$moduleobj->family.'" data-html="'.dol_escape_htmltag($langs->trans($arrayoffamilies[$moduleobj->family]).' <span class="opacitymedium">- '.$moduleobj->family.'</span>').'">'.$langs->trans($arrayoffamilies[$moduleobj->family]).'</option>';
3760 foreach ($arrayoffamilies as $key => $value) {
3761 if ($key != $moduleobj->family) {
3762 print '<option value="'.$key.'" data-html="'.dol_escape_htmltag($langs->trans($value).' <span class="opacitymedium">- '.$key.'</span>').'">'.$langs->trans($value).'</option>';
3763 }
3764 }
3765 print '</select>';
3766 print '<input class="reposition button smallpaddingimp" type="submit" name="modifyfamily" value="'.$langs->trans("Modify").'"/>';
3767 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3768 } else {
3769 print $moduleobj->family;
3770 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=edit_moduledescription&token='.newToken().'&tab='.urlencode($tab).'&module='.urlencode($module).'&keydescription=family">'.img_edit().'</a>';
3771 }
3772 print '</td></tr>';
3773
3774 print '<tr><td>';
3775 print $langs->trans("Picto");
3776 print '</td><td>';
3777 if ($action == 'edit_modulepicto' && GETPOST('keydescription', 'alpha') === 'picto') {
3778 print '<input class="minwidth500" name="propsmodule" value="'.dol_escape_htmltag($moduleobj->picto).'">';
3779 print '<input class="reposition button smallpaddingimp" type="submit" name="modifypicto" value="'.$langs->trans("Modify").'"/>';
3780 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3781 } else {
3782 print $moduleobj->picto;
3783 print ' &nbsp; '.img_picto('', $moduleobj->picto, 'class="valignmiddle pictomodule paddingrightonly"');
3784 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=edit_modulepicto&token='.newToken().'&tab='.urlencode($tab).'&module='.urlencode($module).'&keydescription=picto">'.img_edit().'</a>';
3785 }
3786 print '</td></tr>';
3787
3788 print '<tr><td>';
3789 print $langs->trans("EditorName");
3790 print '</td><td>';
3791 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'editor_name') {
3792 print '<input name="propsmodule" value="'.dol_escape_htmltag($moduleobj->editor_name).'">';
3793 print '<input class="reposition button smallpaddingimp" type="submit" name="modifyname" value="'.$langs->trans("Modify").'"/>';
3794 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3795 } else {
3796 print $moduleobj->editor_name;
3797 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=edit_moduledescription&token='.newToken().'&tab='.urlencode($tab).'&module='.urlencode($module).'&keydescription=editor_name">'.img_edit().'</a>';
3798 }
3799 print '</td></tr>';
3800
3801 print '<tr><td>';
3802 print $langs->trans("EditorUrl");
3803 print '</td><td>';
3804 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'editor_url') {
3805 print '<input name="propsmodule" value="'.dol_escape_htmltag($moduleobj->editor_url).'">';
3806 print '<input class="reposition button smallpaddingimp" type="submit" name="modifyeditorurl" value="'.$langs->trans("Modify").'"/>';
3807 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3808 } else {
3809 if (!empty($moduleobj->editor_url)) {
3810 print '<a href="'.$moduleobj->editor_url.'" target="_blank" rel="noopener">'.$moduleobj->editor_url.' '.img_picto('', 'globe').'</a>';
3811 }
3812 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=edit_moduledescription&token='.newToken().'&tab='.urlencode($tab).'&module='.urlencode($module).'&keydescription=editor_url">'.img_edit().'</a>';
3813 }
3814 print '</td></tr>';
3815
3816 print '</table>';
3817 print '</form>';
3818 } else {
3819 print $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'<br>';
3820 }
3821
3822 if (!empty($moduleobj)) {
3823 print '<br><br>';
3824
3825 // Readme file
3826 print load_fiche_titre($form->textwithpicto($langs->trans("ReadmeFile"), $langs->transnoentitiesnoconv("File").' '.$pathtofilereadme), '', '');
3827
3828 print '<!-- readme file -->';
3829 if (dol_is_file($dirread.'/'.$pathtofilereadme)) {
3830 print '<div class="underbanner clearboth"></div><div class="fichecenter">'.$moduleobj->getDescLong().'</div>';
3831 } else {
3832 print '<span class="opacitymedium">'.$langs->trans("ErrorFileNotFound", $pathtofilereadme).'</span>';
3833 }
3834
3835 print '<br><br>';
3836
3837 // ChangeLog
3838 print load_fiche_titre($form->textwithpicto($langs->trans("ChangeLog"), $langs->transnoentitiesnoconv("File").' '.$pathtochangelog), '', '');
3839
3840 print '<!-- changelog file -->';
3841 if (dol_is_file($dirread.'/'.$pathtochangelog)) {
3842 print '<div class="underbanner clearboth"></div><div class="fichecenter">'.$moduleobj->getChangeLog().'</div>';
3843 } else {
3844 print '<span class="opacitymedium">'.$langs->trans("ErrorFileNotFound", $pathtochangelog).'</span>';
3845 }
3846 }
3847
3848 print dol_get_fiche_end();
3849 } else { // Edit text file
3850 $fullpathoffile = dol_buildpath($file, 0, 1); // Description - level 2
3851
3852 if ($fullpathoffile) {
3853 $content = file_get_contents($fullpathoffile);
3854 }
3855
3856 // New module
3857 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3858 print '<input type="hidden" name="token" value="'.newToken().'">';
3859 print '<input type="hidden" name="action" value="savefile">';
3860 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
3861 print '<input type="hidden" name="tab" value="'.$tab.'">';
3862 print '<input type="hidden" name="module" value="'.$module.'">';
3863
3864 print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', 0, 'formodulesuffix');
3865
3866 $posCursor = (empty($find)) ? array() : array('find' => $find);
3867 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
3868 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
3869
3870 print dol_get_fiche_end();
3871
3872 print '<center>';
3873 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
3874 print ' &nbsp; ';
3875 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
3876 print '</center>';
3877
3878 print '</form>';
3879 }
3880 } else {
3881 print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', $MAXTABFOROBJECT, 'formodulesuffix'); // Level 2
3882 }
3883
3884 if ($tab == 'languages') {
3885 print '<!-- tab=languages -->'."\n";
3886 if ($action != 'editfile' || empty($file)) {
3887 print '<span class="opacitymedium">'.$langs->trans("LanguageDefDesc").'</span><br>';
3888 print '<br>';
3889
3890
3891 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3892 print '<input type="hidden" name="token" value="'.newToken().'">';
3893 print '<input type="hidden" name="action" value="addlanguage">';
3894 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
3895 print '<input type="hidden" name="tab" value="'.$tab.'">';
3896 print '<input type="hidden" name="module" value="'.$module.'">';
3897 print $formadmin->select_language(getDolGlobalString('MAIN_LANG_DEFAULT'), 'newlangcode', 0, array(), 1, 0, 0, 'minwidth300', 1);
3898 print '<input type="submit" name="addlanguage" class="button smallpaddingimp" value="'.dol_escape_htmltag($langs->trans("AddLanguageFile")).'"><br>';
3899 print '</form>';
3900
3901 print '<br>';
3902 print '<br>';
3903
3904 $modulelowercase = strtolower($module);
3905
3906 // Dir for module
3907 $diroflang = dol_buildpath($modulelowercase, 0);
3908 $diroflang .= '/langs';
3909 $langfiles = dol_dir_list($diroflang, 'files', 1, '\.lang$');
3910
3911 if (!preg_match('/custom/', $dirread)) {
3912 // If this is not a module into custom
3913 $diroflang = $dirread;
3914 $diroflang .= '/langs';
3915 $langfiles = dol_dir_list($diroflang, 'files', 1, $modulelowercase.'\.lang$');
3916 }
3917
3918 print '<table class="none">';
3919 foreach ($langfiles as $langfile) {
3920 $pathtofile = $modulelowercase.'/langs/'.$langfile['relativename'];
3921 if (!preg_match('/custom/', $dirread)) { // If this is not a module into custom
3922 $pathtofile = 'langs/'.$langfile['relativename'];
3923 }
3924 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("LanguageFile").' '.basename(dirname($pathtofile)).' : <strong class="wordbreak">'.$pathtofile.'</strong>';
3925 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=ini&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
3926 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
3927 print '</td>';
3928 }
3929 print '</table>';
3930 } else {
3931 // Edit text language file
3932
3933 //print $langs->trans("UseAsciiDocFormat").'<br>';
3934
3935 $fullpathoffile = dol_buildpath($file, 0);
3936
3937 $content = file_get_contents($fullpathoffile);
3938
3939 // New module
3940 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3941 print '<input type="hidden" name="token" value="'.newToken().'">';
3942 print '<input type="hidden" name="action" value="savefile">';
3943 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
3944 print '<input type="hidden" name="tab" value="'.$tab.'">';
3945 print '<input type="hidden" name="module" value="'.$module.'">';
3946
3947 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
3948 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'text'));
3949 print '<br>';
3950 print '<center>';
3951 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
3952 print ' &nbsp; ';
3953 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
3954 print '</center>';
3955
3956 print '</form>';
3957 }
3958 }
3959
3960 if ($tab == 'objects') {
3961 print '<!-- tab=objects -->'."\n";
3962 $head3 = array();
3963 $h = 0;
3964
3965 // Dir for module
3966 $dir = $dirread.'/'.$modulelowercase.'/class';
3967
3968 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj=newobject';
3969 $head3[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewObjectInModulebuilder").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
3970 $head3[$h][2] = 'newobject';
3971 $h++;
3972
3973 // Scan for object class files
3974 $listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$');
3975
3976 $firstobjectname = '';
3977 foreach ($listofobject as $fileobj) {
3978 if (preg_match('/^api_/', $fileobj['name'])) {
3979 continue;
3980 }
3981 if (preg_match('/^actions_/', $fileobj['name'])) {
3982 continue;
3983 }
3984
3985 $tmpcontent = file_get_contents($fileobj['fullname']);
3986 if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
3987 //$objectname = preg_replace('/\.txt$/', '', $fileobj['name']);
3988 $objectname = $reg[1];
3989 if (empty($firstobjectname)) {
3990 $firstobjectname = $objectname;
3991 }
3992 $pictoname = 'generic';
3993 if (preg_match('/\$picto\s*=\s*["\']([^"\']+)["\']/', $tmpcontent, $reg)) {
3994 $pictoname = $reg[1];
3995 }
3996
3997 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname;
3998 $head3[$h][1] = img_picto('', $pictoname, 'class="pictofixedwidth valignmiddle"').$objectname;
3999 $head3[$h][2] = $objectname;
4000 $h++;
4001 }
4002 }
4003
4004 if ($h > 1) {
4005 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj=deleteobject';
4006 $head3[$h][1] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("DangerZone");
4007 $head3[$h][2] = 'deleteobject';
4008 $h++;
4009 }
4010
4011 // If tabobj was not defined, then we check if there is one obj. If yes, we force on it, if no, we will show tab to create new objects.
4012 if ($tabobj == 'newobjectifnoobj') {
4013 if ($firstobjectname) {
4014 $tabobj = $firstobjectname;
4015 } else {
4016 $tabobj = 'newobject';
4017 }
4018 }
4019
4020 print dol_get_fiche_head($head3, $tabobj, '', -1, '', 0, '', '', 0, 'forobjectsuffix'); // Level 3
4021
4022
4023 if ($tabobj == 'newobject') {
4024 // New object tab
4025 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4026 print '<input type="hidden" name="token" value="'.newToken().'">';
4027 print '<input type="hidden" name="action" value="initobject">';
4028 print '<input type="hidden" name="tab" value="objects">';
4029 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
4030
4031 print '<span class="opacitymedium">'.$langs->trans("EnterNameOfObjectDesc").'</span><br><br>';
4032
4033 print '<div class="tagtable">';
4034
4035 print '<div class="tagtr"><div class="tagtd">';
4036 print '<span class="opacitymedium">'.$langs->trans("ObjectKey").'</span> &nbsp; ';
4037 print '</div><div class="tagtd">';
4038 print '<input type="text" name="objectname" maxlength="64" value="'.dol_escape_htmltag(GETPOSTISSET('objectname') ? GETPOST('objectname', 'alpha') : $modulename).'" autofocus>';
4039 print $form->textwithpicto('', $langs->trans("Example").': MyObject, ACamelCaseName, ...');
4040 print '</div></div>';
4041
4042 print '<div class="tagtr"><div class="tagtd">';
4043 print '<span class="opacitymedium">'.$langs->trans("Picto").'</span> &nbsp; ';
4044 print '</div><div class="tagtd">';
4045 print '<input type="text" name="idpicto" value="fa-file" placeholder="'.dol_escape_htmltag($langs->trans("Picto")).'">';
4046 print $form->textwithpicto('', $langs->trans("Example").': fa-file, fa-globe, ... any font awesome code.<br>Advanced syntax is fa-fakey[_faprefix[_facolor[_fasize]]]');
4047 print '</div></div>';
4048
4049 print '<div class="tagtr"><div class="tagtd">';
4050 print '<span class="opacitymedium">'.$langs->trans("DefinePropertiesFromExistingTable").'</span> &nbsp; ';
4051 print '</div><div class="tagtd">';
4052 print '<input type="text" name="initfromtablename" value="'.GETPOST('initfromtablename').'" placeholder="'.$langs->trans("TableName").'">';
4053 print $form->textwithpicto('', $langs->trans("DefinePropertiesFromExistingTableDesc").'<br>'.$langs->trans("DefinePropertiesFromExistingTableDesc2"));
4054 print '</div></div>';
4055
4056 print '</div>';
4057
4058 print '<br>';
4059 print '<input type="checkbox" name="includerefgeneration" id="includerefgeneration" value="includerefgeneration"> <label class="margintoponly" for="includerefgeneration">'.$form->textwithpicto($langs->trans("IncludeRefGeneration"), $langs->trans("IncludeRefGenerationHelp")).'</label><br>';
4060 print '<input type="checkbox" name="includedocgeneration" id="includedocgeneration" value="includedocgeneration"> <label for="includedocgeneration">'.$form->textwithpicto($langs->trans("IncludeDocGeneration"), $langs->trans("IncludeDocGenerationHelp")).'</label><br>';
4061 print '<input type="checkbox" name="generatepermissions" id="generatepermissions" value="generatepermissions"> <label for="generatepermissions">'.$form->textwithpicto($langs->trans("GeneratePermissions"), $langs->trans("GeneratePermissionsHelp")).'</label><br>';
4062 print '<br>';
4063 print '<input type="submit" class="button small" name="create" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
4064 print '<br>';
4065 print '<br>';
4066 /*
4067 print '<br>';
4068 print '<span class="opacitymedium">'.$langs->trans("or").'</span>';
4069 print '<br>';
4070 print '<br>';
4071 //print '<input type="checkbox" name="initfromtablecheck"> ';
4072 print $langs->trans("InitStructureFromExistingTable");
4073 print '<input type="text" name="initfromtablename" value="" placeholder="'.$langs->trans("TableName").'">';
4074 print '<input type="submit" class="button smallpaddingimp" name="createtablearray" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
4075 print '<br>';
4076 */
4077
4078 print '</form>';
4079 } elseif ($tabobj == 'createproperty') {
4080 $attributesUnique = array(
4081 'proplabel' => $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")),
4082 'propname' => $form->textwithpicto($langs->trans("Code"), $langs->trans("PropertyDesc"), 1, 'help', 'extracss', 0, 3, 'propertyhelp'),
4083 'proptype' => $form->textwithpicto($langs->trans("Type"), $langs->trans("TypeOfFieldsHelpIntro").'<br><br>'.$langs->trans("TypeOfFieldsHelp"), 1, 'help', 'extracss', 0, 3, 'typehelp'),
4084 'proparrayofkeyval' => $form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")),
4085 'propnotnull' => $form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")),
4086 'propdefault' => $langs->trans("DefaultValue"),
4087 'propindex' => $langs->trans("DatabaseIndex"),
4088 'propforeignkey' => $form->textwithpicto($langs->trans("ForeignKey"), $langs->trans("ForeignKeyDesc"), 1, 'help', 'extracss', 0, 3, 'foreignkeyhelp'),
4089 'propposition' => $langs->trans("Position"),
4090 'propenabled' => $form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc"), 1, 'help', 'extracss', 0, 3, 'enabledhelp'),
4091 'propvisible' => $form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc").'<br><br>'.$langs->trans("ItCanBeAnExpression"), 1, 'help', 'extracss', 0, 3, 'visiblehelp'),
4092 'propnoteditable' => $langs->trans("NotEditable"),
4093 //'propalwayseditable' => $langs->trans("AlwaysEditable"),
4094 'propsearchall' => $form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")),
4095 'propisameasure' => $form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")),
4096 'propcss' => $langs->trans("CSSClass"),
4097 'propcssview' => $langs->trans("CSSViewClass"),
4098 'propcsslist' => $langs->trans("CSSListClass"),
4099 'prophelp' => $langs->trans("KeyForTooltip"),
4100 'propshowoncombobox' => $langs->trans("ShowOnCombobox"),
4101 //'propvalidate' => $form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")),
4102 'propcomment' => $langs->trans("Comment"),
4103 );
4104 print '<form action="'.$_SERVER["PHP_SELF"].'?tab=objects&module='.urlencode($module).'&tabobj=createproperty&obj='.urlencode(GETPOST('obj')).'" method="POST">';
4105 print '<input type="hidden" name="token" value="'.newToken().'">';
4106 print '<input type="hidden" name="action" value="addproperty">';
4107 print '<input type="hidden" name="tab" value="objects">';
4108 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
4109 print '<input type="hidden" name="obj" value="'.dol_escape_htmltag(GETPOST('obj')).'">';
4110
4111 print '<table class="border centpercent tableforfieldcreate">'."\n";
4112 $counter = 0;
4113 foreach ($attributesUnique as $key => $attribute) {
4114 if ($counter % 2 === 0) {
4115 print '<tr>';
4116 }
4117 if ($key == 'propname' || $key == 'proplabel') {
4118 print '<td class="titlefieldcreate fieldrequired">'.$attribute.'</td><td class="valuefieldcreate maxwidth50"><input class="maxwidth200" id="'.$key.'" type="text" name="'.$key.'" value="'.dol_escape_htmltag(GETPOST($key, 'alpha')).'"></td>';
4119 } elseif ($key == 'proptype') {
4120 print '<td class="titlefieldcreate fieldrequired">'.$attribute.'</td><td class="valuefieldcreate maxwidth50">';
4121 print '<input class="maxwidth200" id="'.$key.'" list="datalist'.$key.'" type="text" name="'.$key.'" value="'.dol_escape_htmltag(GETPOST($key, 'alpha')).'">';
4122 //print '<div id="suggestions"></div>';
4123 print '<datalist id="datalist'.$key.'">';
4124 print '<option>varchar(128)</option>';
4125 print '<option>email</option>';
4126 print '<option>phone</option>';
4127 print '<option>ip</option>';
4128 print '<option>url</option>';
4129 print '<option>password</option>';
4130 print '<option>text</option>';
4131 print '<option>html</option>';
4132 print '<option>date</option>';
4133 print '<option>datetime</option>';
4134 print '<option>integer</option>';
4135 print '<option>stars(5)</option>';
4136 print '<option>double(28,4)</option>';
4137 print '<option>real</option>';
4138 print '<option>integer:ClassName:RelativePath/To/ClassFile.class.php[:1[:FILTER]]</option>';
4139 // Combo with list of fields
4140 /*
4141 if (empty($formadmin)) {
4142 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
4143 $formadmin = new FormAdmin($db);
4144 }
4145 print $formadmin->selectTypeOfFields($key, GETPOST($key, 'alpha'));
4146 */
4147 print '</datalist>';
4148 print '</td>';
4149 //} elseif ($key == 'propvalidate') {
4150 // print '<td class="titlefieldcreate">'.$attribute.'</td><td class="valuefieldcreate maxwidth50"><input type="number" step="1" min="0" max="1" class="text maxwidth100" value="'.dol_escape_htmltag(GETPOST($key, 'alpha')).'"></td>';
4151 } elseif ($key == 'propvisible') {
4152 print '<td class="titlefieldcreate">'.$attribute.'</td><td class="valuefieldcreate"><input class="maxwidth200" type="text" name="'.$key.'" value="'.dol_escape_htmltag(GETPOSTISSET($key) ? GETPOST($key, 'alpha') : "1").'"></td>';
4153 } elseif ($key == 'propenabled') {
4154 //$default = "isModEnabled('".strtolower($module)."')";
4155 $default = 1;
4156 print '<td class="titlefieldcreate">'.$attribute.'</td><td class="valuefieldcreate"><input class="maxwidth200" type="text" name="'.$key.'" value="'.dol_escape_htmltag(GETPOSTISSET($key) ? GETPOST($key, 'alpha') : $default).'"></td>';
4157 } elseif ($key == 'proparrayofkeyval') {
4158 print '<td class="titlefieldcreate tdproparrayofkeyval">'.$attribute.'</td><td class="valuefieldcreate"><textarea class="maxwidth200" name="'.$key.'">'.dol_escape_htmltag(GETPOSTISSET($key) ? GETPOST($key, 'alpha') : "").'</textarea></td>';
4159 } else {
4160 print '<td class="titlefieldcreate">'.$attribute.'</td><td class="valuefieldcreate"><input class="maxwidth200" type="text" name="'.$key.'" value="'.dol_escape_htmltag(GETPOSTISSET($key) ? GETPOST($key, 'alpha') : '').'"></td>';
4161 }
4162 $counter++;
4163 if ($counter % 2 === 0) {
4164 print '</tr>';
4165 }
4166 }
4167 if ($counter % 2 !== 0) {
4168 while ($counter % 2 !== 0) {
4169 print '<td></td>';
4170 $counter++;
4171 }
4172 print '</tr>';
4173 }
4174 print '</table><br>'."\n";
4175 print '<div class="center">';
4176 print '<input type="submit" class="button button-save" name="add" value="' . dol_escape_htmltag($langs->trans('Create')) . '">';
4177 print '<input type="button" class="button button-cancel" name="cancel" value="' . dol_escape_htmltag($langs->trans('Cancel')) . '" onclick="goBack()">';
4178 print '</div>';
4179 print '</form>';
4180 // javascript
4181 print '<script>
4182 function goBack() {
4183 var url = "'.$_SERVER["PHP_SELF"].'?tab=objects&module='.urlencode($module).'";
4184 window.location.href = url;
4185 }
4186 $(document).ready(function() {
4187 $("#proplabel").on("keyup", function() {
4188 console.log("key up on label");
4189 s = cleanString($("#proplabel").val());
4190 $("#propname").val(s);
4191 });
4192
4193 function cleanString( stringtoclean )
4194 {
4195 // allow "a-z", "A-Z", "0-9" and "_"
4196 stringtoclean = stringtoclean.replace(/[^a-z0-9_]+/ig, "");
4197 stringtoclean = stringtoclean.toLowerCase();
4198 if (!isNaN(stringtoclean)) {
4199 return ""
4200 }
4201 while ( stringtoclean.length > 1 && !isNaN( stringtoclean.charAt(0)) ){
4202 stringtoclean = stringtoclean.substr(1)
4203 }
4204 if (stringtoclean.length > 28) {
4205 stringtoclean = stringtoclean.substring(0, 27);
4206 }
4207 return stringtoclean;
4208 }
4209
4210 });';
4211 print '</script>';
4212 } elseif ($tabobj == 'deleteobject') {
4213 // Delete object tab
4214 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4215 print '<input type="hidden" name="token" value="'.newToken().'">';
4216 print '<input type="hidden" name="action" value="confirm_deleteobject">';
4217 print '<input type="hidden" name="tab" value="objects">';
4218 print '<input type="hidden" name="tabobj" value="deleteobject">';
4219 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
4220
4221 print $langs->trans("EnterNameOfObjectToDeleteDesc").'<br><br>';
4222
4223 print '<input type="text" name="objectname" value="" placeholder="'.dol_escape_htmltag($langs->trans("ObjectKey")).'" autofocus>';
4224 print '<input type="submit" class="button smallpaddingimp" name="delete" value="'.dol_escape_htmltag($langs->trans("Delete")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
4225 print '</form>';
4226 } else {
4227 // tabobj = module
4228 if ($action == 'deleteproperty') {
4229 $formconfirm = $form->formconfirm(
4230 $_SERVER["PHP_SELF"].'?propertykey='.urlencode(GETPOST('propertykey', 'alpha')).'&objectname='.urlencode($objectname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj),
4231 $langs->trans('Delete'),
4232 $langs->trans('ConfirmDeleteProperty', GETPOST('propertykey', 'alpha')),
4233 'confirm_deleteproperty',
4234 '',
4235 0,
4236 1
4237 );
4238
4239 // Print form confirm
4240 print $formconfirm;
4241 }
4242 if ($action != 'editfile' || empty($file)) {
4243 try {
4244 //$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
4245
4246 $pathtoclass = strtolower($module).'/class/'.strtolower($tabobj).'.class.php';
4247 $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'.class.php';
4248 $pathtoagenda = strtolower($module).'/'.strtolower($tabobj).'_agenda.php';
4249 $pathtocard = strtolower($module).'/'.strtolower($tabobj).'_card.php';
4250 $pathtodocument = strtolower($module).'/'.strtolower($tabobj).'_document.php';
4251 $pathtolist = strtolower($module).'/'.strtolower($tabobj).'_list.php';
4252 $pathtonote = strtolower($module).'/'.strtolower($tabobj).'_note.php';
4253 $pathtocontact = strtolower($module).'/'.strtolower($tabobj).'_contact.php';
4254 $pathtophpunit = strtolower($module).'/test/phpunit/'.strtolower($tabobj).'Test.php';
4255
4256 // Try to load object class file
4257 clearstatcache(true);
4258 if (function_exists('opcache_invalidate')) {
4259 opcache_invalidate($dirread.'/'.$pathtoclass, true); // remove the include cache hell !
4260 }
4261
4262 if (empty($forceddirread) && empty($dirread)) {
4263 $result = dol_include_once($pathtoclass);
4264 $stringofinclude = "dol_include_once(".$pathtoclass.")";
4265 } else {
4266 $result = include_once $dirread.'/'.$pathtoclass;
4267 $stringofinclude = "@include_once ".$dirread.'/'.$pathtoclass;
4268 }
4269
4270 if (class_exists($tabobj)) {
4271 try {
4272 $tmpobject = @new $tabobj($db);
4273 } catch (Exception $e) {
4274 dol_syslog('Failed to load Constructor of class: '.$e->getMessage(), LOG_WARNING);
4275 }
4276 } else {
4277 print '<span class="warning">'.$langs->trans('Failed to find the class '.$tabobj.' despite the '.$stringofinclude).'</span><br><br>';
4278 }
4279
4280 // Define path for sql file
4281 $pathtosql = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'-'.strtolower($module).'.sql';
4282 $result = dol_buildpath($pathtosql);
4283 if (! dol_is_file($result)) {
4284 $pathtosql = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'.sql';
4285 $result = dol_buildpath($pathtosql);
4286 if (! dol_is_file($result)) {
4287 $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($tabobj).'-'.strtolower($module).'.sql';
4288 $result = dol_buildpath($pathtosql);
4289 if (! dol_is_file($result)) {
4290 $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
4291 $result = dol_buildpath($pathtosql);
4292 if (! dol_is_file($result)) {
4293 $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'.sql';
4294 $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_extrafields.sql';
4295 $result = dol_buildpath($pathtosql);
4296 } else {
4297 $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_extrafields-'.strtolower($module).'.sql';
4298 }
4299 } else {
4300 $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields-'.strtolower($module).'.sql';
4301 }
4302 } else {
4303 $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields.sql';
4304 }
4305 } else {
4306 $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields-'.strtolower($module).'.sql';
4307 }
4308 $pathtosqlroot = preg_replace('/\/llx_.*$/', '', $pathtosql);
4309
4310 $pathtosqlkey = preg_replace('/\.sql$/', '.key.sql', $pathtosql);
4311 $pathtosqlextrakey = preg_replace('/\.sql$/', '.key.sql', $pathtosqlextra);
4312
4313 $pathtolib = strtolower($module).'/lib/'.strtolower($module).'.lib.php';
4314 $pathtoobjlib = strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($tabobj).'.lib.php';
4315
4316 $tmpobject = $tmpobject ?? null; // @phan-suppress-current-line PhanPluginDuplicateExpressionAssignmentOperation
4317 if (is_object($tmpobject) && property_exists($tmpobject, 'picto')) {
4318 $pathtopicto = $tmpobject->picto;
4319 $realpathtopicto = '';
4320 } else {
4321 $pathtopicto = strtolower($module).'/img/object_'.strtolower($tabobj).'.png';
4322 $realpathtopicto = $dirread.'/'.$pathtopicto;
4323 }
4324
4325 //var_dump($pathtoclass);
4326 //var_dump($dirread);
4327 $realpathtoclass = $dirread.'/'.$pathtoclass;
4328 $realpathtoapi = $dirread.'/'.$pathtoapi;
4329 $realpathtoagenda = $dirread.'/'.$pathtoagenda;
4330 $realpathtocard = $dirread.'/'.$pathtocard;
4331 $realpathtodocument = $dirread.'/'.$pathtodocument;
4332 $realpathtolist = $dirread.'/'.$pathtolist;
4333 $realpathtonote = $dirread.'/'.$pathtonote;
4334 $realpathtocontact = $dirread.'/'.$pathtocontact;
4335 $realpathtophpunit = $dirread.'/'.$pathtophpunit;
4336 $realpathtosql = $dirread.'/'.$pathtosql;
4337 $realpathtosqlextra = $dirread.'/'.$pathtosqlextra;
4338 $realpathtosqlkey = $dirread.'/'.$pathtosqlkey;
4339 $realpathtosqlextrakey = $dirread.'/'.$pathtosqlextrakey;
4340 $realpathtolib = $dirread.'/'.$pathtolib;
4341 $realpathtoobjlib = $dirread.'/'.$pathtoobjlib;
4342
4343 if (empty($realpathtoapi)) { // For compatibility with some old modules
4344 $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'s.class.php';
4345 $realpathtoapi = $dirread.'/'.$pathtoapi;
4346 }
4347
4348 $urloflist = dol_buildpath('/'.$pathtolist, 1);
4349 $urlofcard = dol_buildpath('/'.$pathtocard, 1);
4350
4351 $objs = array();
4352
4353 print '<!-- section for object -->';
4354 print '<div class="fichehalfleft smallxxx">';
4355 // Main DAO class file
4356 print '<span class="fa fa-file"></span> '.$langs->trans("ClassFile").' : <strong>'.(dol_is_file($realpathtoclass) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtoclass).(dol_is_file($realpathtoclass) ? '' : '</strike>').'</strong>';
4357 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtoclass).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4358 print '<br>';
4359 // Image
4360 if ($realpathtopicto && dol_is_file($realpathtopicto)) {
4361 print '<span class="fa fa-file-image-o"></span> '.$langs->trans("Image").' : <strong>'.(dol_is_file($realpathtopicto) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtopicto).(dol_is_file($realpathtopicto) ? '' : '</strike>').'</strong>';
4362 //print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtopicto).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4363 print '<br>';
4364 } elseif (!empty($tmpobject)) {
4365 print '<span class="fa fa-file-image-o"></span> '.$langs->trans("Image").' : '.img_picto('', $tmpobject->picto, 'class="pictofixedwidth valignmiddle"').$tmpobject->picto;
4366 print '<br>';
4367 }
4368
4369 // API file
4370 print '<br>';
4371 print '<span class="fa fa-file"></span> '.$langs->trans("ApiClassFile").' : <strong class="wordbreak">'.(dol_is_file($realpathtoapi) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtoapi).(dol_is_file($realpathtoapi) ? '' : '</span></strike>').'</strong>';
4372 if (dol_is_file($realpathtoapi)) {
4373 $file = file_get_contents($realpathtoapi);
4374 if (preg_match('/var '.$tabobj.'\s+([^\s]*)\s/ims', $file, $objs)) {
4375 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4376 print ' ';
4377 print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
4378 print $form->textwithpicto('', $langs->trans("InfoForApiFile"), 1, 'warning');
4379 print ' &nbsp; ';
4380 // Comparing to null (phan considers $modulelowercase can be null here)
4381 if ($modulelowercase !== null && !isModEnabled($modulelowercase)) { // If module is not activated
4382 print '<a href="#" class="classfortooltip" target="apiexplorer" title="'.$langs->trans("ModuleMustBeEnabled", $module).'"><strike>'.$langs->trans("ApiExplorer").'</strike></a>';
4383 } else {
4384 print '<a href="'.DOL_URL_ROOT.'/api/index.php/explorer/" target="apiexplorer">'.$langs->trans("ApiExplorer").'</a>';
4385 }
4386 } else {
4387 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initapi&token='.newToken().'&format=php&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans('AddAPIsForThisObject'), 'generate', 'class="paddingleft"').'</a>';
4388 }
4389 } else {
4390 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initapi&token='.newToken().'&format=php&file='.urlencode($pathtoapi).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
4391 }
4392 // PHPUnit
4393 print '<br>';
4394 print '<span class="fa fa-file"></span> '.$langs->trans("TestClassFile").' : <strong class="wordbreak">'.(dol_is_file($realpathtophpunit) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtophpunit).(dol_is_file($realpathtophpunit) ? '' : '</span></strike>').'</strong>';
4395 if (dol_is_file($realpathtophpunit)) {
4396 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtophpunit).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4397 print ' ';
4398 print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtophpunit).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
4399 } else {
4400 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initphpunit&token='.newToken().'&format=php&file='.urlencode($pathtophpunit).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
4401 }
4402 print '<br>';
4403
4404 print '<br>';
4405
4406 print '<span class="fa fa-file"></span> '.$langs->trans("PageForLib").' : <strong class="wordbreak">'.(dol_is_file($realpathtolib) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtolib).(dol_is_file($realpathtolib) ? '' : '</strike>').'</strong>';
4407 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtolib).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4408 print '<br>';
4409 print '<span class="fa fa-file"></span> '.$langs->trans("PageForObjLib").' : <strong class="wordbreak">'.(dol_is_file($realpathtoobjlib) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtoobjlib).(dol_is_file($realpathtoobjlib) ? '' : '</strike>').'</strong>';
4410 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtoobjlib).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4411 print '<br>';
4412
4413 print '<br>';
4414 print '<span class="fa fa-file"></span> '.$langs->trans("SqlFile").' : <strong class="wordbreak">'.(dol_is_file($realpathtosql) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtosql).(dol_is_file($realpathtosql) ? '' : '</strike>').'</strong>';
4415 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=sql&file='.urlencode($pathtosql).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4416 print ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=droptable&token='.newToken().'">'.$langs->trans("DropTableIfEmpty").'</a>';
4417 //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
4418 print '<br>';
4419 print '<span class="fa fa-file"></span> '.$langs->trans("SqlFileKey").' : <strong class="wordbreak">'.(dol_is_file($realpathtosqlkey) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlkey).(dol_is_file($realpathtosqlkey) ? '' : '</strike>').'</strong>';
4420 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=sql&file='.urlencode($pathtosqlkey).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4421 //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
4422 print '<br>';
4423 print '<span class="fa fa-file"></span> '.$langs->trans("SqlFileExtraFields").' : <strong class="wordbreak">'.(dol_is_file($realpathtosqlextra) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlextra).(dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey) ? '' : '</span></strike>').'</strong>';
4424 if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) {
4425 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&file='.urlencode($pathtosqlextra).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4426 print ' ';
4427 print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtosqlextra).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
4428 print ' &nbsp; ';
4429 print '<a class="reposition editfielda" href="'.$_SERVER["PHP_SELF"].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=droptableextrafields&token='.newToken().'">'.$langs->trans("DropTableIfEmpty").'</a>';
4430 } else {
4431 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initsqlextrafields&token='.newToken().'&format=sql&file='.urlencode($pathtosqlextra).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
4432 }
4433 //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
4434 print '<br>';
4435 print '<span class="fa fa-file"></span> '.$langs->trans("SqlFileKeyExtraFields").' : <strong class="wordbreak">'.(dol_is_file($realpathtosqlextrakey) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlextrakey).(dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey) ? '' : '</span></strike>').'</strong>';
4436 if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) {
4437 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=sql&file='.urlencode($pathtosqlextrakey).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4438 print ' ';
4439 print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtosqlextrakey).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
4440 } else {
4441 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initsqlextrafields&token='.newToken().'&format=sql&file='.urlencode($pathtosqlextra).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
4442 }
4443 print '<br>';
4444 print '</div>';
4445
4446 print '<div class="fichehalfleft smallxxxx">';
4447 print '<span class="fa fa-file"></span> '.$langs->trans("PageForList").' : <strong class="wordbreak"><a href="'.$urloflist.'" target="_test">'.(dol_is_file($realpathtolist) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtolist).(dol_is_file($realpathtolist) ? '' : '</span></strike>').'</a></strong>';
4448 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtolist).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4449 print '<br>';
4450 print '<span class="fa fa-file"></span> '.$langs->trans("PageForCreateEditView").' : <strong class="wordbreak"><a href="'.$urlofcard.'?action=create" target="_test">'.(dol_is_file($realpathtocard) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtocard).(dol_is_file($realpathtocard) ? '' : '</strike>').'?action=create</a></strong>';
4451 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtocard).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4452 print '<br>';
4453 // Page contact
4454 print '<span class="fa fa-file"></span> '.$langs->trans("PageForContactTab").' : <strong class="wordbreak">'.(dol_is_file($realpathtocontact) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtocontact).(dol_is_file($realpathtocontact) ? '' : '</span></strike>').'</strong>';
4455 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4456 if (dol_is_file($realpathtocontact)) {
4457 print ' ';
4458 print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtocontact).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
4459 } else {
4460 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initpagecontact&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
4461 }
4462 print '<br>';
4463 // Page document
4464 print '<span class="fa fa-file"></span> '.$langs->trans("PageForDocumentTab").' : <strong class="wordbreak">'.(dol_is_file($realpathtodocument) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtodocument).(dol_is_file($realpathtodocument) ? '' : '</span></strike>').'</strong>';
4465 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtodocument).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4466 if (dol_is_file($realpathtodocument)) {
4467 print ' ';
4468 print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtodocument).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
4469 } else {
4470 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initpagedocument&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
4471 }
4472 print '<br>';
4473 // Page notes
4474 print '<span class="fa fa-file"></span> '.$langs->trans("PageForNoteTab").' : <strong class="wordbreak">'.(dol_is_file($realpathtonote) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtonote).(dol_is_file($realpathtonote) ? '' : '</span></strike>').'</strong>';
4475 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtonote).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4476 if (dol_is_file($realpathtonote)) {
4477 print ' ';
4478 print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtonote).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
4479 } else {
4480 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initpagenote&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
4481 }
4482 print '<br>';
4483 // Page agenda
4484 print '<span class="fa fa-file"></span> '.$langs->trans("PageForAgendaTab").' : <strong class="wordbreak">'.(dol_is_file($realpathtoagenda) ? '' : '<strike><span class="opacitymedium">').preg_replace('/^'.strtolower($module).'\//', '', $pathtoagenda).(dol_is_file($realpathtoagenda) ? '' : '</span></strike>').'</strong>';
4485 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&format=php&token='.newToken().'&file='.urlencode($pathtoagenda).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4486 if (dol_is_file($realpathtoagenda)) {
4487 print ' ';
4488 print '<a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtoagenda).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
4489 } else {
4490 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initpageagenda&token='.newToken().'&format=php&file='.urlencode($pathtocontact).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
4491 }
4492 print '<br>';
4493 print '<br>';
4494
4495 print '</div>';
4496
4497 print '<br><br><br>';
4498
4499 if (!empty($tmpobject)) {
4500 $reflector = new ReflectionClass($tabobj);
4501 $reflectorproperties = $reflector->getProperties(); // Can also use get_object_vars
4502 $reflectorpropdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars
4503 //$propstat = $reflector->getStaticProperties();
4504 //var_dump($reflectorpropdefault);
4505
4506 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4507 print '<input type="hidden" name="token" value="'.newToken().'">';
4508 print '<input type="hidden" name="action" value="addproperty">';
4509 print '<input type="hidden" name="tab" value="objects">';
4510 print '<input type="hidden" name="page_y" value="">';
4511 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module.($forceddirread ? '@'.$dirread : '')).'">';
4512 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
4513
4514 print '<input class="button smallpaddingimp" type="submit" name="regenerateclasssql" value="'.$langs->trans("RegenerateClassAndSql").'">';
4515 print '<br><br class="clearboth">';
4516 print '<br class="clearboth">';
4517
4518 $mod = strtolower($module);
4519 $obj = strtolower($tabobj);
4520 $newproperty = dolGetButtonTitle($langs->trans('NewProperty'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.urlencode($module).'&tabobj=createproperty&obj='.urlencode($tabobj));
4521 $nbOfProperties = count($reflectorpropdefault['fields']);
4522
4523 print_barre_liste($langs->trans("ObjectProperties"), 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, $nbOfProperties, '', 0, $newproperty, 'margintoponly', 0, 0, 0, 1);
4524
4525 //var_dump($reflectorpropdefault);exit;
4526 print '<!-- Table with properties of object -->'."\n";
4527 print '<div class="div-table-responsive">';
4528 print '<table class="noborder small">';
4529 print '<tr class="liste_titre">';
4530 print '<th class="tdsticky tdstickygray">';
4531 $htmltext = $langs->trans("PropertyDesc").'<br><br><a class="" href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank" rel="noopener noreferrer external">'.$langs->trans("SeeExamples").'</a>';
4532 print $form->textwithpicto($langs->trans("Code"), $htmltext, 1, 'help', 'extracss', 0, 3, 'propertyhelp');
4533 print '</th>';
4534 print '<th>';
4535 print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey"));
4536 print '</th>';
4537 print '<th>'.$form->textwithpicto($langs->trans("Type"), $langs->trans("TypeOfFieldsHelpIntro").'<br><br>'.$langs->trans("TypeOfFieldsHelp"), 1, 'help', 'extracss', 0, 3, 'typehelp').'</th>';
4538 print '<th>'.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).'</th>';
4539 print '<th class="center">'.$form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")).'</th>';
4540 print '<th class="center">'.$langs->trans("DefaultValue").'</th>';
4541 print '<th class="center">'.$langs->trans("DatabaseIndex").'</th>';
4542 print '<th class="center">'.$form->textwithpicto($langs->trans("ForeignKey"), $langs->trans("ForeignKeyDesc"), 1, 'help', 'extracss', 0, 3, 'foreignkeyhelp').'</th>';
4543 print '<th class="right">'.$langs->trans("Position").'</th>';
4544 print '<th class="center">'.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc"), 1, 'help', 'extracss', 0, 3, 'enabledhelp').'</th>';
4545 print '<th class="center">'.$form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc").'<br><br>'.$langs->trans("ItCanBeAnExpression"), 1, 'help', 'extracss', 0, 3, 'visiblehelp').'</th>';
4546 print '<th class="center">'.$langs->trans("NotEditable").'</th>';
4547 //print '<th class="center">'.$langs->trans("AlwaysEditable").'</th>';
4548 print '<th class="center">'.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).'</th>';
4549 print '<th class="center">'.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).'</th>';
4550 print '<th class="center">'.$langs->trans("CSSClass").'</th>';
4551 print '<th class="center">'.$langs->trans("CSSViewClass").'</th>';
4552 print '<th class="center">'.$langs->trans("CSSListClass").'</th>';
4553 print '<th>'.$langs->trans("KeyForTooltip").'</th>';
4554 print '<th class="center">'.$langs->trans("ShowOnCombobox").'</th>';
4555 //print '<th class="center">'.$langs->trans("Disabled").'</th>';
4556 print '<th>'.$form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")).'</th>';
4557 print '<th>'.$langs->trans("Comment").'</th>';
4558 print '<th class="tdstickyright tdstickyghostwhite"></th>';
4559 print '</tr>';
4560
4561 // We must use $reflectorpropdefault['fields'] to get list of fields because $tmpobject->fields may have been
4562 // modified during the constructor and we want value into head of class before constructor is called.
4563 //$properties = dol_sort_array($tmpobject->fields, 'position');
4564 $properties = dol_sort_array($reflectorpropdefault['fields'], 'position');
4565 if (!empty($properties)) {
4566 // List of existing properties
4567 foreach ($properties as $propkey => $propval) {
4568 /* If from Reflection
4569 if ($propval->class == $tabobj)
4570 {
4571 $propname=$propval->getName();
4572 $comment=$propval->getDocComment();
4573 $type=gettype($tmpobject->$propname);
4574 $default=$propdefault[$propname];
4575 // Discard generic properties
4576 if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'ismultientitymanaged'))) continue;
4577
4578 // Keep or not lines
4579 if (in_array($propname, array('fk_element', 'lines'))) continue;
4580 }*/
4581
4582 $propname = $propkey;
4583 $proplabel = $propval['label'];
4584 $proptype = $propval['type'];
4585 $proparrayofkeyval = !empty($propval['arrayofkeyval']) ? $propval['arrayofkeyval'] : '';
4586 $propnotnull = !empty($propval['notnull']) ? $propval['notnull'] : '0';
4587 $propdefault = !empty($propval['default']) ? $propval['default'] : '';
4588 $propindex = !empty($propval['index']) ? $propval['index'] : '';
4589 $propforeignkey = !empty($propval['foreignkey']) ? $propval['foreignkey'] : '';
4590 $propposition = $propval['position'];
4591 $propenabled = $propval['enabled'];
4592 $propvisible = $propval['visible'];
4593 $propnoteditable = !empty($propval['noteditable']) ? $propval['noteditable'] : 0;
4594 //$propalwayseditable = !empty($propval['alwayseditable'])?$propval['alwayseditable']:0;
4595 $propsearchall = !empty($propval['searchall']) ? $propval['searchall'] : 0;
4596 $propisameasure = !empty($propval['isameasure']) ? $propval['isameasure'] : 0;
4597 $propcss = !empty($propval['css']) ? $propval['css'] : '';
4598 $propcssview = !empty($propval['cssview']) ? $propval['cssview'] : '';
4599 $propcsslist = !empty($propval['csslist']) ? $propval['csslist'] : '';
4600 $prophelp = !empty($propval['help']) ? $propval['help'] : '';
4601 $propshowoncombobox = !empty($propval['showoncombobox']) ? $propval['showoncombobox'] : 0;
4602 //$propdisabled=$propval['disabled'];
4603 $propvalidate = !empty($propval['validate']) ? $propval['validate'] : 0;
4604 $propcomment = !empty($propval['comment']) ? $propval['comment'] : '';
4605
4606 print '<!-- line for object property -->'."\n";
4607 print '<tr class="oddeven">';
4608
4609 print '<td class="tdsticky tdstickygray">';
4610 print dol_escape_htmltag($propname);
4611 print '</td>';
4612 if ($action == 'editproperty' && $propname == $propertykey) {
4613 print '<td>';
4614 print '<input type="hidden" name="propname" value="'.dol_escape_htmltag($propname).'">';
4615 print '<input name="proplabel" class="maxwidth125" value="'.dol_escape_htmltag($proplabel).'">';
4616 print '</td>';
4617 print '<td class="tdoverflowmax150">';
4618 print '<input name="proptype" class="maxwidth125" value="'.dol_escape_htmltag($proptype).'"></input>';
4619 print '</td>';
4620 print '<td class="tdoverflowmax200">';
4621 print '<textarea name="proparrayofkeyval">';
4622 if (isset($proparrayofkeyval)) {
4623 if (is_array($proparrayofkeyval) || $proparrayofkeyval != '') {
4624 print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE));
4625 }
4626 }
4627 print '</textarea>';
4628 print '</td>';
4629 print '<td>';
4630 print '<input class="center width50" name="propnotnull" value="'.dol_escape_htmltag($propnotnull).'">';
4631 print '</td>';
4632 print '<td>';
4633 print '<input class="maxwidth50" name="propdefault" value="'.dol_escape_htmltag($propdefault).'">';
4634 print '</td>';
4635 print '<td class="center">';
4636 print '<input class="center maxwidth50" name="propindex" value="'.dol_escape_htmltag($propindex).'">';
4637 print '</td>';
4638 print '<td>';
4639 print '<input class="center maxwidth100" name="propforeignkey" value="'.dol_escape_htmltag($propforeignkey).'">';
4640 print '</td>';
4641 print '<td>';
4642 print '<input class="right width50" name="propposition" value="'.dol_escape_htmltag($propposition).'">';
4643 print '</td>';
4644 print '<td>';
4645 print '<input class="center width75" name="propenabled" value="'.dol_escape_htmltag($propenabled).'">';
4646 print '</td>';
4647 print '<td>';
4648 print '<input class="center width75" name="propvisible" value="'.dol_escape_htmltag($propvisible).'">';
4649 print '</td>';
4650 print '<td>';
4651 print '<input class="center width50" name="propnoteditable" size="2" value="'.dol_escape_htmltag($propnoteditable).'">';
4652 print '</td>';
4653 /*print '<td>';
4654 print '<input class="center" name="propalwayseditable" size="2" value="'.dol_escape_htmltag($propalwayseditable).'">';
4655 print '</td>';*/
4656 print '<td>';
4657 print '<input class="center width50" name="propsearchall" value="'.dol_escape_htmltag($propsearchall).'">';
4658 print '</td>';
4659 print '<td>';
4660 print '<input class="center width50" name="propisameasure" value="'.dol_escape_htmltag($propisameasure).'">';
4661 print '</td>';
4662 print '<td>';
4663 print '<input class="center maxwidth50" name="propcss" value="'.dol_escape_htmltag($propcss).'">';
4664 print '</td>';
4665 print '<td>';
4666 print '<input class="center maxwidth50" name="propcssview" value="'.dol_escape_htmltag($propcssview).'">';
4667 print '</td>';
4668 print '<td>';
4669 print '<input class="center maxwidth50" name="propcsslist" value="'.dol_escape_htmltag($propcsslist).'">';
4670 print '</td>';
4671 print '<td>';
4672 print '<input class="maxwidth100" name="prophelp" value="'.dol_escape_htmltag($prophelp).'">';
4673 print '</td>';
4674 print '<td>';
4675 print '<input class="center maxwidth50" name="propshowoncombobox" value="'.dol_escape_htmltag($propshowoncombobox).'">';
4676 print '</td>';
4677 print '<td>';
4678 print '<input type="number" step="1" min="0" max="1" class="text maxwidth100" name="propvalidate" value="'.dol_escape_htmltag($propvalidate).'">';
4679 print '</td>';
4680 print '<td>';
4681 print '<input class="maxwidth100" name="propcomment" value="'.dol_escape_htmltag($propcomment).'">';
4682 print '</td>';
4683 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
4684 print '<input class="reposition button smallpaddingimp" type="submit" name="edit" value="'.$langs->trans("Save").'">';
4685 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
4686 print '</td>';
4687 } else {
4688 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($proplabel).'">';
4689 print dol_escape_htmltag($proplabel);
4690 print '</td>';
4691 print '<td class="tdoverflowmax200">';
4692 $pictoType = '';
4693 $matches = array();
4694 if (preg_match('/^varchar/', $proptype, $matches)) {
4695 $pictoType = 'varchar';
4696 } elseif (preg_match('/^integer:/', $proptype, $matches)) {
4697 $pictoType = 'link';
4698 } elseif (strpos($proptype, 'integer') === 0) {
4699 $pictoType = substr($proptype, 0, 3);
4700 } elseif (strpos($proptype, 'timestamp') === 0) {
4701 $pictoType = 'datetime';
4702 } elseif (strpos($proptype, 'real') === 0) {
4703 $pictoType = 'double';
4704 } elseif (strpos($proptype, 'stars') === 0) {
4705 $pictoType = 'stars';
4706 }
4707 print(!empty($pictoType) ? getPictoForType($pictoType) : getPictoForType($proptype)).'<span title="'.dol_escape_htmltag($proptype).'">'.dol_escape_htmltag($proptype).'</span>';
4708 print '</td>';
4709 print '<td class="tdoverflowmax200">';
4710 if ($proparrayofkeyval) {
4711 print '<span title="'.dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE)).'">';
4712 print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE));
4713 print '</span>';
4714 }
4715 print '</td>';
4716 print '<td class="center">';
4717 print dol_escape_htmltag($propnotnull);
4718 print '</td>';
4719 print '<td>';
4720 print dol_escape_htmltag($propdefault);
4721 print '</td>';
4722 print '<td class="center">';
4723 print $propindex ? '1' : '';
4724 print '</td>';
4725 print '<td class="center">';
4726 print $propforeignkey ? dol_escape_htmltag($propforeignkey) : '';
4727 print '</td>';
4728 print '<td class="right">';
4729 print dol_escape_htmltag($propposition);
4730 print '</td>';
4731 print '<td class="center tdoverflowmax100" title="'.($propnoteditable ? dol_escape_htmltag($propnoteditable) : '').'">';
4732 print $propenabled ? dol_escape_htmltag($propenabled) : '';
4733 print '</td>';
4734 // Visibility
4735 print '<td class="center tdoverflowmax100" title="'.($propvisible ? dol_escape_htmltag($propvisible) : '0').'">';
4736 print $propvisible ? dol_escape_htmltag($propvisible) : '0';
4737 print '</td>';
4738 // Readonly
4739 print '<td class="center tdoverflowmax100" title="'.($propnoteditable ? dol_escape_htmltag($propnoteditable) : '').'">';
4740 print $propnoteditable ? dol_escape_htmltag($propnoteditable) : '';
4741 print '</td>';
4742 /*print '<td class="center">';
4743 print $propalwayseditable ? dol_escape_htmltag($propalwayseditable) : '';
4744 print '</td>';*/
4745 print '<td class="center">';
4746 print $propsearchall ? '1' : '';
4747 print '</td>';
4748 print '<td class="center">';
4749 print $propisameasure ? dol_escape_htmltag($propisameasure) : '';
4750 print '</td>';
4751 print '<td class="center tdoverflowmax100" title="'.($propcss ? dol_escape_htmltag($propcss) : '').'">';
4752 print $propcss ? dol_escape_htmltag($propcss) : '';
4753 print '</td>';
4754 print '<td class="center tdoverflowmax100" title="'.($propcssview ? dol_escape_htmltag($propcssview) : '').'">';
4755 print $propcssview ? dol_escape_htmltag($propcssview) : '';
4756 print '</td>';
4757 print '<td class="center tdoverflowmax100" title="'.($propcsslist ? dol_escape_htmltag($propcsslist) : '').'">';
4758 print $propcsslist ? dol_escape_htmltag($propcsslist) : '';
4759 print '</td>';
4760 // Key for tooltop
4761 print '<td class="tdoverflowmax150" title="'.($prophelp ? dol_escape_htmltag($prophelp) : '').'">';
4762 print $prophelp ? dol_escape_htmltag($prophelp) : '';
4763 print '</td>';
4764 print '<td class="center">';
4765 print $propshowoncombobox ? dol_escape_htmltag($propshowoncombobox) : '';
4766 print '</td>';
4767 /*print '<td class="center">';
4768 print $propdisabled?$propdisabled:'';
4769 print '</td>';*/
4770 print '<td class="center">';
4771 print $propvalidate ? dol_escape_htmltag($propvalidate) : '';
4772 print '</td>';
4773 print '<td class="tdoverflowmax200">';
4774 print '<span title="'.dol_escape_htmltag($propcomment).'">';
4775 print dol_escape_htmltag($propcomment);
4776 print '</span>';
4777 print '</td>';
4778 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
4779 if ($propname != 'rowid') {
4780 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=editproperty&token='.newToken().'&propertykey='.urlencode($propname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_edit().'</a>';
4781 print '<a class="reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=deleteproperty&token='.newToken().'&propertykey='.urlencode($propname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_delete().'</a>';
4782 }
4783 print '</td>';
4784 }
4785 print '</tr>';
4786 }
4787 } else {
4788 if ($tab == 'specifications') {
4789 if ($action != 'editfile' || empty($file)) {
4790 print '<span class="opacitymedium">'.$langs->trans("SpecDefDesc").'</span><br>';
4791 print '<br>';
4792
4793 $specs = dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/'));
4794
4795 foreach ($specs as $spec) {
4796 $pathtofile = $modulelowercase.'/doc/'.$spec['relativename'];
4797 $format = 'asciidoc';
4798 if (preg_match('/\.md$/i', $spec['name'])) {
4799 $format = 'markdown';
4800 }
4801 print '<span class="fa fa-file"></span> '.$langs->trans("SpecificationFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
4802 print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format='.$format.'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4803 print '<br>';
4804 }
4805 } else {
4806 // Use MD or asciidoc
4807
4808 //print $langs->trans("UseAsciiDocFormat").'<br>';
4809
4810 $fullpathoffile = dol_buildpath($file, 0);
4811
4812 $content = file_get_contents($fullpathoffile);
4813
4814 // New module
4815 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4816 print '<input type="hidden" name="token" value="'.newToken().'">';
4817 print '<input type="hidden" name="action" value="savefile">';
4818 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
4819 print '<input type="hidden" name="tab" value="'.$tab.'">';
4820 print '<input type="hidden" name="module" value="'.$module.'">';
4821
4822 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
4823 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
4824 print '<br>';
4825 print '<center>';
4826 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
4827 print ' &nbsp; ';
4828 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
4829 print '</center>';
4830
4831 print '</form>';
4832 }
4833 }
4834 print '<tr><td><span class="warning">'.$langs->trans('Property %s not found in the class. The class was probably not generated by modulebuilder.', $field).'</warning></td></tr>';
4835 }
4836 print '</table>';
4837 print '</div>';
4838
4839 print '</form>';
4840 } else {
4841 print '<span class="warning">'.$langs->trans('Failed to init the object with the new %s (%s)', $tabobj, (string) $db).'</warning>';
4842 }
4843 } catch (Exception $e) {
4844 print 'ee';
4845 print $e->getMessage();
4846 print 'ff';
4847 }
4848 } else {
4849 if (empty($forceddirread)) {
4850 $fullpathoffile = dol_buildpath($file, 0);
4851 } else {
4852 $fullpathoffile = $dirread.'/'.$file;
4853 }
4854
4855 $content = file_get_contents($fullpathoffile);
4856
4857 // New module
4858 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4859 print '<input type="hidden" name="token" value="'.newToken().'">';
4860 print '<input type="hidden" name="action" value="savefile">';
4861 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
4862 print '<input type="hidden" name="tab" value="'.$tab.'">';
4863 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
4864 print '<input type="hidden" name="module" value="'.$module.($forceddirread ? '@'.$dirread : '').'">';
4865
4866 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
4867 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
4868 print '<br>';
4869 print '<center>';
4870 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
4871 print ' &nbsp; ';
4872 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
4873 print '</center>';
4874
4875 print '</form>';
4876 }
4877 }
4878
4879 print dol_get_fiche_end(); // Level 3
4880 }
4881
4882 if ($tab == 'dictionaries') {
4883 print '<!-- tab=dictionaries -->'."\n";
4884 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
4885
4886 $dicts = $moduleobj->dictionaries;
4887
4888 if ($action == 'deletedict') {
4889 $formconfirm = $form->formconfirm(
4890 $_SERVER["PHP_SELF"].'?dictionnarykey='.urlencode((string) (GETPOSTINT('dictionnarykey'))).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)),
4891 $langs->trans('Delete'),
4892 $langs->trans('Confirm Delete Dictionnary', GETPOST('dictionnarykey', 'alpha')),
4893 'confirm_deletedictionary',
4894 '',
4895 0,
4896 1
4897 );
4898 print $formconfirm;
4899 }
4900
4901 if ($action != 'editfile' || empty($file)) {
4902 print '<span class="opacitymedium">';
4903 $htmlhelp = $langs->trans("DictionariesDefDescTooltip", '{s1}');
4904 $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/dict.php">'.$langs->trans('Setup').' - '.$langs->trans('Dictionaries').'</a>', $htmlhelp);
4905 print $form->textwithpicto($langs->trans("DictionariesDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
4906 print '</span>';
4907 print '<br>';
4908
4909 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
4910 print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=DICTIONARIES">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
4911 print '<br>';
4912 if (is_array($dicts) && !empty($dicts)) {
4913 print '<span class="fa fa-file"></span> '.$langs->trans("LanguageFile").' :</span> ';
4914 print '<strong class="wordbreak">'.$dicts['langs'].'</strong>';
4915 print '<br>';
4916 }
4917 print '<br>';
4918
4919 $head3 = array();
4920 $h = 0;
4921
4922 // Dir for module
4923 //$dir = $dirread.'/'.$modulelowercase.'/class';
4924
4925 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic=newdictionary';
4926 $head3[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewDictionary").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
4927 $head3[$h][2] = 'newdictionary';
4928 $h++;
4929
4930 // Scan for object class files
4931 //$listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$');
4932
4933 $firstdicname = '';
4934 // if (!empty($dicts['tabname'])) {
4935 // foreach ($dicts['tabname'] as $key => $dic) {
4936 // $dicname = $dic;
4937 // $diclabel = $dicts['tablib'][$key];
4938
4939 // if (empty($firstdicname)) {
4940 // $firstdicname = $dicname;
4941 // }
4942
4943 // $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic='.$dicname;
4944 // $head3[$h][1] = $diclabel;
4945 // $head3[$h][2] = $dicname;
4946 // $h++;
4947 // }
4948 // }
4949
4950 // if ($h > 1) {
4951 // $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic=deletedictionary';
4952 // $head3[$h][1] = $langs->trans("DangerZone");
4953 // $head3[$h][2] = 'deletedictionary';
4954 // $h++;
4955 // }
4956
4957 // If tabobj was not defined, then we check if there is one obj. If yes, we force on it, if no, we will show tab to create new objects.
4958 // if ($tabdic == 'newdicifnodic') {
4959 // if ($firstdicname) {
4960 // $tabdic = $firstdicname;
4961 // } else {
4962 // $tabdic = 'newdictionary';
4963 // }
4964 // }
4965 //print dol_get_fiche_head($head3, $tabdic, '', -1, ''); // Level 3
4966
4967
4968 $newdict = dolGetButtonTitle($langs->trans('NewDictionary'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/modulebuilder/index.php?tab=dictionaries&module='.urlencode($module).'&tabdic=newdictionary');
4969 print_barre_liste($langs->trans("ListOfDictionariesEntries"), 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, '', '', 0, $newdict, '', 0, 0, 0, 1);
4970
4971 if ($tabdic != 'newdictionary') {
4972 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4973 print '<input type="hidden" name="token" value="'.newToken().'">';
4974 print '<input type="hidden" name="action" value="addDictionary">';
4975 print '<input type="hidden" name="tab" value="dictionaries">';
4976 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
4977 print '<input type="hidden" name="tabdic" value="'.dol_escape_htmltag($tabdic).'">';
4978
4979 print '<div class="div-table-responsive">';
4980 print '<table class="noborder">';
4981
4982 print '<tr class="liste_titre">';
4983 print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'thsticky thstickygrey ');
4984 print_liste_field_titre("Table", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4985 print_liste_field_titre("Label", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4986 print_liste_field_titre("SQL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4987 print_liste_field_titre("SQLSort", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4988 print_liste_field_titre("FieldsView", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4989 print_liste_field_titre("FieldsEdit", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4990 print_liste_field_titre("FieldsInsert", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4991 print_liste_field_titre("Rowid", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4992 print_liste_field_titre("Condition", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4993 print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4994 print "</tr>\n";
4995
4996 if (!empty($dicts) && is_array($dicts) && !empty($dicts['tabname']) && is_array($dicts['tabname'])) {
4997 $i = 0;
4998 $maxi = count($dicts['tabname']);
4999 while ($i < $maxi) {
5000 if ($action == 'editdict' && $i == GETPOSTINT('dictionnarykey') - 1) {
5001 print '<tr class="oddeven">';
5002 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5003 print '<input type="hidden" name="token" value="'.newToken().'">';
5004 print '<input type="hidden" name="tab" value="dictionaries">';
5005 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5006 print '<input type="hidden" name="action" value="updatedictionary">';
5007 print '<input type="hidden" name="dictionnarykey" value="'.($i + 1).'">';
5008
5009 print '<td class="tdsticky tdstickygray">';
5010 print($i + 1);
5011 print '</td>';
5012
5013 print '<td>';
5014 print '<input type="text" name="tabname" value="'.$dicts['tabname'][$i].'" readonly class="tdstickygray">';
5015 print '</td>';
5016
5017 print '<td>';
5018 print '<input type="text" name="tablib" value="'.$dicts['tablib'][$i].'">';
5019 print '</td>';
5020
5021 print '<td>';
5022 print '<input type="text" name="tabsql" value="'.$dicts['tabsql'][$i].'" readonly class="tdstickygray">';
5023 print '</td>';
5024
5025 print '<td>';
5026 print '<select name="tabsqlsort">';
5027 print '<option value="'.dol_escape_htmltag($dicts['tabsqlsort'][$i]).'">'.$dicts['tabsqlsort'][$i].'</option>';
5028 print '</select>';
5029 print '</td>';
5030
5031 print '<td><select name="tabfield" >';
5032 print '<option value="'.dol_escape_htmltag($dicts['tabfield'][$i]).'">'.$dicts['tabfield'][$i].'</option>';
5033 print '</select></td>';
5034
5035 print '<td><select name="tabfieldvalue" >';
5036 print '<option value="'.dol_escape_htmltag($dicts['tabfieldvalue'][$i]).'">'.$dicts['tabfieldvalue'][$i].'</option>';
5037 print '</select></td>';
5038
5039 print '<td><select name="tabfieldinsert" >';
5040 print '<option value="'.dol_escape_htmltag($dicts['tabfieldinsert'][$i]).'">'.$dicts['tabfieldinsert'][$i].'</option>';
5041 print '</select></td>';
5042
5043 print '<td>';
5044 print '<input type="text" name="tabrowid" value="'.dol_escape_htmltag($dicts['tabrowid'][$i]).'" readonly class="tdstickygray">';
5045 print '</td>';
5046
5047 print '<td>';
5048 print '<input type="text" name="tabcond" value="'.dol_escape_htmltag((empty($dicts['tabcond'][$i]) ? 'disabled' : 'enabled')).'" readonly class="tdstickygray">';
5049 print '</td>';
5050
5051 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5052 print '<input id ="updatedict" class="reposition button smallpaddingimp" type="submit" name="updatedict" value="'.$langs->trans("Modify").'"/>';
5053 print '<br>';
5054 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
5055 print '</td>';
5056
5057 print '</form>';
5058 print '</tr>';
5059 } else {
5060 print '<tr class="oddeven">';
5061
5062 print '<td class="tdsticky tdstickygray">';
5063 print($i + 1);
5064 print '</td>';
5065
5066 print '<td>';
5067 print $dicts['tabname'][$i];
5068 print '</td>';
5069
5070 print '<td>';
5071 print $dicts['tablib'][$i];
5072 print '</td>';
5073
5074 print '<td>';
5075 print $dicts['tabsql'][$i];
5076 print '</td>';
5077
5078 print '<td>';
5079 print $dicts['tabsqlsort'][$i];
5080 print '</td>';
5081
5082 print '<td>';
5083 print $dicts['tabfield'][$i];
5084 print '</td>';
5085
5086 print '<td>';
5087 print $dicts['tabfieldvalue'][$i];
5088 print '</td>';
5089
5090 print '<td>';
5091 print $dicts['tabfieldinsert'][$i];
5092 print '</td>';
5093
5094 print '<td >';
5095 print $dicts['tabrowid'][$i];
5096 print '</td>';
5097
5098 print '<td >';
5099 print $dicts['tabcond'][$i];
5100 print '</td>';
5101
5102 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5103 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=editdict&token='.newToken().'&dictionnarykey='.urlencode((string) ($i + 1)).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)).'">'.img_edit().'</a>';
5104 print '<a class="marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=deletedict&token='.newToken().'&dictionnarykey='.urlencode((string) ($i + 1)).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)).'">'.img_delete().'</a>';
5105 print '</td>';
5106
5107 print '</tr>';
5108 }
5109 $i++;
5110 }
5111 } else {
5112 print '<tr><td colspan="11"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
5113 }
5114
5115 print '</table>';
5116 print '</div>';
5117
5118 print '</form>';
5119 }
5120
5121 if ($tabdic == 'newdictionary') {
5122 // New dic tab
5123 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5124 print '<input type="hidden" name="token" value="'.newToken().'">';
5125 print '<input type="hidden" name="action" value="initdic">';
5126 print '<input type="hidden" name="tab" value="dictionaries">';
5127 print '<input type="hidden" name="tabdic" value="'.$tabdic.'">';
5128
5129 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5130
5131 print '<span class="opacitymedium">'.$langs->trans("EnterNameOfDictionaryDesc").'</span><br><br>';
5132
5133 print dol_get_fiche_head();
5134 print '<table class="border centpercent">';
5135 print '<tbody>';
5136 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Table").'</td><td><input type="text" name="dicname" maxlength="64" value="'.dol_escape_htmltag(GETPOST('dicname', 'alpha') ? GETPOST('dicname', 'alpha') : $modulename).'" placeholder="'.dol_escape_htmltag($langs->trans("DicKey")).'" autofocus></td>';
5137 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td><td><input type="text" name="label" value="'.dol_escape_htmltag(GETPOST('label', 'alpha')).'"></td></tr>';
5138 print '<tr><td class="titlefieldcreate">'.$langs->trans("SQL").'</td><td><input type="text" style="width:50%;" name="sql" value="'.dol_escape_htmltag(GETPOST('sql', 'alpha')).'"></td></tr>';
5139 print '<tr><td class="titlefieldcreate">'.$langs->trans("SQLSort").'</td><td><input type="text" name="sqlsort" value="'.dol_escape_htmltag(GETPOST('sqlsort', 'alpha')).'" readonly></td></tr>';
5140 print '<tr><td class="titlefieldcreate">'.$langs->trans("FieldsView").'</td><td><input type="text" name="field" value="'.dol_escape_htmltag(GETPOST('field', 'alpha')).'"></td></tr>';
5141 print '<tr><td class="titlefieldcreate">'.$langs->trans("FieldsEdit").'</td><td><input type="text" name="fieldvalue" value="'.dol_escape_htmltag(GETPOST('fieldvalue', 'alpha')).'"></td></tr>';
5142 print '<tr><td class="titlefieldcreate">'.$langs->trans("FieldsInsert").'</td><td><input type="text" name="fieldinsert" value="'.dol_escape_htmltag(GETPOST('fieldinsert', 'alpha')).'"></td></tr>';
5143 print '<tr><td class="titlefieldcreate">'.$langs->trans("Rowid").'</td><td><input type="text" name="rowid" value="'.dol_escape_htmltag(GETPOST('rowid', 'alpha')).'"></td></tr>';
5144 print '<tr></tr>';
5145 print '</tbody></table>';
5146 print '<input type="submit" class="button" name="create" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
5147 print '<input id="cancel" type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5148 print dol_get_fiche_end();
5149 print '</form>';
5150 print '<script>
5151 $(document).ready(function() {
5152 $("input[name=\'dicname\']").on("blur", function() {
5153 if ($(this).val().length > 0) {
5154 $("input[name=\'label\']").val($(this).val());
5155 $("input[name=\'sql\']").val("SELECT f.rowid as rowid, f.code, f.label, f.active FROM llx_c_" + $(this).val() + " as f");
5156 $("input[name=\'sqlsort\']").val("label ASC");
5157 $("input[name=\'field\']").val("code,label");
5158 $("input[name=\'fieldvalue\']").val("code,label");
5159 $("input[name=\'fieldinsert\']").val("code,label");
5160 $("input[name=\'rowid\']").val("rowid");
5161 } else {
5162 $("input[name=\'label\']").val("");
5163 $("input[name=\'sql\']").val("");
5164 $("input[name=\'sqlsort\']").val("");
5165 $("input[name=\'field\']").val("");
5166 $("input[name=\'fieldvalue\']").val("");
5167 $("input[name=\'fieldinsert\']").val("");
5168 $("input[name=\'rowid\']").val("");
5169 }
5170 });
5171 $("input[id=\'cancel\']").click(function() {
5172 window.history.back();
5173 });
5174 });
5175 </script>';
5176
5177 /*print '<br>';
5178 print '<br>';
5179 print '<br>';
5180 print '<span class="opacitymedium">'.$langs->trans("or").'</span>';
5181 print '<br>';
5182 print '<br>';
5183 //print '<input type="checkbox" name="initfromtablecheck"> ';
5184 print $langs->trans("InitStructureFromExistingTable");
5185 print '<input type="text" name="initfromtablename" value="" placeholder="'.$langs->trans("TableName").'">';
5186 print '<input type="submit" class="button smallpaddingimp" name="createtablearray" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
5187 print '<br>';
5188 */
5189 } elseif ($tabdic == 'deletedictionary') {
5190 // Delete dic tab
5191 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5192 print '<input type="hidden" name="token" value="'.newToken().'">';
5193 print '<input type="hidden" name="action" value="confirm_deletedictionary">';
5194 print '<input type="hidden" name="tab" value="dictionaries">';
5195 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5196
5197 print $langs->trans("EnterNameOfDictionnaryToDeleteDesc").'<br><br>';
5198
5199 print '<input type="text" name="dicname" value="'.dol_escape_htmltag($modulename).'" placeholder="'.dol_escape_htmltag($langs->trans("DicKey")).'">';
5200 print '<input type="submit" class="button smallpaddingimp" name="delete" value="'.dol_escape_htmltag($langs->trans("Delete")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
5201 print '</form>';
5202 }
5203
5204 print dol_get_fiche_end();
5205 } else {
5206 $fullpathoffile = dol_buildpath($file, 0);
5207
5208 $content = file_get_contents($fullpathoffile);
5209
5210 // New module
5211 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5212 print '<input type="hidden" name="token" value="'.newToken().'">';
5213 print '<input type="hidden" name="action" value="savefile">';
5214 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5215 print '<input type="hidden" name="tab" value="'.$tab.'">';
5216 print '<input type="hidden" name="module" value="'.$module.'">';
5217
5218 $posCursor = (empty($find)) ? array() : array('find' => $find);
5219 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5220 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5221 print '<br>';
5222 print '<center>';
5223 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5224 print ' &nbsp; ';
5225 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5226 print '</center>';
5227
5228 print '</form>';
5229 }
5230 }
5231
5232 if ($tab == 'menus') {
5233 print '<!-- tab=menus -->'."\n";
5234 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
5235 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
5236 $destdir = $dirins.'/'.strtolower($module);
5237 $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
5238 $objects = dolGetListOfObjectClasses($destdir);
5239
5240 $leftmenus = array();
5241
5242 $menus = $moduleobj->menu;
5243
5244 $permissions = $moduleobj->rights;
5245 $crud = array('read' => 'CRUDRead', 'write' => 'CRUDCreateWrite', 'delete' => 'Delete');
5246
5247 //grouped permissions
5248 $groupedRights = array();
5249 foreach ($permissions as $right) {
5250 $key = $right[4];
5251 if (!isset($groupedRights[$key])) {
5252 $groupedRights[$key] = array();
5253 }
5254 $groupedRights[$key][] = $right;
5255 }
5256 $groupedRights_json = json_encode($groupedRights);
5257
5258 if ($action == 'deletemenu') {
5259 $formconfirms = $form->formconfirm(
5260 $_SERVER["PHP_SELF"].'?menukey='.urlencode((string) (GETPOSTINT('menukey'))).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)),
5261 $langs->trans('Delete'),
5262 ($menus[GETPOST('menukey')]['fk_menu'] === 'fk_mainmenu='.strtolower($module) ? $langs->trans('Warning: you will delete all menus linked to this one.', GETPOSTINT('menukey')) : $langs->trans('Confirm Delete Menu', GETPOSTINT('menukey'))),
5263 'confirm_deletemenu',
5264 '',
5265 0,
5266 1
5267 );
5268 print $formconfirms;
5269 }
5270 if ($action != 'editfile' || empty($file)) {
5271 print '<span class="opacitymedium">';
5272 $htmlhelp = $langs->trans("MenusDefDescTooltip", '{s1}');
5273 $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/menus/index.php">'.$langs->trans('Setup').' - '.$langs->trans('Menus').'</a>', $htmlhelp);
5274 print $form->textwithpicto($langs->trans("MenusDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
5275 print '</span>';
5276 print '<br>';
5277
5278 // Links to editable files
5279 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5280 print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=TOPMENU">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
5281 print '<br>';
5282
5283 // Search all files of modules mentioned by menu
5284 $listODifferentUrlsInMenu = array();
5285 foreach ($menus as $obj) {
5286 if (preg_match('/^\/'.preg_quote(strtolower($module), '/').'\//', $obj['url']) && !empty($pathoffile)) {
5287 if (!empty($listODifferentUrlsInMenu[$pathoffile])) { // Test to avoid to show same file twice.
5288 continue;
5289 }
5290 $pathtofile = $obj['url'];
5291 $listODifferentUrlsInMenu[$pathoffile] = $pathtofile;
5292 print '<span class="fa fa-file"></span> '.$langs->trans("PageLinkedByAMenuEntry").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5293 print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=TOPMENU">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
5294 print '<br>';
5295 }
5296 }
5297
5298
5299 print '<br>';
5300 print load_fiche_titre($langs->trans("ListOfMenusEntries"), '', '');
5301
5302 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5303 print '<input type="hidden" name="token" value="'.newToken().'">';
5304 print '<input type="hidden" name="action" value="addmenu">';
5305 print '<input type="hidden" name="tab" value="menus">';
5306 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5307 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
5308
5309 print '<div class="div-table-responsive">';
5310 print '<table class="noborder small">';
5311
5312 $htmltextenabled = '<u>'.$langs->trans("Examples").':</u><br>';
5313 $htmltextenabled .= '1 <span class="opacitymedium">(module always enabled)</span><br>';
5314 $htmltextenabled .= '0 <span class="opacitymedium">(module always disabled)</span><br>';
5315 $htmltextenabled .= 'isModEnabled(\''.dol_escape_htmltag(strtolower($module)).'\') <span class="opacitymedium">(enabled when module is enabled)</span>';
5316 $htmltextperms = '<u>'.$langs->trans("Examples").':</u><br>';
5317 $htmltextperms .= '1 <span class="opacitymedium">(access always allowed)</span><br>';
5318 $htmltextperms .= '$user->hasright(\''.dol_escape_htmltag(strtolower($module)).'\', \'myobject\', \'read\') <span class="opacitymedium">(access allowed if user has permission module->object->read)</span>';
5319
5320 print '<tr class="liste_titre">';
5321 print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center tdsticky tdstickygray ');
5322 print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
5323 print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center');
5324 print_liste_field_titre("LinkToParentMenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'minwidth100 ');
5325 print_liste_field_titre("mainmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
5326 print_liste_field_titre("leftmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
5327 print_liste_field_titre("URL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->transnoentitiesnoconv('DetailUrl'));
5328 print_liste_field_titre("LanguageFile", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
5329 print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right ');
5330 print_liste_field_titre("Enabled", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans('DetailEnabled').'<br><br>'.$htmltextenabled);
5331 print_liste_field_titre("Rights", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailRight').'<br><br>'.$htmltextperms);
5332 print_liste_field_titre("Target", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailTarget'));
5333 print_liste_field_titre("MenuForUsers", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center minwidth100 ', $langs->trans('DetailUser'));
5334 print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans(''));
5335 print "</tr>\n";
5336
5337 $r = count($menus) + 1;
5338 // for adding menu on module
5339 print '<tr>';
5340 print '<td class="center tdsticky tdstickygray"><input type="hidden" readonly class="center maxwidth50" name="propenabled" value="#"></td>';
5341 print '<td class="center">';
5342 print '<select class="maxwidth50" name="type">';
5343 print '<option value="">'.$langs->trans("........").'</option><option value="'.dol_escape_htmltag("left").'">left</option><option value="'.dol_escape_htmltag("top").'">top</option>';
5344 print '</select></td>';
5345 print '<td class="left"><input type="text" class="left maxwidth100" name="titre" value="'.dol_escape_htmltag(GETPOST('titre', 'alpha')).'"></td>';
5346 print '<td class="left">';
5347 print '<select name="fk_menu">';
5348 print '<option value="">'.$langs->trans("........").'</option>';
5349 foreach ($menus as $obj) {
5350 if ($obj['type'] == 'left' && !empty($obj['leftmenu'])) {
5351 print "<option value=".strtolower($obj['leftmenu']).">".$obj['leftmenu']."</option>";
5352 }
5353 }
5354 print '</select>';
5355 print '</td>';
5356 print '<td class="left"><input type="text" class="left maxwidth50" name="mainmenu" value="'.(empty(GETPOST('mainmenu')) ? strtolower($module) : dol_escape_htmltag(GETPOST('mainmenu', 'alpha'))).'"></td>';
5357 print '<td class="center"><input id="leftmenu" type="text" class="left maxwidth50" name="leftmenu" value="'.dol_escape_htmltag(GETPOST('leftmenu', 'alpha')).'"></td>';
5358 // URL
5359 print '<td class="left"><input id="url" type="text" class="left maxwidth100" name="url" value="'.dol_escape_htmltag(GETPOST('url', 'alpha')).'"></td>';
5360 print '<td class="left"><input type="text" class="left maxwidth75" name="langs" value="'.strtolower($module).'@'.strtolower($module).'" readonly></td>';
5361 // Position
5362 print '<td class="center"><input type="text" class="center maxwidth50 tdstickygray" name="position" value="'.(1000 + $r).'" readonly></td>';
5363 // Enabled
5364 print '<td class="center">';
5365 print '<input type="enabled" class="maxwidth125" value="'.dol_escape_htmltag(GETPOSTISSET('enabled') ? GETPOST('enabled') : 'isModEnabled(\''.$module.'\')').'">';
5366 /*
5367 print '<select class="maxwidth" name="enabled">';
5368 print '<option value="1" selected>'.$langs->trans("Show").'</option>';
5369 print '<option value="0">'.$langs->trans("Hide").'</option>';
5370 print '</select>';
5371 */
5372 print '</td>';
5373 // Perms
5374 print '<td class="left">';
5375 print '<select class="maxwidth" name="objects" id="objects">';
5376 print '<option value=""></option>';
5377 if (is_array($objects)) {
5378 foreach ($objects as $value) {
5379 print '<option value="'.strtolower($value).'">'.dol_escape_htmltag(strtolower($value)).'</option>';
5380 }
5381 }
5382 print '</select>';
5383 print '<select class="maxwidth hideobject" name="perms" id="perms">';
5384 print '</select>';
5385 print '</td>';
5386 print '<td class="center"><input type="text" class="center maxwidth50" name="target" value="'.dol_escape_htmltag(GETPOST('target', 'alpha')).'"></td>';
5387 print '<td class="center"><select class="maxwidth10" name="user"><option value="2">'.$langs->trans("AllMenus").'</option><option value="0">'.$langs->trans("Internal").'</option><option value="1">'.$langs->trans("External").'</option></select></td>';
5388
5389 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5390 print '<input type="submit" class="button" name="add" value="'.$langs->trans("Add").'">';
5391 print '</td>';
5392 print '</tr>';
5393 // end form for add menu
5394
5395 //var_dump($menus);
5396
5397 // Loop on each menu entry
5398 if (count($menus)) {
5399 $i = 0;
5400 foreach ($menus as $menu) {
5401 $i++;
5402 //for get parent in menu
5403 $string = dol_escape_htmltag($menu['fk_menu']);
5404 $value = substr($string, strpos($string, 'fk_leftmenu=') + strlen('fk_leftmenu='));
5405
5406 $propFk_menu = !empty($menu['fk_menu']) ? $menu['fk_menu'] : GETPOST('fk_menu');
5407 $propTitre = !empty($menu['titre']) ? $menu['titre'] : GETPOST('titre');
5408 $propMainmenu = !empty($menu['mainmenu']) ? $menu['mainmenu'] : GETPOST('mainmenu');
5409 $propLeftmenu = !empty($menu['leftmenu']) ? $menu['leftmenu'] : GETPOST('leftmenu');
5410 $propUrl = !empty($menu['url']) ? $menu['url'] : GETPOST('url', 'alpha');
5411 $propPerms = !empty($menu['perms']) ? $menu['perms'] : GETPOST('perms');
5412 $propUser = !empty($menu['user']) ? $menu['user'] : GETPOST('user');
5413 $propTarget = !empty($menu['target']) ? $menu['target'] : GETPOST('target');
5414 $propEnabled = !empty($menu['enabled']) ? $menu['enabled'] : GETPOST('enabled');
5415
5416 $objPerms = (empty($arguments[1]) ? '' : trim($arguments[1]));
5417 $valPerms = (empty($arguments[2]) ? '' : trim($arguments[2]));
5418
5419 //$tabobject = ''; // We can't know what is $tabobject in most cases
5420
5421 if ($action == 'editmenu' && GETPOSTINT('menukey') == $i) {
5422 //var_dump($propPerms);exit;
5423 print '<tr class="oddeven">';
5424 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5425 print '<input type="hidden" name="token" value="'.newToken().'">';
5426 print '<input type="hidden" name="action" value="update_menu">';
5427 print '<input type="hidden" name="tab" value="menus">';
5428 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5429 print '<input type="hidden" name="menukey" value="'.$i.'"/>';
5430 //print '<input type="hidden" name="tabobject" value="'.dol_escape_htmltag($tabobject).'">';
5431 print '<td class="tdsticky tdstickygray">';
5432 print $i;
5433 print '</td>';
5434 // Position (top, left)
5435 print '<td class="center">
5436 <select class="center maxwidth50" name="type">
5437 <option value="'.dol_escape_htmltag($menu['type']).'">
5438 '.dol_escape_htmltag($menu['type']).'
5439 </option>';
5440 print '<option value="'.($menu['type'] == 'left' ? 'top' : 'left').'">';
5441 if ($menu['type'] == 'left') {
5442 print 'top';
5443 } else {
5444 print 'left';
5445 }
5446 print '</option></select></td>';
5447 // Title
5448 print '<td><input type="text" class="left maxwidth100" name="titre" value="'.dol_escape_htmltag($propTitre).'"></td>';
5449 // Parent menu
5450 print '<td>';
5451 /*print '<select name="fk_menu" class="left maxwidth">';
5452 print '<option value="'.dol_escape_htmltag($propFk_menu).'">'.dol_escape_htmltag($value).'</option>';
5453 foreach ($menus as $obj) {
5454 if ($obj['type'] == 'left' && $obj['leftmenu'] != $value && $obj['leftmenu'] != $menu['leftmenu']) {
5455 print "<option value=".strtolower($obj['leftmenu']).">".$obj['leftmenu']."</option>";
5456 }
5457 }
5458 print '</select>';*/
5459 print '<input type="text" name="fk_menu" class="maxwidth150" value="'.dol_escape_htmltag($propFk_menu).'">';
5460 print '</td>';
5461 print '<td><input type="text" class="left maxwidth50" name="mainmenu" value="'.dol_escape_htmltag($propMainmenu).'" readonly></td>';
5462 print '<td><input type="text" class="left maxwidth50" name="leftmenu" value="'.dol_escape_htmltag($propLeftmenu).'" readonly></td>';
5463 // URL
5464 print '<td><input type="text" class="left maxwidth250" name="url" value="'.dol_escape_htmltag($propUrl).'"></td>';
5465 print '<td><input type="text" class="left maxwidth50" name="langs" value="'.strtolower($module).'@'.strtolower($module).'" readonly></td>';
5466 // Position
5467 print '<td class="center"><input type="text" class="center maxwidth50 tdstickygray" name="position" value="'.($menu['position']).'" readonly></td>';
5468 // Enabled
5469 print '<td class="nowraponall">';
5470 print '<input type="text" class="maxwidth125" name="enabled" value="'.dol_escape_htmltag($propEnabled != '' ? $propEnabled : "isModEnabled('".dol_escape_htmltag($module)."')").'">';
5471 $htmltext = '<u>'.$langs->trans("Examples").':</u><br>';
5472 $htmltext .= '1 <span class="opacitymedium">(always enabled)</span><br>';
5473 $htmltext .= '0 <span class="opacitymedium">(always disabled)</span><br>';
5474 $htmltext .= 'isModEnabled(\''.dol_escape_htmltag($module).'\') <span class="opacitymedium">(enabled when module is enabled)</span><br>';
5475 print $form->textwithpicto('', $htmltext);
5476 /*
5477 print '<select class="maxwidth50" name="enabledselect">';
5478 print '<option value="1">1 (always enabled)</option>';
5479 print '<option value="0">0 (always disabled)</option>';
5480 print '<option value="isModEnabled(\''.dol_escape_htmltag($module).'\')" >isModEnabled(\''.dol_escape_htmltag($module).'\')</option>';
5481 print '</select>';
5482 */
5483 print '</td>';
5484 // Permissions
5485 print '<td class="nowraponall">';
5486 print '<input type="text" name="perms" value="'.dol_escape_htmltag($propPerms).'">';
5487 /*
5488 if (!empty($objPerms)) {
5489 print '<input type="hidden" name="objects" value="'.$objPerms.'" />';
5490 print '<select class="center maxwidth50" name="perms">';
5491 if (!empty($valPerms)) {
5492 print '<option selected value="'.dol_escape_htmltag($valPerms).'">'.dol_escape_htmltag($langs->trans($crud[$valPerms])).'</option>';
5493 foreach ($crud as $key => $val) {
5494 if ($valPerms != $key) {
5495 print '<option value="'.dol_escape_htmltag($key).'">'.dol_escape_htmltag($langs->trans($val)).'</option>';
5496 }
5497 }
5498 }
5499 print '</select>';
5500 } else {
5501 print '<select class="center maxwidth50" name="objects">';
5502 print '<option></option>';
5503 foreach ($objects as $obj) {
5504 print '<option value="'.dol_escape_htmltag(strtolower($obj)).'">'.dol_escape_htmltag($obj).'</option>';
5505 }
5506 print '</select>';
5507 print '<select class="center maxwidth50" name="perms">';
5508 foreach ($crud as $key => $val) {
5509 print '<option value="'.dol_escape_htmltag($key).'">'.dol_escape_htmltag($key).'</option>';
5510 }
5511 print '</select>';
5512 }*/
5513 print '</td>';
5514 // Target
5515 print '<td class="center"><input type="text" class="center maxwidth50" name="target" value="'.dol_escape_htmltag($propTarget).'"></td>';
5516 print '<td class="center"><select class="center maxwidth10" name="user"><option value="2">'.$langs->trans("AllMenus").'</option><option value="0">'.$langs->trans("Internal").'</option><option value="1">'.$langs->trans("External").'</option></select></td>';
5517 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite maxwidth75">';
5518 print '<input class="reposition button smallpaddingimp" type="submit" name="edit" value="'.$langs->trans("Modify").'">';
5519 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
5520 print '</td>';
5521 print '</form>';
5522 print '</tr>';
5523 } else {
5524 print '<tr class="oddeven">';
5525
5526 print '<td class="tdsticky tdstickygray">';
5527 print $i;
5528 print '</td>';
5529
5530 print '<td class="center">';
5531 print dol_escape_htmltag($menu['type']);
5532 print '</td>';
5533
5534 // Title
5535 print '<td>';
5536 print dol_escape_htmltag($menu['titre']);
5537 print '</td>';
5538
5539 // Parent menu
5540 print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($menu['fk_menu']).'">';
5541 print dol_escape_htmltag($menu['fk_menu']);
5542 print '</td>';
5543
5544 print '<td>';
5545 print dol_escape_htmltag($menu['mainmenu']);
5546 print '</td>';
5547
5548 print '<td>';
5549 print dol_escape_htmltag($menu['leftmenu']);
5550 print '</td>';
5551
5552 print '<td class="tdoverflowmax250" title="'.dol_escape_htmltag($menu['url']).'">';
5553 print dol_escape_htmltag($menu['url']);
5554 print '</td>';
5555
5556 print '<td>';
5557 print dol_escape_htmltag($menu['langs']);
5558 print '</td>';
5559
5560 // Position
5561 print '<td class="center">';
5562 print dol_escape_htmltag((string) $menu['position']);
5563 print '</td>';
5564
5565 // Enabled
5566 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($menu['enabled']).'">';
5567 print dol_escape_htmltag($menu['enabled']);
5568 print '</td>';
5569
5570 // Perms
5571 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($menu['perms']).'">';
5572 print dol_escape_htmltag($langs->trans($menu['perms']));
5573 print '</td>';
5574
5575 // Target
5576 print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['target']).'">';
5577 print dol_escape_htmltag($menu['target']);
5578 print '</td>';
5579
5580 print '<td class="center">';
5581 if ($menu['user'] == 2) {
5582 print $langs->trans("AllMenus");
5583 } elseif ($menu['user'] == 0) {
5584 print $langs->trans('Internal');
5585 } elseif ($menu['user'] == 1) {
5586 print $langs->trans('External');
5587 } else {
5588 print $menu['user']; // should not happen
5589 }
5590 print '</td>';
5591 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5592 if ($menu['titre'] != 'Module'.$module.'Name') {
5593 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=editmenu&token='.newToken().'&menukey='.urlencode((string) ($i)).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)).'&tabobj='.urlencode((string) ($tabobj)).'">'.img_edit().'</a>';
5594 print '<a class="deletefielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=deletemenu&token='.newToken().'&menukey='.urlencode((string) ($i - 1)).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)).'">'.img_delete().'</a>';
5595 }
5596 print '</td>';
5597 }
5598 print '</tr>';
5599 }
5600 } else {
5601 print '<tr><td colspan="14"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
5602 }
5603
5604 print '</table>';
5605 print '</div>';
5606 print '</form>';
5607
5608
5609 print '<script>
5610 $(document).ready(function() {
5611 //for fill in auto url
5612 $("#leftmenu").on("input", function() {
5613 var inputLeftMenu = $("#leftmenu").val();
5614 if (inputLeftMenu !== \'\') {
5615 var url = \''.dol_escape_js(strtolower($module)).'\' + inputLeftMenu + \'.php\';
5616 $("#url").val(url);
5617 }else {
5618 $("#url").val("");
5619 }
5620 });
5621
5622 var groupedRights = ' . $groupedRights_json . ';
5623 var objectsSelect = $("select[id=\'objects\']");
5624 var permsSelect = $("select[id=\'perms\']");
5625
5626 objectsSelect.change(function() {
5627 var selectedObject = $(this).val();
5628
5629 permsSelect.empty();
5630
5631 var rights = groupedRights[selectedObject];
5632
5633 if (rights) {
5634 for (var i = 0; i < rights.length; i++) {
5635 var right = rights[i];
5636 var option = $("<option></option>").attr("value", right[5]).text(right[5]);
5637 permsSelect.append(option);
5638 }
5639 } else {
5640 var option = $("<option></option>").attr("value", "read").text("read");
5641 permsSelect.append(option);
5642 }
5643
5644 if (selectedObject !== "" && selectedObject !== null && rights) {
5645 permsSelect.show();
5646 } else {
5647 permsSelect.hide();
5648 }
5649 if (objectsSelect.val() === "" || objectsSelect.val() === null) {
5650 permsSelect.hide();
5651 }
5652 });
5653 });
5654 </script>';
5655
5656 // display permissions for each object
5657 } else {
5658 $fullpathoffile = dol_buildpath($file, 0);
5659
5660 $content = file_get_contents($fullpathoffile);
5661
5662 // New module
5663 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5664 print '<input type="hidden" name="token" value="'.newToken().'">';
5665 print '<input type="hidden" name="action" value="savefile">';
5666 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5667 print '<input type="hidden" name="tab" value="'.$tab.'">';
5668 print '<input type="hidden" name="module" value="'.$module.'">';
5669
5670 $posCursor = (empty($find)) ? array() : array('find' => $find);
5671 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5672 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5673 print '<br>';
5674 print '<center>';
5675 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5676 print ' &nbsp; ';
5677 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5678 print '</center>';
5679
5680 print '</form>';
5681 }
5682 }
5683
5684 if ($tab == 'permissions') {
5685 print '<!-- tab=permissions -->'."\n";
5686 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
5687
5688 $perms = $moduleobj->rights;
5689
5690 // Get list of existing objects
5691 $dir = $dirread.'/'.$modulelowercase.'/class';
5692 $listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$');
5693 $objects = array('myobject');
5694 $reg = array();
5695 foreach ($listofobject as $fileobj) {
5696 $tmpcontent = file_get_contents($fileobj['fullname']);
5697 if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
5698 $objects[$fileobj['fullname']] = $reg[1];
5699 }
5700 }
5701
5702 // declared select list for actions and labels permissions
5703 $crud = array('read' => 'CRUDRead', 'write' => 'CRUDCreateWrite', 'delete' => 'Delete');
5704 $labels = array("Read objects of ".$module, "Create/Update objects of ".$module, "Delete objects of ".$module);
5705
5706 $action = GETPOST('action', 'alpha');
5707
5708 if ($action == 'deleteright') {
5709 $formconfirm = $form->formconfirm(
5710 $_SERVER["PHP_SELF"].'?permskey='.urlencode((string) (GETPOSTINT('permskey'))).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)).'&tabobj='.urlencode((string) ($tabobj)),
5711 $langs->trans('Delete'),
5712 $langs->trans('Confirm Delete Right', GETPOST('permskey', 'alpha')),
5713 'confirm_deleteright',
5714 '',
5715 0,
5716 1
5717 );
5718 print $formconfirm;
5719 }
5720
5721 if ($action != 'editfile' || empty($file)) {
5722 print '<!-- Tab to manage permissions -->'."\n";
5723 print '<span class="opacitymedium">';
5724 $htmlhelp = $langs->trans("PermissionsDefDescTooltip", '{s1}');
5725 $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/perms.php">'.$langs->trans('DefaultRights').'</a>', $htmlhelp);
5726 print $form->textwithpicto($langs->trans("PermissionsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
5727 print '</span>';
5728 print '<br>';
5729
5730 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5731 print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=PERMISSIONS">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
5732 print '<br>';
5733
5734 print '<br>';
5735 print load_fiche_titre($langs->trans("ListOfPermissionsDefined"), '', '');
5736
5737 print '<!-- form to add permissions -->'."\n";
5738 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5739 print '<input type="hidden" name="token" value="'.newToken().'">';
5740 print '<input type="hidden" name="action" value="addright">';
5741 print '<input type="hidden" name="tab" value="permissions">';
5742 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5743 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
5744
5745 print '<div class="div-table-responsive">';
5746 print '<table class="noborder">';
5747
5748 print '<tr class="liste_titre">';
5749 print_liste_field_titre("ID", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5750 print_liste_field_titre("Object", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5751 print_liste_field_titre("CRUD", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5752 print_liste_field_titre("Label", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5753 print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5754 print "</tr>\n";
5755
5756 //form for add new right
5757 print '<tr class="small">';
5758 print '<td><input type="hidden" readonly name="id" class="width75" value="0"></td>';
5759
5760 print '<td><select class="minwidth100" name="permissionObj" id="permissionObj">';
5761 print '<option value=""></option>';
5762 foreach ($objects as $obj) {
5763 if ($obj != 'myobject') {
5764 print '<option value="'.$obj.'">'.$obj.'</option>';
5765 }
5766 }
5767 print '</select></td>';
5768
5769 print '<td><select class="maxwidth75" name="crud" id="crud">';
5770 print '<option value=""></option>';
5771 foreach ($crud as $key => $val) {
5772 print '<option value="'.$key.'">'.$langs->trans($val).'</option>';
5773 }
5774 print '</td>';
5775
5776 print '<td >';
5777 print '<input type="text" name="label" id="label" class="minwidth200">';
5778 print '</td>';
5779
5780 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5781 print '<input type="submit" class="button" name="add" value="'.$langs->trans("Add").'">';
5782 print '</td>';
5783 print '</tr>';
5784
5785 if (count($perms)) {
5786 $i = 0;
5787 foreach ($perms as $perm) {
5788 $i++;
5789
5790 // section for editing right
5791 if ($action == 'edit_right' && $perm[0] == GETPOSTINT('permskey')) {
5792 print '<tr class="oddeven">';
5793 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="modifPerms">';
5794 print '<input type="hidden" name="token" value="'.newToken().'">';
5795 print '<input type="hidden" name="tab" value="permissions">';
5796 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5797 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
5798 print '<input type="hidden" name="action" value="update_right">';
5799 print '<input type="hidden" name="counter" value="'.$i.'">';
5800
5801 print '<input type="hidden" name="permskey" value="'.$perm[0].'">';
5802
5803 print '<td class="tdsticky tdstickygray">';
5804 print '<input class="width75" type="text" readonly value="'.dol_escape_htmltag($perm[0]).'"/>';
5805 print '</td>';
5806
5807 print '<td>';
5808 print '<select name="crud">';
5809 print '<option value="'.dol_escape_htmltag($perm[5]).'">'.$langs->trans($perm[5]).'</option>';
5810 foreach ($crud as $i => $x) {
5811 if ($perm[5] != $i) {
5812 print '<option value="'.$i.'">'.$langs->trans(ucfirst($x)).'</option>';
5813 }
5814 }
5815 print '</select>';
5816 print '</td>';
5817
5818 print '<td><select name="permissionObj" >';
5819 print '<option value="'.dol_escape_htmltag($perm[4]).'">'.ucfirst($perm[4]).'</option>';
5820 print '</select></td>';
5821
5822 print '<td>';
5823 print '<input type="text" name="label" value="'.dol_escape_htmltag($perm[1]).'">';
5824 print '</td>';
5825
5826 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5827 print '<input id ="modifyPerm" class="reposition button smallpaddingimp" type="submit" name="modifyright" value="'.$langs->trans("Modify").'"/>';
5828 print '<br>';
5829 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
5830 print '</td>';
5831
5832 print '</form>';
5833 print '</tr>';
5834 } else {
5835 // $perm can be module->object->crud or module->crud
5836 print '<tr class="oddeven">';
5837
5838 print '<td>';
5839 print dol_escape_htmltag($perm[0]);
5840 print '</td>';
5841
5842 print '<td>';
5843 if (in_array($perm[5], array('lire', 'read', 'creer', 'write', 'effacer', 'delete'))) {
5844 print dol_escape_htmltag(ucfirst($perm[4]));
5845 } else {
5846 print ''; // No particular object
5847 }
5848 print '</td>';
5849
5850 print '<td>';
5851 if (in_array($perm[5], array('lire', 'read', 'creer', 'write', 'effacer', 'delete'))) {
5852 print ucfirst($langs->trans($perm[5]));
5853 } else {
5854 print ucfirst($langs->trans($perm[4]));
5855 }
5856 print '</td>';
5857
5858 print '<td>';
5859 print $langs->trans($perm[1]);
5860 print '</td>';
5861
5862 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5863 print '<a class="editfielda reposition marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=edit_right&token='.newToken().'&permskey='.urlencode($perm[0]).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_edit().'</a>';
5864 print '<a class="marginleftonly marginrighttonly paddingright paddingleft" href="'.$_SERVER["PHP_SELF"].'?action=deleteright&token='.newToken().'&permskey='.urlencode((string) ($i)).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)).'&tabobj='.urlencode((string) ($tabobj)).'">'.img_delete().'</a>';
5865
5866 print '</td>';
5867
5868 print '</tr>';
5869 }
5870 }
5871 } else {
5872 print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
5873 }
5874
5875 print '</table>';
5876 print '</div>';
5877
5878 print '</form>';
5879 print '<script>
5880 function updateInputField() {
5881 value1 = $("#crud").val();
5882 value2 = $("#permissionObj").val();
5883
5884 // Vérifie si les deux sélections sont faites
5885 if (value1 && value2) {
5886 switch(value1.toLowerCase()){
5887 case "read":
5888 $("#label").val("Read "+value2+" object of '.ucfirst($module).'")
5889 break;
5890 case "write":
5891 $("#label").val("Create/Update "+value2+" object of '.ucfirst($module).'")
5892 break;
5893 case "delete":
5894 $("#label").val("Delete "+value2+" object of '.ucfirst($module).'")
5895 break;
5896 default:
5897 $("#label").val("")
5898 }
5899 }
5900 }
5901
5902 $("#crud, #permissionObj").change(function(){
5903 console.log("We change selection");
5904 updateInputField();
5905 });
5906
5907 </script>';
5908 } else {
5909 $fullpathoffile = dol_buildpath($file, 0);
5910
5911 $content = file_get_contents($fullpathoffile);
5912
5913 // New module
5914 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5915 print '<input type="hidden" name="token" value="'.newToken().'">';
5916 print '<input type="hidden" name="action" value="savefile">';
5917 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5918 print '<input type="hidden" name="tab" value="'.$tab.'">';
5919 print '<input type="hidden" name="module" value="'.$module.'">';
5920
5921 $posCursor = (empty($find)) ? array() : array('find' => $find);
5922 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5923 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5924 print '<br>';
5925 print '<center>';
5926 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5927 print ' &nbsp; ';
5928 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5929 print '</center>';
5930
5931 print '</form>';
5932 }
5933 }
5934
5935 if ($tab == 'hooks') {
5936 print '<!-- tab=hooks -->'."\n";
5937 if ($action != 'editfile' || empty($file)) {
5938 print '<span class="opacitymedium">'.$langs->trans("HooksDefDesc").'</span><br>';
5939 print '<br>';
5940
5941 print '<table>';
5942
5943 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
5944 print '<tr><td>';
5945 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5946 print '</td><td>';
5947 print '<a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=HOOKSCONTEXTS">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
5948 print '</td></tr>';
5949
5950 print '<tr><td>';
5951 $pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
5952 print '<span class="fa fa-file"></span> '.$langs->trans("HooksFile").' : ';
5953 if (dol_is_file($dirins.'/'.$pathtohook)) {
5954 print '<strong class="wordbreak">'.$pathtohook.'</strong>';
5955 print '</td>';
5956 print '<td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Edit"), 'edit').'</a> ';
5957 print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
5958 } else {
5959 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
5960 print '<a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=inithook&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</td>';
5961 print '<td></td>';
5962 }
5963 print '</tr>';
5964 } else {
5965 $fullpathoffile = dol_buildpath($file, 0);
5966
5967 $content = file_get_contents($fullpathoffile);
5968
5969 // New module
5970 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5971 print '<input type="hidden" name="token" value="'.newToken().'">';
5972 print '<input type="hidden" name="action" value="savefile">';
5973 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5974 print '<input type="hidden" name="tab" value="'.$tab.'">';
5975 print '<input type="hidden" name="module" value="'.$module.'">';
5976
5977 $posCursor = (empty($find)) ? array() : array('find' => $find);
5978 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5979 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5980 print '<br>';
5981 print '<center>';
5982 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5983 print ' &nbsp; ';
5984 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5985 print '</center>';
5986
5987 print '</form>';
5988 }
5989 }
5990
5991 if ($tab == 'triggers') {
5992 print '<!-- tab=triggers -->'."\n";
5993 require_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
5994
5995 $interfaces = new Interfaces($db);
5996 $triggers = $interfaces->getTriggersList(array('/'.strtolower($module).'/core/triggers'));
5997
5998 if ($action != 'editfile' || empty($file)) {
5999 print '<span class="opacitymedium">'.$langs->trans("TriggerDefDesc").'</span><br>';
6000 print '<br>';
6001
6002 print '<table>';
6003
6004 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6005 print '<tr><td>';
6006 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6007 print '</td><td>';
6008 print '<a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=module_parts">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
6009 print '</td></tr>';
6010
6011 if (!empty($triggers)) {
6012 foreach ($triggers as $trigger) {
6013 $pathtofile = $trigger['relpath'];
6014
6015 print '<tr><td>';
6016 print '<span class="fa fa-file"></span> '.$langs->trans("TriggersFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6017 print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
6018 print '<td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
6019 print '</tr>';
6020 }
6021 } else {
6022 print '<tr><td>';
6023 print '<span class="fa fa-file"></span> '.$langs->trans("TriggersFile");
6024 print ' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6025 print '<a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=inittrigger&token='.newToken().'&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
6026 print '<td></td>';
6027 print '</tr>';
6028 }
6029
6030 print '</table>';
6031 } else {
6032 $fullpathoffile = dol_buildpath($file, 0);
6033
6034 $content = file_get_contents($fullpathoffile);
6035
6036 // New module
6037 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6038 print '<input type="hidden" name="token" value="'.newToken().'">';
6039 print '<input type="hidden" name="action" value="savefile">';
6040 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6041 print '<input type="hidden" name="tab" value="'.$tab.'">';
6042 print '<input type="hidden" name="module" value="'.$module.'">';
6043
6044 $posCursor = (empty($find)) ? array() : array('find' => $find);
6045 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
6046 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6047 print '<br>';
6048 print '<center>';
6049 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6050 print ' &nbsp; ';
6051 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6052 print '</center>';
6053
6054 print '</form>';
6055 }
6056 }
6057
6058 if ($tab == 'css') {
6059 print '<!-- tab=css -->'."\n";
6060 if ($action != 'editfile' || empty($file)) {
6061 print '<span class="opacitymedium">'.$langs->trans("CSSDesc").'</span><br>';
6062 print '<br>';
6063
6064 print '<table>';
6065
6066 print '<tr><td>';
6067 $pathtohook = strtolower($module).'/css/'.strtolower($module).'.css.php';
6068 print '<span class="fa fa-file"></span> '.$langs->trans("CSSFile").' : ';
6069 if (dol_is_file($dirins.'/'.$pathtohook)) {
6070 print '<strong class="wordbreak">'.$pathtohook.'</strong>';
6071 print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
6072 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&format='.$format.'&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
6073 } else {
6074 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6075 print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initcss&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
6076 }
6077 print '</tr>';
6078 } else {
6079 $fullpathoffile = dol_buildpath($file, 0);
6080
6081 $content = file_get_contents($fullpathoffile);
6082
6083 // New module
6084 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6085 print '<input type="hidden" name="token" value="'.newToken().'">';
6086 print '<input type="hidden" name="action" value="savefile">';
6087 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6088 print '<input type="hidden" name="tab" value="'.$tab.'">';
6089 print '<input type="hidden" name="module" value="'.$module.'">';
6090
6091 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
6092 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6093 print '<br>';
6094 print '<center>';
6095 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6096 print ' &nbsp; ';
6097 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6098 print '</center>';
6099
6100 print '</form>';
6101 }
6102 }
6103
6104 if ($tab == 'js') {
6105 print '<!-- tab=js -->'."\n";
6106 if ($action != 'editfile' || empty($file)) {
6107 print '<span class="opacitymedium">'.$langs->trans("JSDesc").'</span><br>';
6108 print '<br>';
6109
6110 print '<table>';
6111
6112 print '<tr><td>';
6113 $pathtohook = strtolower($module).'/js/'.strtolower($module).'.js.php';
6114 print '<span class="fa fa-file"></span> '.$langs->trans("JSFile").' : ';
6115 if (dol_is_file($dirins.'/'.$pathtohook)) {
6116 print '<strong class="wordbreak">'.$pathtohook.'</strong>';
6117 print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
6118 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
6119 } else {
6120 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6121 print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initjs&token='.newToken().'&format=php&file='.urlencode($pathtohook).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
6122 }
6123 print '</tr>';
6124 } else {
6125 $fullpathoffile = dol_buildpath($file, 0);
6126
6127 $content = file_get_contents($fullpathoffile);
6128
6129 // New module
6130 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6131 print '<input type="hidden" name="token" value="'.newToken().'">';
6132 print '<input type="hidden" name="action" value="savefile">';
6133 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6134 print '<input type="hidden" name="tab" value="'.$tab.'">';
6135 print '<input type="hidden" name="module" value="'.$module.'">';
6136
6137 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
6138 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6139 print '<br>';
6140 print '<center>';
6141 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6142 print ' &nbsp; ';
6143 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6144 print '</center>';
6145
6146 print '</form>';
6147 }
6148 }
6149
6150 if ($tab == 'widgets') {
6151 print '<!-- tab=widgets -->'."\n";
6152 require_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php';
6153
6154 $widgets = ModeleBoxes::getWidgetsList(array('/'.strtolower($module).'/core/boxes'));
6155
6156 if ($action != 'editfile' || empty($file)) {
6157 print '<span class="opacitymedium">'.$langs->trans("WidgetDesc").'</span><br>';
6158 print '<br>';
6159
6160 print '<table>';
6161 if (!empty($widgets)) {
6162 foreach ($widgets as $widget) {
6163 $pathtofile = $widget['relpath'];
6164
6165 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("WidgetFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6166 print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
6167 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
6168 print '</tr>';
6169 }
6170 } else {
6171 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("WidgetFile").' : <span class="opacitymedium">'.$langs->trans("NoWidget").'</span>';
6172 print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initwidget&token='.newToken().'&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
6173 print '</td></tr>';
6174 }
6175 print '</table>';
6176 } else {
6177 $fullpathoffile = dol_buildpath($file, 0);
6178
6179 $content = file_get_contents($fullpathoffile);
6180
6181 // New module
6182 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6183 print '<input type="hidden" name="token" value="'.newToken().'">';
6184 print '<input type="hidden" name="action" value="savefile">';
6185 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6186 print '<input type="hidden" name="tab" value="'.$tab.'">';
6187 print '<input type="hidden" name="module" value="'.$module.'">';
6188
6189 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
6190 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6191 print '<br>';
6192 print '<center>';
6193 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6194 print ' &nbsp; ';
6195 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6196 print '</center>';
6197
6198 print '</form>';
6199 }
6200 }
6201
6202 if ($tab == 'emailings') {
6203 print '<!-- tab=emailings -->'."\n";
6204 require_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
6205
6206 $emailingselectors = MailingTargets::getEmailingSelectorsList(array('/'.strtolower($module).'/core/modules/mailings'));
6207
6208 if ($action != 'editfile' || empty($file)) {
6209 print '<span class="opacitymedium">'.$langs->trans("EmailingSelectorDesc").'</span><br>';
6210 print '<br>';
6211
6212 print '<table>';
6213 if (!empty($emailingselectors)) {
6214 foreach ($emailingselectors as $emailingselector) {
6215 $pathtofile = $emailingselector['relpath'];
6216
6217 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("EmailingSelectorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6218 print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
6219 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
6220 print '</tr>';
6221 }
6222 } else {
6223 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("EmailingSelectorFile").' : <span class="opacitymedium">'.$langs->trans("NoEmailingSelector").'</span>';
6224 print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initemailing&token='.newToken().'&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
6225 print '</td></tr>';
6226 }
6227 print '</table>';
6228 } else {
6229 $fullpathoffile = dol_buildpath($file, 0);
6230
6231 $content = file_get_contents($fullpathoffile);
6232
6233 // New module
6234 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6235 print '<input type="hidden" name="token" value="'.newToken().'">';
6236 print '<input type="hidden" name="action" value="savefile">';
6237 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6238 print '<input type="hidden" name="tab" value="'.$tab.'">';
6239 print '<input type="hidden" name="module" value="'.$module.'">';
6240
6241 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
6242 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6243 print '<br>';
6244 print '<center>';
6245 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6246 print ' &nbsp; ';
6247 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6248 print '</center>';
6249
6250 print '</form>';
6251 }
6252 }
6253
6254 if ($tab == 'exportimport') {
6255 print '<!-- tab=exportimport -->'."\n";
6256 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6257
6258 $exportlist = $moduleobj->export_label;
6259 $importlist = $moduleobj->import_label;
6260
6261 if ($action != 'editfile' || empty($file)) {
6262 print '<span class="opacitymedium">'.$langs->transnoentities('ImportExportProfiles').'</span><br>';
6263 print '<br>';
6264
6265 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' ('.$langs->trans("ExportsArea").') : <strong class="wordbreak">'.$pathtofile.'</strong>';
6266 print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=EXPORT">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
6267 print '<br>';
6268 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' ('.$langs->trans("ImportArea").') : <strong class="wordbreak">'.$pathtofile.'</strong>';
6269 print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=IMPORT">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
6270 print '<br>';
6271 } else {
6272 $fullpathoffile = dol_buildpath($file, 0);
6273
6274 $content = file_get_contents($fullpathoffile);
6275
6276 // New module
6277 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6278 print '<input type="hidden" name="token" value="'.newToken().'">';
6279 print '<input type="hidden" name="action" value="savefile">';
6280 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6281 print '<input type="hidden" name="tab" value="'.$tab.'">';
6282 print '<input type="hidden" name="module" value="'.$module.'">';
6283
6284 $posCursor = (empty($find)) ? array() : array('find' => $find);
6285 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
6286 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6287 print '<br>';
6288 print '<center>';
6289 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6290 print ' &nbsp; ';
6291 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6292 print '</center>';
6293
6294 print '</form>';
6295 }
6296 }
6297
6298 if ($tab == 'cli') {
6299 print '<!-- tab=cli -->'."\n";
6300 $clifiles = array();
6301 $i = 0;
6302
6303 $dircli = array('/'.strtolower($module).'/scripts');
6304
6305 foreach ($dircli as $reldir) {
6306 $dir = dol_buildpath($reldir, 0);
6307 $newdir = dol_osencode($dir);
6308
6309 // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call)
6310 if (!is_dir($newdir)) {
6311 continue;
6312 }
6313
6314 $handle = opendir($newdir);
6315
6316 if (is_resource($handle)) {
6317 while (($tmpfile = readdir($handle)) !== false) {
6318 if (is_readable($newdir.'/'.$tmpfile) && preg_match('/^(.+)\.php/', $tmpfile, $reg)) {
6319 if (preg_match('/\.back$/', $tmpfile)) {
6320 continue;
6321 }
6322
6323 $clifiles[$i]['relpath'] = preg_replace('/^\//', '', $reldir).'/'.$tmpfile;
6324
6325 $i++;
6326 }
6327 }
6328 closedir($handle);
6329 }
6330 }
6331
6332 if ($action != 'editfile' || empty($file)) {
6333 print '<span class="opacitymedium">'.$langs->trans("CLIDesc").'</span><br>';
6334 print '<br>';
6335
6336 print '<table>';
6337 if (!empty($clifiles)) {
6338 foreach ($clifiles as $clifile) {
6339 $pathtofile = $clifile['relpath'];
6340
6341 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("CLIFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6342 print '</td><td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
6343 print '<td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
6344 print '</tr>';
6345 }
6346 } else {
6347 print '<tr><td><span class="fa fa-file"></span> '.$langs->trans("CLIFile").' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6348 print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initcli&token='.newToken().'&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';
6349 print '</td></tr>';
6350 }
6351 print '</table>';
6352 } else {
6353 $fullpathoffile = dol_buildpath($file, 0);
6354
6355 $content = file_get_contents($fullpathoffile);
6356
6357 // New module
6358 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6359 print '<input type="hidden" name="token" value="'.newToken().'">';
6360 print '<input type="hidden" name="action" value="savefile">';
6361 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6362 print '<input type="hidden" name="tab" value="'.$tab.'">';
6363 print '<input type="hidden" name="module" value="'.$module.'">';
6364
6365 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
6366 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6367 print '<br>';
6368 print '<center>';
6369 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6370 print ' &nbsp; ';
6371 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6372 print '</center>';
6373
6374 print '</form>';
6375 }
6376 }
6377
6378 if ($tab == 'cron') {
6379 print '<!-- tab=cron -->'."\n";
6380 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6381
6382 $cronjobs = $moduleobj->cronjobs;
6383
6384 if ($action != 'editfile' || empty($file)) {
6385 print '<span class="opacitymedium">'.str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/cron/list.php">'.$langs->transnoentities('CronList').'</a>', $langs->trans("CronJobDefDesc", '{s1}')).'</span><br>';
6386 print '<br>';
6387
6388 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6389 print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format=php&file='.urlencode($pathtofile).'&find=CRON">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
6390 print '<br>';
6391
6392 print '<br>';
6393 print load_fiche_titre($langs->trans("CronJobProfiles"), '', '');
6394
6395 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6396 print '<input type="hidden" name="token" value="'.newToken().'">';
6397 print '<input type="hidden" name="action" value="addproperty">';
6398 print '<input type="hidden" name="tab" value="objects">';
6399 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
6400 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
6401
6402 print '<div class="div-table-responsive">';
6403 print '<table class="noborder">';
6404
6405 print '<tr class="liste_titre">';
6406 print_liste_field_titre("CronLabel", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
6407 print_liste_field_titre("CronTask", '', '', "", $param, '', $sortfield, $sortorder);
6408 print_liste_field_titre("CronFrequency", '', "", "", $param, '', $sortfield, $sortorder);
6409 print_liste_field_titre("StatusAtInstall", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
6410 print_liste_field_titre("Comment", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
6411 print "</tr>\n";
6412
6413 if (count($cronjobs)) {
6414 foreach ($cronjobs as $cron) {
6415 print '<tr class="oddeven">';
6416
6417 print '<td>';
6418 print $cron['label'];
6419 print '</td>';
6420
6421 print '<td>';
6422 $texttoshow = null;
6423 if ($cron['jobtype'] == 'method') {
6424 $text = $langs->trans("CronClass");
6425 $texttoshow = $langs->trans('CronModule').': '.$module.'<br>';
6426 $texttoshow .= $langs->trans('CronClass').': '.$cron['class'].'<br>';
6427 $texttoshow .= $langs->trans('CronObject').': '.$cron['objectname'].'<br>';
6428 $texttoshow .= $langs->trans('CronMethod').': '.$cron['method'];
6429 $texttoshow .= '<br>'.$langs->trans('CronArgs').': '.$cron['parameters'];
6430 $texttoshow .= '<br>'.$langs->trans('Comment').': '.$langs->trans($cron['comment']);
6431 } elseif ($cron['jobtype'] == 'command') {
6432 $text = $langs->trans('CronCommand');
6433 $texttoshow = $langs->trans('CronCommand').': '.dol_trunc($cron['command']);
6434 $texttoshow .= '<br>'.$langs->trans('CronArgs').': '.$cron['parameters'];
6435 $texttoshow .= '<br>'.$langs->trans('Comment').': '.$langs->trans($cron['comment']);
6436 }
6437 print $form->textwithpicto($text, $texttoshow, 1);
6438 print '</td>';
6439
6440 print '<td>';
6441 if ($cron['unitfrequency'] == "60") {
6442 print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes');
6443 }
6444 if ($cron['unitfrequency'] == "3600") {
6445 print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours');
6446 }
6447 if ($cron['unitfrequency'] == "86400") {
6448 print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days');
6449 }
6450 if ($cron['unitfrequency'] == "604800") {
6451 print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks');
6452 }
6453 print '</td>';
6454
6455 print '<td>';
6456 print $cron['status'];
6457 print '</td>';
6458
6459 print '<td>';
6460 if (!empty($cron['comment'])) {
6461 print $cron['comment'];
6462 }
6463 print '</td>';
6464
6465 print '</tr>';
6466 }
6467 } else {
6468 print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
6469 }
6470
6471 print '</table>';
6472 print '</div>';
6473
6474 print '</form>';
6475 } else {
6476 $fullpathoffile = dol_buildpath($file, 0);
6477
6478 $content = file_get_contents($fullpathoffile);
6479
6480 // New module
6481 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6482 print '<input type="hidden" name="token" value="'.newToken().'">';
6483 print '<input type="hidden" name="action" value="savefile">';
6484 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6485 print '<input type="hidden" name="tab" value="'.$tab.'">';
6486 print '<input type="hidden" name="module" value="'.$module.'">';
6487
6488 $posCursor = (empty($find)) ? array() : array('find' => $find);
6489 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
6490 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6491 print '<br>';
6492 print '<center>';
6493 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6494 print ' &nbsp; ';
6495 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6496 print '</center>';
6497
6498 print '</form>';
6499 }
6500 }
6501
6502 if ($tab == 'specifications') {
6503 print '<!-- tab=specifications -->'."\n";
6504 $specs = dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/'));
6505
6506 if ($action != 'editfile' || empty($file)) {
6507 print '<span class="opacitymedium">'.$langs->trans("SpecDefDesc").'</span><br>';
6508 print '<br>';
6509
6510 print '<table>';
6511 if (is_array($specs) && !empty($specs)) {
6512 foreach ($specs as $spec) {
6513 $pathtofile = $modulelowercase.'/doc/'.$spec['relativename'];
6514 $format = 'asciidoc';
6515 if (preg_match('/\.md$/i', $spec['name'])) {
6516 $format = 'markdown';
6517 }
6518 print '<tr><td>';
6519 print '<span class="fa fa-file"></span> '.$langs->trans("SpecificationFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6520 print '</td><td><a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&token='.newToken().'&format='.$format.'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
6521 print '<td><a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&format='.$format.'&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Delete"), 'delete').'</a></td>';
6522 print '</tr>';
6523 }
6524 } else {
6525 print '<tr><td>';
6526 print '<span class="fa fa-file"></span> '.$langs->trans("SpecificationFile").' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6527 print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initdoc&token='.newToken().'&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
6528 print '</tr>';
6529 }
6530 print '</table>';
6531 } else {
6532 // Use MD or asciidoc
6533
6534 //print $langs->trans("UseAsciiDocFormat").'<br>';
6535
6536 $fullpathoffile = dol_buildpath($file, 0);
6537
6538 $content = file_get_contents($fullpathoffile);
6539
6540 // New module
6541 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6542 print '<input type="hidden" name="token" value="'.newToken().'">';
6543 print '<input type="hidden" name="action" value="savefile">';
6544 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6545 print '<input type="hidden" name="tab" value="'.$tab.'">';
6546 print '<input type="hidden" name="module" value="'.$module.'">';
6547
6548 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%');
6549 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6550 print '<br>';
6551 print '<center>';
6552 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6553 print ' &nbsp; ';
6554 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6555 print '</center>';
6556
6557 print '</form>';
6558 }
6559
6560 print '<br><br><br>';
6561
6562 $FILENAMEDOC = $modulelowercase.'.html';
6563 $FILENAMEDOCPDF = $modulelowercase.'.pdf';
6564 $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC;
6565 $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC;
6566 $outputfiledocrel = $modulelowercase.'/doc/'.$FILENAMEDOC;
6567 $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF;
6568 $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF;
6569 $outputfiledocrelpdf = $modulelowercase.'/doc/'.$FILENAMEDOCPDF;
6570
6571 // HTML
6572 print '<span class="fa fa-file"></span> '.$langs->trans("PathToModuleDocumentation", "HTML").' : ';
6573 if (!dol_is_file($outputfiledoc)) {
6574 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6575 } else {
6576 print '<strong>';
6577 print '<a href="'.$outputfiledocurl.'" target="_blank" rel="noopener noreferrer">';
6578 print $outputfiledoc;
6579 print '</a>';
6580 print '</strong>';
6581 print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledoc), 'dayhour').')</span>';
6582 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&format='.$format.'&file='.urlencode($outputfiledocrel).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
6583 }
6584 print '</strong><br>';
6585
6586 // PDF
6587 print '<span class="fa fa-file"></span> '.$langs->trans("PathToModuleDocumentation", "PDF").' : ';
6588 if (!dol_is_file($outputfiledocpdf)) {
6589 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6590 } else {
6591 print '<strong>';
6592 print '<a href="'.$outputfiledocurlpdf.'" target="_blank" rel="noopener noreferrer">';
6593 print $outputfiledocpdf;
6594 print '</a>';
6595 print '</strong>';
6596 print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledocpdf), 'dayhour').')</span>';
6597 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&format='.$format.'&file='.urlencode($outputfiledocrelpdf).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
6598 }
6599 print '</strong><br>';
6600
6601 print '<br>';
6602
6603 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="generatedoc">';
6604 print '<input type="hidden" name="token" value="'.newToken().'">';
6605 print '<input type="hidden" name="action" value="generatedoc">';
6606 print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
6607 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
6608 print '<input type="submit" class="button" name="generatedoc" value="'.$langs->trans("BuildDocumentation").'"';
6609 if (!is_array($specs) || empty($specs)) {
6610 print ' disabled="disabled"';
6611 }
6612 print '>';
6613 print '</form>';
6614 }
6615
6616 if ($tab == 'buildpackage') {
6617 print '<!-- tab=buildpackage -->'."\n";
6618 print '<span class="opacitymedium">'.$langs->trans("BuildPackageDesc").'</span>';
6619 print '<br>';
6620
6621 if (!class_exists('ZipArchive') && !defined('ODTPHP_PATHTOPCLZIP')) {
6622 print img_warning().' '.$langs->trans("ErrNoZipEngine");
6623 print '<br>';
6624 }
6625
6626 $modulelowercase = strtolower($module);
6627
6628 // Zip file to build
6629 $FILENAMEZIP = '';
6630
6631 // Load module
6632 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6633 dol_include_once($pathtofile);
6634 $class = 'mod'.$module;
6635 $moduleobj = null;
6636 if (class_exists($class)) {
6637 try {
6638 $moduleobj = new $class($db);
6639 '@phan-var-force DolibarrModules $moduleobj';
6641 } catch (Exception $e) {
6642 $error++;
6643 dol_print_error($db, $e->getMessage());
6644 }
6645 }
6646 if ($moduleobj === null) {
6647 $error++;
6648 $langs->load("errors");
6649 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
6650 exit;
6651 }
6652
6653 $arrayversion = explode('.', $moduleobj->version, 3);
6654 if (count($arrayversion)) {
6655 $FILENAMEZIP = "module_".$modulelowercase.'-'.$arrayversion[0].(empty($arrayversion[1]) ? '.0' : '.'.$arrayversion[1]).(empty($arrayversion[2]) ? '' : ".".$arrayversion[2]).".zip";
6656 $outputfilezip = dol_buildpath($modulelowercase, 0).'/bin/'.$FILENAMEZIP;
6657 }
6658
6659 print '<br>';
6660
6661 print '<span class="fa fa-file"></span> '.$langs->trans("PathToModulePackage").' : ';
6662 if (!dol_is_file($outputfilezip)) {
6663 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6664 } else {
6665 $relativepath = $modulelowercase.'/bin/'.$FILENAMEZIP;
6666 print '<strong><a href="'.DOL_URL_ROOT.'/document.php?modulepart=packages&file='.urlencode($relativepath).'">'.$outputfilezip.'</a></strong>';
6667 print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfilezip), 'dayhour').')</span>';
6668 print ' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=confirm_removefile&token='.newToken().'&file='.urlencode($relativepath).'">'.img_picto($langs->trans("Delete"), 'delete').'</a>';
6669 }
6670 print '</strong>';
6671
6672 print '<br>';
6673
6674 print '<br>';
6675
6676 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="generatepackage">';
6677 print '<input type="hidden" name="token" value="'.newToken().'">';
6678 print '<input type="hidden" name="action" value="generatepackage">';
6679 print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
6680 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
6681 print '<input type="submit" class="button" name="generatepackage" value="'.$langs->trans("BuildPackage").'">';
6682 print '</form>';
6683 }
6684
6685 if ($tab == 'tabs') {
6686 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6687
6688 $tabs = $moduleobj->tabs;
6689
6690 if ($action != 'editfile' || empty($file)) {
6691 print '<span class="opacitymedium">';
6692 $htmlhelp = $langs->trans("TabsDefDescTooltip", '{s1}');
6693 $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/menus/index.php">'.$langs->trans('Setup').' - '.$langs->trans('Tabs').'</a>', $htmlhelp);
6694 print $form->textwithpicto($langs->trans("TabsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
6695 print '</span>';
6696 print '<br>';
6697
6698 print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong>'.$pathtofile.'</strong>';
6699 print ' <a class="editfielda paddingleft paddingright" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=editfile&format=php&file='.urlencode($pathtofile).'&find=TABS">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
6700 print '<br>';
6701
6702 print '<br>';
6703 print load_fiche_titre($langs->trans("ListOfTabsEntries"), '', '');
6704
6705 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6706 print '<input type="hidden" name="token" value="'.newToken().'">';
6707 print '<input type="hidden" name="action" value="addproperty">';
6708 print '<input type="hidden" name="tab" value="objects">';
6709 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
6710 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
6711
6712 print '<div class="div-table-responsive">';
6713 print '<table class="noborder small">';
6714
6715 print '<tr class="liste_titre">';
6716 print_liste_field_titre("ObjectType", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6717 print_liste_field_titre("Tab", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6718 print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6719 print_liste_field_titre("LangFile", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6720 print_liste_field_titre("Condition", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6721 print_liste_field_titre("Path", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6722 print "</tr>\n";
6723
6724 if (count($tabs)) {
6725 foreach ($tabs as $tab) {
6726 $parts = explode(':', $tab['data']);
6727
6728 $objectType = $parts[0];
6729 $tabName = $parts[1];
6730 $tabTitle = isset($parts[2]) ? $parts[2] : '';
6731 $langFile = isset($parts[3]) ? $parts[3] : '';
6732 $condition = isset($parts[4]) ? $parts[4] : '';
6733 $path = isset($parts[5]) ? $parts[5] : '';
6734
6735 // If we want to remove the tab, then the format is 'objecttype:tabname:optionalcondition'
6736 // See: https://wiki.dolibarr.org/index.php?title=Tabs_system#To_remove_an_existing_tab
6737 if ($tabName[0] === '-') {
6738 $tabTitle = '';
6739 $condition = isset($parts[2]) ? $parts[2] : '';
6740 }
6741
6742 print '<tr class="oddeven">';
6743
6744 print '<td>';
6745 print dol_escape_htmltag($parts[0]);
6746 print '</td>';
6747
6748 print '<td>';
6749 if ($tabName[0] === "+") {
6750 print '<span class="badge badge-status4 badge-status">' . dol_escape_htmltag($tabName) . '</span>';
6751 } else {
6752 print '<span class="badge badge-status8 badge-status">' . dol_escape_htmltag($tabName) . '</span>';
6753 }
6754 print '</td>';
6755
6756 print '<td>';
6757 print dol_escape_htmltag($tabTitle);
6758 print '</td>';
6759
6760 print '<td>';
6761 print dol_escape_htmltag($langFile);
6762 print '</td>';
6763
6764 print '<td>';
6765 print dol_escape_htmltag($condition);
6766 print '</td>';
6767
6768 print '<td>';
6769 print dol_escape_htmltag($path);
6770 print '</td>';
6771
6772 print '</tr>';
6773 }
6774 } else {
6775 print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
6776 }
6777
6778 print '</table>';
6779 print '</div>';
6780
6781 print '</form>';
6782 } else {
6783 $fullpathoffile = dol_buildpath($file, 0);
6784
6785 $content = file_get_contents($fullpathoffile);
6786
6787 // New module
6788 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6789 print '<input type="hidden" name="token" value="'.newToken().'">';
6790 print '<input type="hidden" name="action" value="savefile">';
6791 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6792 print '<input type="hidden" name="tab" value="'.$tab.'">';
6793 print '<input type="hidden" name="module" value="'.$module.'">';
6794
6795 $posCursor = (empty($find)) ? array() : array('find' => $find);
6796 $doleditor = new DolEditor('editfilecontent', $content, '', 300, 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
6797 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6798 print '<br>';
6799 print '<center>';
6800 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6801 print ' &nbsp; ';
6802 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6803 print '</center>';
6804
6805 print '</form>';
6806 }
6807 }
6808
6809 if ($tab != 'description') {
6810 print dol_get_fiche_end();
6811 }
6812 }
6813}
6814
6815print dol_get_fiche_end(); // End modules
6816
6817
6818// End of page
6819llxFooter();
6820$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
unActivateModule($value, $requiredby=1)
Disable a module.
activateModule($value, $withdeps=1, $noconfverification=0)
Enable a module.
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:459
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
print $object position
Definition edit.php:204
Class to manage a WYSIWYG editor.
Class to generate html code for admin pages.
Class to manage generation of HTML components Only common components must be here.
Class to manage triggers.
static getEmailingSelectorsList($forcedir=null)
Return list of widget.
static getWidgetsList($forcedirwidget=null)
Return list of widget.
Class to manage utility methods.
dol_filemtime($pathoffile)
Return time of a file.
dol_copy($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=0)
Copy a file to another file.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_delete_dir($dir, $nophperrors=0)
Remove a directory (not recursive, so content must be empty).
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement=null, $excludesubdir=0, $excludefileext=null, $excludearchivefiles=0)
Copy a dir to another dir.
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
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_is_dir_empty($dir)
Return if path is empty.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
dolExplodeIntoArray($string, $delimiter=';', $kv='=')
Split a string with 2 keys into key array.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $disabled='', $morecss='classlink button bordertransp', $jsonopen='', $backtopagejsfields='', $accesskey='')
Return HTML code to output a button to open a dialog popup box.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
getPictoForType($key, $morecss='')
Return the picto for a data type.
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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...
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_sanitizePathName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a path name.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
a disabled
treeview li table
No Email.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
$moduleobj
Definition index.php:3253
foreach( $dirsrootforscan as $tmpdirread) moduleBuilderShutdownFunction()
Add management to catch fatal errors - shutdown handler.
Definition index.php:238
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)
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.
dolGetListOfObjectClasses($destdir)
Get list of existing objects from a directory.
writePropsInAsciiDoc($file, $objectname, $destfile)
Write all properties of the object in AsciiDoc format.
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.
$conf db user
Active Directory does not allow anonymous connections.
Definition repair.php:154
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:150
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:153
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.