dolibarr 21.0.0-alpha
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
46// Load translation files required by the page
47$langs->loadLangs(array("admin", "modulebuilder", "exports", "other", "cron", "errors"));
48
49// GET Parameters
50$action = GETPOST('action', 'aZ09');
51$confirm = GETPOST('confirm', 'alpha');
52$cancel = GETPOST('cancel', 'alpha');
53
54$sortfield = GETPOST('sortfield', 'alpha');
55$sortorder = GETPOST('sortorder', 'aZ09');
56
57$module = GETPOST('module', 'alpha');
58$tab = GETPOST('tab', 'aZ09');
59$tabobj = GETPOST('tabobj', 'alpha');
60$tabdic = GETPOST('tabdic', 'alpha');
61$propertykey = GETPOST('propertykey', 'alpha');
62if (empty($module)) {
63 $module = 'initmodule';
64}
65if (empty($tab)) {
66 $tab = 'description';
67}
68if (empty($tabobj)) {
69 $tabobj = 'newobjectifnoobj';
70}
71if (empty($tabdic)) {
72 $tabdic = 'newdicifnodic';
73}
74$file = GETPOST('file', 'alpha');
75$find = GETPOST('find', 'alpha');
76
77$modulename = dol_sanitizeFileName(GETPOST('modulename', 'alpha'));
78$objectname = dol_sanitizeFileName(GETPOST('objectname', 'alpha'));
79$dicname = dol_sanitizeFileName(GETPOST('dicname', 'alpha'));
80$editorname = GETPOST('editorname', 'alpha');
81$editorurl = GETPOST('editorurl', 'alpha');
82$version = GETPOST('version', 'alpha');
83$family = GETPOST('family', 'alpha');
84$picto = GETPOST('idpicto', 'alpha');
85$idmodule = GETPOST('idmodule', 'alpha');
86
87// Security check
88if (!isModEnabled('modulebuilder')) {
89 accessforbidden('Module ModuleBuilder not enabled');
90}
91if (!$user->hasRight("modulebuilder", "run")) {
92 accessforbidden('ModuleBuilderNotAllowed');
93}
94
95// Dir for custom dirs
96$tmp = explode(',', $dolibarr_main_document_root_alt);
97$dirins = $tmp[0];
98$dirread = $dirins;
99$forceddirread = 0;
100
101$tmpdir = explode('@', $module);
102if (!empty($tmpdir[1])) {
103 $module = $tmpdir[0];
104 $dirread = $tmpdir[1];
105 $forceddirread = 1;
106}
107if (GETPOST('dirins', 'alpha')) {
108 $dirread = $dirins = GETPOST('dirins', 'alpha');
109 $forceddirread = 1;
110}
111
112$FILEFLAG = 'modulebuilder.txt';
113
114$now = dol_now();
115$newmask = 0;
116if (empty($newmask) && getDolGlobalString('MAIN_UMASK')) {
117 $newmask = getDolGlobalString('MAIN_UMASK');
118}
119if (empty($newmask)) { // This should no happen
120 $newmask = '0664';
121}
122
123$result = restrictedArea($user, 'modulebuilder', 0);
124
125$error = 0;
126
127$form = new Form($db);
128
129// Define $listofmodules
130$dirsrootforscan = array($dirread);
131
132// Add also the core modules into the list of modules to show/edit
133if ($dirread != DOL_DOCUMENT_ROOT && (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2 || getDolGlobalString('MODULEBUILDER_ADD_DOCUMENT_ROOT'))) {
134 $dirsrootforscan[] = DOL_DOCUMENT_ROOT;
135}
136
137// Search modules to edit
138$textforlistofdirs = '<!-- Directory scanned -->'."\n";
139$listofmodules = array();
140$i = 0;
141foreach ($dirsrootforscan as $tmpdirread) {
142 $moduletype = 'external';
143 if ($tmpdirread == DOL_DOCUMENT_ROOT) {
144 $moduletype = 'internal';
145 }
146
147 $dirsincustom = dol_dir_list($tmpdirread, 'directories');
148 if (is_array($dirsincustom) && count($dirsincustom) > 0) {
149 foreach ($dirsincustom as $dircustomcursor) {
150 $fullname = $dircustomcursor['fullname'];
151 if (dol_is_file($fullname.'/'.$FILEFLAG)) {
152 // Get real name of module (MyModule instead of mymodule)
153 $dirtoscanrel = basename($fullname).'/core/modules/';
154
155 $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$');
156 if (empty($descriptorfiles)) { // If descriptor not found into module dir, we look into main module dir.
157 $dirtoscanrel = 'core/modules/';
158 $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$');
159 }
160 $modulenamewithcase = '';
161 $moduledescriptorrelpath = '';
162 $moduledescriptorfullpath = '';
163
164 foreach ($descriptorfiles as $descriptorcursor) {
165 $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']);
166 $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase);
167 $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name'];
168 $moduledescriptorfullpath = $descriptorcursor['fullname'];
169 //var_dump($descriptorcursor);
170 }
171 if ($modulenamewithcase) {
172 $listofmodules[$dircustomcursor['name']] = array(
173 'modulenamewithcase' => $modulenamewithcase,
174 'moduledescriptorrelpath' => $moduledescriptorrelpath,
175 'moduledescriptorfullpath' => $moduledescriptorfullpath,
176 'moduledescriptorrootpath' => $tmpdirread,
177 'moduletype' => $moduletype
178 );
179 }
180 //var_dump($listofmodules);
181 }
182 }
183 }
184
185 if ($forceddirread && empty($listofmodules)) { // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir
186 $listofmodules[strtolower($module)] = array(
187 'modulenamewithcase' => $module,
188 'moduledescriptorrelpath' => 'notyetimplemented',
189 'moduledescriptorfullpath' => 'notyetimplemented',
190 'moduledescriptorrootpath' => 'notyetimplemented',
191 );
192 }
193
194 // Show description of content
195 $newdircustom = $dirins;
196 if (empty($newdircustom)) {
197 $newdircustom = img_warning();
198 }
199 // If dirread was forced to somewhere else, by using URL
200 // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product
201 if (empty($i)) {
202 $textforlistofdirs .= $langs->trans("DirScanned").' : ';
203 } else {
204 $textforlistofdirs .= ', ';
205 }
206 $textforlistofdirs .= '<strong class="wordbreakimp">'.$tmpdirread.'</strong>';
207 if ($tmpdirread == DOL_DOCUMENT_ROOT) {
208 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
209 $textforlistofdirs .= $form->textwithpicto('', $langs->trans("ConstantIsOn", "MAIN_FEATURES_LEVEL"));
210 }
211 if (getDolGlobalString('MODULEBUILDER_ADD_DOCUMENT_ROOT')) {
212 $textforlistofdirs .= $form->textwithpicto('', $langs->trans("ConstantIsOn", "MODULEBUILDER_ADD_DOCUMENT_ROOT"));
213 }
214 }
215 $i++;
216}
217
218
219/*
220 * Actions
221 */
222
223if ($dirins && $action == 'initmodule' && $modulename) {
224 $modulename = ucfirst($modulename); // Force first letter in uppercase
225
226 if (preg_match('/[^a-z0-9_]/i', $modulename)) {
227 $error++;
228 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
229 }
230
231 if (!$error) {
232 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
233 $destdir = $dirins.'/'.strtolower($modulename);
234
235 $arrayreplacement = array(
236 'mymodule' => strtolower($modulename),
237 'MyModule' => $modulename
238 );
239 $result = dolCopyDir($srcdir, $destdir, 0, 0, $arrayreplacement);
240 //dol_mkdir($destfile);
241 if ($result <= 0) {
242 if ($result < 0) {
243 $error++;
244 $langs->load("errors");
245 setEventMessages($langs->trans("ErrorFailToCopyDir", $srcdir, $destdir), null, 'errors');
246 } else {
247 // $result == 0
248 setEventMessages($langs->trans("AllFilesDidAlreadyExist", $srcdir, $destdir), null, 'warnings');
249 }
250 }
251
252 // Copy last 'html.formsetup.class.php' to backport folder
253 if (getDolGlobalInt('MODULEBUILDER_SUPPORT_COMPATIBILITY_V16')) {
254 $tryToCopyFromSetupClass = true;
255 $backportDest = $destdir .'/backport/v16/core/class';
256 $backportFileSrc = DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php';
257 $backportFileDest = $backportDest.'/html.formsetup.class.php';
258 $result = dol_mkdir($backportDest);
259
260 if ($result < 0) {
261 $error++;
262 $langs->load("errors");
263 setEventMessages($langs->trans("ErrorFailToCreateDir", $backportDest), null, 'errors');
264 $tryToCopyFromSetupClass = false;
265 }
266
267 if ($tryToCopyFromSetupClass) {
268 $result = dol_copy($backportFileSrc, $backportFileDest);
269 if ($result <= 0) {
270 if ($result < 0) {
271 $error++;
272 $langs->load("errors");
273 setEventMessages($langs->trans("ErrorFailToCopyFile", $backportFileSrc, $backportFileDest), null, 'errors');
274 } else {
275 setEventMessages($langs->trans("FileDidAlreadyExist", $backportFileDest), null, 'warnings');
276 }
277 }
278 }
279 }
280
281 if (getDolGlobalString('MODULEBUILDER_USE_ABOUT')) {
282 dol_delete_file($destdir.'/admin/about.php');
283 }
284
285 // Delete dir and files that can be generated in sub tabs later if we need them (we want a minimal module first)
286 dol_delete_dir_recursive($destdir.'/ajax');
287 dol_delete_dir_recursive($destdir.'/build/doxygen');
288 dol_delete_dir_recursive($destdir.'/core/modules/mailings');
289 dol_delete_dir_recursive($destdir.'/core/modules/'.strtolower($modulename));
290 dol_delete_dir_recursive($destdir.'/core/tpl');
291 dol_delete_dir_recursive($destdir.'/core/triggers');
292 dol_delete_dir_recursive($destdir.'/doc');
293 //dol_delete_dir_recursive($destdir.'/.tx');
294 dol_delete_dir_recursive($destdir.'/core/boxes');
295
296 dol_delete_file($destdir.'/admin/myobject_extrafields.php');
297
298 dol_delete_file($destdir.'/class/actions_'.strtolower($modulename).'.class.php');
299 dol_delete_file($destdir.'/class/api_'.strtolower($modulename).'.class.php');
300
301 dol_delete_file($destdir.'/css/'.strtolower($modulename).'.css.php');
302
303 dol_delete_file($destdir.'/js/'.strtolower($modulename).'.js.php');
304
305 dol_delete_file($destdir.'/scripts/'.strtolower($modulename).'.php');
306
307 dol_delete_file($destdir.'/sql/data.sql');
308 dol_delete_file($destdir.'/sql/update_x.x.x-y.y.y.sql');
309
310 // Delete some files related to Object (because the previous dolCopyDir has copied everything)
311 dol_delete_file($destdir.'/myobject_card.php');
312 dol_delete_file($destdir.'/myobject_contact.php');
313 dol_delete_file($destdir.'/myobject_note.php');
314 dol_delete_file($destdir.'/myobject_document.php');
315 dol_delete_file($destdir.'/myobject_agenda.php');
316 dol_delete_file($destdir.'/myobject_list.php');
317 dol_delete_file($destdir.'/lib/'.strtolower($modulename).'_myobject.lib.php');
318 dol_delete_file($destdir.'/test/phpunit/functional/'.$modulename.'FunctionalTest.php');
319 dol_delete_file($destdir.'/test/phpunit/MyObjectTest.php');
320 dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject.sql');
321 dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject_extrafields.sql');
322 dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject.key.sql');
323 dol_delete_file($destdir.'/sql/llx_'.strtolower($modulename).'_myobject_extrafields.key.sql');
324 dol_delete_file($destdir.'/class/myobject.class.php');
325
326 dol_delete_dir($destdir.'/class', 1);
327 dol_delete_dir($destdir.'/css', 1);
328 dol_delete_dir($destdir.'/js', 1);
329 dol_delete_dir($destdir.'/scripts', 1);
330 dol_delete_dir($destdir.'/sql', 1);
331 dol_delete_dir($destdir.'/test/phpunit/functionnal', 1);
332 dol_delete_dir($destdir.'/test/phpunit', 1);
333 dol_delete_dir($destdir.'/test', 1);
334 }
335
336 // Edit PHP files
337 if (!$error) {
338 $listofphpfilestoedit = dol_dir_list($destdir, 'files', 1, '\.(php|MD|js|sql|txt|xml|lang)$', '', 'fullname', SORT_ASC, 0, 1);
339 foreach ($listofphpfilestoedit as $phpfileval) {
340 //var_dump($phpfileval['fullname']);
341 $arrayreplacement = array(
342 'mymodule' => strtolower($modulename),
343 'MyModule' => $modulename,
344 'MYMODULE' => strtoupper($modulename),
345 'My module' => $modulename,
346 'my module' => $modulename,
347 'Mon module' => $modulename,
348 'mon module' => $modulename,
349 'htdocs/modulebuilder/template' => strtolower($modulename),
350 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : ''),
351 'Editor name' => $editorname,
352 'https://www.example.com' => $editorurl,
353 '$this->version = \'1.0\'' => '$this->version = \''.$version.'\'',
354 '$this->picto = \'generic\';' => (empty($picto)) ? '$this->picto = \'generic\'' : '$this->picto = \''.$picto.'\';',
355 "modulefamily" => $family,
356 '500000' => $idmodule
357 );
358
359 if (getDolGlobalString('MODULEBUILDER_SPECIFIC_AUTHOR')) {
360 $arrayreplacement['---Put here your own copyright and developer email---'] = dol_print_date($now, '%Y').' ' . getDolGlobalString('MODULEBUILDER_SPECIFIC_AUTHOR');
361 }
362
363 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
364 $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement);
365 //var_dump($result);
366 if ($result < 0) {
367 setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
368 }
369 }
370
371 if (getDolGlobalString('MODULEBUILDER_SPECIFIC_README')) {
372 setEventMessages($langs->trans("ContentOfREADMECustomized"), null, 'warnings');
373 dol_delete_file($destdir.'/README.md');
374 file_put_contents($destdir.'/README.md', $conf->global->MODULEBUILDER_SPECIFIC_README);
375 }
376 // for create file to add properties
377 // file_put_contents($destdir.'/'.strtolower($modulename).'propertycard.php','');
378 // $srcFileCard = DOL_DOCUMENT_ROOT.'/modulebuilder/card.php';
379 // $destFileCard = $dirins.'/'.strtolower($modulename).'/template/card.php';
380 // dol_copy($srcFileCard, $destdir.'/'.strtolower($modulename).'propertycard.php', 0,1, $arrayreplacement);
381 }
382
383 if (!$error) {
384 setEventMessages('ModuleInitialized', null);
385 $module = $modulename;
386
387 clearstatcache(true);
388 if (function_exists('opcache_invalidate')) {
389 opcache_reset(); // remove the include cache hell !
390 }
391
392 header("Location: ".$_SERVER["PHP_SELF"].'?module='.$modulename);
393 exit;
394 }
395}
396
397
398// init API, PHPUnit
399if ($dirins && in_array($action, array('initapi', 'initphpunit', 'initpagecontact', 'initpagedocument', 'initpagenote', 'initpageagenda')) && !empty($module)) {
400 $modulename = ucfirst($module); // Force first letter in uppercase
401 $objectname = $tabobj;
402 $varnametoupdate = '';
403 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
404 $destdir = $dirins.'/'.strtolower($module);
405
406 // Get list of existing objects
407 $objects = dolGetListOfObjectClasses($destdir);
408
409
410 if ($action == 'initapi') {
411 if (file_exists($dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php')) {
412 $result = dol_copy(DOL_DOCUMENT_ROOT.'/modulebuilder/template/class/api_mymodule.class.php', $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php', 0, 1);
413 }
414 dol_mkdir($dirins.'/'.strtolower($module).'/class');
415 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
416 $srcfile = $srcdir.'/class/api_mymodule.class.php';
417 $destfile = $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php';
418 } elseif ($action == 'initphpunit') {
419 dol_mkdir($dirins.'/'.strtolower($module).'/test/phpunit');
420 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
421 $srcfile = $srcdir.'/test/phpunit/MyObjectTest.php';
422 $destfile = $dirins.'/'.strtolower($module).'/test/phpunit/'.strtolower($objectname).'Test.php';
423 } elseif ($action == 'initpagecontact') {
424 dol_mkdir($dirins.'/'.strtolower($module));
425 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
426 $srcfile = $srcdir.'/myobject_contact.php';
427 $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_contact.php';
428 $varnametoupdate = 'showtabofpagecontact';
429 } elseif ($action == 'initpagedocument') {
430 dol_mkdir($dirins.'/'.strtolower($module));
431 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
432 $srcfile = $srcdir.'/myobject_document.php';
433 $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_document.php';
434 $varnametoupdate = 'showtabofpagedocument';
435 } elseif ($action == 'initpagenote') {
436 dol_mkdir($dirins.'/'.strtolower($module));
437 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
438 $srcfile = $srcdir.'/myobject_note.php';
439 $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_note.php';
440 $varnametoupdate = 'showtabofpagenote';
441 } elseif ($action == 'initpageagenda') {
442 dol_mkdir($dirins.'/'.strtolower($module));
443 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
444 $srcfile = $srcdir.'/myobject_agenda.php';
445 $destfile = $dirins.'/'.strtolower($module).'/'.strtolower($objectname).'_agenda.php';
446 $varnametoupdate = 'showtabofpageagenda';
447 }
448
449 //var_dump($srcfile);
450 //var_dump($destfile);
451 if (!file_exists($destfile)) {
452 $result = dol_copy($srcfile, $destfile, 0, 0);
453 }
454
455 if ($result > 0) {
456 //var_dump($phpfileval['fullname']);
457 $arrayreplacement = array(
458 'mymodule' => strtolower($modulename),
459 'MyModule' => $modulename,
460 'MYMODULE' => strtoupper($modulename),
461 'My module' => $modulename,
462 'my module' => $modulename,
463 'Mon module' => $modulename,
464 'mon module' => $modulename,
465 'htdocs/modulebuilder/template' => strtolower($modulename),
466 'myobject' => strtolower($objectname),
467 'MyObject' => $objectname,
468 'MYOBJECT' => strtoupper($objectname),
469 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
470 );
471
472 if ($action == 'initapi') {
473 if (count($objects) >= 1) {
474 addObjectsToApiFile($srcfile, $destfile, $objects, $modulename);
475 }
476 } else {
477 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
478 dolReplaceInFile($destfile, $arrayreplacement);
479 }
480
481 if ($varnametoupdate) {
482 // Now we update the object file to set $$varnametoupdate to 1
483 $srcfile = $dirins.'/'.strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php';
484 $arrayreplacement = array('/\$'.preg_quote($varnametoupdate, '/').' = 0;/' => '$'.$varnametoupdate.' = 1;');
485 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
486 dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
487 }
488 } else {
489 $langs->load("errors");
490 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
491 }
492}
493
494
495// init ExtraFields
496if ($dirins && $action == 'initsqlextrafields' && !empty($module)) {
497 $modulename = ucfirst($module); // Force first letter in uppercase
498 $objectname = $tabobj;
499
500 dol_mkdir($dirins.'/'.strtolower($module).'/sql');
501 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
502 $srcfile1 = $srcdir.'/sql/llx_mymodule_myobject_extrafields.sql';
503 $destfile1 = $dirins.'/'.strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql';
504 //var_dump($srcfile);
505 //var_dump($destfile);
506 $result1 = dol_copy($srcfile1, $destfile1, 0, 0);
507 $srcfile2 = $srcdir.'/sql/llx_mymodule_myobject_extrafields.key.sql';
508 $destfile2 = $dirins.'/'.strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql';
509 //var_dump($srcfile);
510 //var_dump($destfile);
511 $result2 = dol_copy($srcfile2, $destfile2, 0, 0);
512
513 if ($result1 > 0 && $result2 > 0) {
514 $modulename = ucfirst($module); // Force first letter in uppercase
515
516 //var_dump($phpfileval['fullname']);
517 $arrayreplacement = array(
518 'mymodule' => strtolower($modulename),
519 'MyModule' => $modulename,
520 'MYMODULE' => strtoupper($modulename),
521 'My module' => $modulename,
522 'my module' => $modulename,
523 'Mon module' => $modulename,
524 'mon module' => $modulename,
525 'htdocs/modulebuilder/template' => strtolower($modulename),
526 'My Object' => $objectname,
527 'MyObject' => $objectname,
528 'my object' => strtolower($objectname),
529 'myobject' => strtolower($objectname),
530 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
531 );
532
533 dolReplaceInFile($destfile1, $arrayreplacement);
534 dolReplaceInFile($destfile2, $arrayreplacement);
535 } else {
536 $langs->load("errors");
537 if ($result1 <= 0) {
538 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile1), null, 'errors');
539 }
540 if ($result2 <= 0) {
541 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile2), null, 'errors');
542 }
543 }
544
545 // Now we update the object file to set $this->isextrafieldmanaged to 1
546 $srcfile = $dirins.'/'.strtolower($module).'/class/'.strtolower($objectname).'.class.php';
547 $arrayreplacement = array('/\$this->isextrafieldmanaged = 0;/' => '$this->isextrafieldmanaged = 1;');
548 dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
549}
550
551
552// init Hook
553if ($dirins && $action == 'inithook' && !empty($module)) {
554 dol_mkdir($dirins.'/'.strtolower($module).'/class');
555 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
556 $srcfile = $srcdir.'/class/actions_mymodule.class.php';
557 $destfile = $dirins.'/'.strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
558 //var_dump($srcfile);
559 //var_dump($destfile);
560 $result = dol_copy($srcfile, $destfile, 0, 0);
561
562 if ($result > 0) {
563 $modulename = ucfirst($module); // Force first letter in uppercase
564
565 //var_dump($phpfileval['fullname']);
566 $arrayreplacement = array(
567 'mymodule' => strtolower($modulename),
568 'MyModule' => $modulename,
569 'MYMODULE' => strtoupper($modulename),
570 'My module' => $modulename,
571 'my module' => $modulename,
572 'Mon module' => $modulename,
573 'mon module' => $modulename,
574 'htdocs/modulebuilder/template' => strtolower($modulename),
575 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
576 );
577
578 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
579 dolReplaceInFile($destfile, $arrayreplacement);
580 } else {
581 $langs->load("errors");
582 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
583 }
584}
585
586
587// init Trigger
588if ($dirins && $action == 'inittrigger' && !empty($module)) {
589 dol_mkdir($dirins.'/'.strtolower($module).'/core/triggers');
590 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
591 $srcfile = $srcdir.'/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php';
592 $destfile = $dirins.'/'.strtolower($module).'/core/triggers/interface_99_mod'.$module.'_'.$module.'Triggers.class.php';
593 //var_dump($srcfile);
594 //var_dump($destfile);
595 $result = dol_copy($srcfile, $destfile, 0, 0);
596
597 if ($result > 0) {
598 $modulename = ucfirst($module); // Force first letter in uppercase
599
600 //var_dump($phpfileval['fullname']);
601 $arrayreplacement = array(
602 'mymodule' => strtolower($modulename),
603 'MyModule' => $modulename,
604 'MYMODULE' => strtoupper($modulename),
605 'My module' => $modulename,
606 'my module' => $modulename,
607 'Mon module' => $modulename,
608 'mon module' => $modulename,
609 'htdocs/modulebuilder/template' => strtolower($modulename),
610 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
611 );
612
613 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
614 dolReplaceInFile($destfile, $arrayreplacement);
615 } else {
616 $langs->load("errors");
617 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
618 }
619}
620
621
622// init Widget
623if ($dirins && $action == 'initwidget' && !empty($module)) {
624 dol_mkdir($dirins.'/'.strtolower($module).'/core/boxes');
625 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
626 $srcfile = $srcdir.'/core/boxes/mymodulewidget1.php';
627 $destfile = $dirins.'/'.strtolower($module).'/core/boxes/'.strtolower($module).'widget1.php';
628 //var_dump($srcfile);
629 //var_dump($destfile);
630 $result = dol_copy($srcfile, $destfile, 0, 0);
631
632 if ($result > 0) {
633 $modulename = ucfirst($module); // Force first letter in uppercase
634
635 //var_dump($phpfileval['fullname']);
636 $arrayreplacement = array(
637 'mymodule' => strtolower($modulename),
638 'MyModule' => $modulename,
639 'MYMODULE' => strtoupper($modulename),
640 'My module' => $modulename,
641 'my module' => $modulename,
642 'Mon module' => $modulename,
643 'mon module' => $modulename,
644 'htdocs/modulebuilder/template' => strtolower($modulename),
645 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
646 );
647
648 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
649 dolReplaceInFile($destfile, $arrayreplacement);
650 } else {
651 $langs->load("errors");
652 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
653 }
654}
655
656
657// init EmailSelector
658if ($dirins && $action == 'initemailing' && !empty($module)) {
659 dol_mkdir($dirins.'/'.strtolower($module).'/core/modules/mailings');
660 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
661 $srcfile = $srcdir.'/core/modules/mailings/mailing_mymodule_selector1.modules.php';
662 $destfile = $dirins.'/'.strtolower($module).'/core/modules/mailings/mailing_'.strtolower($module).'_selector1.modules.php';
663 //var_dump($srcfile);
664 //var_dump($destfile);
665 $result = dol_copy($srcfile, $destfile, 0, 0);
666
667 if ($result > 0) {
668 $modulename = ucfirst($module); // Force first letter in uppercase
669
670 //var_dump($phpfileval['fullname']);
671 $arrayreplacement = array(
672 'mymodule' => strtolower($modulename),
673 'MyModule' => $modulename,
674 'MYMODULE' => strtoupper($modulename),
675 'My module' => $modulename,
676 'my module' => $modulename,
677 'Mon module' => $modulename,
678 'mon module' => $modulename,
679 'htdocs/modulebuilder/template' => strtolower($modulename),
680 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
681 );
682
683 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
684 dolReplaceInFile($destfile, $arrayreplacement);
685 } else {
686 $langs->load("errors");
687 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
688 }
689}
690
691
692// init CSS
693if ($dirins && $action == 'initcss' && !empty($module)) {
694 dol_mkdir($dirins.'/'.strtolower($module).'/css');
695 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
696 $srcfile = $srcdir.'/css/mymodule.css.php';
697 $destfile = $dirins.'/'.strtolower($module).'/css/'.strtolower($module).'.css.php';
698 //var_dump($srcfile);
699 //var_dump($destfile);
700 $result = dol_copy($srcfile, $destfile, 0, 0);
701
702 if ($result > 0) {
703 $modulename = ucfirst($module); // Force first letter in uppercase
704
705 //var_dump($phpfileval['fullname']);
706 $arrayreplacement = array(
707 'mymodule' => strtolower($modulename),
708 'MyModule' => $modulename,
709 'MYMODULE' => strtoupper($modulename),
710 'My module' => $modulename,
711 'my module' => $modulename,
712 'Mon module' => $modulename,
713 'mon module' => $modulename,
714 'htdocs/modulebuilder/template' => strtolower($modulename),
715 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : ''),
716 );
717
718 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
719 dolReplaceInFile($destfile, $arrayreplacement);
720
721 // Update descriptor file to uncomment file
722 $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
723 $arrayreplacement = array('/\/\/\s*\''.preg_quote('/'.strtolower($module).'/css/'.strtolower($module).'.css.php', '/').'\'/' => '\'/'.strtolower($module).'/css/'.strtolower($module).'.css.php\'');
724 dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
725 } else {
726 $langs->load("errors");
727 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
728 }
729}
730
731
732// init JS
733if ($dirins && $action == 'initjs' && !empty($module)) {
734 dol_mkdir($dirins.'/'.strtolower($module).'/js');
735 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
736 $srcfile = $srcdir.'/js/mymodule.js.php';
737 $destfile = $dirins.'/'.strtolower($module).'/js/'.strtolower($module).'.js.php';
738 //var_dump($srcfile);
739 //var_dump($destfile);
740 $result = dol_copy($srcfile, $destfile, 0, 0);
741
742 if ($result > 0) {
743 $modulename = ucfirst($module); // Force first letter in uppercase
744
745 //var_dump($phpfileval['fullname']);
746 $arrayreplacement = array(
747 'mymodule' => strtolower($modulename),
748 'MyModule' => $modulename,
749 'MYMODULE' => strtoupper($modulename),
750 'My module' => $modulename,
751 'my module' => $modulename,
752 'Mon module' => $modulename,
753 'mon module' => $modulename,
754 'htdocs/modulebuilder/template' => strtolower($modulename),
755 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
756 );
757
758 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
759 dolReplaceInFile($destfile, $arrayreplacement);
760
761 // Update descriptor file to uncomment file
762 $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
763 $arrayreplacement = array('/\/\/\s*\''.preg_quote('/'.strtolower($module).'/js/'.strtolower($module).'.js.php', '/').'\'/' => '\'/'.strtolower($module).'/js/'.strtolower($module).'.js.php\'');
764 dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
765 } else {
766 $langs->load("errors");
767 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
768 }
769}
770
771
772// init CLI
773if ($dirins && $action == 'initcli' && !empty($module)) {
774 dol_mkdir($dirins.'/'.strtolower($module).'/scripts');
775 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
776 $srcfile = $srcdir.'/scripts/mymodule.php';
777 $destfile = $dirins.'/'.strtolower($module).'/scripts/'.strtolower($module).'.php';
778 //var_dump($srcfile);
779 //var_dump($destfile);
780 $result = dol_copy($srcfile, $destfile, 0, 0);
781
782 if ($result > 0) {
783 $modulename = ucfirst($module); // Force first letter in uppercase
784
785 //var_dump($phpfileval['fullname']);
786 $arrayreplacement = array(
787 'mymodule' => strtolower($modulename),
788 'MyModule' => $modulename,
789 'MYMODULE' => strtoupper($modulename),
790 'My module' => $modulename,
791 'my module' => $modulename,
792 'Mon module' => $modulename,
793 'mon module' => $modulename,
794 'htdocs/modulebuilder/template' => strtolower($modulename),
795 '__MYCOMPANY_NAME__' => $mysoc->name,
796 '__KEYWORDS__' => $modulename,
797 '__USER_FULLNAME__' => $user->getFullName($langs),
798 '__USER_EMAIL__' => $user->email,
799 '__YYYY-MM-DD__' => dol_print_date($now, 'dayrfc'),
800 '---Put here your own copyright and developer email---' => dol_print_date($now, 'dayrfc').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
801 );
802
803 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
804 dolReplaceInFile($destfile, $arrayreplacement);
805 } else {
806 $langs->load("errors");
807 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
808 }
809}
810
811
812// init Doc
813if ($dirins && $action == 'initdoc' && !empty($module)) {
814 dol_mkdir($dirins.'/'.strtolower($module).'/doc');
815 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
816 $srcfile = $srcdir.'/doc/Documentation.asciidoc';
817 $destfile = $dirins.'/'.strtolower($module).'/doc/Documentation.asciidoc';
818 //var_dump($srcfile);
819 //var_dump($destfile);
820 $result = dol_copy($srcfile, $destfile, 0, 0);
821
822 if ($result > 0) {
823 $modulename = ucfirst($module); // Force first letter in uppercase
824 $modulelowercase = strtolower($module);
825
826 //var_dump($phpfileval['fullname']);
827 $arrayreplacement = array(
828 'mymodule' => strtolower($modulename),
829 'MyModule' => $modulename,
830 'MYMODULE' => strtoupper($modulename),
831 'My module' => $modulename,
832 'my module' => $modulename,
833 'Mon module' => $modulename,
834 'mon module' => $modulename,
835 'htdocs/modulebuilder/template' => strtolower($modulename),
836 '__MYCOMPANY_NAME__' => $mysoc->name,
837 '__KEYWORDS__' => $modulename,
838 '__USER_FULLNAME__' => $user->getFullName($langs),
839 '__USER_EMAIL__' => $user->email,
840 '__YYYY-MM-DD__' => dol_print_date($now, 'dayrfc'),
841 '---Put here your own copyright and developer email---' => dol_print_date($now, 'dayrfc').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
842 );
843
844 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
845 dolReplaceInFile($destfile, $arrayreplacement);
846
847 // add table of properties
848 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
849 $destdir = $dirins.'/'.strtolower($module);
850 $objects = dolGetListOfObjectClasses($destdir);
851 foreach ($objects as $path => $obj) {
852 writePropsInAsciiDoc($path, $obj, $destfile);
853 }
854
855 // add table of permissions
856 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
857 writePermsInAsciiDoc($moduledescriptorfile, $destfile);
858
859 // add api urls if file exist
860 if (file_exists($dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php')) {
861 $apiFile = $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php';
862 writeApiUrlsInDoc($apiFile, $destfile);
863 }
864
865 // add ChangeLog in Doc
866 if (file_exists($dirins.'/'.strtolower($module).'/ChangeLog.md')) {
867 $changeLog = $dirins.'/'.strtolower($module).'/ChangeLog.md';
868 $string = file_get_contents($changeLog);
869
870 $replace = explode("\n", $string);
871 $strreplace = array();
872 foreach ($replace as $line) {
873 if ($line === '') {
874 continue;
875 }
876 if (strpos($line, '##') !== false) {
877 $strreplace[$line] = str_replace('##', '', $line);
878 } else {
879 $strreplace[$line] = $line;
880 }
881 }
882 $stringLog = implode("\n", $strreplace);
883 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
884 dolReplaceInFile($destfile, array('//include::ChangeLog.md[]' => '','__CHANGELOG__' => $stringLog));
885 }
886
887 // Delete old documentation files
888 $FILENAMEDOC = $modulelowercase.'.html';
889 $FILENAMEDOCPDF = $modulelowercase.'.pdf';
890 $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC;
891 $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC;
892 $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF;
893 $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF;
894
895 dol_delete_file($outputfiledoc, 0, 0, 0, null, false, 0);
896 dol_delete_file($outputfiledocpdf, 0, 0, 0, null, false, 0);
897 } else {
898 $langs->load("errors");
899 setEventMessages($langs->trans('ErrorFailToCreateFile', $destfile), null, 'errors');
900 }
901}
902
903
904// add Language
905if ($dirins && $action == 'addlanguage' && !empty($module)) {
906 $newlangcode = GETPOST('newlangcode', 'aZ09');
907
908 if ($newlangcode) {
909 $modulelowercase = strtolower($module);
910
911 // Dir for module
912 $diroflang = dol_buildpath($modulelowercase, 0);
913
914 if ($diroflang == $dolibarr_main_document_root.'/'.$modulelowercase) {
915 // This is not a custom module, we force diroflang to htdocs root
916 $diroflang = $dolibarr_main_document_root;
917
918 $srcfile = $diroflang.'/langs/en_US/'.$modulelowercase.'.lang';
919 $destfile = $diroflang.'/langs/'.$newlangcode.'/'.$modulelowercase.'.lang';
920
921 $result = dol_copy($srcfile, $destfile, 0, 0);
922 if ($result < 0) {
923 setEventMessages($langs->trans("ErrorFailToCopyFile", $srcfile, $destfile), null, 'errors');
924 }
925 } else {
926 $srcdir = $diroflang.'/langs/en_US';
927 $srcfile = $diroflang.'/langs/en_US/'.$modulelowercase.'.lang';
928 $destdir = $diroflang.'/langs/'.$newlangcode;
929
930 $arrayofreplacement = array();
931 if (!dol_is_dir($srcfile) || !dol_is_file($srcfile)) {
932 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template/langs/en_US';
933 $arrayofreplacement = array('mymodule' => $modulelowercase);
934 }
935 $result = dolCopyDir($srcdir, $destdir, 0, 0, $arrayofreplacement);
936 }
937 } else {
938 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Language")), null, 'errors');
939 }
940}
941
942
943// Remove/delete File
944if ($dirins && $action == 'confirm_removefile' && !empty($module)) {
945 $objectname = $tabobj;
946 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
947 $destdir = $dirins.'/'.strtolower($module);
948
949 $relativefilename = dol_sanitizePathName(GETPOST('file', 'restricthtml'));
950
951 // Now we delete the file
952 if ($relativefilename) {
953 $dirnametodelete = dirname($relativefilename);
954 $filetodelete = $dirins.'/'.$relativefilename;
955 $dirtodelete = $dirins.'/'.$dirnametodelete;
956
957 // Get list of existing objects
958 $objects = dolGetListOfObjectClasses($destdir);
959
960 $keyofobjecttodelete = array_search($objectname, $objects);
961 if ($keyofobjecttodelete !== false) {
962 unset($objects[$keyofobjecttodelete]);
963 }
964
965 // Delete or modify the file
966 if (strpos($relativefilename, 'api') !== false) {
967 $file_api = $destdir.'/class/api_'.strtolower($module).'.class.php';
968
969 $removeFile = removeObjectFromApiFile($file_api, $objects, $objectname);
970
971 if (count($objects) == 0) {
972 $result = dol_delete_file($filetodelete);
973 }
974
975 if ($removeFile) {
976 setEventMessages($langs->trans("ApiObjectDeleted"), null);
977 }
978 } else {
979 $result = dol_delete_file($filetodelete);
980 }
981
982 if (!$result) {
983 setEventMessages($langs->trans("ErrorFailToDeleteFile", basename($filetodelete)), null, 'errors');
984 } else {
985 // If we delete a .sql file, we delete also the other .sql file
986 if (preg_match('/\.sql$/', $relativefilename)) {
987 if (preg_match('/\.key\.sql$/', $relativefilename)) {
988 $relativefilename = preg_replace('/\.key\.sql$/', '.sql', $relativefilename);
989 $filetodelete = $dirins.'/'.$relativefilename;
990 $result = dol_delete_file($filetodelete);
991 } elseif (preg_match('/\.sql$/', $relativefilename)) {
992 $relativefilename = preg_replace('/\.sql$/', '.key.sql', $relativefilename);
993 $filetodelete = $dirins.'/'.$relativefilename;
994 $result = dol_delete_file($filetodelete);
995 }
996 }
997
998 if (dol_is_dir_empty($dirtodelete)) {
999 dol_delete_dir($dirtodelete);
1000 }
1001
1002 // Update descriptor file to comment file
1003 if (in_array($tab, array('css', 'js'))) {
1004 $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
1005 $arrayreplacement = array('/^\s*\''.preg_quote('/'.$relativefilename, '/').'\',*/m' => ' // \'/'.$relativefilename.'\',');
1006 dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
1007 }
1008
1009 if (preg_match('/_extrafields/', $relativefilename)) {
1010 // Now we update the object file to set $isextrafieldmanaged to 0
1011 $srcfile = $dirins.'/'.strtolower($module).'/class/'.strtolower($objectname).'.class.php';
1012 $arrayreplacement = array('/\$isextrafieldmanaged = 1;/' => '$isextrafieldmanaged = 0;');
1013 dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
1014 }
1015
1016 // Now we update the lib file to set $showtabofpagexxx to 0
1017 $varnametoupdate = '';
1018 $reg = array();
1019 if (preg_match('/_([a-z]+)\.php$/', $relativefilename, $reg)) {
1020 $varnametoupdate = 'showtabofpage'.$reg[1];
1021 }
1022 if ($varnametoupdate) {
1023 $srcfile = $dirins.'/'.strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php';
1024 $arrayreplacement = array('/\$'.preg_quote($varnametoupdate, '/').' = 1;/' => '$'.preg_quote($varnametoupdate, '/').' = 0;');
1025 dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1);
1026 }
1027 }
1028 }
1029}
1030
1031// Init an object
1032if ($dirins && $action == 'initobject' && $module && $objectname) {
1033 $warning = 0;
1034
1035 $objectname = ucfirst($objectname);
1036
1037 $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
1038 $moduletype = $listofmodules[strtolower($module)]['moduletype'];
1039
1040 if (preg_match('/[^a-z0-9_]/i', $objectname)) {
1041 $error++;
1042 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
1043 $tabobj = 'newobject';
1044 }
1045 if (class_exists($objectname)) {
1046 // TODO Add a more efficient detection. Scan disk ?
1047 $error++;
1048 setEventMessages($langs->trans("AnObjectWithThisClassNameAlreadyExists"), null, 'errors');
1049 $tabobj = 'newobject';
1050 }
1051
1052 $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
1053 $destdir = $dirins.'/'.strtolower($module);
1054
1055 // The dir was not created by init
1056 dol_mkdir($destdir.'/class');
1057 dol_mkdir($destdir.'/img');
1058 dol_mkdir($destdir.'/lib');
1059 dol_mkdir($destdir.'/scripts');
1060 dol_mkdir($destdir.'/sql');
1061
1062 // Scan dir class to find if an object with the same name already exists.
1063 if (!$error) {
1064 $dirlist = dol_dir_list($destdir.'/class', 'files', 0, '\.txt$');
1065 $alreadyfound = false;
1066 foreach ($dirlist as $key => $val) {
1067 $filefound = preg_replace('/\.txt$/', '', $val['name']);
1068 if (strtolower($objectname) == strtolower($filefound) && $objectname != $filefound) {
1069 $alreadyfound = true;
1070 $error++;
1071 setEventMessages($langs->trans("AnObjectAlreadyExistWithThisNameAndDiffCase"), null, 'errors');
1072 break;
1073 }
1074 }
1075 }
1076
1077 // If we must reuse an existing table for properties, define $stringforproperties
1078 $stringforproperties = '';
1079 $tablename = GETPOST('initfromtablename', 'alpha');
1080 if ($tablename) {
1081 $_results = $db->DDLDescTable($tablename);
1082 if (empty($_results)) {
1083 $error++;
1084 $langs->load("errors");
1085 setEventMessages($langs->trans("ErrorTableNotFound", $tablename), null, 'errors');
1086 } else {
1114 /*public $fields=array(
1115 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'),
1116 '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'),
1117 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'notnull'=>1, 'index'=>1, 'position'=>20),
1118 'label' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth200', 'help'=>'Help text', 'alwayseditable'=>'1'),
1119 'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text'),
1120 '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'),
1121 'description' =>array('type'=>'text', 'label'=>'Descrption', 'enabled'=>1, 'visible'=>0, 'position'=>60),
1122 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61),
1123 'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62),
1124 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>500),
1125 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501),
1126 //'date_valid' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502),
1127 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>510),
1128 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511),
1129 //'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>512),
1130 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000),
1131 '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')),
1132 );*/
1133
1134 $stringforproperties = '// BEGIN MODULEBUILDER PROPERTIES'."\n";
1135 $stringforproperties .= 'public $fields=array('."\n";
1136 $i = 10;
1137 while ($obj = $db->fetch_object($_results)) {
1138 // fieldname
1139 $fieldname = $obj->Field;
1140 // type
1141 $type = $obj->Type;
1142 if ($type == 'int(11)') {
1143 $type = 'integer';
1144 }
1145 if ($type == 'float') {
1146 $type = 'real';
1147 }
1148 if (strstr($type, 'tinyint')) {
1149 $type = 'integer';
1150 }
1151 if ($obj->Field == 'fk_soc') {
1152 $type = 'integer:Societe:societe/class/societe.class.php';
1153 }
1154 if (preg_match('/^fk_proj/', $obj->Field)) {
1155 $type = 'integer:Project:projet/class/project.class.php:1:fk_statut=1';
1156 }
1157 if (preg_match('/^fk_prod/', $obj->Field)) {
1158 $type = 'integer:Product:product/class/product.class.php:1';
1159 }
1160 if ($obj->Field == 'fk_warehouse') {
1161 $type = 'integer:Entrepot:product/stock/class/entrepot.class.php';
1162 }
1163 if (preg_match('/^(fk_user|fk_commercial)/', $obj->Field)) {
1164 $type = 'integer:User:user/class/user.class.php';
1165 }
1166
1167 // notnull
1168 $notnull = ($obj->Null == 'YES' ? 0 : 1);
1169 if ($fieldname == 'fk_user_modif') {
1170 $notnull = -1;
1171 }
1172 // label
1173 $label = preg_replace('/_/', '', ucfirst($fieldname));
1174 if ($fieldname == 'rowid') {
1175 $label = 'TechnicalID';
1176 }
1177 if ($fieldname == 'import_key') {
1178 $label = 'ImportId';
1179 }
1180 if ($fieldname == 'fk_soc') {
1181 $label = 'ThirdParty';
1182 }
1183 if ($fieldname == 'tms') {
1184 $label = 'DateModification';
1185 }
1186 if ($fieldname == 'datec') {
1187 $label = 'DateCreation';
1188 }
1189 if ($fieldname == 'date_valid') {
1190 $label = 'DateValidation';
1191 }
1192 if ($fieldname == 'datev') {
1193 $label = 'DateValidation';
1194 }
1195 if ($fieldname == 'note_private') {
1196 $label = 'NotePublic';
1197 }
1198 if ($fieldname == 'note_public') {
1199 $label = 'NotePrivate';
1200 }
1201 if ($fieldname == 'fk_user_creat') {
1202 $label = 'UserAuthor';
1203 }
1204 if ($fieldname == 'fk_user_modif') {
1205 $label = 'UserModif';
1206 }
1207 if ($fieldname == 'fk_user_valid') {
1208 $label = 'UserValidation';
1209 }
1210 // visible
1211 $visible = -1;
1212 if ($fieldname == 'entity') {
1213 $visible = -2;
1214 }
1215 if ($fieldname == 'import_key') {
1216 $visible = -2;
1217 }
1218 if ($fieldname == 'fk_user_creat') {
1219 $visible = -2;
1220 }
1221 if ($fieldname == 'fk_user_modif') {
1222 $visible = -2;
1223 }
1224 if (in_array($fieldname, array('ref_ext', 'model_pdf', 'note_public', 'note_private'))) {
1225 $visible = 0;
1226 }
1227 // enabled
1228 $enabled = 1;
1229 // default
1230 $default = '';
1231 if ($fieldname == 'entity') {
1232 $default = 1;
1233 }
1234 // position
1235 $position = $i;
1236 if (in_array($fieldname, array('status', 'statut', 'fk_status', 'fk_statut'))) {
1237 $position = 500;
1238 }
1239 if ($fieldname == 'import_key') {
1240 $position = 900;
1241 }
1242 // $alwayseditable
1243 if ($fieldname == 'label') {
1244 $alwayseditable = 1;
1245 }
1246 // index
1247 $index = 0;
1248 if ($fieldname == 'entity') {
1249 $index = 1;
1250 }
1251 // css, cssview, csslist
1252 $css = '';
1253 $cssview = '';
1254 $csslist = '';
1255 if (preg_match('/^fk_/', $fieldname)) {
1256 $css = 'maxwidth500 widthcentpercentminusxx';
1257 }
1258 if ($fieldname == 'label') {
1259 $css = 'minwidth300';
1260 $cssview = 'wordbreak';
1261 }
1262 if (in_array($fieldname, array('note_public', 'note_private'))) {
1263 $cssview = 'wordbreak';
1264 }
1265 if (in_array($fieldname, array('ref', 'label')) || preg_match('/integer:/', $type)) {
1266 $csslist = 'tdoverflowmax150';
1267 }
1268
1269 // type
1270 $picto = $obj->Picto;
1271 if ($obj->Field == 'fk_soc') {
1272 $picto = 'company';
1273 }
1274 if (preg_match('/^fk_proj/', $obj->Field)) {
1275 $picto = 'project';
1276 }
1277
1278 // Build the property string
1279 $stringforproperties .= "'".$obj->Field."'=>array('type'=>'".$type."', 'label'=>'".$label."',";
1280 if ($default != '') {
1281 $stringforproperties .= " 'default'=>".$default.",";
1282 }
1283 $stringforproperties .= " 'enabled'=>".$enabled.",";
1284 $stringforproperties .= " 'visible'=>".$visible;
1285 if ($notnull) {
1286 $stringforproperties .= ", 'notnull'=>".$notnull;
1287 }
1288 if ($alwayseditable) {
1289 $stringforproperties .= ", 'alwayseditable'=>1";
1290 }
1291 if ($fieldname == 'ref' || $fieldname == 'code') {
1292 $stringforproperties .= ", 'showoncombobox'=>1";
1293 }
1294 $stringforproperties .= ", 'position'=>".$position;
1295 if ($index) {
1296 $stringforproperties .= ", 'index'=>".$index;
1297 }
1298 if ($picto) {
1299 $stringforproperties .= ", 'picto'=>'".$picto."'";
1300 }
1301 if ($css) {
1302 $stringforproperties .= ", 'css'=>'".$css."'";
1303 }
1304 if ($cssview) {
1305 $stringforproperties .= ", 'cssview'=>'".$cssview."'";
1306 }
1307 if ($csslist) {
1308 $stringforproperties .= ", 'csslist'=>'".$csslist."'";
1309 }
1310 $stringforproperties .= "),\n";
1311 $i += 5;
1312 }
1313 $stringforproperties .= ');'."\n";
1314 $stringforproperties .= '// END MODULEBUILDER PROPERTIES'."\n";
1315 }
1316 }
1317
1318 if (!$error) {
1319 // Copy some files
1320 $filetogenerate = array(
1321 'myobject_card.php' => strtolower($objectname).'_card.php',
1322 'myobject_note.php' => strtolower($objectname).'_note.php',
1323 'myobject_contact.php' => strtolower($objectname).'_contact.php',
1324 'myobject_document.php' => strtolower($objectname).'_document.php',
1325 'myobject_agenda.php' => strtolower($objectname).'_agenda.php',
1326 'myobject_list.php' => strtolower($objectname).'_list.php',
1327 'admin/myobject_extrafields.php' => 'admin/'.strtolower($objectname).'_extrafields.php',
1328 'lib/mymodule_myobject.lib.php' => 'lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php',
1329 //'test/phpunit/MyObjectTest.php'=>'test/phpunit/'.strtolower($objectname).'Test.php',
1330 'sql/llx_mymodule_myobject.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql',
1331 'sql/llx_mymodule_myobject.key.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql',
1332 'sql/llx_mymodule_myobject_extrafields.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql',
1333 'sql/llx_mymodule_myobject_extrafields.key.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql',
1334 //'scripts/mymodule.php'=>'scripts/'.strtolower($objectname).'.php',
1335 'class/myobject.class.php' => 'class/'.strtolower($objectname).'.class.php',
1336 //'class/api_mymodule.class.php'=>'class/api_'.strtolower($module).'.class.php',
1337 );
1338
1339 if (GETPOST('includerefgeneration', 'aZ09')) {
1340 dol_mkdir($destdir.'/core/modules/'.strtolower($module));
1341
1342 $filetogenerate += array(
1343 'core/modules/mymodule/mod_myobject_advanced.php' => 'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_advanced.php',
1344 'core/modules/mymodule/mod_myobject_standard.php' => 'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_standard.php',
1345 'core/modules/mymodule/modules_myobject.php' => 'core/modules/'.strtolower($module).'/modules_'.strtolower($objectname).'.php',
1346 );
1347 }
1348 if (GETPOST('includedocgeneration', 'aZ09')) {
1349 dol_mkdir($destdir.'/core/modules/'.strtolower($module));
1350 dol_mkdir($destdir.'/core/modules/'.strtolower($module).'/doc');
1351
1352 $filetogenerate += array(
1353 'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php' => 'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php',
1354 'core/modules/mymodule/doc/pdf_standard_myobject.modules.php' => 'core/modules/'.strtolower($module).'/doc/pdf_standard_'.strtolower($objectname).'.modules.php'
1355 );
1356 }
1357 if (GETPOST('generatepermissions', 'aZ09')) {
1358 $firstobjectname = 'myobject';
1359 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1360 dol_include_once($pathtofile);
1361 $class = 'mod'.$module;
1362 if (class_exists($class)) {
1363 try {
1364 $moduleobj = new $class($db);
1365 } catch (Exception $e) {
1366 $error++;
1367 dol_print_error($db, $e->getMessage());
1368 }
1369 }
1370 $rights = $moduleobj->rights;
1371 $moduledescriptorfile = $destdir.'/core/modules/mod'.$module.'.class.php';
1372 $checkComment = checkExistComment($moduledescriptorfile, 1);
1373 if ($checkComment < 0) {
1374 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
1375 } else {
1376 $generatePerms = reWriteAllPermissions($moduledescriptorfile, $rights, null, null, $objectname, $module, -2);
1377 if ($generatePerms < 0) {
1378 setEventMessages($langs->trans("WarningPermissionAlreadyExist", $langs->transnoentities($objectname)), null, 'warnings');
1379 }
1380 }
1381 }
1382
1383 if (!$error) {
1384 foreach ($filetogenerate as $srcfile => $destfile) {
1385 $result = dol_copy($srcdir.'/'.$srcfile, $destdir.'/'.$destfile, $newmask, 0);
1386 if ($result <= 0) {
1387 if ($result < 0) {
1388 $warning++;
1389 $langs->load("errors");
1390 setEventMessages($langs->trans("ErrorFailToCopyFile", $srcdir.'/'.$srcfile, $destdir.'/'.$destfile), null, 'errors');
1391 } else {
1392 // $result == 0
1393 setEventMessages($langs->trans("FileAlreadyExists", $destfile), null, 'warnings');
1394 }
1395 }
1396 $arrayreplacement = array(
1397 '/myobject\.class\.php/' => strtolower($objectname).'.class.php',
1398 '/myobject\.lib\.php/' => strtolower($objectname).'.lib.php',
1399 );
1400
1401 dolReplaceInFile($destdir.'/'.$destfile, $arrayreplacement, '', 0, 0, 1);
1402 }
1403 }
1404
1405 // Replace property section with $stringforproperties
1406 if (!$error && $stringforproperties) {
1407 //var_dump($stringforproperties);exit;
1408 $arrayreplacement = array(
1409 '/\/\/ BEGIN MODULEBUILDER PROPERTIES.*\/\/ END MODULEBUILDER PROPERTIES/ims' => $stringforproperties
1410 );
1411
1412 dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', 0, 0, 1);
1413 }
1414
1415 // Edit the class 'class/'.strtolower($objectname).'.class.php'
1416 if (GETPOST('includerefgeneration', 'aZ09')) {
1417 // Replace 'visible'=>1, 'noteditable'=>0, 'default'=>''
1418 $arrayreplacement = array(
1419 '/\'visible\'=>1,\s*\'noteditable\'=>0,\s*\'default\'=>\'\'/' => "'visible'=>4, 'noteditable'=>1, 'default'=>'(PROV)'"
1420 );
1421 //var_dump($arrayreplacement);exit;
1422 //var_dump($destdir.'/class/'.strtolower($objectname).'.class.php');exit;
1423 dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', 0, 0, 1);
1424
1425 $arrayreplacement = array(
1426 '/\'models\' => 0,/' => '\'models\' => 1,'
1427 );
1428 dolReplaceInFile($destdir.'/core/modules/mod'.$module.'.class.php', $arrayreplacement, '', 0, 0, 1);
1429 }
1430
1431 // Edit the setup file and the card page
1432 if (GETPOST('includedocgeneration', 'aZ09')) {
1433 // Replace some var init into some files
1434 $arrayreplacement = array(
1435 '/\$includedocgeneration = 0;/' => '$includedocgeneration = 1;'
1436 );
1437 dolReplaceInFile($destdir.'/class/'.strtolower($objectname).'.class.php', $arrayreplacement, '', 0, 0, 1);
1438 dolReplaceInFile($destdir.'/'.strtolower($objectname).'_card.php', $arrayreplacement, '', 0, 0, 1);
1439
1440 $arrayreplacement = array(
1441 '/\'models\' => 0,/' => '\'models\' => 1,'
1442 );
1443
1444 dolReplaceInFile($destdir.'/core/modules/mod'.$module.'.class.php', $arrayreplacement, '', 0, 0, 1);
1445 }
1446
1447 // TODO Update entries '$myTmpObjects['MyObject']=array('includerefgeneration'=>0, 'includedocgeneration'=>0);'
1448
1449
1450 // Scan for object class files
1451 $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
1452
1453 $firstobjectname = '';
1454 foreach ($listofobject as $fileobj) {
1455 if (preg_match('/^api_/', $fileobj['name'])) {
1456 continue;
1457 }
1458 if (preg_match('/^actions_/', $fileobj['name'])) {
1459 continue;
1460 }
1461
1462 $tmpcontent = file_get_contents($fileobj['fullname']);
1463 $reg = array();
1464 if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
1465 $objectnameloop = $reg[1];
1466 if (empty($firstobjectname)) {
1467 $firstobjectname = $objectnameloop;
1468 }
1469 }
1470
1471 // Regenerate left menu entry in descriptor for $objectname
1472 $stringtoadd = "
1473 \$this->menu[\$r++]=array(
1474 'fk_menu'=>'fk_mainmenu=mymodule',
1475 'type'=>'left',
1476 'titre'=>'MyObject',
1477 'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'),
1478 'mainmenu'=>'mymodule',
1479 'leftmenu'=>'myobject',
1480 'url'=>'/mymodule/myobject_list.php',
1481 'langs'=>'mymodule@mymodule',
1482 'position'=>1000+\$r,
1483 'enabled'=>'isModEnabled(\"mymodule\")',
1484 'perms'=>'".(GETPOST('generatepermissions') ? '$user->hasRight("mymodule", "myobject", "read")' : '1')."',
1485 'target'=>'',
1486 'user'=>2,
1487 'object'=>'MyObject'
1488 );
1489 \$this->menu[\$r++]=array(
1490 'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=myobject',
1491 'type'=>'left',
1492 'titre'=>'List MyObject',
1493 'mainmenu'=>'mymodule',
1494 'leftmenu'=>'mymodule_myobject_list',
1495 'url'=>'/mymodule/myobject_list.php',
1496 'langs'=>'mymodule@mymodule',
1497 'position'=>1000+\$r,
1498 'enabled'=>'isModEnabled(\"mymodule\")',
1499 'perms'=>'".(GETPOST('generatepermissions') ? '$user->hasRight("mymodule", "myobject", "read")' : '1')."',
1500 'target'=>'',
1501 'user'=>2,
1502 'object'=>'MyObject'
1503 );
1504 \$this->menu[\$r++]=array(
1505 'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=myobject',
1506 'type'=>'left',
1507 'titre'=>'New MyObject',
1508 'mainmenu'=>'mymodule',
1509 'leftmenu'=>'mymodule_myobject_new',
1510 'url'=>'/mymodule/myobject_card.php?action=create',
1511 'langs'=>'mymodule@mymodule',
1512 'position'=>1000+\$r,
1513 'enabled'=>'isModEnabled(\"mymodule\")',
1514 'perms'=>'".(GETPOST('generatepermissions') ? '$user->hasRight("mymodule", "myobject", "write")' : '1')."',
1515 'target'=>'',
1516 'user'=>2,
1517 'object'=>'MyObject'
1518 );";
1519 $stringtoadd = preg_replace('/MyObject/', $objectname, $stringtoadd);
1520 $stringtoadd = preg_replace('/mymodule/', strtolower($module), $stringtoadd);
1521 $stringtoadd = preg_replace('/myobject/', strtolower($objectname), $stringtoadd);
1522
1523 $moduledescriptorfile = $destdir.'/core/modules/mod'.$module.'.class.php';
1524 }
1525 // TODO Allow a replace with regex using dolReplaceInFile with param arryreplacementisregex to 1
1526 // TODO Avoid duplicate addition
1527
1528 // load class and check if menu exist with same object name
1529 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1530 dol_include_once($pathtofile);
1531 $class = 'mod'.$module;
1532 if (class_exists($class)) {
1533 try {
1534 $moduleobj = new $class($db);
1535 } catch (Exception $e) {
1536 $error++;
1537 dol_print_error($db, $e->getMessage());
1538 }
1539 }
1540 $menus = $moduleobj->menu;
1541 $counter = 0 ;
1542 foreach ($menus as $menu) {
1543 if ($menu['leftmenu'] == strtolower($objectname)) {
1544 $counter++;
1545 }
1546 }
1547 if (!$counter) {
1548 $checkComment = checkExistComment($moduledescriptorfile, 0);
1549 if ($checkComment < 0) {
1550 $warning++;
1551 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), basename($moduledescriptorfile)), null, 'warnings');
1552 } else {
1553 $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 */');
1554 dolReplaceInFile($moduledescriptorfile, $arrayofreplacement);
1555 }
1556 }
1557 // Add module descriptor to list of files to replace "MyObject' string with real name of object.
1558 $filetogenerate[] = 'core/modules/mod'.$module.'.class.php';
1559 }
1560
1561 if (!$error) {
1562 // Edit PHP files to make replacement
1563 foreach ($filetogenerate as $destfile) {
1564 $phpfileval['fullname'] = $destdir.'/'.$destfile;
1565
1566 //var_dump($phpfileval['fullname']);
1567 $arrayreplacement = array(
1568 'mymodule' => strtolower($module),
1569 'MyModule' => $module,
1570 'MYMODULE' => strtoupper($module),
1571 'My module' => $module,
1572 'my module' => $module,
1573 'mon module' => $module,
1574 'Mon module' => $module,
1575 'htdocs/modulebuilder/template/' => strtolower($modulename),
1576 'myobject' => strtolower($objectname),
1577 'MyObject' => $objectname,
1578 //'MYOBJECT'=>strtoupper($objectname),
1579 '---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
1580 );
1581
1582 if (getDolGlobalString('MODULEBUILDER_SPECIFIC_AUTHOR')) {
1583 $arrayreplacement['---Put here your own copyright and developer email---'] = dol_print_date($now, '%Y').' ' . getDolGlobalString('MODULEBUILDER_SPECIFIC_AUTHOR');
1584 }
1585
1586 $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement);
1587 //var_dump($result);
1588 if ($result < 0) {
1589 setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
1590 }
1591 }
1592 }
1593
1594 if (!$error) {
1595 // Edit the class file to write properties
1596 $object = rebuildObjectClass($destdir, $module, $objectname, $newmask);
1597
1598 if (is_numeric($object) && $object <= 0) {
1599 $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
1600 setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
1601 $warning++;
1602 }
1603 // check if documentation was generate and add table of properties object
1604 $file = $destdir.'/class/'.strtolower($objectname).'.class.php';
1605 $destfile = $destdir.'/doc/Documentation.asciidoc';
1606
1607 if (file_exists($destfile)) {
1608 writePropsInAsciiDoc($file, $objectname, $destfile);
1609 }
1610 }
1611 if (!$error) {
1612 // Edit sql with new properties
1613 $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, '', $object);
1614
1615 if ($result <= 0) {
1616 setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null);
1617 $error++;
1618 }
1619 }
1620
1621 if (!$error) {
1622 setEventMessages($langs->trans('FilesForObjectInitialized', $objectname), null);
1623 $tabobj = $objectname;
1624 } else {
1625 $tabobj = 'newobject';
1626 }
1627
1628 // check if module is enabled
1629 if (isModEnabled(strtolower($module))) {
1630 $result = unActivateModule(strtolower($module));
1631 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity);
1632 if ($result) {
1633 setEventMessages($result, null, 'errors');
1634 }
1635 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
1636 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module);
1637 exit;
1638 }
1639}
1640
1641// Add a dictionary
1642if ($dirins && $action == 'initdic' && $module && empty($cancel)) {
1643 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1644 $destdir = $dirins.'/'.strtolower($module);
1645 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
1646
1647 if (!GETPOST('dicname')) {
1648 $error++;
1649 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Table")), null, 'errors');
1650 }
1651 if (!GETPOST('label')) {
1652 $error++;
1653 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
1654 }
1655 if (!$error) {
1656 $newdicname = $dicname;
1657 if (!preg_match('/^c_/', $newdicname)) {
1658 $newdicname = 'c_'.$dicname;
1659 }
1660 dol_include_once($pathtofile);
1661 $class = 'mod'.$module;
1662
1663 if (class_exists($class)) {
1664 try {
1665 $moduleobj = new $class($db);
1666 } catch (Exception $e) {
1667 $error++;
1668 dol_print_error($db, $e->getMessage());
1669 }
1670 } else {
1671 $error++;
1672 $langs->load("errors");
1673 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
1674 exit;
1675 }
1676 $dictionaries = $moduleobj->dictionaries;
1677 $checkComment = checkExistComment($moduledescriptorfile, 2);
1678 if ($checkComment < 0) {
1679 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Dictionaries"), "mod".$module."class.php"), null, 'warnings');
1680 } else {
1681 createNewDictionnary($module, $moduledescriptorfile, $newdicname, $dictionaries);
1682 if (function_exists('opcache_invalidate')) {
1683 opcache_reset(); // remove the include cache hell !
1684 }
1685 clearstatcache(true);
1686 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : ''));
1687 exit;
1688 }
1689 }
1690}
1691
1692// Delete a SQL table
1693if ($dirins && ($action == 'droptable' || $action == 'droptableextrafields') && !empty($module) && !empty($tabobj)) {
1694 $objectname = $tabobj;
1695
1696 $arrayoftables = array();
1697 if ($action == 'droptable') {
1698 $arrayoftables[] = MAIN_DB_PREFIX.strtolower($module).'_'.strtolower($tabobj);
1699 }
1700 if ($action == 'droptableextrafields') {
1701 $arrayoftables[] = MAIN_DB_PREFIX.strtolower($module).'_'.strtolower($tabobj).'_extrafields';
1702 }
1703
1704 foreach ($arrayoftables as $tabletodrop) {
1705 $nb = -1;
1706 $sql = "SELECT COUNT(*) as nb FROM ".$tabletodrop;
1707 $resql = $db->query($sql);
1708 if ($resql) {
1709 $obj = $db->fetch_object($resql);
1710 if ($obj) {
1711 $nb = $obj->nb;
1712 }
1713 } else {
1714 if ($db->lasterrno() == 'DB_ERROR_NOSUCHTABLE') {
1715 setEventMessages($langs->trans("TableDoesNotExists", $tabletodrop), null, 'warnings');
1716 } else {
1717 dol_print_error($db);
1718 }
1719 }
1720 if ($nb == 0) {
1721 $resql = $db->DDLDropTable($tabletodrop);
1722 //var_dump($resql);
1723 setEventMessages($langs->trans("TableDropped", $tabletodrop), null, 'mesgs');
1724 } elseif ($nb > 0) {
1725 setEventMessages($langs->trans("TableNotEmptyDropCanceled", $tabletodrop), null, 'warnings');
1726 }
1727 }
1728}
1729
1730if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && (!empty($tabobj) || !empty(GETPOST('obj')))) {
1731 $error = 0;
1732
1733 $objectname = (GETPOST('obj') ? GETPOST('obj') : $tabobj);
1734
1735 $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
1736 $moduletype = $listofmodules[strtolower($module)]['moduletype'];
1737
1738 $srcdir = $dirread.'/'.strtolower($module);
1739 $destdir = $dirins.'/'.strtolower($module);
1740 dol_mkdir($destdir);
1741
1742 $objects = dolGetListOfObjectClasses($destdir);
1743 if (!in_array($objectname, array_values($objects))) {
1744 $error++;
1745 setEventMessages($langs->trans("ErrorObjectNotFound", $langs->transnoentities($objectname)), null, 'errors');
1746 }
1747 // We click on add property
1748 if (!GETPOST('regenerateclasssql') && !GETPOST('regeneratemissing')) {
1749 if (!GETPOST('propname', 'aZ09')) {
1750 $error++;
1751 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Name")), null, 'errors');
1752 }
1753 if (!GETPOST('proplabel', 'alpha')) {
1754 $error++;
1755 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
1756 }
1757 if (!GETPOST('proptype', 'alpha')) {
1758 $error++;
1759 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors');
1760 }
1761
1762 if (!$error && !GETPOST('regenerateclasssql') && !GETPOST('regeneratemissing')) {
1763 $addfieldentry = array(
1764 'name' => GETPOST('propname', 'aZ09'),
1765 'label' => GETPOST('proplabel', 'alpha'),
1766 'type' => strtolower(GETPOST('proptype', 'alpha')),
1767 'arrayofkeyval' => GETPOST('proparrayofkeyval', 'alphawithlgt'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}'
1768 'visible' => GETPOST('propvisible', 'alphanohtml'),
1769 'enabled' => GETPOST('propenabled', 'alphanohtml'),
1770 'position' => GETPOSTINT('propposition'),
1771 'notnull' => GETPOSTINT('propnotnull'),
1772 'index' => GETPOSTINT('propindex'),
1773 'foreignkey' => GETPOST('propforeignkey', 'alpha'),
1774 'searchall' => GETPOSTINT('propsearchall'),
1775 'isameasure' => GETPOSTINT('propisameasure'),
1776 'comment' => GETPOST('propcomment', 'alpha'),
1777 'help' => GETPOST('prophelp', 'alpha'),
1778 'css' => GETPOST('propcss', 'alpha'), // Can be 'maxwidth500 widthcentpercentminusxx' for example
1779 'cssview' => GETPOST('propcssview', 'alpha'),
1780 'csslist' => GETPOST('propcsslist', 'alpha'),
1781 'default' => GETPOST('propdefault', 'restricthtml'),
1782 'noteditable' => intval(GETPOSTINT('propnoteditable')),
1783 //'alwayseditable'=>intval(GETPOST('propalwayseditable', 'int')),
1784 'validate' => GETPOSTINT('propvalidate')
1785 );
1786
1787 if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) {
1788 $tmpdecode = json_decode($addfieldentry['arrayofkeyval'], true);
1789 if ($tmpdecode) { // If string is already a json
1790 $addfieldentry['arrayofkeyval'] = $tmpdecode;
1791 } else { // If string is a list of lines with "key,value"
1792 $tmparray = dolExplodeIntoArray($addfieldentry['arrayofkeyval'], "\n", ",");
1793 $addfieldentry['arrayofkeyval'] = $tmparray;
1794 }
1795 }
1796 }
1797 } else {
1798 $addfieldentry = array();
1799 }
1800
1801 /*if (GETPOST('regeneratemissing'))
1802 {
1803 setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings');
1804 $error++;
1805 }*/
1806
1807 $moduletype = $listofmodules[strtolower($module)]['moduletype'];
1808
1809 // Edit the class file to write properties
1810 if (!$error) {
1811 $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry, $moduletype);
1812
1813 if (is_numeric($object) && $object <= 0) {
1814 $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
1815 setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
1816 $error++;
1817 }
1818 }
1819
1820 // Edit sql with new properties
1821 if (!$error) {
1822 $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object, $moduletype);
1823
1824 if ($result <= 0) {
1825 setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null, 'errors');
1826 $error++;
1827 }
1828 }
1829
1830 if (!$error) {
1831 clearstatcache(true);
1832
1833 setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null);
1834
1835 setEventMessages($langs->trans('WarningDatabaseIsNotUpdated'), null);
1836
1837 // Make a redirect to reload all data
1838 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname.'&nocache='.time());
1839 exit;
1840 }
1841}
1842
1843if ($dirins && $action == 'confirm_deleteproperty' && $propertykey) {
1844 $objectname = $tabobj;
1845
1846 $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
1847 $moduletype = $listofmodules[strtolower($module)]['moduletype'];
1848
1849 $srcdir = $dirread.'/'.strtolower($module);
1850 $destdir = $dirins.'/'.strtolower($module);
1851 dol_mkdir($destdir);
1852
1853 // Edit the class file to write properties
1854 if (!$error) {
1855 $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey);
1856
1857 if (is_numeric($object) && $object <= 0) {
1858 $pathoffiletoeditsrc = $destdir.'/class/'.strtolower($objectname).'.class.php';
1859 setEventMessages($langs->trans('ErrorFailToCreateFile', $pathoffiletoeditsrc), null, 'errors');
1860 $error++;
1861 }
1862 }
1863
1864 // Edit sql with new properties
1865 if (!$error) {
1866 $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object);
1867
1868 if ($result <= 0) {
1869 setEventMessages($langs->trans('ErrorFailToCreateFile', '.sql'), null, 'errors');
1870 $error++;
1871 }
1872 }
1873
1874 if (!$error) {
1875 setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null);
1876
1877 clearstatcache(true);
1878
1879 // Make a redirect to reload all data
1880 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname);
1881 exit;
1882 }
1883}
1884
1885if ($dirins && $action == 'confirm_deletemodule') {
1886 if (preg_match('/[^a-z0-9_]/i', $module)) {
1887 $error++;
1888 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
1889 }
1890
1891 if (!$error) {
1892 $modulelowercase = strtolower($module);
1893
1894 // Dir for module
1895 $dir = $dirins.'/'.$modulelowercase;
1896
1897 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1898
1899 // Dir for module
1900 $dir = dol_buildpath($modulelowercase, 0);
1901
1902 // Zip file to build
1903 $FILENAMEZIP = '';
1904
1905 // Load module
1906 dol_include_once($pathtofile);
1907 $class = 'mod'.$module;
1908
1909 if (class_exists($class)) {
1910 try {
1911 $moduleobj = new $class($db);
1912 } catch (Exception $e) {
1913 $error++;
1914 dol_print_error($db, $e->getMessage());
1915 }
1916 } else {
1917 $error++;
1918 $langs->load("errors");
1919 setEventMessages($langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module), null, 'warnings');
1920 }
1921
1922 if ($moduleobj) {
1923 $moduleobj->remove();
1924 }
1925
1926 $result = dol_delete_dir_recursive($dir);
1927
1928 if ($result > 0) {
1929 setEventMessages($langs->trans("DirWasRemoved", $modulelowercase), null);
1930
1931 clearstatcache(true);
1932 if (function_exists('opcache_invalidate')) {
1933 opcache_reset(); // remove the include cache hell !
1934 }
1935
1936 header("Location: ".$_SERVER["PHP_SELF"].'?module=deletemodule');
1937 exit;
1938 } else {
1939 setEventMessages($langs->trans("PurgeNothingToDelete"), null, 'warnings');
1940 }
1941 }
1942
1943 $action = '';
1944 $module = 'deletemodule';
1945}
1946
1947if ($dirins && $action == 'confirm_deleteobject' && $objectname) {
1948 if (preg_match('/[^a-z0-9_]/i', $objectname)) {
1949 $error++;
1950 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
1951 }
1952
1953 if (!$error) {
1954 $modulelowercase = strtolower($module);
1955 $objectlowercase = strtolower($objectname);
1956
1957 // Dir for module
1958 $dir = $dirins.'/'.$modulelowercase;
1959
1960 // Delete some files
1961 $filetodelete = array(
1962 'myobject_card.php' => strtolower($objectname).'_card.php',
1963 'myobject_note.php' => strtolower($objectname).'_note.php',
1964 'myobject_contact.php' => strtolower($objectname).'_contact.php',
1965 'myobject_document.php' => strtolower($objectname).'_document.php',
1966 'myobject_agenda.php' => strtolower($objectname).'_agenda.php',
1967 'myobject_list.php' => strtolower($objectname).'_list.php',
1968 'admin/myobject_extrafields.php' => 'admin/'.strtolower($objectname).'_extrafields.php',
1969 'lib/mymodule_myobject.lib.php' => 'lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php',
1970 'test/phpunit/MyObjectTest.php' => 'test/phpunit/'.strtolower($objectname).'Test.php',
1971 'sql/llx_mymodule_myobject.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql',
1972 'sql/llx_mymodule_myobject_extrafields.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql',
1973 'sql/llx_mymodule_myobject.key.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql',
1974 'sql/llx_mymodule_myobject_extrafields.key.sql' => 'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.key.sql',
1975 'scripts/myobject.php' => 'scripts/'.strtolower($objectname).'.php',
1976 'class/myobject.class.php' => 'class/'.strtolower($objectname).'.class.php',
1977 'class/api_myobject.class.php' => 'class/api_'.strtolower($module).'.class.php',
1978 'core/modules/mymodule/mod_myobject_advanced.php' => 'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_advanced.php',
1979 'core/modules/mymodule/mod_myobject_standard.php' => 'core/modules/'.strtolower($module).'/mod_'.strtolower($objectname).'_standard.php',
1980 'core/modules/mymodule/modules_myobject.php' => 'core/modules/'.strtolower($module).'/modules_'.strtolower($objectname).'.php',
1981 'core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php' => 'core/modules/'.strtolower($module).'/doc/doc_generic_'.strtolower($objectname).'_odt.modules.php',
1982 'core/modules/mymodule/doc/pdf_standard_myobject.modules.php' => 'core/modules/'.strtolower($module).'/doc/pdf_standard_'.strtolower($objectname).'.modules.php'
1983 );
1984
1985 //menu for the object selected
1986 // load class and check if menu,permission,documentation exist for this object
1987 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
1988 dol_include_once($pathtofile);
1989 $class = 'mod'.$module;
1990 if (class_exists($class)) {
1991 try {
1992 $moduleobj = new $class($db);
1993 } catch (Exception $e) {
1994 $error++;
1995 dol_print_error($db, $e->getMessage());
1996 }
1997 }
1998 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
1999
2000 // delete menus linked to the object
2001 $menus = $moduleobj->menu;
2002 $rewriteMenu = checkExistComment($moduledescriptorfile, 0);
2003
2004 if ($rewriteMenu < 0) {
2005 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), "mod".$module."class.php"), null, 'warnings');
2006 } else {
2007 reWriteAllMenus($moduledescriptorfile, $menus, $objectname, null, -1);
2008 }
2009
2010 // regenerate permissions and delete them
2011 $permissions = $moduleobj->rights;
2012 $rewritePerms = checkExistComment($moduledescriptorfile, 1);
2013 if ($rewritePerms < 0) {
2014 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
2015 } else {
2016 reWriteAllPermissions($moduledescriptorfile, $permissions, null, null, $objectname, '', -1);
2017 }
2018 if ($rewritePerms && $rewriteMenu) {
2019 // check if documentation has been generated
2020 $file_doc = $dirins.'/'.strtolower($module).'/doc/Documentation.asciidoc';
2021 deletePropsAndPermsFromDoc($file_doc, $objectname);
2022
2023 clearstatcache(true);
2024 if (function_exists('opcache_invalidate')) {
2025 opcache_reset(); // remove the include cache hell !
2026 }
2027 $resultko = 0;
2028 foreach ($filetodelete as $tmpfiletodelete) {
2029 $resulttmp = dol_delete_file($dir.'/'.$tmpfiletodelete, 0, 0, 1);
2030 $resulttmp = dol_delete_file($dir.'/'.$tmpfiletodelete.'.back', 0, 0, 1);
2031 if (!$resulttmp) {
2032 $resultko++;
2033 }
2034 }
2035
2036 if ($resultko == 0) {
2037 setEventMessages($langs->trans("FilesDeleted"), null);
2038 } else {
2039 setEventMessages($langs->trans("ErrorSomeFilesCouldNotBeDeleted"), null, 'warnings');
2040 }
2041 }
2042 }
2043
2044 $action = '';
2045 if (! $error) {
2046 $tabobj = 'newobject';
2047 } else {
2048 $tabobj = 'deleteobject';
2049 }
2050
2051 // check if module is enabled
2052 if (isModEnabled(strtolower($module))) {
2053 $result = unActivateModule(strtolower($module));
2054 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
2055 if ($result) {
2056 setEventMessages($result, null, 'errors');
2057 }
2058 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2059 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&tabobj=deleteobject&module='.urlencode($module));
2060 exit;
2061 }
2062}
2063
2064if (($dirins && $action == 'confirm_deletedictionary' && $dicname) || ($dirins && $action == 'confirm_deletedictionary' && GETPOST('dictionnarykey'))) {
2065 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2066 $destdir = $dirins.'/'.strtolower($module);
2067 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2068
2069 if (preg_match('/[^a-z0-9_]/i', $dicname)) {
2070 $error++;
2071 setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
2072 }
2073
2074 if (!empty($dicname)) {
2075 $newdicname = $dicname;
2076 if (!preg_match('/^c_/', $newdicname)) {
2077 $newdicname = 'c_'.strtolower($dicname);
2078 }
2079 }
2080
2081 dol_include_once($pathtofile);
2082 $class = 'mod'.$module;
2083
2084 if (class_exists($class)) {
2085 try {
2086 $moduleobj = new $class($db);
2087 } catch (Exception $e) {
2088 $error++;
2089 dol_print_error($db, $e->getMessage());
2090 }
2091 } else {
2092 $error++;
2093 $langs->load("errors");
2094 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
2095 exit;
2096 }
2097
2098 $dicts = $moduleobj->dictionaries;
2099 $checkComment = checkExistComment($moduledescriptorfile, 2);
2100 if ($checkComment < 0) {
2101 $error++;
2102 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Dictionaries"), "mod".$module."class.php"), null, 'warnings');
2103 }
2104
2105 if (!empty(GETPOST('dictionnarykey'))) {
2106 $newdicname = $dicts['tabname'][GETPOST('dictionnarykey') - 1];
2107 }
2108
2109 //chercher la table dicname
2110 $checkTable = $db->DDLDescTable(MAIN_DB_PREFIX.strtolower($newdicname));
2111 if ($checkTable && $db->num_rows($checkTable) <= 0) {
2112 $error++;
2113 }
2114
2115 // search the key by name
2116 $keyToDelete = null;
2117 foreach ($dicts['tabname'] as $key => $table) {
2118 //var_dump($table." /////// ".$newdicname);exit;
2119 if (strtolower($table) === $newdicname) {
2120 $keyToDelete = $key;
2121 break;
2122 }
2123 }
2124 // delete all dicname's key values from the dictionary
2125 if ($keyToDelete !== null) {
2126 $keysToDelete = ['tabname', 'tablib', 'tabsql', 'tabsqlsort', 'tabfield', 'tabfieldvalue', 'tabfieldinsert', 'tabrowid', 'tabcond', 'tabhelp'];
2127 foreach ($keysToDelete as $key) {
2128 unset($dicts[$key][$keyToDelete]);
2129 }
2130 } else {
2131 $error++;
2132 setEventMessages($langs->trans("ErrorDictionaryNotFound", ucfirst($dicname)), null, 'errors');
2133 }
2134 if (!$error) {
2135 // delete table
2136 $_results = $db->DDLDropTable(MAIN_DB_PREFIX.strtolower($newdicname));
2137 if ($_results < 0) {
2138 dol_print_error($db);
2139 $langs->load("errors");
2140 setEventMessages($langs->trans("ErrorTableNotFound", $newdicname), null, 'errors');
2141 }
2142 // rebuild file after update dictionaries
2143 $result = updateDictionaryInFile($module, $moduledescriptorfile, $dicts);
2144 if ($result > 0) {
2145 setEventMessages($langs->trans("DictionaryDeleted", ucfirst(substr($newdicname, 2))), null);
2146 }
2147 if (function_exists('opcache_invalidate')) {
2148 opcache_reset(); // remove the include cache hell !
2149 }
2150 clearstatcache(true);
2151 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : ''));
2152 exit;
2153 }
2154}
2155if ($dirins && $action == 'updatedictionary' && GETPOST('dictionnarykey')) {
2156 $keydict = GETPOST('dictionnarykey') - 1 ;
2157
2158 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2159 $destdir = $dirins.'/'.strtolower($module);
2160 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2161 dol_include_once($pathtofile);
2162 $class = 'mod'.$module;
2163
2164 if (class_exists($class)) {
2165 try {
2166 $moduleobj = new $class($db);
2167 } catch (Exception $e) {
2168 $error++;
2169 dol_print_error($db, $e->getMessage());
2170 }
2171 } else {
2172 $error++;
2173 $langs->load("errors");
2174 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
2175 exit;
2176 }
2177
2178 $dicts = $moduleobj->dictionaries;
2179 if (!empty(GETPOST('tablib')) && GETPOST('tablib') !== $dicts['tablib'][$keydict]) {
2180 $dicts['tablib'][$keydict] = ucfirst(strtolower(GETPOST('tablib')));
2181 $checkComment = checkExistComment($moduledescriptorfile, 2);
2182 if ($checkComment < 0) {
2183 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Dictionaries"), "mod".$module."class.php"), null, 'warnings');
2184 } else {
2185 $updateDict = updateDictionaryInFile($module, $moduledescriptorfile, $dicts);
2186 if ($updateDict > 0) {
2187 setEventMessages($langs->trans("DictionaryNameUpdated", ucfirst(GETPOST('tablib'))), null);
2188 }
2189 if (function_exists('opcache_invalidate')) {
2190 opcache_reset(); // remove the include cache hell !
2191 }
2192 clearstatcache(true);
2193 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : ''));
2194 exit;
2195 }
2196 }
2197 //var_dump(GETPOST('tablib'));exit;
2198}
2199if ($dirins && $action == 'generatedoc') {
2200 $modulelowercase = strtolower($module);
2201
2202 // Dir for module
2203 $dirofmodule = dol_buildpath($modulelowercase, 0).'/doc';
2204
2205 $FILENAMEDOC = strtolower($module).'.html';
2206
2207 $util = new Utils($db);
2208 $result = $util->generateDoc($module);
2209
2210 if ($result > 0) {
2211 setEventMessages($langs->trans("DocFileGeneratedInto", $dirofmodule), null);
2212 } else {
2213 setEventMessages($util->error, $util->errors, 'errors');
2214 }
2215}
2216
2217if ($dirins && $action == 'generatepackage') {
2218 $modulelowercase = strtolower($module);
2219
2220 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2221
2222 // Dir for module
2223 $dir = dol_buildpath($modulelowercase, 0);
2224
2225 // Zip file to build
2226 $FILENAMEZIP = '';
2227
2228 // Load module
2229 dol_include_once($pathtofile);
2230 $class = 'mod'.$module;
2231
2232 if (class_exists($class)) {
2233 try {
2234 $moduleobj = new $class($db);
2235 } catch (Exception $e) {
2236 $error++;
2237 dol_print_error($db, $e->getMessage());
2238 }
2239 } else {
2240 $error++;
2241 $langs->load("errors");
2242 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
2243 exit;
2244 }
2245
2246 $arrayversion = explode('.', $moduleobj->version, 3);
2247 if (count($arrayversion)) {
2248 $FILENAMEZIP = "module_".$modulelowercase.'-'.$arrayversion[0].(empty($arrayversion[1]) ? '.0' : '.'.$arrayversion[1]).(empty($arrayversion[2]) ? '' : '.'.$arrayversion[2]).'.zip';
2249
2250 $dirofmodule = dol_buildpath($modulelowercase, 0).'/bin';
2251 $outputfilezip = $dirofmodule.'/'.$FILENAMEZIP;
2252 if ($dirofmodule) {
2253 if (!dol_is_dir($dirofmodule)) {
2254 dol_mkdir($dirofmodule);
2255 }
2256 // Note: We exclude /bin/ to not include the already generated zip
2257 $result = dol_compress_dir($dir, $outputfilezip, 'zip', '/\/bin\/|\.git|\.old|\.back|\.ssh/', $modulelowercase);
2258 } else {
2259 $result = -1;
2260 }
2261
2262 if ($result > 0) {
2263 setEventMessages($langs->trans("ZipFileGeneratedInto", $outputfilezip), null);
2264 } else {
2265 $error++;
2266 $langs->load("errors");
2267 setEventMessages($langs->trans("ErrorFailToGenerateFile", $outputfilezip), null, 'errors');
2268 }
2269 } else {
2270 $error++;
2271 $langs->load("errors");
2272 setEventMessages($langs->trans("ErrorCheckVersionIsDefined"), null, 'errors');
2273 }
2274}
2275
2276// Add permission
2277if ($dirins && $action == 'addright' && !empty($module) && empty($cancel)) {
2278 $error = 0;
2279
2280 // load class and check if right exist
2281 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2282 dol_include_once($pathtofile);
2283 $class = 'mod'.$module;
2284 if (class_exists($class)) {
2285 try {
2286 $moduleobj = new $class($db);
2287 } catch (Exception $e) {
2288 $error++;
2289 dol_print_error($db, $e->getMessage());
2290 }
2291 }
2292
2293 // verify information entered
2294 if (!GETPOST('label', 'alpha')) {
2295 $error++;
2296 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
2297 }
2298 if (!GETPOST('permissionObj', 'alpha')) {
2299 $error++;
2300 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Rights")), null, 'errors');
2301 }
2302
2303 $id = GETPOST('id', 'alpha');
2304 $label = GETPOST('label', 'alpha');
2305 $objectForPerms = strtolower(GETPOST('permissionObj', 'alpha'));
2306 $crud = GETPOST('crud', 'alpha');
2307
2308 //check existing object permission
2309 $counter = 0;
2310 $permsForObject = array();
2311 $permissions = $moduleobj->rights;
2312 $allObject = array();
2313
2314 $countPerms = count($permissions);
2315
2316 for ($i = 0; $i < $countPerms; $i++) {
2317 if ($permissions[$i][4] == $objectForPerms) {
2318 $counter++;
2319 if (count($permsForObject) < 3) {
2320 $permsForObject[] = $permissions[$i];
2321 }
2322 }
2323 $allObject[] = $permissions[$i][4];
2324 }
2325
2326 // check if label of object already exists
2327 $countPermsObj = count($permsForObject);
2328 for ($j = 0; $j < $countPermsObj; $j++) {
2329 if (in_array($crud, $permsForObject[$j])) {
2330 $error++;
2331 setEventMessages($langs->trans("ErrorExistingPermission", $langs->transnoentities($crud), $langs->transnoentities($objectForPerms)), null, 'errors');
2332 }
2333 }
2334
2335 if (!$error) {
2336 $key = $countPerms + 1;
2337 //prepare right to add
2338 $rightToAdd = [
2339 0 => $id,
2340 1 => $label,
2341 4 => $objectForPerms,
2342 5 => $crud
2343 ];
2344
2345 if (isModEnabled(strtolower($module))) {
2346 $result = unActivateModule(strtolower($module));
2347 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
2348 if ($result) {
2349 setEventMessages($result, null, 'errors');
2350 }
2351 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2352 }
2353 }
2354 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2355 //rewriting all permissions after add a right
2356 $rewrite = checkExistComment($moduledescriptorfile, 1);
2357 if ($rewrite < 0) {
2358 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
2359 } else {
2360 reWriteAllPermissions($moduledescriptorfile, $permissions, $key, $rightToAdd, '', '', 1);
2361 setEventMessages($langs->trans('PermissionAddedSuccesfuly'), null);
2362
2363 clearstatcache(true);
2364 if (function_exists('opcache_invalidate')) {
2365 opcache_reset(); // remove the include cache hell !
2366 }
2367 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
2368 exit;
2369 }
2370}
2371
2372
2373// Update permission
2374if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright') && empty($cancel)) {
2375 $error = 0;
2376 // load class and check if right exist
2377 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2378 dol_include_once($pathtofile);
2379 $class = 'mod'.$module;
2380 if (class_exists($class)) {
2381 try {
2382 $moduleobj = new $class($db);
2383 } catch (Exception $e) {
2384 $error++;
2385 dol_print_error($db, $e->getMessage());
2386 }
2387 }
2388 // verify information entered
2389 if (!GETPOST('label', 'alpha')) {
2390 $error++;
2391 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
2392 }
2393 if (!GETPOST('permissionObj', 'alpha')) {
2394 $error++;
2395 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Rights")), null, 'errors');
2396 }
2397
2398 $label = GETPOST('label', 'alpha');
2399 $objectForPerms = strtolower(GETPOST('permissionObj', 'alpha'));
2400 $crud = GETPOST('crud', 'alpha');
2401
2402
2403 if ($label == "Read objects of $module" && $crud != "read") {
2404 $crud = "read";
2405 // $label = "Read objects of $module";
2406 }
2407 if ($label == "Create/Update objects of $module" && $crud != "write") {
2408 $crud = "write";
2409 // $label = "Create/Update objects of $module";
2410 }
2411 if ($label == "Delete objects of $module" && $crud != "delete") {
2412 $crud = "delete";
2413 // $label = "Delete objects of $module";
2414 }
2415
2416 $permissions = $moduleobj->rights;
2417 $key = (int) GETPOST('counter') - 1;
2418 //get permission want to delete from permissions array
2419 $x1 = $permissions[$key][1];
2420 $x2 = $permissions[$key][4];
2421 $x3 = $permissions[$key][5];
2422 //check existing object permission
2423 $counter = 0;
2424 $permsForObject = array();
2425 $permissions = $moduleobj->rights;
2426 $firstRight = 0;
2427 $existRight = 0;
2428 $allObject = array();
2429
2430 $countPerms = count($permissions);
2431 for ($i = 0; $i < $countPerms; $i++) {
2432 if ($permissions[$i][4] == $objectForPerms) {
2433 $counter++;
2434 if (count($permsForObject) < 3) {
2435 $permsForObject[] = $permissions[$i];
2436 }
2437 }
2438 $allObject[] = $permissions[$i][4];
2439 }
2440
2441 if ($label != $x1 && $crud != $x3) {
2442 $countPermsObj = count($permsForObject);
2443 for ($j = 0; $j < $countPermsObj; $j++) {
2444 if (in_array($label, $permsForObject[$j])) {
2445 $error++;
2446 setEventMessages($langs->trans("ErrorExistingPermission", $langs->transnoentities($label), $langs->transnoentities($objectForPerms)), null, 'errors');
2447 }
2448 }
2449 }
2450
2451 if (!$error) {
2452 if (isModEnabled(strtolower($module))) {
2453 $result = unActivateModule(strtolower($module));
2454 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->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 update permission needed
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, $rightUpdated, '', '', 2);
2468 setEventMessages($langs->trans('PermissionUpdatedSuccesfuly'), null);
2469 clearstatcache(true);
2470 if (function_exists('opcache_invalidate')) {
2471 opcache_reset(); // remove the include cache hell !
2472 }
2473 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
2474 exit;
2475 }
2476 }
2477}
2478// Delete permission
2479if ($dirins && $action == 'confirm_deleteright' && !empty($module) && GETPOSTINT('permskey')) {
2480 $error = 0;
2481 // load class and check if right exist
2482 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2483 dol_include_once($pathtofile);
2484 $class = 'mod'.$module;
2485 if (class_exists($class)) {
2486 try {
2487 $moduleobj = new $class($db);
2488 } catch (Exception $e) {
2489 $error++;
2490 dol_print_error($db, $e->getMessage());
2491 }
2492 }
2493
2494 $permissions = $moduleobj->rights;
2495 $key = GETPOSTINT('permskey') - 1;
2496
2497 if (!$error) {
2498 // check if module is enabled
2499 if (isModEnabled(strtolower($module))) {
2500 $result = unActivateModule(strtolower($module));
2501 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
2502 if ($result) {
2503 setEventMessages($result, null, 'errors');
2504 }
2505 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2506 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
2507 exit;
2508 }
2509
2510 // rewriting all permissions
2511 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2512 $rewrite = checkExistComment($moduledescriptorfile, 1);
2513 if ($rewrite < 0) {
2514 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Permissions"), "mod".$module."class.php"), null, 'warnings');
2515 } else {
2516 reWriteAllPermissions($moduledescriptorfile, $permissions, $key, null, '', '', 0);
2517 setEventMessages($langs->trans('PermissionDeletedSuccesfuly'), null);
2518
2519 clearstatcache(true);
2520 if (function_exists('opcache_invalidate')) {
2521 opcache_reset(); // remove the include cache hell !
2522 }
2523
2524 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
2525 exit;
2526 }
2527 }
2528}
2529// Save file
2530if ($action == 'savefile' && empty($cancel)) {
2531 $relofcustom = basename($dirins);
2532
2533 if ($relofcustom) {
2534 // Check that relative path ($file) start with name 'custom'
2535 if (!preg_match('/^'.$relofcustom.'/', $file)) {
2536 $file = $relofcustom.'/'.$file;
2537 }
2538
2539 $pathoffile = dol_buildpath($file, 0);
2540 $pathoffilebackup = dol_buildpath($file.'.back', 0);
2541
2542 // Save old version
2543 if (dol_is_file($pathoffile)) {
2544 dol_copy($pathoffile, $pathoffilebackup, 0, 1);
2545 }
2546
2547 $check = 'restricthtml';
2548 $srclang = dol_mimetype($pathoffile, '', 3);
2549 if ($srclang == 'md') {
2550 $check = 'restricthtml';
2551 }
2552 if ($srclang == 'lang') {
2553 $check = 'restricthtml';
2554 }
2555 if ($srclang == 'php') {
2556 $check = 'none';
2557 }
2558
2559 $content = GETPOST('editfilecontent', $check);
2560
2561 // Save file on disk
2562 if ($content) {
2563 dol_delete_file($pathoffile);
2564 $result = file_put_contents($pathoffile, $content);
2565 if ($result) {
2566 dolChmod($pathoffile, $newmask);
2567
2568 setEventMessages($langs->trans("FileSaved"), null);
2569 } else {
2570 setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
2571 }
2572 } else {
2573 setEventMessages($langs->trans("ContentCantBeEmpty"), null, 'errors');
2574 //$action='editfile';
2575 $error++;
2576 }
2577 }
2578}
2579
2580// Enable module
2581if ($action == 'set' && $user->admin) {
2582 $param = '';
2583 if ($module) {
2584 $param .= '&module='.urlencode($module);
2585 }
2586 if ($tab) {
2587 $param .= '&tab='.urlencode($tab);
2588 }
2589 if ($tabobj) {
2590 $param .= '&tabobj='.urlencode($tabobj);
2591 }
2592
2593 $value = GETPOST('value', 'alpha');
2594 $resarray = activateModule($value);
2595 if (!empty($resarray['errors'])) {
2596 setEventMessages('', $resarray['errors'], 'errors');
2597 } else {
2598 //var_dump($resarray);exit;
2599 if ($resarray['nbperms'] > 0) {
2600 $tmpsql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."user WHERE admin <> 1";
2601 $resqltmp = $db->query($tmpsql);
2602 if ($resqltmp) {
2603 $obj = $db->fetch_object($resqltmp);
2604 //var_dump($obj->nb);exit;
2605 if ($obj && $obj->nb > 1) {
2606 $msg = $langs->trans('ModuleEnabledAdminMustCheckRights');
2607 setEventMessages($msg, null, 'warnings');
2608 }
2609 } else {
2610 dol_print_error($db);
2611 }
2612 }
2613 }
2614 header("Location: ".$_SERVER["PHP_SELF"]."?".$param);
2615 exit;
2616}
2617
2618// Disable module
2619if ($action == 'reset' && $user->admin) {
2620 $param = '';
2621 if ($module) {
2622 $param .= '&module='.urlencode($module);
2623 }
2624 if ($tab) {
2625 $param .= '&tab='.urlencode($tab);
2626 }
2627 if ($tabobj) {
2628 $param .= '&tabobj='.urlencode($tabobj);
2629 }
2630
2631 $value = GETPOST('value', 'alpha');
2632 $result = unActivateModule($value);
2633 if ($result) {
2634 setEventMessages($result, null, 'errors');
2635 }
2636 header("Location: ".$_SERVER["PHP_SELF"]."?".$param);
2637 exit;
2638}
2639
2640// delete menu
2641if ($dirins && $action == 'confirm_deletemenu' && GETPOSTINT('menukey')) {
2642 // check if module is enabled
2643 if (isModEnabled(strtolower($module))) {
2644 $result = unActivateModule(strtolower($module));
2645 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
2646 if ($result) {
2647 setEventMessages($result, null, 'errors');
2648 }
2649 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2650 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2651 exit;
2652 }
2653 // load class and check if menu exist
2654 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2655 dol_include_once($pathtofile);
2656 $class = 'mod'.$module;
2657 if (class_exists($class)) {
2658 try {
2659 $moduleobj = new $class($db);
2660 } catch (Exception $e) {
2661 $error++;
2662 dol_print_error($db, $e->getMessage());
2663 }
2664 }
2665 // get all objects and convert value to lower case for compare
2666 $dir = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
2667 $destdir = $dir.'/'.strtolower($module);
2668 $objects = dolGetListOfObjectClasses($destdir);
2669 $result = array_map('strtolower', $objects);
2670
2671 $menus = $moduleobj->menu;
2672 $key = GETPOSTINT('menukey');
2673 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2674
2675 $checkcomment = checkExistComment($moduledescriptorfile, 0);
2676 if ($checkcomment < 0) {
2677 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), "mod".$module."class.php"), null, 'warnings');
2678 } else {
2679 if ($menus[$key]['fk_menu'] === 'fk_mainmenu='.strtolower($module)) {
2680 if (in_array(strtolower($menus[$key]['leftmenu']), $result)) {
2681 reWriteAllMenus($moduledescriptorfile, $menus, $menus[$key]['leftmenu'], $key, -1);
2682 } else {
2683 reWriteAllMenus($moduledescriptorfile, $menus, null, $key, 0);
2684 }
2685 } else {
2686 reWriteAllMenus($moduledescriptorfile, $menus, null, $key, 0);
2687 }
2688
2689 clearstatcache(true);
2690 if (function_exists('opcache_invalidate')) {
2691 opcache_reset(); // remove the include cache hell !
2692 }
2693
2694 setEventMessages($langs->trans('MenuDeletedSuccessfuly'), null);
2695 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2696 exit;
2697 }
2698}
2699
2700// Add menu in module without initial object
2701if ($dirins && $action == 'addmenu' && empty($cancel)) {
2702 // check if module is enabled
2703 if (isModEnabled(strtolower($module))) {
2704 $result = unActivateModule(strtolower($module));
2705 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
2706 if ($result) {
2707 setEventMessages($result, null, 'errors');
2708 }
2709 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2710 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2711 exit;
2712 }
2713 $error = 0;
2714
2715 // load class and check if right exist
2716 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2717 dol_include_once($pathtofile);
2718 $class = 'mod'.$module;
2719 if (class_exists($class)) {
2720 try {
2721 $moduleobj = new $class($db);
2722 } catch (Exception $e) {
2723 $error++;
2724 dol_print_error($db, $e->getMessage());
2725 }
2726 }
2727 // get all menus
2728 $menus = $moduleobj->menu;
2729
2730 //verify fields required
2731 if (!GETPOST('type', 'alpha')) {
2732 $error++;
2733 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors');
2734 }
2735 if (!GETPOST('titre', 'alpha')) {
2736 $error++;
2737 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Title")), null, 'errors');
2738 }
2739 if (!GETPOST('user', 'alpha')) {
2740 $error++;
2741 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("DetailUser")), null, 'errors');
2742 }
2743 if (!GETPOST('url', 'alpha')) {
2744 $error++;
2745 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Url")), null, 'errors');
2746 }
2747 if (!empty(GETPOST('target'))) {
2748 $targets = array('_blank','_self','_parent','_top','');
2749 if (!in_array(GETPOST('target'), $targets)) {
2750 $error++;
2751 setEventMessages($langs->trans("ErrorFieldValue", $langs->transnoentities("target")), null, 'errors');
2752 }
2753 }
2754
2755
2756 // check if title or url already exist in menus
2757
2758 foreach ($menus as $menu) {
2759 if (!empty(GETPOST('url')) && GETPOST('url') == $menu['url']) {
2760 $error++;
2761 setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentities("url")), null, 'errors');
2762 break;
2763 }
2764 if (strtolower(GETPOST('titre')) == strtolower($menu['titre'])) {
2765 $error++;
2766 setEventMessages($langs->trans("ErrorFieldExist", $langs->transnoentities("titre")), null, 'errors');
2767 break;
2768 }
2769 }
2770
2771 if (GETPOST('type', 'alpha') == 'left' && !empty(GETPOST('lefmenu', 'alpha'))) {
2772 if (!str_contains(GETPOST('leftmenu'), strtolower($module))) {
2773 $error++;
2774 setEventMessages($langs->trans("WarningFieldsMustContains", $langs->transnoentities("LeftmenuId")), null, 'errors');
2775 }
2776 }
2777 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
2778 $destdir = $dirins.'/'.strtolower($module);
2779 $objects = dolGetListOfObjectClasses($destdir);
2780
2781 if (GETPOST('type', 'alpha') == 'left') {
2782 if (empty(GETPOST('leftmenu')) && count($objects) > 0) {
2783 $error++;
2784 setEventMessages($langs->trans("ErrorCoherenceMenu", $langs->transnoentities("LeftmenuId"), $langs->transnoentities("type")), null, 'errors');
2785 }
2786 }
2787 if (GETPOST('type', 'alpha') == 'top') {
2788 $error++;
2789 setEventMessages($langs->trans("ErrorTypeMenu", $langs->transnoentities("type")), null, 'errors');
2790 }
2791
2792 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2793 if (!$error) {
2794 //stock forms in array
2795 $menuToAdd = array(
2796 'fk_menu' => GETPOST('fk_menu', 'alpha'),
2797 'type' => GETPOST('type', 'alpha'),
2798 'titre' => ucfirst(GETPOST('titre', 'alpha')),
2799 'prefix' => '',
2800 'mainmenu' => GETPOST('mainmenu', 'alpha'),
2801 'leftmenu' => GETPOST('leftmenu', 'alpha'),
2802 'url' => GETPOST('url', 'alpha'),
2803 'langs' => strtolower($module)."@".strtolower($module),
2804 'position' => '',
2805 'enabled' => GETPOST('enabled', 'alpha'),
2806 'perms' => '$user->hasRight("'.strtolower($module).'", "'.GETPOST('objects', 'alpha').'", "'.GETPOST('perms', 'alpha').'")',
2807 'target' => GETPOST('target', 'alpha'),
2808 'user' => GETPOST('user', 'alpha'),
2809 );
2810
2811 if (GETPOST('type') == 'left') {
2812 unset($menuToAdd['prefix']);
2813 if (empty(GETPOST('fk_menu'))) {
2814 $menuToAdd['fk_menu'] = 'fk_mainmenu='.GETPOST('mainmenu', 'alpha');
2815 } else {
2816 $menuToAdd['fk_menu'] = 'fk_mainmenu='.GETPOST('mainmenu', 'alpha').',fk_leftmenu='.GETPOST('fk_menu');
2817 }
2818 }
2819 if (GETPOST('enabled') == '1') {
2820 $menuToAdd['enabled'] = 'isModEnabled("'.strtolower($module).'")';
2821 } else {
2822 $menuToAdd['enabled'] = "0";
2823 }
2824 if (empty(GETPOST('objects'))) {
2825 $menuToAdd['perms'] = '1';
2826 }
2827
2828 $checkcomment = checkExistComment($moduledescriptorfile, 0);
2829 if ($checkcomment < 0) {
2830 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), "mod".$module."class.php"), null, 'warnings');
2831 } else {
2832 // Write all menus
2833 $result = reWriteAllMenus($moduledescriptorfile, $menus, $menuToAdd, null, 1);
2834
2835 clearstatcache(true);
2836 if (function_exists('opcache_invalidate')) {
2837 opcache_reset();
2838 }
2839 /*if ($result < 0) {
2840 setEventMessages($langs->trans('ErrorMenuExistValue'), null, 'errors');
2841 header("Location: ".$_SERVER["PHP_SELF"].'?action=editmenu&token='.newToken().'&menukey='.urlencode($key+1).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.($key+1));
2842 exit;
2843 }*/
2844
2845 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2846 setEventMessages($langs->trans('MenuAddedSuccesfuly'), null);
2847 exit;
2848 }
2849 }
2850}
2851
2852// Modify a menu entry
2853if ($dirins && $action == "update_menu" && GETPOSTINT('menukey') && GETPOST('tabobj')) {
2854 $objectname = GETPOST('tabobj');
2855 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
2856 $destdir = $dirins.'/'.strtolower($module);
2857 $objects = dolGetListOfObjectClasses($destdir);
2858
2859 if (empty($cancel)) {
2860 if (isModEnabled(strtolower($module))) {
2861 $result = unActivateModule(strtolower($module));
2862 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
2863 if ($result) {
2864 setEventMessages($result, null, 'errors');
2865 }
2866 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2867 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2868 exit;
2869 }
2870 $error = 0;
2871 // for loading class and the menu wants to modify
2872 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2873 dol_include_once($pathtofile);
2874 $class = 'mod'.$module;
2875 if (class_exists($class)) {
2876 try {
2877 $moduleobj = new $class($db);
2878 } catch (Exception $e) {
2879 $error++;
2880 dol_print_error($db, $e->getMessage());
2881 }
2882 }
2883 $menus = $moduleobj->menu;
2884 $key = GETPOSTINT('menukey') - 1;
2885
2886 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2887 //stock forms in array
2888 $menuModify = array(
2889 'fk_menu' => GETPOST('fk_menu', 'alpha'),
2890 'type' => GETPOST('type', 'alpha'),
2891 'titre' => ucfirst(GETPOST('titre', 'alpha')),
2892 'mainmenu' => GETPOST('mainmenu', 'alpha'),
2893 'leftmenu' => $menus[$key]['leftmenu'],
2894 'url' => GETPOST('url', 'alpha'),
2895 'langs' => strtolower($module)."@".strtolower($module),
2896 'position' => '',
2897 'enabled' => GETPOST('enabled', 'alpha'),
2898 'perms' => GETPOST('perms', 'alpha'),
2899 'target' => GETPOST('target', 'alpha'),
2900 'user' => GETPOST('user', 'alpha'),
2901 );
2902 if (!empty(GETPOST('fk_menu')) && GETPOST('fk_menu') != $menus[$key]['fk_menu']) {
2903 $menuModify['fk_menu'] = 'fk_mainmenu='.GETPOST('mainmenu').',fk_leftmenu='.GETPOST('fk_menu');
2904 } elseif (GETPOST('fk_menu') == $menus[$key]['fk_menu']) {
2905 $menuModify['fk_menu'] = $menus[$key]['fk_menu'];
2906 } else {
2907 $menuModify['fk_menu'] = 'fk_mainmenu='.GETPOST('mainmenu');
2908 }
2909 if ($menuModify['enabled'] === '') {
2910 $menuModify['enabled'] = '1';
2911 }
2912 if ($menuModify['perms'] === '') {
2913 $menuModify['perms'] = '1';
2914 }
2915
2916 if (GETPOST('type', 'alpha') == 'top') {
2917 $error++;
2918 setEventMessages($langs->trans("ErrorTypeMenu", $langs->transnoentities("type")), null, 'errors');
2919 }
2920
2921 if (!$error) {
2922 //update menu
2923 $checkComment = checkExistComment($moduledescriptorfile, 0);
2924
2925 if ($checkComment < 0) {
2926 setEventMessages($langs->trans("WarningCommentNotFound", $langs->trans("Menus"), "mod".$module."class.php"), null, 'warnings');
2927 } else {
2928 // Write all menus
2929 $result = reWriteAllMenus($moduledescriptorfile, $menus, $menuModify, $key, 2);
2930
2931 clearstatcache(true);
2932 if (function_exists('opcache_invalidate')) {
2933 opcache_reset();
2934 }
2935
2936 if ($result < 0) {
2937 setEventMessages($langs->trans('ErrorMenuExistValue'), null, 'errors');
2938 //var_dump($_SESSION);exit;
2939 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));
2940 exit;
2941 }
2942
2943 setEventMessages($langs->trans('MenuUpdatedSuccessfuly'), null);
2944 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2945 exit;
2946 }
2947 }
2948 } else {
2949 $_POST['type'] = ''; // TODO Use a var here and later
2950 $_POST['titre'] = '';
2951 $_POST['fk_menu'] = '';
2952 $_POST['leftmenu'] = '';
2953 $_POST['url'] = '';
2954 }
2955}
2956
2957// update properties description of module
2958if ($dirins && $action == "update_props_module" && !empty(GETPOST('keydescription', 'alpha')) && empty($cancel)) {
2959 if (isModEnabled(strtolower($module))) {
2960 $result = unActivateModule(strtolower($module));
2961 dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
2962 if ($result) {
2963 setEventMessages($result, null, 'errors');
2964 }
2965 setEventMessages($langs->trans('WarningModuleNeedRefresh', $langs->transnoentities($module)), null, 'warnings');
2966 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
2967 exit;
2968 }
2969 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
2970 $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
2971 $modulelogfile = $dirins.'/'.strtolower($module).'/ChangeLog.md';
2972
2973 dol_include_once($pathtofile);
2974
2975 $class = 'mod'.$module;
2976 if (class_exists($class)) {
2977 try {
2978 $moduleobj = new $class($db);
2979 } catch (Exception $e) {
2980 $error++;
2981 dol_print_error($db, $e->getMessage());
2982 }
2983 }
2984
2985 $keydescription = GETPOST('keydescription', 'alpha');
2986 switch ($keydescription) {
2987 case 'desc':
2988 $propertyToUpdate = 'description';
2989 break;
2990 case 'version':
2991 case 'family':
2992 case 'picto':
2993 case 'editor_name':
2994 case 'editor_url':
2995 $propertyToUpdate = $keydescription;
2996 break;
2997 default:
2998 $error = GETPOST('keydescription');
2999 break;
3000 }
3001
3002 if (isset($propertyToUpdate) && !empty(GETPOST('propsmodule'))) {
3003 $newValue = GETPOST('propsmodule');
3004 $lineToReplace = "\t\t\$this->$propertyToUpdate = ";
3005 $newLine = "\t\t\$this->$propertyToUpdate = '$newValue';\n";
3006
3007 //for change version in log file
3008 if ($propertyToUpdate === 'version') {
3009 dolReplaceInFile($modulelogfile, array("## ".$moduleobj->$propertyToUpdate => $newValue));
3010 }
3011
3012 $fileLines = file($moduledescriptorfile);
3013 foreach ($fileLines as &$line) {
3014 if (strpos($line, $lineToReplace) === 0) {
3015 dolReplaceInFile($moduledescriptorfile, array($line => $newLine));
3016 break;
3017 }
3018 }
3019
3020 clearstatcache(true);
3021 if (function_exists('opcache_invalidate')) {
3022 opcache_reset();
3023 }
3024 setEventMessages($langs->trans('PropertyModuleUpdated', $propertyToUpdate), null);
3025 header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=description&module='.$module);
3026 exit;
3027 }
3028}
3029
3030/*
3031 * View
3032 */
3033
3034$form = new Form($db);
3035$formadmin = new FormAdmin($db);
3036
3037// Set dir where external modules are installed
3038if (!dol_is_dir($dirins)) {
3039 dol_mkdir($dirins);
3040}
3041$dirins_ok = (dol_is_dir($dirins));
3042
3043$help_url = '';
3044$morejs = array(
3045 '/includes/ace/src/ace.js',
3046 '/includes/ace/src/ext-statusbar.js',
3047 '/includes/ace/src/ext-language_tools.js',
3048 //'/includes/ace/src/ext-chromevox.js'
3049);
3050$morecss = array();
3051
3052llxHeader('', $langs->trans("ModuleBuilder"), $help_url, '', 0, 0, $morejs, $morecss, '', 'classforhorizontalscrolloftabs');
3053
3054
3055$text = $langs->trans("ModuleBuilder");
3056
3057print load_fiche_titre($text, '', 'title_setup');
3058
3059print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'</span>';
3060print '<br class="hideonsmartphone">';
3061
3062//print $textforlistofdirs;
3063//print '<br>';
3064
3065
3066
3067$message = '';
3068if (!$dirins) {
3069 $message = info_admin($langs->trans("ConfFileMustContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT));
3070 $allowfromweb = -1;
3071} else {
3072 if ($dirins_ok) {
3073 if (!is_writable(dol_osencode($dirins))) {
3074 $langs->load("errors");
3075 $message = info_admin($langs->trans("ErrorFailedToWriteInDir", $dirins));
3076 $allowfromweb = 0;
3077 }
3078 } else {
3079 $message = info_admin($langs->trans("NotExistsDirect", $dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample"));
3080 $allowfromweb = 0;
3081 }
3082}
3083if ($message) {
3084 print $message;
3085}
3086
3087//print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'<br>';
3088$infomodulesfound = '<div style="padding: 12px 9px 12px">'.$form->textwithpicto('', $langs->trans("ModuleBuilderDesc3", count($listofmodules)).'<br><br>'.$langs->trans("ModuleBuilderDesc4", $FILEFLAG).'<br>'.$textforlistofdirs).'</div>';
3089
3090
3091
3092$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
3093$allowonlineinstall = true;
3094if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
3095 $allowonlineinstall = false;
3096}
3097if (empty($allowonlineinstall)) {
3098 if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
3099 // Show clean message
3100 $message = info_admin($langs->trans('InstallModuleFromWebHasBeenDisabledContactUs'));
3101 } else {
3102 // Show technical message
3103 $message = info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock'), 0, 0, 1, 'warning');
3104 }
3105
3106 print $message;
3107
3108 llxFooter();
3109 exit(0);
3110}
3111
3112
3113// Load module descriptor
3114$error = 0;
3115$moduleobj = null;
3116
3117
3118if (!empty($module) && $module != 'initmodule' && $module != 'deletemodule') {
3119 $modulelowercase = strtolower($module);
3120 $loadclasserrormessage = '';
3121
3122 // Load module
3123 try {
3124 $fullpathdirtodescriptor = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
3125
3126 //throw(new Exception());
3127 dol_include_once($fullpathdirtodescriptor);
3128
3129 $class = 'mod'.$module;
3130 } catch (Throwable $e) { // This is called in PHP 7 only (includes Error and Exception)
3131 $loadclasserrormessage = $e->getMessage()."<br>\n";
3132 $loadclasserrormessage .= 'File: '.$e->getFile()."<br>\n";
3133 $loadclasserrormessage .= 'Line: '.$e->getLine()."<br>\n";
3134 }
3135
3136 if (class_exists($class)) {
3137 try {
3138 $moduleobj = new $class($db);
3139 } catch (Exception $e) {
3140 $error++;
3141 print $e->getMessage();
3142 }
3143 } else {
3144 if (empty($forceddirread)) {
3145 $error++;
3146 }
3147 $langs->load("errors");
3148 print '<!-- ErrorFailedToLoadModuleDescriptorForXXX -->';
3149 print img_warning('').' '.$langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'<br>';
3150 print $loadclasserrormessage;
3151 }
3152}
3153
3154print '<br>';
3155
3156
3157// Tabs for all modules
3158$head = array();
3159$h = 0;
3160
3161$head[$h][0] = $_SERVER["PHP_SELF"].'?module=initmodule';
3162$head[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewModule").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
3163$head[$h][2] = 'initmodule';
3164$h++;
3165
3166$linktoenabledisable = '';
3167
3168if (is_array($listofmodules) && count($listofmodules) > 0) {
3169 // Define $linktoenabledisable
3170 $modulelowercase = strtolower($module);
3171
3172 $param = '';
3173 if ($tab) {
3174 $param .= '&tab='.urlencode($tab);
3175 }
3176 if ($module) {
3177 $param .= '&module='.urlencode($module);
3178 }
3179 if ($tabobj) {
3180 $param .= '&tabobj='.urlencode($tabobj);
3181 }
3182
3183 $urltomodulesetup = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?search_keyword='.urlencode($module).'">'.$langs->trans('Home').'-'.$langs->trans("Setup").'-'.$langs->trans("Modules").'</a>';
3184
3185 // Define $linktoenabledisable to show after module title
3186 if (isModEnabled($modulelowercase)) { // If module is already activated
3187 $linktoenabledisable .= '<a class="reposition asetresetmodule valignmiddle" href="'.$_SERVER["PHP_SELF"].'?id='.$moduleobj->numero.'&action=reset&token='.newToken().'&value=mod'.$module.$param.'">';
3188 $linktoenabledisable .= img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', '', 1);
3189 $linktoenabledisable .= '</a>';
3190
3191 $linktoenabledisable .= $form->textwithpicto('', $langs->trans("Warning").' : '.$langs->trans("ModuleIsLive"), -1, 'warning');
3192
3193 $objMod = $moduleobj;
3194 $backtourlparam = '';
3195 $backtourlparam .= ($backtourlparam ? '&' : '?').'module='.$module; // No urlencode here, done later
3196 if ($tab) {
3197 $backtourlparam .= ($backtourlparam ? '&' : '?').'tab='.$tab; // No urlencode here, done later
3198 }
3199 $backtourl = $_SERVER["PHP_SELF"].$backtourlparam;
3200
3201 $regs = array();
3202 if (is_array($objMod->config_page_url)) {
3203 $i = 0;
3204 foreach ($objMod->config_page_url as $page) {
3205 $urlpage = $page;
3206 if ($i++) {
3207 $linktoenabledisable .= ' <a href="'.$urlpage.'" title="'.$langs->trans($page).'">'.img_picto(ucfirst($page), "setup").'</a>';
3208 // print '<a href="'.$page.'">'.ucfirst($page).'</a>&nbsp;';
3209 } else {
3210 if (preg_match('/^([^@]+)@([^@]+)$/i', $urlpage, $regs)) {
3211 $urltouse = dol_buildpath('/'.$regs[2].'/admin/'.$regs[1], 1);
3212 $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>';
3213 } else {
3214 // Case standard admin page (not a page provided by the
3215 // module but a page provided by dolibarr)
3216 $urltouse = DOL_URL_ROOT.'/admin/'.$urlpage;
3217 $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>';
3218 }
3219 }
3220 }
3221 } elseif (preg_match('/^([^@]+)@([^@]+)$/i', $objMod->config_page_url, $regs)) {
3222 $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>';
3223 }
3224 } else {
3225 if (!empty($moduleobj)) {
3226 $linktoenabledisable .= '<a class="reposition asetresetmodule valignmiddle" href="'.$_SERVER["PHP_SELF"].'?id='.$moduleobj->numero.'&action=set&token='.newToken().'&value=mod'.$module.$param.'">';
3227 $linktoenabledisable .= img_picto($langs->trans("ModuleIsNotActive", $urltomodulesetup), 'switch_off', 'style="padding-right: 8px"', false, 0, 0, '', 'classfortooltip', 1);
3228 $linktoenabledisable .= "</a>\n";
3229 }
3230 }
3231
3232 // Loop to show tab of each module
3233 foreach ($listofmodules as $tmpmodule => $tmpmodulearray) {
3234 $head[$h][0] = $_SERVER["PHP_SELF"].'?module='.$tmpmodulearray['modulenamewithcase'].($forceddirread ? '@'.$dirread : '');
3235 $head[$h][1] = $tmpmodulearray['modulenamewithcase'];
3236 $head[$h][2] = $tmpmodulearray['modulenamewithcase'];
3237
3238 if ($tmpmodulearray['modulenamewithcase'] == $module) {
3239 $head[$h][4] = '<span class="inline-block">'.$linktoenabledisable.'</span>';
3240 }
3241
3242 $h++;
3243 }
3244}
3245
3246$head[$h][0] = $_SERVER["PHP_SELF"].'?module=deletemodule';
3247$head[$h][1] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("DangerZone");
3248$head[$h][2] = 'deletemodule';
3249$h++;
3250
3251
3252print dol_get_fiche_head($head, $module, '', -1, '', 0, $infomodulesfound, '', 8); // Modules
3253
3254if ($module == 'initmodule') {
3255 // New module
3256 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3257 print '<input type="hidden" name="token" value="'.newToken().'">';
3258 print '<input type="hidden" name="action" value="initmodule">';
3259 print '<input type="hidden" name="module" value="initmodule">';
3260
3261 //print '<span class="opacitymedium">'.$langs->trans("ModuleBuilderDesc2", 'conf/conf.php', $newdircustom).'</span><br>';
3262 print '<br>';
3263
3264 print '<div class="tagtable">';
3265
3266 print '<div class="tagtr"><div class="tagtd paddingright">';
3267 print '<span class="opacitymedium">'.$langs->trans("IdModule").'</span>';
3268 print '</div><div class="tagtd">';
3269 print '<input type="text" name="idmodule" class="width75" value="500000" placeholder="'.dol_escape_htmltag($langs->trans("IdModule")).'">';
3270 print '<span class="opacitymedium">';
3271 print ' &nbsp; (';
3272 print dolButtonToOpenUrlInDialogPopup('popup_modules_id', $langs->transnoentitiesnoconv("SeeIDsInUse"), $langs->transnoentitiesnoconv("SeeIDsInUse"), '/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', '', '');
3273 print ' - ';
3274 print '<a href="https://wiki.dolibarr.org/index.php/List_of_modules_id" target="_blank" rel="noopener noreferrer external">'.$langs->trans("SeeReservedIDsRangeHere").'</a>';
3275 print ')';
3276 print '</span>';
3277 print '</div></div>';
3278
3279 print '<div class="tagtr"><div class="tagtd paddingright">';
3280 print '<span class="opacitymedium fieldrequired">'.$langs->trans("ModuleName").'</span>';
3281 print '</div><div class="tagtd">';
3282 print '<input type="text" name="modulename" value="'.dol_escape_htmltag($modulename).'" autofocus>';
3283 print ' '.$form->textwithpicto('', $langs->trans("EnterNameOfModuleDesc"));
3284 print '</div></div>';
3285
3286 print '<div class="tagtr"><div class="tagtd paddingright">';
3287 print '<span class="opacitymedium">'.$langs->trans("Description").'</span>';
3288 print '</div><div class="tagtd">';
3289 print '<input type="text" name="description" value="" class="minwidth500"><br>';
3290 print '</div></div>';
3291
3292 print '<div class="tagtr"><div class="tagtd paddingright">';
3293 print '<span class="opacitymedium">'.$langs->trans("Version").'</span>';
3294 print '</div><div class="tagtd">';
3295 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")).'">';
3296 print '</div></div>';
3297
3298 print '<div class="tagtr"><div class="tagtd paddingright">';
3299 print '<span class="opacitymedium">'.$langs->trans("Family").'</span>';
3300 print '</div><div class="tagtd">';
3301 print '<select name="family" id="family" class="minwidth400">';
3302 $arrayoffamilies = array(
3303 'hr' => "ModuleFamilyHr",
3304 'crm' => "ModuleFamilyCrm",
3305 'srm' => "ModuleFamilySrm",
3306 'financial' => 'ModuleFamilyFinancial',
3307 'products' => 'ModuleFamilyProducts',
3308 'projects' => 'ModuleFamilyProjects',
3309 'ecm' => 'ModuleFamilyECM',
3310 'technic' => 'ModuleFamilyTechnic',
3311 'portal' => 'ModuleFamilyPortal',
3312 'interface' => 'ModuleFamilyInterface',
3313 'base' => 'ModuleFamilyBase',
3314 'other' => 'ModuleFamilyOther'
3315 );
3316 foreach ($arrayoffamilies as $key => $value) {
3317 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>';
3318 }
3319 print '</select>';
3320 print ajax_combobox("family");
3321 print '</div></div>';
3322
3323 print '<div class="tagtr"><div class="tagtd paddingright">';
3324 print '<span class="opacitymedium">'.$langs->trans("Picto").'</span>';
3325 print '</div><div class="tagtd">';
3326 print '<input type="text" name="idpicto" value="'.(GETPOSTISSET('idpicto') ? GETPOST('idpicto') : getDolGlobalString('MODULEBUILDER_DEFAULTPICTO', 'fa-file-o')).'" placeholder="'.dol_escape_htmltag($langs->trans("Picto")).'">';
3327 print $form->textwithpicto('', $langs->trans("Example").': fa-file-o, fa-globe, ... any font awesome code.<br>Advanced syntax is fa-fakey[_faprefix[_facolor[_fasize]]]');
3328 print '</div></div>';
3329
3330 print '<div class="tagtr"><div class="tagtd paddingright">';
3331 print '<span class="opacitymedium">'.$langs->trans("EditorName").'</span>';
3332 print '</div><div class="tagtd">';
3333 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>';
3334 print '</div></div>';
3335
3336 print '<div class="tagtr"><div class="tagtd paddingright">';
3337 print '<span class="opacitymedium">'.$langs->trans("EditorUrl").'</span>';
3338 print '</div><div class="tagtd">';
3339 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>';
3340 print '</div></div>';
3341
3342 print '<br><input type="submit" class="button" name="create" value="'.dol_escape_htmltag($langs->trans("Create")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
3343 print '</form>';
3344} elseif ($module == 'deletemodule') {
3345 print '<!-- Form to init a module -->'."\n";
3346 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="delete">';
3347 print '<input type="hidden" name="token" value="'.newToken().'">';
3348 print '<input type="hidden" name="action" value="confirm_deletemodule">';
3349 print '<input type="hidden" name="module" value="deletemodule">';
3350
3351 print $langs->trans("EnterNameOfModuleToDeleteDesc").'<br><br>';
3352
3353 print '<input type="text" name="module" placeholder="'.dol_escape_htmltag($langs->trans("ModuleKey")).'" value="" autofocus>';
3354 print '<input type="submit" class="button smallpaddingimp" value="'.$langs->trans("Delete").'"'.($dirins ? '' : ' disabled="disabled"').'>';
3355 print '</form>';
3356} elseif (!empty($module)) {
3357 // Tabs for module
3358 if (!$error) {
3359 $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
3360 $destdir = $dirread.'/'.strtolower($module);
3361 $objects = dolGetListOfObjectClasses($destdir);
3362 $diroflang = dol_buildpath($modulelowercase, 0)."/langs";
3363 $countLangs = countItemsInDirectory($diroflang, 2);
3364 $countDictionaries = (!empty($moduleobj->dictionaries) ? count($moduleobj->dictionaries['tabname']) : 0);
3365 $countRights = count($moduleobj->rights);
3366 $countMenus = count($moduleobj->menu);
3367 $countTriggers = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/triggers");
3368 $countWidgets = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/boxes");
3369 $countEmailingSelectors = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/modules/mailings");
3370 $countCss = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/css");
3371 $countJs = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/js");
3372 $countCLI = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/scripts");
3373 $hasDoc = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/doc");
3374 //var_dump($moduleobj->dictionaries);exit;
3375 $head2 = array();
3376 $h = 0;
3377
3378 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=description&module='.$module.($forceddirread ? '@'.$dirread : '');
3379 $head2[$h][1] = $langs->trans("Description");
3380 $head2[$h][2] = 'description';
3381 $h++;
3382
3383 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '');
3384 $head2[$h][1] = ((!is_array($objects) || count($objects) <= 0) ? $langs->trans("Objects") : $langs->trans("Objects").'<span class="marginleftonlyshort badge">'.count($objects)."</span>");
3385 $head2[$h][2] = 'objects';
3386 $h++;
3387
3388 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=languages&module='.$module.($forceddirread ? '@'.$dirread : '');
3389 $head2[$h][1] = ($countLangs <= 0 ? $langs->trans("Languages") : $langs->trans("Languages").'<span class="marginleftonlyshort badge">'.$countLangs."</span>");
3390 $head2[$h][2] = 'languages';
3391 $h++;
3392
3393 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '');
3394 $head2[$h][1] = ($countDictionaries == 0 ? $langs->trans("Dictionaries") : $langs->trans('Dictionaries').'<span class="marginleftonlyshort badge">'.$countDictionaries."</span>");
3395 $head2[$h][2] = 'dictionaries';
3396 $h++;
3397
3398 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=permissions&module='.$module.($forceddirread ? '@'.$dirread : '');
3399 $head2[$h][1] = ($countRights <= 0 ? $langs->trans("Permissions") : $langs->trans("Permissions").'<span class="marginleftonlyshort badge">'.$countRights."</span>");
3400 $head2[$h][2] = 'permissions';
3401 $h++;
3402
3403 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=tabs&module='.$module.($forceddirread ? '@'.$dirread : '');
3404 $head2[$h][1] = $langs->trans("Tabs");
3405 $head2[$h][2] = 'tabs';
3406 $h++;
3407
3408 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=menus&module='.$module.($forceddirread ? '@'.$dirread : '');
3409 $head2[$h][1] = ($countMenus <= 0 ? $langs->trans("Menus") : $langs->trans("Menus").'<span class="marginleftonlyshort badge">'.$countMenus."</span>");
3410 $head2[$h][2] = 'menus';
3411 $h++;
3412
3413 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=hooks&module='.$module.($forceddirread ? '@'.$dirread : '');
3414 $head2[$h][1] = $langs->trans("Hooks");
3415 $head2[$h][2] = 'hooks';
3416 $h++;
3417
3418 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=triggers&module='.$module.($forceddirread ? '@'.$dirread : '');
3419 $head2[$h][1] = ($countTriggers <= 0 ? $langs->trans("Triggers") : $langs->trans("Triggers").'<span class="marginleftonlyshort badge">'.$countTriggers."</span>");
3420 $head2[$h][2] = 'triggers';
3421 $h++;
3422
3423 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=widgets&module='.$module.($forceddirread ? '@'.$dirread : '');
3424 $head2[$h][1] = ($countWidgets <= 0 ? $langs->trans("Widgets") : $langs->trans("Widgets").'<span class="marginleftonlyshort badge">'.$countWidgets."</span>");
3425 $head2[$h][2] = 'widgets';
3426 $h++;
3427
3428 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=emailings&module='.$module.($forceddirread ? '@'.$dirread : '');
3429 $head2[$h][1] = ($countEmailingSelectors <= 0 ? $langs->trans("EmailingSelectors") : $langs->trans("EmailingSelectors").'<span class="marginleftonlyshort badge">'.$countEmailingSelectors."</span>");
3430 $head2[$h][2] = 'emailings';
3431 $h++;
3432
3433 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=exportimport&module='.$module.($forceddirread ? '@'.$dirread : '');
3434 $head2[$h][1] = $langs->trans("Export").'-'.$langs->trans("Import");
3435 $head2[$h][2] = 'exportimport';
3436 $h++;
3437
3438 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=css&module='.$module.($forceddirread ? '@'.$dirread : '');
3439 $head2[$h][1] = ($countCss <= 0 ? $langs->trans("CSS") : $langs->trans("CSS")." (".$countCss.")");
3440 $head2[$h][2] = 'css';
3441 $h++;
3442
3443 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=js&module='.$module.($forceddirread ? '@'.$dirread : '');
3444 $head2[$h][1] = ($countJs <= 0 ? $langs->trans("JS") : $langs->trans("JS").'<span class="marginleftonlyshort badge">'.$countJs."</span>");
3445 $head2[$h][2] = 'js';
3446 $h++;
3447
3448 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=cli&module='.$module.($forceddirread ? '@'.$dirread : '');
3449 $head2[$h][1] = ($countCLI <= 0 ? $langs->trans("CLI") : $langs->trans("CLI").'<span class="marginleftonlyshort badge">'.$countCLI."</span>");
3450 $head2[$h][2] = 'cli';
3451 $h++;
3452
3453 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=cron&module='.$module.($forceddirread ? '@'.$dirread : '');
3454 $head2[$h][1] = $langs->trans("CronList");
3455 $head2[$h][2] = 'cron';
3456 $h++;
3457
3458 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=specifications&module='.$module.($forceddirread ? '@'.$dirread : '');
3459 $head2[$h][1] = ($hasDoc <= 0 ? $langs->trans("Documentation") : $langs->trans("Documentation").'<span class="paddingleft badge">'.$hasDoc."</span>");
3460 $head2[$h][2] = 'specifications';
3461 $h++;
3462
3463 $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=buildpackage&module='.$module.($forceddirread ? '@'.$dirread : '');
3464 $head2[$h][1] = $langs->trans("BuildPackage");
3465 $head2[$h][2] = 'buildpackage';
3466 $h++;
3467
3468 $MAXTABFOROBJECT = 15;
3469
3470 print '<!-- Section for a given module -->';
3471
3472 // Note module is inside $dirread
3473
3474 if ($tab == 'description') {
3475 print '<!-- tab=description -->'."\n";
3476 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
3477 $pathtofilereadme = $modulelowercase.'/README.md';
3478 $pathtochangelog = $modulelowercase.'/ChangeLog.md';
3479
3480 $realpathofmodule = realpath($dirread.'/'.$modulelowercase);
3481
3482 if ($action != 'editfile' || empty($file)) {
3483 $morehtmlright = '';
3484 if ($realpathofmodule != $dirread.'/'.$modulelowercase) {
3485 $morehtmlright = '<div style="padding: 12px 9px 12px">'.$form->textwithpicto('', '<span class="opacitymedium">'.$langs->trans("RealPathOfModule").' :</span> <strong class="wordbreak">'.$realpathofmodule.'</strong>').'</div>';
3486 }
3487
3488 print dol_get_fiche_head($head2, $tab, '', -1, '', 0, $morehtmlright, '', $MAXTABFOROBJECT, 'formodulesuffix'); // Description - level 2
3489
3490 print '<span class="opacitymedium">'.$langs->trans("ModuleBuilderDesc".$tab).'</span>';
3491 print '<br><br>';
3492
3493 print '<table>';
3494
3495 print '<tr><td>';
3496 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
3497 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>';
3498 print '</td></tr>';
3499
3500 // List of setup pages
3501 $listofsetuppages = dol_dir_list($realpathofmodule.'/admin', 'files', 0, '\.php$');
3502 foreach ($listofsetuppages as $setuppage) {
3503 //var_dump($setuppage);
3504 print '<tr><td>';
3505 print '<span class="fa fa-file-o"></span> '.$langs->trans("SetupFile").' : ';
3506 print '<strong class="wordbreak bold"><a href="'.dol_buildpath($modulelowercase.'/admin/'.$setuppage['relativename'], 1).'" target="_test">'.$modulelowercase.'/admin/'.$setuppage['relativename'].'</a></strong>';
3507 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>';
3508 print '</td></tr>';
3509 }
3510
3511 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("ReadmeFile").' : <strong class="wordbreak">'.$pathtofilereadme.'</strong>';
3512 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>';
3513 print '</td></tr>';
3514
3515 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("ChangeLog").' : <strong class="wordbreak">'.$pathtochangelog.'</strong>';
3516 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>';
3517 print '</td></tr>';
3518
3519 print '</table>';
3520 print '<br>';
3521
3522 print load_fiche_titre($form->textwithpicto($langs->trans("DescriptorFile"), $langs->transnoentitiesnoconv("File").' '.$pathtofile), '', '');
3523
3524 if (!empty($moduleobj)) {
3525 print '<div class="underbanner clearboth"></div>';
3526 print '<div class="fichecenter">';
3527 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3528 print '<input type="hidden" name="token" value="'.newToken().'">';
3529 print '<input type="hidden" name="action" value="update_props_module">';
3530 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
3531 print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
3532 print '<input type="hidden" name="keydescription" value="'.dol_escape_htmltag(GETPOST('keydescription', 'alpha')).'">';
3533 print '<table class="border centpercent">';
3534 print '<tr class="liste_titre"><td class="titlefield">';
3535 print $langs->trans("Parameter");
3536 print '</td><td>';
3537 print $langs->trans("Value");
3538 print '</td></tr>';
3539
3540 print '<tr><td>';
3541 print $langs->trans("IdModule");
3542 print '</td><td>';
3543 print $moduleobj->numero;
3544 print '<span class="opacitymedium">';
3545 print ' &nbsp; (';
3546 print dolButtonToOpenUrlInDialogPopup('popup_modules_id', $langs->transnoentitiesnoconv("SeeIDsInUse"), $langs->transnoentitiesnoconv("SeeIDsInUse"), '/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', '', '');
3547 print ' - <a href="https://wiki.dolibarr.org/index.php/List_of_modules_id" target="_blank" rel="noopener noreferrer external">'.$langs->trans("SeeReservedIDsRangeHere").'</a>)';
3548 print '</span>';
3549 print '</td></tr>';
3550
3551 print '<tr><td>';
3552 print $langs->trans("ModuleName");
3553 print '</td><td>';
3554 print $moduleobj->getName();
3555 print '</td></tr>';
3556
3557 print '<tr><td>';
3558 print $langs->trans("Description");
3559 print '</td><td>';
3560 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'desc') {
3561 print '<input class="minwidth500" name="propsmodule" value="'.dol_escape_htmltag($moduleobj->description).'">';
3562 print '<input class="reposition button smallpaddingimp" type="submit" name="modifydesc" value="'.$langs->trans("Modify").'"/>';
3563 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3564 } else {
3565 print $moduleobj->getDesc();
3566 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>';
3567 }
3568 print '</td></tr>';
3569
3570 print '<tr><td>';
3571 print $langs->trans("Version");
3572 print '</td><td>';
3573 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'version') {
3574 print '<input name="propsmodule" value="'.dol_escape_htmltag($moduleobj->getVersion()).'">';
3575 print '<input class="reposition button smallpaddingimp" type="submit" name="modifyversion" value="'.$langs->trans("Modify").'"/>';
3576 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3577 } else {
3578 print $moduleobj->getVersion();
3579 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>';
3580 }
3581 print '</td></tr>';
3582
3583 print '<tr><td>';
3584 print $langs->trans("Family");
3585 //print "<br>'crm','financial','hr','projects','products','ecm','technic','interface','other'";
3586 print '</td><td>';
3587 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'family') {
3588 print '<select name="propsmodule" id="family" class="minwidth400">';
3589 $arrayoffamilies = array(
3590 'hr' => "ModuleFamilyHr",
3591 'crm' => "ModuleFamilyCrm",
3592 'srm' => "ModuleFamilySrm",
3593 'financial' => 'ModuleFamilyFinancial',
3594 'products' => 'ModuleFamilyProducts',
3595 'projects' => 'ModuleFamilyProjects',
3596 'ecm' => 'ModuleFamilyECM',
3597 'technic' => 'ModuleFamilyTechnic',
3598 'portal' => 'ModuleFamilyPortal',
3599 'interface' => 'ModuleFamilyInterface',
3600 'base' => 'ModuleFamilyBase',
3601 'other' => 'ModuleFamilyOther'
3602 );
3603 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>';
3604 foreach ($arrayoffamilies as $key => $value) {
3605 if ($key != $moduleobj->family) {
3606 print '<option value="'.$key.'" data-html="'.dol_escape_htmltag($langs->trans($value).' <span class="opacitymedium">- '.$key.'</span>').'">'.$langs->trans($value).'</option>';
3607 }
3608 }
3609 print '</select>';
3610 print '<input class="reposition button smallpaddingimp" type="submit" name="modifyfamily" value="'.$langs->trans("Modify").'"/>';
3611 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3612 } else {
3613 print $moduleobj->family;
3614 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>';
3615 }
3616 print '</td></tr>';
3617
3618 print '<tr><td>';
3619 print $langs->trans("Picto");
3620 print '</td><td>';
3621 if ($action == 'edit_modulepicto' && GETPOST('keydescription', 'alpha') === 'picto') {
3622 print '<input class="minwidth500" name="propsmodule" value="'.dol_escape_htmltag($moduleobj->picto).'">';
3623 print '<input class="reposition button smallpaddingimp" type="submit" name="modifypicto" value="'.$langs->trans("Modify").'"/>';
3624 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3625 } else {
3626 print $moduleobj->picto;
3627 print ' &nbsp; '.img_picto('', $moduleobj->picto, 'class="valignmiddle pictomodule paddingrightonly"');
3628 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>';
3629 }
3630 print '</td></tr>';
3631
3632 print '<tr><td>';
3633 print $langs->trans("EditorName");
3634 print '</td><td>';
3635 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'editor_name') {
3636 print '<input name="propsmodule" value="'.dol_escape_htmltag($moduleobj->editor_name).'">';
3637 print '<input class="reposition button smallpaddingimp" type="submit" name="modifyname" value="'.$langs->trans("Modify").'"/>';
3638 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3639 } else {
3640 print $moduleobj->editor_name;
3641 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>';
3642 }
3643 print '</td></tr>';
3644
3645 print '<tr><td>';
3646 print $langs->trans("EditorUrl");
3647 print '</td><td>';
3648 if ($action == 'edit_moduledescription' && GETPOST('keydescription', 'alpha') === 'editor_url') {
3649 print '<input name="propsmodule" value="'.dol_escape_htmltag($moduleobj->editor_url).'">';
3650 print '<input class="reposition button smallpaddingimp" type="submit" name="modifyeditorurl" value="'.$langs->trans("Modify").'"/>';
3651 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
3652 } else {
3653 if (!empty($moduleobj->editor_url)) {
3654 print '<a href="'.$moduleobj->editor_url.'" target="_blank" rel="noopener">'.$moduleobj->editor_url.' '.img_picto('', 'globe').'</a>';
3655 }
3656 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>';
3657 }
3658 print '</td></tr>';
3659
3660 print '</table>';
3661 print '</form>';
3662 } else {
3663 print $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'<br>';
3664 }
3665
3666 if (!empty($moduleobj)) {
3667 print '<br><br>';
3668
3669 // Readme file
3670 print load_fiche_titre($form->textwithpicto($langs->trans("ReadmeFile"), $langs->transnoentitiesnoconv("File").' '.$pathtofilereadme), '', '');
3671
3672 print '<!-- readme file -->';
3673 if (dol_is_file($dirread.'/'.$pathtofilereadme)) {
3674 print '<div class="underbanner clearboth"></div><div class="fichecenter">'.$moduleobj->getDescLong().'</div>';
3675 } else {
3676 print '<span class="opacitymedium">'.$langs->trans("ErrorFileNotFound", $pathtofilereadme).'</span>';
3677 }
3678
3679 print '<br><br>';
3680
3681 // ChangeLog
3682 print load_fiche_titre($form->textwithpicto($langs->trans("ChangeLog"), $langs->transnoentitiesnoconv("File").' '.$pathtochangelog), '', '');
3683
3684 print '<!-- changelog file -->';
3685 if (dol_is_file($dirread.'/'.$pathtochangelog)) {
3686 print '<div class="underbanner clearboth"></div><div class="fichecenter">'.$moduleobj->getChangeLog().'</div>';
3687 } else {
3688 print '<span class="opacitymedium">'.$langs->trans("ErrorFileNotFound", $pathtochangelog).'</span>';
3689 }
3690 }
3691
3692 print dol_get_fiche_end();
3693 } else { // Edit text file
3694 $fullpathoffile = dol_buildpath($file, 0, 1); // Description - level 2
3695
3696 if ($fullpathoffile) {
3697 $content = file_get_contents($fullpathoffile);
3698 }
3699
3700 // New module
3701 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3702 print '<input type="hidden" name="token" value="'.newToken().'">';
3703 print '<input type="hidden" name="action" value="savefile">';
3704 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
3705 print '<input type="hidden" name="tab" value="'.$tab.'">';
3706 print '<input type="hidden" name="module" value="'.$module.'">';
3707
3708 print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', 0, 'formodulesuffix');
3709
3710 $posCursor = (empty($find)) ? array() : array('find'=>$find);
3711 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
3712 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
3713
3714 print dol_get_fiche_end();
3715
3716 print '<center>';
3717 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
3718 print ' &nbsp; ';
3719 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
3720 print '</center>';
3721
3722 print '</form>';
3723 }
3724 } else {
3725 print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', $MAXTABFOROBJECT, 'formodulesuffix'); // Level 2
3726 }
3727
3728 if ($tab == 'languages') {
3729 print '<!-- tab=languages -->'."\n";
3730 if ($action != 'editfile' || empty($file)) {
3731 print '<span class="opacitymedium">'.$langs->trans("LanguageDefDesc").'</span><br>';
3732 print '<br>';
3733
3734
3735 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3736 print '<input type="hidden" name="token" value="'.newToken().'">';
3737 print '<input type="hidden" name="action" value="addlanguage">';
3738 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
3739 print '<input type="hidden" name="tab" value="'.$tab.'">';
3740 print '<input type="hidden" name="module" value="'.$module.'">';
3741 print $formadmin->select_language(getDolGlobalString('MAIN_LANG_DEFAULT'), 'newlangcode', 0, 0, 1, 0, 0, 'minwidth300', 1);
3742 print '<input type="submit" name="addlanguage" class="button smallpaddingimp" value="'.dol_escape_htmltag($langs->trans("AddLanguageFile")).'"><br>';
3743 print '</form>';
3744
3745 print '<br>';
3746 print '<br>';
3747
3748 $modulelowercase = strtolower($module);
3749
3750 // Dir for module
3751 $diroflang = dol_buildpath($modulelowercase, 0);
3752 $diroflang .= '/langs';
3753 $langfiles = dol_dir_list($diroflang, 'files', 1, '\.lang$');
3754
3755 if (!preg_match('/custom/', $dirread)) {
3756 // If this is not a module into custom
3757 $diroflang = $dirread;
3758 $diroflang .= '/langs';
3759 $langfiles = dol_dir_list($diroflang, 'files', 1, $modulelowercase.'\.lang$');
3760 }
3761
3762 print '<table class="none">';
3763 foreach ($langfiles as $langfile) {
3764 $pathtofile = $modulelowercase.'/langs/'.$langfile['relativename'];
3765 if (!preg_match('/custom/', $dirread)) { // If this is not a module into custom
3766 $pathtofile = 'langs/'.$langfile['relativename'];
3767 }
3768 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("LanguageFile").' '.basename(dirname($pathtofile)).' : <strong class="wordbreak">'.$pathtofile.'</strong>';
3769 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>';
3770 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>';
3771 print '</td>';
3772 }
3773 print '</table>';
3774 } else {
3775 // Edit text language file
3776
3777 //print $langs->trans("UseAsciiDocFormat").'<br>';
3778
3779 $fullpathoffile = dol_buildpath($file, 0);
3780
3781 $content = file_get_contents($fullpathoffile);
3782
3783 // New module
3784 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3785 print '<input type="hidden" name="token" value="'.newToken().'">';
3786 print '<input type="hidden" name="action" value="savefile">';
3787 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
3788 print '<input type="hidden" name="tab" value="'.$tab.'">';
3789 print '<input type="hidden" name="module" value="'.$module.'">';
3790
3791 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
3792 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'text'));
3793 print '<br>';
3794 print '<center>';
3795 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
3796 print ' &nbsp; ';
3797 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
3798 print '</center>';
3799
3800 print '</form>';
3801 }
3802 }
3803
3804 if ($tab == 'objects') {
3805 print '<!-- tab=objects -->'."\n";
3806 $head3 = array();
3807 $h = 0;
3808
3809 // Dir for module
3810 $dir = $dirread.'/'.$modulelowercase.'/class';
3811
3812 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj=newobject';
3813 $head3[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewObjectInModulebuilder").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
3814 $head3[$h][2] = 'newobject';
3815 $h++;
3816
3817 // Scan for object class files
3818 $listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$');
3819
3820 $firstobjectname = '';
3821 foreach ($listofobject as $fileobj) {
3822 if (preg_match('/^api_/', $fileobj['name'])) {
3823 continue;
3824 }
3825 if (preg_match('/^actions_/', $fileobj['name'])) {
3826 continue;
3827 }
3828
3829 $tmpcontent = file_get_contents($fileobj['fullname']);
3830 if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
3831 //$objectname = preg_replace('/\.txt$/', '', $fileobj['name']);
3832 $objectname = $reg[1];
3833 if (empty($firstobjectname)) {
3834 $firstobjectname = $objectname;
3835 }
3836 $pictoname = 'generic';
3837 if (preg_match('/\$picto\s*=\s*["\']([^"\']+)["\']/', $tmpcontent, $reg)) {
3838 $pictoname = $reg[1];
3839 }
3840
3841 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj='.$objectname;
3842 $head3[$h][1] = img_picto('', $pictoname, 'class="pictofixedwidth valignmiddle"').$objectname;
3843 $head3[$h][2] = $objectname;
3844 $h++;
3845 }
3846 }
3847
3848 if ($h > 1) {
3849 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabobj=deleteobject';
3850 $head3[$h][1] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("DangerZone");
3851 $head3[$h][2] = 'deleteobject';
3852 $h++;
3853 }
3854
3855 // 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.
3856 if ($tabobj == 'newobjectifnoobj') {
3857 if ($firstobjectname) {
3858 $tabobj = $firstobjectname;
3859 } else {
3860 $tabobj = 'newobject';
3861 }
3862 }
3863
3864 print dol_get_fiche_head($head3, $tabobj, '', -1, '', 0, '', '', 0, 'forobjectsuffix'); // Level 3
3865
3866
3867 if ($tabobj == 'newobject') {
3868 // New object tab
3869 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
3870 print '<input type="hidden" name="token" value="'.newToken().'">';
3871 print '<input type="hidden" name="action" value="initobject">';
3872 print '<input type="hidden" name="tab" value="objects">';
3873 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
3874
3875 print '<span class="opacitymedium">'.$langs->trans("EnterNameOfObjectDesc").'</span><br><br>';
3876
3877 print '<div class="tagtable">';
3878
3879 print '<div class="tagtr"><div class="tagtd">';
3880 print '<span class="opacitymedium">'.$langs->trans("ObjectKey").'</span> &nbsp; ';
3881 print '</div><div class="tagtd">';
3882 print '<input type="text" name="objectname" maxlength="64" value="'.dol_escape_htmltag(GETPOSTISSET('objectname') ? GETPOST('objectname', 'alpha') : $modulename).'" autofocus>';
3883 print $form->textwithpicto('', $langs->trans("Example").': MyObject, ACamelCaseName, ...');
3884 print '</div></div>';
3885
3886 print '<div class="tagtr"><div class="tagtd">';
3887 print '<span class="opacitymedium">'.$langs->trans("Picto").'</span> &nbsp; ';
3888 print '</div><div class="tagtd">';
3889 print '<input type="text" name="idpicto" value="fa-file-o" placeholder="'.dol_escape_htmltag($langs->trans("Picto")).'">';
3890 print $form->textwithpicto('', $langs->trans("Example").': fa-file-o, fa-globe, ... any font awesome code.<br>Advanced syntax is fa-fakey[_faprefix[_facolor[_fasize]]]');
3891 print '</div></div>';
3892
3893 print '<div class="tagtr"><div class="tagtd">';
3894 print '<span class="opacitymedium">'.$langs->trans("DefinePropertiesFromExistingTable").'</span> &nbsp; ';
3895 print '</div><div class="tagtd">';
3896 print '<input type="text" name="initfromtablename" value="'.GETPOST('initfromtablename').'" placeholder="'.$langs->trans("TableName").'">';
3897 print $form->textwithpicto('', $langs->trans("DefinePropertiesFromExistingTableDesc").'<br>'.$langs->trans("DefinePropertiesFromExistingTableDesc2"));
3898 print '</div></div>';
3899
3900 print '</div>';
3901
3902 print '<br>';
3903 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>';
3904 print '<input type="checkbox" name="includedocgeneration" id="includedocgeneration" value="includedocgeneration"> <label for="includedocgeneration">'.$form->textwithpicto($langs->trans("IncludeDocGeneration"), $langs->trans("IncludeDocGenerationHelp")).'</label><br>';
3905 print '<input type="checkbox" name="generatepermissions" id="generatepermissions" value="generatepermissions"> <label for="generatepermissions">'.$form->textwithpicto($langs->trans("GeneratePermissions"), $langs->trans("GeneratePermissionsHelp")).'</label><br>';
3906 print '<br>';
3907 print '<input type="submit" class="button small" name="create" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
3908 print '<br>';
3909 print '<br>';
3910 /*
3911 print '<br>';
3912 print '<span class="opacitymedium">'.$langs->trans("or").'</span>';
3913 print '<br>';
3914 print '<br>';
3915 //print '<input type="checkbox" name="initfromtablecheck"> ';
3916 print $langs->trans("InitStructureFromExistingTable");
3917 print '<input type="text" name="initfromtablename" value="" placeholder="'.$langs->trans("TableName").'">';
3918 print '<input type="submit" class="button smallpaddingimp" name="createtablearray" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
3919 print '<br>';
3920 */
3921
3922 print '</form>';
3923 } elseif ($tabobj == 'createproperty') {
3924 $attributesUnique = array(
3925 'proplabel' => $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey")),
3926 'propname' => $form->textwithpicto($langs->trans("Code"), $langs->trans("PropertyDesc"), 1, 'help', 'extracss', 0, 3, 'propertyhelp'),
3927 'proptype' => $form->textwithpicto($langs->trans("Type"), $langs->trans("TypeOfFieldsHelpIntro").'<br><br>'.$langs->trans("TypeOfFieldsHelp"), 1, 'help', 'extracss', 0, 3, 'typehelp'),
3928 'proparrayofkeyval' => $form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")),
3929 'propnotnull' => $form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")),
3930 'propdefault' => $langs->trans("DefaultValue"),
3931 'propindex' => $langs->trans("DatabaseIndex"),
3932 'propforeignkey' => $form->textwithpicto($langs->trans("ForeignKey"), $langs->trans("ForeignKeyDesc"), 1, 'help', 'extracss', 0, 3, 'foreignkeyhelp'),
3933 'propposition' => $langs->trans("Position"),
3934 'propenabled' => $form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc"), 1, 'help', 'extracss', 0, 3, 'enabledhelp'),
3935 'propvisible' => $form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc").'<br><br>'.$langs->trans("ItCanBeAnExpression"), 1, 'help', 'extracss', 0, 3, 'visiblehelp'),
3936 'propnoteditable' => $langs->trans("NotEditable"),
3937 //'propalwayseditable' => $langs->trans("AlwaysEditable"),
3938 'propsearchall' => $form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")),
3939 'propisameasure' => $form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")),
3940 'propcss' => $langs->trans("CSSClass"),
3941 'propcssview' => $langs->trans("CSSViewClass"),
3942 'propcsslist' => $langs->trans("CSSListClass"),
3943 'prophelp' => $langs->trans("KeyForTooltip"),
3944 'propshowoncombobox' => $langs->trans("ShowOnCombobox"),
3945 //'propvalidate' => $form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")),
3946 'propcomment' => $langs->trans("Comment"),
3947 );
3948 print '<form action="'.$_SERVER["PHP_SELF"].'?tab=objects&module='.urlencode($module).'&tabobj=createproperty&obj='.urlencode(GETPOST('obj')).'" method="POST">';
3949 print '<input type="hidden" name="token" value="'.newToken().'">';
3950 print '<input type="hidden" name="action" value="addproperty">';
3951 print '<input type="hidden" name="tab" value="objects">';
3952 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
3953 print '<input type="hidden" name="obj" value="'.dol_escape_htmltag(GETPOST('obj')).'">';
3954
3955 print '<table class="border centpercent tableforfieldcreate">'."\n";
3956 $counter = 0;
3957 foreach ($attributesUnique as $key => $attribute) {
3958 if ($counter % 2 === 0) {
3959 print '<tr>';
3960 }
3961 if ($key == 'propname' || $key == 'proplabel') {
3962 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>';
3963 } elseif ($key == 'proptype') {
3964 print '<td class="titlefieldcreate fieldrequired">'.$attribute.'</td><td class="valuefieldcreate maxwidth50">';
3965 print '<input class="maxwidth200" id="'.$key.'" list="datalist'.$key.'" type="text" name="'.$key.'" value="'.dol_escape_htmltag(GETPOST($key, 'alpha')).'">';
3966 //print '<div id="suggestions"></div>';
3967 print '<datalist id="datalist'.$key.'">';
3968 print '<option>varchar(128)</option>';
3969 print '<option>email</option>';
3970 print '<option>phone</option>';
3971 print '<option>ip</option>';
3972 print '<option>url</option>';
3973 print '<option>password</option>';
3974 print '<option>text</option>';
3975 print '<option>html</option>';
3976 print '<option>date</option>';
3977 print '<option>datetime</option>';
3978 print '<option>integer</option>';
3979 print '<option>double(28,4)</option>';
3980 print '<option>real</option>';
3981 print '<option>integer:ClassName:RelativePath/To/ClassFile.class.php[:1[:FILTER]]</option>';
3982 // Combo with list of fields
3983 /*
3984 if (empty($formadmin)) {
3985 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
3986 $formadmin = new FormAdmin($db);
3987 }
3988 print $formadmin->selectTypeOfFields($key, GETPOST($key, 'alpha'));
3989 */
3990 print '</datalist>';
3991 print '</td>';
3992 //} elseif ($key == 'propvalidate') {
3993 // 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>';
3994 } elseif ($key == 'propvisible') {
3995 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>';
3996 } elseif ($key == 'propenabled') {
3997 //$default = "isModEnabled('".strtolower($module)."')";
3998 $default = 1;
3999 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>';
4000 } elseif ($key == 'proparrayofkeyval') {
4001 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>';
4002 } else {
4003 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>';
4004 }
4005 $counter++;
4006 if ($counter % 2 === 0) {
4007 print '</tr>';
4008 }
4009 }
4010 if ($counter % 2 !== 0) {
4011 while ($counter % 2 !== 0) {
4012 print '<td></td>';
4013 $counter++;
4014 }
4015 print '</tr>';
4016 }
4017 print '</table><br>'."\n";
4018 print '<div class="center">';
4019 print '<input type="submit" class="button button-save" name="add" value="' . dol_escape_htmltag($langs->trans('Create')) . '">';
4020 print '<input type="button" class="button button-cancel" name="cancel" value="' . dol_escape_htmltag($langs->trans('Cancel')) . '" onclick="goBack()">';
4021 print '</div>';
4022 print '</form>';
4023 // javascript
4024 print '<script>
4025 function goBack() {
4026 var url = "'.$_SERVER["PHP_SELF"].'?tab=objects&module='.urlencode($module).'";
4027 window.location.href = url;
4028 }
4029 $(document).ready(function() {
4030 $("#proplabel").on("keyup", function() {
4031 console.log("key up on label");
4032 s = cleanString($("#proplabel").val());
4033 $("#propname").val(s);
4034 });
4035
4036 function cleanString( stringtoclean )
4037 {
4038 // allow "a-z", "A-Z", "0-9" and "_"
4039 stringtoclean = stringtoclean.replace(/[^a-z0-9_]+/ig, "");
4040 stringtoclean = stringtoclean.toLowerCase();
4041 if (!isNaN(stringtoclean)) {
4042 return ""
4043 }
4044 while ( stringtoclean.length > 1 && !isNaN( stringtoclean.charAt(0)) ){
4045 stringtoclean = stringtoclean.substr(1)
4046 }
4047 if (stringtoclean.length > 28) {
4048 stringtoclean = stringtoclean.substring(0, 27);
4049 }
4050 return stringtoclean;
4051 }
4052
4053 });';
4054 print '</script>';
4055 } elseif ($tabobj == 'deleteobject') {
4056 // Delete object tab
4057 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4058 print '<input type="hidden" name="token" value="'.newToken().'">';
4059 print '<input type="hidden" name="action" value="confirm_deleteobject">';
4060 print '<input type="hidden" name="tab" value="objects">';
4061 print '<input type="hidden" name="tabobj" value="deleteobject">';
4062 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
4063
4064 print $langs->trans("EnterNameOfObjectToDeleteDesc").'<br><br>';
4065
4066 print '<input type="text" name="objectname" value="" placeholder="'.dol_escape_htmltag($langs->trans("ObjectKey")).'" autofocus>';
4067 print '<input type="submit" class="button smallpaddingimp" name="delete" value="'.dol_escape_htmltag($langs->trans("Delete")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
4068 print '</form>';
4069 } else {
4070 // tabobj = module
4071 if ($action == 'deleteproperty') {
4072 $formconfirm = $form->formconfirm(
4073 $_SERVER["PHP_SELF"].'?propertykey='.urlencode(GETPOST('propertykey', 'alpha')).'&objectname='.urlencode($objectname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj),
4074 $langs->trans('Delete'),
4075 $langs->trans('ConfirmDeleteProperty', GETPOST('propertykey', 'alpha')),
4076 'confirm_deleteproperty',
4077 '',
4078 0,
4079 1
4080 );
4081
4082 // Print form confirm
4083 print $formconfirm;
4084 }
4085 if ($action != 'editfile' || empty($file)) {
4086 try {
4087 //$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
4088
4089 $pathtoclass = strtolower($module).'/class/'.strtolower($tabobj).'.class.php';
4090 $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'.class.php';
4091 $pathtoagenda = strtolower($module).'/'.strtolower($tabobj).'_agenda.php';
4092 $pathtocard = strtolower($module).'/'.strtolower($tabobj).'_card.php';
4093 $pathtodocument = strtolower($module).'/'.strtolower($tabobj).'_document.php';
4094 $pathtolist = strtolower($module).'/'.strtolower($tabobj).'_list.php';
4095 $pathtonote = strtolower($module).'/'.strtolower($tabobj).'_note.php';
4096 $pathtocontact = strtolower($module).'/'.strtolower($tabobj).'_contact.php';
4097 $pathtophpunit = strtolower($module).'/test/phpunit/'.strtolower($tabobj).'Test.php';
4098
4099 // Try to load object class file
4100 clearstatcache(true);
4101 if (function_exists('opcache_invalidate')) {
4102 opcache_invalidate($dirread.'/'.$pathtoclass, true); // remove the include cache hell !
4103 }
4104
4105 if (empty($forceddirread) && empty($dirread)) {
4106 $result = dol_include_once($pathtoclass);
4107 $stringofinclude = "dol_include_once(".$pathtoclass.")";
4108 } else {
4109 $result = @include_once $dirread.'/'.$pathtoclass;
4110 $stringofinclude = "@include_once ".$dirread.'/'.$pathtoclass;
4111 }
4112 if (class_exists($tabobj)) {
4113 try {
4114 $tmpobject = @new $tabobj($db);
4115 } catch (Exception $e) {
4116 dol_syslog('Failed to load Constructor of class: '.$e->getMessage(), LOG_WARNING);
4117 }
4118 } else {
4119 print '<span class="warning">'.$langs->trans('Failed to find the class '.$tabobj.' despite the '.$stringofinclude).'</span><br><br>';
4120 }
4121
4122 // Define path for sql file
4123 $pathtosql = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'-'.strtolower($module).'.sql';
4124 $result = dol_buildpath($pathtosql);
4125 if (! dol_is_file($result)) {
4126 $pathtosql = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'.sql';
4127 $result = dol_buildpath($pathtosql);
4128 if (! dol_is_file($result)) {
4129 $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($tabobj).'-'.strtolower($module).'.sql';
4130 $result = dol_buildpath($pathtosql);
4131 if (! dol_is_file($result)) {
4132 $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
4133 $result = dol_buildpath($pathtosql);
4134 if (! dol_is_file($result)) {
4135 $pathtosql = 'install/mysql/tables/llx_'.strtolower($module).'.sql';
4136 $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_extrafields.sql';
4137 $result = dol_buildpath($pathtosql);
4138 } else {
4139 $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_extrafields-'.strtolower($module).'.sql';
4140 }
4141 } else {
4142 $pathtosqlextra = 'install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields-'.strtolower($module).'.sql';
4143 }
4144 } else {
4145 $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields.sql';
4146 }
4147 } else {
4148 $pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($module).'_'.strtolower($tabobj).'_extrafields-'.strtolower($module).'.sql';
4149 }
4150 $pathtosqlroot = preg_replace('/\/llx_.*$/', '', $pathtosql);
4151
4152 $pathtosqlkey = preg_replace('/\.sql$/', '.key.sql', $pathtosql);
4153 $pathtosqlextrakey = preg_replace('/\.sql$/', '.key.sql', $pathtosqlextra);
4154
4155 $pathtolib = strtolower($module).'/lib/'.strtolower($module).'.lib.php';
4156 $pathtoobjlib = strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($tabobj).'.lib.php';
4157
4158 $tmpobject = $tmpobject ?? null;
4159 if (is_object($tmpobject) && property_exists($tmpobject, 'picto')) {
4160 $pathtopicto = $tmpobject->picto;
4161 $realpathtopicto = '';
4162 } else {
4163 $pathtopicto = strtolower($module).'/img/object_'.strtolower($tabobj).'.png';
4164 $realpathtopicto = $dirread.'/'.$pathtopicto;
4165 }
4166
4167 //var_dump($pathtoclass);
4168 //var_dump($dirread);
4169 $realpathtoclass = $dirread.'/'.$pathtoclass;
4170 $realpathtoapi = $dirread.'/'.$pathtoapi;
4171 $realpathtoagenda = $dirread.'/'.$pathtoagenda;
4172 $realpathtocard = $dirread.'/'.$pathtocard;
4173 $realpathtodocument = $dirread.'/'.$pathtodocument;
4174 $realpathtolist = $dirread.'/'.$pathtolist;
4175 $realpathtonote = $dirread.'/'.$pathtonote;
4176 $realpathtocontact = $dirread.'/'.$pathtocontact;
4177 $realpathtophpunit = $dirread.'/'.$pathtophpunit;
4178 $realpathtosql = $dirread.'/'.$pathtosql;
4179 $realpathtosqlextra = $dirread.'/'.$pathtosqlextra;
4180 $realpathtosqlkey = $dirread.'/'.$pathtosqlkey;
4181 $realpathtosqlextrakey = $dirread.'/'.$pathtosqlextrakey;
4182 $realpathtolib = $dirread.'/'.$pathtolib;
4183 $realpathtoobjlib = $dirread.'/'.$pathtoobjlib;
4184
4185 if (empty($realpathtoapi)) { // For compatibility with some old modules
4186 $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'s.class.php';
4187 $realpathtoapi = $dirread.'/'.$pathtoapi;
4188 }
4189
4190 $urloflist = dol_buildpath('/'.$pathtolist, 1);
4191 $urlofcard = dol_buildpath('/'.$pathtocard, 1);
4192
4193 $objs = array();
4194
4195 print '<!-- section for object -->';
4196 print '<div class="fichehalfleft smallxxx">';
4197 // Main DAO class file
4198 print '<span class="fa fa-file-o"></span> '.$langs->trans("ClassFile").' : <strong>'.(dol_is_file($realpathtoclass) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtoclass).(dol_is_file($realpathtoclass) ? '' : '</strike>').'</strong>';
4199 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>';
4200 print '<br>';
4201 // Image
4202 if ($realpathtopicto && dol_is_file($realpathtopicto)) {
4203 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>';
4204 //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>';
4205 print '<br>';
4206 } elseif (!empty($tmpobject)) {
4207 print '<span class="fa fa-file-image-o"></span> '.$langs->trans("Image").' : '.img_picto('', $tmpobject->picto, 'class="pictofixedwidth valignmiddle"').$tmpobject->picto;
4208 print '<br>';
4209 }
4210
4211 // API file
4212 print '<br>';
4213 print '<span class="fa fa-file-o"></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>';
4214 if (dol_is_file($realpathtoapi)) {
4215 $file = file_get_contents($realpathtoapi);
4216 if (preg_match('/var '.$tabobj.'\s+([^\s]*)\s/ims', $file, $objs)) {
4217 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>';
4218 print ' ';
4219 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>';
4220 print $form->textwithpicto('', $langs->trans("InfoForApiFile"), 1, 'warning');
4221 print ' &nbsp; ';
4222 // Comparing to null (phan considers $modulelowercase can be null here)
4223 if ($modulelowercase !== null && !isModEnabled($modulelowercase)) { // If module is not activated
4224 print '<a href="#" class="classfortooltip" target="apiexplorer" title="'.$langs->trans("ModuleMustBeEnabled", $module).'"><strike>'.$langs->trans("ApiExplorer").'</strike></a>';
4225 } else {
4226 print '<a href="'.DOL_URL_ROOT.'/api/index.php/explorer/" target="apiexplorer">'.$langs->trans("ApiExplorer").'</a>';
4227 }
4228 } else {
4229 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>';
4230 }
4231 } else {
4232 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>';
4233 }
4234 // PHPUnit
4235 print '<br>';
4236 print '<span class="fa fa-file-o"></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>';
4237 if (dol_is_file($realpathtophpunit)) {
4238 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>';
4239 print ' ';
4240 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>';
4241 } else {
4242 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>';
4243 }
4244 print '<br>';
4245
4246 print '<br>';
4247
4248 print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForLib").' : <strong class="wordbreak">'.(dol_is_file($realpathtolib) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtolib).(dol_is_file($realpathtolib) ? '' : '</strike>').'</strong>';
4249 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>';
4250 print '<br>';
4251 print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForObjLib").' : <strong class="wordbreak">'.(dol_is_file($realpathtoobjlib) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtoobjlib).(dol_is_file($realpathtoobjlib) ? '' : '</strike>').'</strong>';
4252 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>';
4253 print '<br>';
4254
4255 print '<br>';
4256 print '<span class="fa fa-file-o"></span> '.$langs->trans("SqlFile").' : <strong class="wordbreak">'.(dol_is_file($realpathtosql) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtosql).(dol_is_file($realpathtosql) ? '' : '</strike>').'</strong>';
4257 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>';
4258 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>';
4259 //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
4260 print '<br>';
4261 print '<span class="fa fa-file-o"></span> '.$langs->trans("SqlFileKey").' : <strong class="wordbreak">'.(dol_is_file($realpathtosqlkey) ? '' : '<strike>').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlkey).(dol_is_file($realpathtosqlkey) ? '' : '</strike>').'</strong>';
4262 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>';
4263 //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
4264 print '<br>';
4265 print '<span class="fa fa-file-o"></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>';
4266 if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) {
4267 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>';
4268 print ' ';
4269 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>';
4270 print ' &nbsp; ';
4271 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>';
4272 } else {
4273 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>';
4274 }
4275 //print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
4276 print '<br>';
4277 print '<span class="fa fa-file-o"></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>';
4278 if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) {
4279 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>';
4280 print ' ';
4281 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>';
4282 } else {
4283 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>';
4284 }
4285 print '<br>';
4286 print '</div>';
4287
4288 print '<div class="fichehalfleft smallxxxx">';
4289 print '<span class="fa fa-file-o"></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>';
4290 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>';
4291 print '<br>';
4292 print '<span class="fa fa-file-o"></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>';
4293 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>';
4294 print '<br>';
4295 // Page contact
4296 print '<span class="fa fa-file-o"></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>';
4297 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>';
4298 if (dol_is_file($realpathtocontact)) {
4299 print ' ';
4300 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>';
4301 } else {
4302 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>';
4303 }
4304 print '<br>';
4305 // Page document
4306 print '<span class="fa fa-file-o"></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>';
4307 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>';
4308 if (dol_is_file($realpathtodocument)) {
4309 print ' ';
4310 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>';
4311 } else {
4312 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>';
4313 }
4314 print '<br>';
4315 // Page notes
4316 print '<span class="fa fa-file-o"></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>';
4317 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>';
4318 if (dol_is_file($realpathtonote)) {
4319 print ' ';
4320 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>';
4321 } else {
4322 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>';
4323 }
4324 print '<br>';
4325 // Page agenda
4326 print '<span class="fa fa-file-o"></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>';
4327 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>';
4328 if (dol_is_file($realpathtoagenda)) {
4329 print ' ';
4330 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>';
4331 } else {
4332 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>';
4333 }
4334 print '<br>';
4335 print '<br>';
4336
4337 print '</div>';
4338
4339 print '<br><br><br>';
4340
4341 if (!empty($tmpobject)) {
4342 $reflector = new ReflectionClass($tabobj);
4343 $reflectorproperties = $reflector->getProperties(); // Can also use get_object_vars
4344 $reflectorpropdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars
4345 //$propstat = $reflector->getStaticProperties();
4346 //var_dump($reflectorpropdefault);
4347
4348 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4349 print '<input type="hidden" name="token" value="'.newToken().'">';
4350 print '<input type="hidden" name="action" value="addproperty">';
4351 print '<input type="hidden" name="tab" value="objects">';
4352 print '<input type="hidden" name="page_y" value="">';
4353 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module.($forceddirread ? '@'.$dirread : '')).'">';
4354 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
4355
4356 print '<input class="button smallpaddingimp" type="submit" name="regenerateclasssql" value="'.$langs->trans("RegenerateClassAndSql").'">';
4357 print '<br><br>';
4358
4359 $mod = strtolower($module);
4360 $obj = strtolower($tabobj);
4361 $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));
4362 $nbOfProperties = count($reflectorpropdefault['fields']);
4363
4364 print_barre_liste($langs->trans("ObjectProperties"), 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, $nbOfProperties, '', 0, $newproperty, '', 0, 0, 0, 1);
4365
4366 //var_dump($reflectorpropdefault);exit;
4367 print '<!-- Table with properties of object -->'."\n";
4368 print '<div class="div-table-responsive">';
4369 print '<table class="noborder small">';
4370 print '<tr class="liste_titre">';
4371 print '<th class="tdsticky tdstickygray">';
4372 $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>';
4373 print $form->textwithpicto($langs->trans("Code"), $htmltext, 1, 'help', 'extracss', 0, 3, 'propertyhelp');
4374 print '</th>';
4375 print '<th>';
4376 print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey"));
4377 print '</th>';
4378 print '<th>'.$form->textwithpicto($langs->trans("Type"), $langs->trans("TypeOfFieldsHelpIntro").'<br><br>'.$langs->trans("TypeOfFieldsHelp"), 1, 'help', 'extracss', 0, 3, 'typehelp').'</th>';
4379 print '<th>'.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).'</th>';
4380 print '<th class="center">'.$form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")).'</th>';
4381 print '<th class="center">'.$langs->trans("DefaultValue").'</th>';
4382 print '<th class="center">'.$langs->trans("DatabaseIndex").'</th>';
4383 print '<th class="center">'.$form->textwithpicto($langs->trans("ForeignKey"), $langs->trans("ForeignKeyDesc"), 1, 'help', 'extracss', 0, 3, 'foreignkeyhelp').'</th>';
4384 print '<th class="right">'.$langs->trans("Position").'</th>';
4385 print '<th class="center">'.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc"), 1, 'help', 'extracss', 0, 3, 'enabledhelp').'</th>';
4386 print '<th class="center">'.$form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc").'<br><br>'.$langs->trans("ItCanBeAnExpression"), 1, 'help', 'extracss', 0, 3, 'visiblehelp').'</th>';
4387 print '<th class="center">'.$langs->trans("NotEditable").'</th>';
4388 //print '<th class="center">'.$langs->trans("AlwaysEditable").'</th>';
4389 print '<th class="center">'.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).'</th>';
4390 print '<th class="center">'.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).'</th>';
4391 print '<th class="center">'.$langs->trans("CSSClass").'</th>';
4392 print '<th class="center">'.$langs->trans("CSSViewClass").'</th>';
4393 print '<th class="center">'.$langs->trans("CSSListClass").'</th>';
4394 print '<th>'.$langs->trans("KeyForTooltip").'</th>';
4395 print '<th class="center">'.$langs->trans("ShowOnCombobox").'</th>';
4396 //print '<th class="center">'.$langs->trans("Disabled").'</th>';
4397 print '<th>'.$form->textwithpicto($langs->trans("Validate"), $langs->trans("ValidateModBuilderDesc")).'</th>';
4398 print '<th>'.$langs->trans("Comment").'</th>';
4399 print '<th class="tdstickyright tdstickyghostwhite"></th>';
4400 print '</tr>';
4401
4402 // We must use $reflectorpropdefault['fields'] to get list of fields because $tmpobject->fields may have been
4403 // modified during the constructor and we want value into head of class before constructor is called.
4404 //$properties = dol_sort_array($tmpobject->fields, 'position');
4405 $properties = dol_sort_array($reflectorpropdefault['fields'], 'position');
4406 if (!empty($properties)) {
4407 // List of existing properties
4408 foreach ($properties as $propkey => $propval) {
4409 /* If from Reflection
4410 if ($propval->class == $tabobj)
4411 {
4412 $propname=$propval->getName();
4413 $comment=$propval->getDocComment();
4414 $type=gettype($tmpobject->$propname);
4415 $default=$propdefault[$propname];
4416 // Discard generic properties
4417 if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'ismultientitymanaged'))) continue;
4418
4419 // Keep or not lines
4420 if (in_array($propname, array('fk_element', 'lines'))) continue;
4421 }*/
4422
4423 $propname = $propkey;
4424 $proplabel = $propval['label'];
4425 $proptype = $propval['type'];
4426 $proparrayofkeyval = !empty($propval['arrayofkeyval']) ? $propval['arrayofkeyval'] : '';
4427 $propnotnull = !empty($propval['notnull']) ? $propval['notnull'] : '0';
4428 $propdefault = !empty($propval['default']) ? $propval['default'] : '';
4429 $propindex = !empty($propval['index']) ? $propval['index'] : '';
4430 $propforeignkey = !empty($propval['foreignkey']) ? $propval['foreignkey'] : '';
4431 $propposition = $propval['position'];
4432 $propenabled = $propval['enabled'];
4433 $propvisible = $propval['visible'];
4434 $propnoteditable = !empty($propval['noteditable']) ? $propval['noteditable'] : 0;
4435 //$propalwayseditable = !empty($propval['alwayseditable'])?$propval['alwayseditable']:0;
4436 $propsearchall = !empty($propval['searchall']) ? $propval['searchall'] : 0;
4437 $propisameasure = !empty($propval['isameasure']) ? $propval['isameasure'] : 0;
4438 $propcss = !empty($propval['css']) ? $propval['css'] : '';
4439 $propcssview = !empty($propval['cssview']) ? $propval['cssview'] : '';
4440 $propcsslist = !empty($propval['csslist']) ? $propval['csslist'] : '';
4441 $prophelp = !empty($propval['help']) ? $propval['help'] : '';
4442 $propshowoncombobox = !empty($propval['showoncombobox']) ? $propval['showoncombobox'] : 0;
4443 //$propdisabled=$propval['disabled'];
4444 $propvalidate = !empty($propval['validate']) ? $propval['validate'] : 0;
4445 $propcomment = !empty($propval['comment']) ? $propval['comment'] : '';
4446
4447 print '<!-- line for object property -->'."\n";
4448 print '<tr class="oddeven">';
4449
4450 print '<td class="tdsticky tdstickygray">';
4451 print dol_escape_htmltag($propname);
4452 print '</td>';
4453 if ($action == 'editproperty' && $propname == $propertykey) {
4454 print '<td>';
4455 print '<input type="hidden" name="propname" value="'.dol_escape_htmltag($propname).'">';
4456 print '<input name="proplabel" class="maxwidth125" value="'.dol_escape_htmltag($proplabel).'">';
4457 print '</td>';
4458 print '<td class="tdoverflowmax150">';
4459 print '<input name="proptype" class="maxwidth125" value="'.dol_escape_htmltag($proptype).'"></input>';
4460 print '</td>';
4461 print '<td class="tdoverflowmax200">';
4462 print '<textarea name="proparrayofkeyval">';
4463 if (isset($proparrayofkeyval)) {
4464 if (is_array($proparrayofkeyval) || $proparrayofkeyval != '') {
4465 print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE));
4466 }
4467 }
4468 print '</textarea>';
4469 print '</td>';
4470 print '<td>';
4471 print '<input class="center width50" name="propnotnull" value="'.dol_escape_htmltag($propnotnull).'">';
4472 print '</td>';
4473 print '<td>';
4474 print '<input class="maxwidth50" name="propdefault" value="'.dol_escape_htmltag($propdefault).'">';
4475 print '</td>';
4476 print '<td class="center">';
4477 print '<input class="center maxwidth50" name="propindex" value="'.dol_escape_htmltag($propindex).'">';
4478 print '</td>';
4479 print '<td>';
4480 print '<input class="center maxwidth100" name="propforeignkey" value="'.dol_escape_htmltag($propforeignkey).'">';
4481 print '</td>';
4482 print '<td>';
4483 print '<input class="right width50" name="propposition" value="'.dol_escape_htmltag($propposition).'">';
4484 print '</td>';
4485 print '<td>';
4486 print '<input class="center width75" name="propenabled" value="'.dol_escape_htmltag($propenabled).'">';
4487 print '</td>';
4488 print '<td>';
4489 print '<input class="center width75" name="propvisible" value="'.dol_escape_htmltag($propvisible).'">';
4490 print '</td>';
4491 print '<td>';
4492 print '<input class="center width50" name="propnoteditable" size="2" value="'.dol_escape_htmltag($propnoteditable).'">';
4493 print '</td>';
4494 /*print '<td>';
4495 print '<input class="center" name="propalwayseditable" size="2" value="'.dol_escape_htmltag($propalwayseditable).'">';
4496 print '</td>';*/
4497 print '<td>';
4498 print '<input class="center width50" name="propsearchall" value="'.dol_escape_htmltag($propsearchall).'">';
4499 print '</td>';
4500 print '<td>';
4501 print '<input class="center width50" name="propisameasure" value="'.dol_escape_htmltag($propisameasure).'">';
4502 print '</td>';
4503 print '<td>';
4504 print '<input class="center maxwidth50" name="propcss" value="'.dol_escape_htmltag($propcss).'">';
4505 print '</td>';
4506 print '<td>';
4507 print '<input class="center maxwidth50" name="propcssview" value="'.dol_escape_htmltag($propcssview).'">';
4508 print '</td>';
4509 print '<td>';
4510 print '<input class="center maxwidth50" name="propcsslist" value="'.dol_escape_htmltag($propcsslist).'">';
4511 print '</td>';
4512 print '<td>';
4513 print '<input class="maxwidth100" name="prophelp" value="'.dol_escape_htmltag($prophelp).'">';
4514 print '</td>';
4515 print '<td>';
4516 print '<input class="center maxwidth50" name="propshowoncombobox" value="'.dol_escape_htmltag($propshowoncombobox).'">';
4517 print '</td>';
4518 print '<td>';
4519 print '<input type="number" step="1" min="0" max="1" class="text maxwidth100" name="propvalidate" value="'.dol_escape_htmltag($propvalidate).'">';
4520 print '</td>';
4521 print '<td>';
4522 print '<input class="maxwidth100" name="propcomment" value="'.dol_escape_htmltag($propcomment).'">';
4523 print '</td>';
4524 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
4525 print '<input class="reposition button smallpaddingimp" type="submit" name="edit" value="'.$langs->trans("Save").'">';
4526 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
4527 print '</td>';
4528 } else {
4529 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($proplabel).'">';
4530 print dol_escape_htmltag($proplabel);
4531 print '</td>';
4532 print '<td class="tdoverflowmax200">';
4533 $pictoType = '';
4534 $matches = array();
4535 if (preg_match('/^varchar/', $proptype, $matches)) {
4536 $pictoType = 'varchar';
4537 } elseif (preg_match('/^integer:/', $proptype, $matches)) {
4538 $pictoType = 'link';
4539 } elseif (strpos($proptype, 'integer') === 0) {
4540 $pictoType = substr($proptype, 0, 3);
4541 } elseif (strpos($proptype, 'timestamp') === 0) {
4542 $pictoType = 'datetime';
4543 } elseif (strpos($proptype, 'real') === 0) {
4544 $pictoType = 'double';
4545 }
4546 print(!empty($pictoType) ? getPictoForType($pictoType) : getPictoForType($proptype)).'<span title="'.dol_escape_htmltag($proptype).'">'.dol_escape_htmltag($proptype).'</span>';
4547 print '</td>';
4548 print '<td class="tdoverflowmax200">';
4549 if ($proparrayofkeyval) {
4550 print '<span title="'.dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE)).'">';
4551 print dol_escape_htmltag(json_encode($proparrayofkeyval, JSON_UNESCAPED_UNICODE));
4552 print '</span>';
4553 }
4554 print '</td>';
4555 print '<td class="center">';
4556 print dol_escape_htmltag($propnotnull);
4557 print '</td>';
4558 print '<td>';
4559 print dol_escape_htmltag($propdefault);
4560 print '</td>';
4561 print '<td class="center">';
4562 print $propindex ? '1' : '';
4563 print '</td>';
4564 print '<td class="center">';
4565 print $propforeignkey ? dol_escape_htmltag($propforeignkey) : '';
4566 print '</td>';
4567 print '<td class="right">';
4568 print dol_escape_htmltag($propposition);
4569 print '</td>';
4570 print '<td class="center tdoverflowmax100" title="'.($propnoteditable ? dol_escape_htmltag($propnoteditable) : '').'">';
4571 print $propenabled ? dol_escape_htmltag($propenabled) : '';
4572 print '</td>';
4573 // Visibility
4574 print '<td class="center tdoverflowmax100" title="'.($propvisible ? dol_escape_htmltag($propvisible) : '0').'">';
4575 print $propvisible ? dol_escape_htmltag($propvisible) : '0';
4576 print '</td>';
4577 // Readonly
4578 print '<td class="center tdoverflowmax100" title="'.($propnoteditable ? dol_escape_htmltag($propnoteditable) : '').'">';
4579 print $propnoteditable ? dol_escape_htmltag($propnoteditable) : '';
4580 print '</td>';
4581 /*print '<td class="center">';
4582 print $propalwayseditable ? dol_escape_htmltag($propalwayseditable) : '';
4583 print '</td>';*/
4584 print '<td class="center">';
4585 print $propsearchall ? '1' : '';
4586 print '</td>';
4587 print '<td class="center">';
4588 print $propisameasure ? dol_escape_htmltag($propisameasure) : '';
4589 print '</td>';
4590 print '<td class="center tdoverflowmax100" title="'.($propcss ? dol_escape_htmltag($propcss) : '').'">';
4591 print $propcss ? dol_escape_htmltag($propcss) : '';
4592 print '</td>';
4593 print '<td class="center tdoverflowmax100" title="'.($propcssview ? dol_escape_htmltag($propcssview) : '').'">';
4594 print $propcssview ? dol_escape_htmltag($propcssview) : '';
4595 print '</td>';
4596 print '<td class="center tdoverflowmax100" title="'.($propcsslist ? dol_escape_htmltag($propcsslist) : '').'">';
4597 print $propcsslist ? dol_escape_htmltag($propcsslist) : '';
4598 print '</td>';
4599 // Key for tooltop
4600 print '<td class="tdoverflowmax150" title="'.($prophelp ? dol_escape_htmltag($prophelp) : '').'">';
4601 print $prophelp ? dol_escape_htmltag($prophelp) : '';
4602 print '</td>';
4603 print '<td class="center">';
4604 print $propshowoncombobox ? dol_escape_htmltag($propshowoncombobox) : '';
4605 print '</td>';
4606 /*print '<td class="center">';
4607 print $propdisabled?$propdisabled:'';
4608 print '</td>';*/
4609 print '<td class="center">';
4610 print $propvalidate ? dol_escape_htmltag($propvalidate) : '';
4611 print '</td>';
4612 print '<td class="tdoverflowmax200">';
4613 print '<span title="'.dol_escape_htmltag($propcomment).'">';
4614 print dol_escape_htmltag($propcomment);
4615 print '</span>';
4616 print '</td>';
4617 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
4618 if ($propname != 'rowid') {
4619 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>';
4620 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>';
4621 }
4622 print '</td>';
4623 }
4624 print '</tr>';
4625 }
4626 } else {
4627 if ($tab == 'specifications') {
4628 if ($action != 'editfile' || empty($file)) {
4629 print '<span class="opacitymedium">'.$langs->trans("SpecDefDesc").'</span><br>';
4630 print '<br>';
4631
4632 $specs = dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/'));
4633
4634 foreach ($specs as $spec) {
4635 $pathtofile = $modulelowercase.'/doc/'.$spec['relativename'];
4636 $format = 'asciidoc';
4637 if (preg_match('/\.md$/i', $spec['name'])) {
4638 $format = 'markdown';
4639 }
4640 print '<span class="fa fa-file-o"></span> '.$langs->trans("SpecificationFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
4641 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>';
4642 print '<br>';
4643 }
4644 } else {
4645 // Use MD or asciidoc
4646
4647 //print $langs->trans("UseAsciiDocFormat").'<br>';
4648
4649 $fullpathoffile = dol_buildpath($file, 0);
4650
4651 $content = file_get_contents($fullpathoffile);
4652
4653 // New module
4654 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4655 print '<input type="hidden" name="token" value="'.newToken().'">';
4656 print '<input type="hidden" name="action" value="savefile">';
4657 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
4658 print '<input type="hidden" name="tab" value="'.$tab.'">';
4659 print '<input type="hidden" name="module" value="'.$module.'">';
4660
4661 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
4662 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
4663 print '<br>';
4664 print '<center>';
4665 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
4666 print ' &nbsp; ';
4667 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
4668 print '</center>';
4669
4670 print '</form>';
4671 }
4672 }
4673 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>';
4674 }
4675 print '</table>';
4676 print '</div>';
4677
4678 print '</form>';
4679 } else {
4680 print '<span class="warning">'.$langs->trans('Failed to init the object with the new %s (%s)', $tabobj, (string) $db).'</warning>';
4681 }
4682 } catch (Exception $e) {
4683 print $e->getMessage();
4684 }
4685 } else {
4686 if (empty($forceddirread)) {
4687 $fullpathoffile = dol_buildpath($file, 0);
4688 } else {
4689 $fullpathoffile = $dirread.'/'.$file;
4690 }
4691
4692 $content = file_get_contents($fullpathoffile);
4693
4694 // New module
4695 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4696 print '<input type="hidden" name="token" value="'.newToken().'">';
4697 print '<input type="hidden" name="action" value="savefile">';
4698 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
4699 print '<input type="hidden" name="tab" value="'.$tab.'">';
4700 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
4701 print '<input type="hidden" name="module" value="'.$module.($forceddirread ? '@'.$dirread : '').'">';
4702
4703 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
4704 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
4705 print '<br>';
4706 print '<center>';
4707 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
4708 print ' &nbsp; ';
4709 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
4710 print '</center>';
4711
4712 print '</form>';
4713 }
4714 }
4715
4716 print dol_get_fiche_end(); // Level 3
4717 }
4718
4719 if ($tab == 'dictionaries') {
4720 print '<!-- tab=dictionaries -->'."\n";
4721 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
4722
4723 $dicts = $moduleobj->dictionaries;
4724
4725 if ($action == 'deletedict') {
4726 $formconfirm = $form->formconfirm(
4727 $_SERVER["PHP_SELF"].'?dictionnarykey='.urlencode((string) (GETPOSTINT('dictionnarykey'))).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)),
4728 $langs->trans('Delete'),
4729 $langs->trans('Confirm Delete Dictionnary', GETPOST('dictionnarykey', 'alpha')),
4730 'confirm_deletedictionary',
4731 '',
4732 0,
4733 1
4734 );
4735 print $formconfirm;
4736 }
4737
4738 if ($action != 'editfile' || empty($file)) {
4739 print '<span class="opacitymedium">';
4740 $htmlhelp = $langs->trans("DictionariesDefDescTooltip", '{s1}');
4741 $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/dict.php">'.$langs->trans('Setup').' - '.$langs->trans('Dictionaries').'</a>', $htmlhelp);
4742 print $form->textwithpicto($langs->trans("DictionariesDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
4743 print '</span>';
4744 print '<br>';
4745
4746 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
4747 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>';
4748 print '<br>';
4749 if (is_array($dicts) && !empty($dicts)) {
4750 print '<span class="fa fa-file-o"></span> '.$langs->trans("LanguageFile").' :</span> ';
4751 print '<strong class="wordbreak">'.$dicts['langs'].'</strong>';
4752 print '<br>';
4753 }
4754
4755 $head3 = array();
4756 $h = 0;
4757
4758 // Dir for module
4759 //$dir = $dirread.'/'.$modulelowercase.'/class';
4760
4761 $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic=newdictionary';
4762 $head3[$h][1] = '<span class="valignmiddle text-plus-circle">'.$langs->trans("NewDictionary").'</span><span class="fa fa-plus-circle valignmiddle paddingleft"></span>';
4763 $head3[$h][2] = 'newdictionary';
4764 $h++;
4765
4766 // Scan for object class files
4767 //$listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$');
4768
4769 $firstdicname = '';
4770 // if (!empty($dicts['tabname'])) {
4771 // foreach ($dicts['tabname'] as $key => $dic) {
4772 // $dicname = $dic;
4773 // $diclabel = $dicts['tablib'][$key];
4774
4775 // if (empty($firstdicname)) {
4776 // $firstdicname = $dicname;
4777 // }
4778
4779 // $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic='.$dicname;
4780 // $head3[$h][1] = $diclabel;
4781 // $head3[$h][2] = $dicname;
4782 // $h++;
4783 // }
4784 // }
4785
4786 // if ($h > 1) {
4787 // $head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=dictionaries&module='.$module.($forceddirread ? '@'.$dirread : '').'&tabdic=deletedictionary';
4788 // $head3[$h][1] = $langs->trans("DangerZone");
4789 // $head3[$h][2] = 'deletedictionary';
4790 // $h++;
4791 // }
4792
4793 // 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.
4794 // if ($tabdic == 'newdicifnodic') {
4795 // if ($firstdicname) {
4796 // $tabdic = $firstdicname;
4797 // } else {
4798 // $tabdic = 'newdictionary';
4799 // }
4800 // }
4801 //print dol_get_fiche_head($head3, $tabdic, '', -1, ''); // Level 3
4802
4803
4804 $newdict = dolGetButtonTitle($langs->trans('NewDictionary'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/modulebuilder/index.php?tab=dictionaries&module='.urlencode($module).'&tabdic=newdictionary');
4805 print_barre_liste($langs->trans("ListOfDictionariesEntries"), '', $_SERVER["PHP_SELF"], '', '', '', '', 0, '', '', 0, $newdict, '', 0, 0, 0, 1);
4806
4807 if ($tabdic != 'newdictionary') {
4808 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4809 print '<input type="hidden" name="token" value="'.newToken().'">';
4810 print '<input type="hidden" name="action" value="addDictionary">';
4811 print '<input type="hidden" name="tab" value="dictionaries">';
4812 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
4813 print '<input type="hidden" name="tabdic" value="'.dol_escape_htmltag($tabdic).'">';
4814
4815 print '<div class="div-table-responsive">';
4816 print '<table class="noborder">';
4817
4818 print '<tr class="liste_titre">';
4819 print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'thsticky thstickygrey ');
4820 print_liste_field_titre("Table", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4821 print_liste_field_titre("Label", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4822 print_liste_field_titre("SQL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4823 print_liste_field_titre("SQLSort", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4824 print_liste_field_titre("FieldsView", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4825 print_liste_field_titre("FieldsEdit", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4826 print_liste_field_titre("FieldsInsert", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4827 print_liste_field_titre("Rowid", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4828 print_liste_field_titre("Condition", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4829 print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
4830 print "</tr>\n";
4831
4832 if (!empty($dicts) && is_array($dicts) && !empty($dicts['tabname']) && is_array($dicts['tabname'])) {
4833 $i = 0;
4834 $maxi = count($dicts['tabname']);
4835 while ($i < $maxi) {
4836 if ($action == 'editdict' && $i == GETPOSTINT('dictionnarykey') - 1) {
4837 print '<tr class="oddeven">';
4838 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4839 print '<input type="hidden" name="token" value="'.newToken().'">';
4840 print '<input type="hidden" name="tab" value="dictionaries">';
4841 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
4842 print '<input type="hidden" name="action" value="updatedictionary">';
4843 print '<input type="hidden" name="dictionnarykey" value="'.($i + 1).'">';
4844
4845 print '<td class="tdsticky tdstickygray">';
4846 print($i + 1);
4847 print '</td>';
4848
4849 print '<td>';
4850 print '<input type="text" name="tabname" value="'.$dicts['tabname'][$i].'" readonly class="tdstickygray">';
4851 print '</td>';
4852
4853 print '<td>';
4854 print '<input type="text" name="tablib" value="'.$dicts['tablib'][$i].'">';
4855 print '</td>';
4856
4857 print '<td>';
4858 print '<input type="text" name="tabsql" value="'.$dicts['tabsql'][$i].'" readonly class="tdstickygray">';
4859 print '</td>';
4860
4861 print '<td>';
4862 print '<select name="tabsqlsort">';
4863 print '<option value="'.dol_escape_htmltag($dicts['tabsqlsort'][$i]).'">'.$dicts['tabsqlsort'][$i].'</option>';
4864 print '</select>';
4865 print '</td>';
4866
4867 print '<td><select name="tabfield" >';
4868 print '<option value="'.dol_escape_htmltag($dicts['tabfield'][$i]).'">'.$dicts['tabfield'][$i].'</option>';
4869 print '</select></td>';
4870
4871 print '<td><select name="tabfieldvalue" >';
4872 print '<option value="'.dol_escape_htmltag($dicts['tabfieldvalue'][$i]).'">'.$dicts['tabfieldvalue'][$i].'</option>';
4873 print '</select></td>';
4874
4875 print '<td><select name="tabfieldinsert" >';
4876 print '<option value="'.dol_escape_htmltag($dicts['tabfieldinsert'][$i]).'">'.$dicts['tabfieldinsert'][$i].'</option>';
4877 print '</select></td>';
4878
4879 print '<td>';
4880 print '<input type="text" name="tabrowid" value="'.dol_escape_htmltag($dicts['tabrowid'][$i]).'" readonly class="tdstickygray">';
4881 print '</td>';
4882
4883 print '<td>';
4884 print '<input type="text" name="tabcond" value="'.dol_escape_htmltag((empty($dicts['tabcond'][$i]) ? 'disabled' : 'enabled')).'" readonly class="tdstickygray">';
4885 print '</td>';
4886
4887 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
4888 print '<input id ="updatedict" class="reposition button smallpaddingimp" type="submit" name="updatedict" value="'.$langs->trans("Modify").'"/>';
4889 print '<br>';
4890 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
4891 print '</td>';
4892
4893 print '</form>';
4894 print '</tr>';
4895 } else {
4896 print '<tr class="oddeven">';
4897
4898 print '<td class="tdsticky tdstickygray">';
4899 print($i + 1);
4900 print '</td>';
4901
4902 print '<td>';
4903 print $dicts['tabname'][$i];
4904 print '</td>';
4905
4906 print '<td>';
4907 print $dicts['tablib'][$i];
4908 print '</td>';
4909
4910 print '<td>';
4911 print $dicts['tabsql'][$i];
4912 print '</td>';
4913
4914 print '<td>';
4915 print $dicts['tabsqlsort'][$i];
4916 print '</td>';
4917
4918 print '<td>';
4919 print $dicts['tabfield'][$i];
4920 print '</td>';
4921
4922 print '<td>';
4923 print $dicts['tabfieldvalue'][$i];
4924 print '</td>';
4925
4926 print '<td>';
4927 print $dicts['tabfieldinsert'][$i];
4928 print '</td>';
4929
4930 print '<td >';
4931 print $dicts['tabrowid'][$i];
4932 print '</td>';
4933
4934 print '<td >';
4935 print $dicts['tabcond'][$i];
4936 print '</td>';
4937
4938 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
4939 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>';
4940 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>';
4941 print '</td>';
4942
4943 print '</tr>';
4944 }
4945 $i++;
4946 }
4947 } else {
4948 print '<tr><td colspan="11"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
4949 }
4950
4951 print '</table>';
4952 print '</div>';
4953
4954 print '</form>';
4955 }
4956
4957 if ($tabdic == 'newdictionary') {
4958 // New dic tab
4959 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
4960 print '<input type="hidden" name="token" value="'.newToken().'">';
4961 print '<input type="hidden" name="action" value="initdic">';
4962 print '<input type="hidden" name="tab" value="dictionaries">';
4963 print '<input type="hidden" name="tabdic" value="'.$tabdic.'">';
4964
4965 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
4966
4967 print '<span class="opacitymedium">'.$langs->trans("EnterNameOfDictionaryDesc").'</span><br><br>';
4968
4969 print dol_get_fiche_head();
4970 print '<table class="border centpercent">';
4971 print '<tbody>';
4972 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>';
4973 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>';
4974 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>';
4975 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>';
4976 print '<tr><td class="titlefieldcreate">'.$langs->trans("FieldsView").'</td><td><input type="text" name="field" value="'.dol_escape_htmltag(GETPOST('field', 'alpha')).'"></td></tr>';
4977 print '<tr><td class="titlefieldcreate">'.$langs->trans("FieldsEdit").'</td><td><input type="text" name="fieldvalue" value="'.dol_escape_htmltag(GETPOST('fieldvalue', 'alpha')).'"></td></tr>';
4978 print '<tr><td class="titlefieldcreate">'.$langs->trans("FieldsInsert").'</td><td><input type="text" name="fieldinsert" value="'.dol_escape_htmltag(GETPOST('fieldinsert', 'alpha')).'"></td></tr>';
4979 print '<tr><td class="titlefieldcreate">'.$langs->trans("Rowid").'</td><td><input type="text" name="rowid" value="'.dol_escape_htmltag(GETPOST('rowid', 'alpha')).'"></td></tr>';
4980 print '<tr></tr>';
4981 print '</tbody></table>';
4982 print '<input type="submit" class="button" name="create" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
4983 print '<input id="cancel" type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
4984 print dol_get_fiche_end();
4985 print '</form>';
4986 print '<script>
4987 $(document).ready(function() {
4988 $("input[name=\'dicname\']").on("blur", function() {
4989 if ($(this).val().length > 0) {
4990 $("input[name=\'label\']").val($(this).val());
4991 $("input[name=\'sql\']").val("SELECT f.rowid as rowid, f.code, f.label, f.active FROM llx_c_" + $(this).val() + " as f");
4992 $("input[name=\'sqlsort\']").val("label ASC");
4993 $("input[name=\'field\']").val("code,label");
4994 $("input[name=\'fieldvalue\']").val("code,label");
4995 $("input[name=\'fieldinsert\']").val("code,label");
4996 $("input[name=\'rowid\']").val("rowid");
4997 } else {
4998 $("input[name=\'label\']").val("");
4999 $("input[name=\'sql\']").val("");
5000 $("input[name=\'sqlsort\']").val("");
5001 $("input[name=\'field\']").val("");
5002 $("input[name=\'fieldvalue\']").val("");
5003 $("input[name=\'fieldinsert\']").val("");
5004 $("input[name=\'rowid\']").val("");
5005 }
5006 });
5007 $("input[id=\'cancel\']").click(function() {
5008 window.history.back();
5009 });
5010 });
5011 </script>';
5012
5013 /*print '<br>';
5014 print '<br>';
5015 print '<br>';
5016 print '<span class="opacitymedium">'.$langs->trans("or").'</span>';
5017 print '<br>';
5018 print '<br>';
5019 //print '<input type="checkbox" name="initfromtablecheck"> ';
5020 print $langs->trans("InitStructureFromExistingTable");
5021 print '<input type="text" name="initfromtablename" value="" placeholder="'.$langs->trans("TableName").'">';
5022 print '<input type="submit" class="button smallpaddingimp" name="createtablearray" value="'.dol_escape_htmltag($langs->trans("GenerateCode")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
5023 print '<br>';
5024 */
5025 } elseif ($tabdic == 'deletedictionary') {
5026 // Delete dic tab
5027 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5028 print '<input type="hidden" name="token" value="'.newToken().'">';
5029 print '<input type="hidden" name="action" value="confirm_deletedictionary">';
5030 print '<input type="hidden" name="tab" value="dictionaries">';
5031 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5032
5033 print $langs->trans("EnterNameOfDictionnaryToDeleteDesc").'<br><br>';
5034
5035 print '<input type="text" name="dicname" value="'.dol_escape_htmltag($modulename).'" placeholder="'.dol_escape_htmltag($langs->trans("DicKey")).'">';
5036 print '<input type="submit" class="button smallpaddingimp" name="delete" value="'.dol_escape_htmltag($langs->trans("Delete")).'"'.($dirins ? '' : ' disabled="disabled"').'>';
5037 print '</form>';
5038 }
5039
5040 print dol_get_fiche_end();
5041 } else {
5042 $fullpathoffile = dol_buildpath($file, 0);
5043
5044 $content = file_get_contents($fullpathoffile);
5045
5046 // New module
5047 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5048 print '<input type="hidden" name="token" value="'.newToken().'">';
5049 print '<input type="hidden" name="action" value="savefile">';
5050 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5051 print '<input type="hidden" name="tab" value="'.$tab.'">';
5052 print '<input type="hidden" name="module" value="'.$module.'">';
5053
5054 $posCursor = (empty($find)) ? array() : array('find'=>$find);
5055 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5056 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5057 print '<br>';
5058 print '<center>';
5059 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5060 print ' &nbsp; ';
5061 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5062 print '</center>';
5063
5064 print '</form>';
5065 }
5066 }
5067
5068 if ($tab == 'menus') {
5069 print '<!-- tab=menus -->'."\n";
5070 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
5071 $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
5072 $destdir = $dirins.'/'.strtolower($module);
5073 $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
5074 $objects = dolGetListOfObjectClasses($destdir);
5075
5076 $leftmenus = array();
5077
5078 $menus = $moduleobj->menu;
5079
5080 $permissions = $moduleobj->rights;
5081 $crud = array('read' => 'CRUDRead', 'write' => 'CRUDCreateWrite', 'delete' => 'Delete');
5082
5083 //grouped permissions
5084 $groupedRights = array();
5085 foreach ($permissions as $right) {
5086 $key = $right[4];
5087 if (!isset($groupedRights[$key])) {
5088 $groupedRights[$key] = array();
5089 }
5090 $groupedRights[$key][] = $right;
5091 }
5092 $groupedRights_json = json_encode($groupedRights);
5093
5094 if ($action == 'deletemenu') {
5095 $formconfirms = $form->formconfirm(
5096 $_SERVER["PHP_SELF"].'?menukey='.urlencode((string) (GETPOSTINT('menukey'))).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)),
5097 $langs->trans('Delete'),
5098 ($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'))),
5099 'confirm_deletemenu',
5100 '',
5101 0,
5102 1
5103 );
5104 print $formconfirms;
5105 }
5106 if ($action != 'editfile' || empty($file)) {
5107 print '<span class="opacitymedium">';
5108 $htmlhelp = $langs->trans("MenusDefDescTooltip", '{s1}');
5109 $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);
5110 print $form->textwithpicto($langs->trans("MenusDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
5111 print '</span>';
5112 print '<br>';
5113
5114 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5115 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>';
5116 print '<br>';
5117
5118 print '<br>';
5119 print load_fiche_titre($langs->trans("ListOfMenusEntries"), '', '');
5120
5121 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5122 print '<input type="hidden" name="token" value="'.newToken().'">';
5123 print '<input type="hidden" name="action" value="addmenu">';
5124 print '<input type="hidden" name="tab" value="menus">';
5125 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5126 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
5127
5128 print '<div class="div-table-responsive">';
5129 print '<table class="noborder small">';
5130
5131 $htmltextenabled = '<u>'.$langs->trans("Examples").':</u><br>';
5132 $htmltextenabled .= '1 <span class="opacitymedium">(module always enabled)</span><br>';
5133 $htmltextenabled .= '0 <span class="opacitymedium">(module always disabled)</span><br>';
5134 $htmltextenabled .= 'isModEnabled(\''.dol_escape_htmltag(strtolower($module)).'\') <span class="opacitymedium">(enabled when module is enabled)</span>';
5135 $htmltextperms = '<u>'.$langs->trans("Examples").':</u><br>';
5136 $htmltextperms .= '1 <span class="opacitymedium">(access always allowed)</span><br>';
5137 $htmltextperms .= '$user->hasright(\''.dol_escape_htmltag(strtolower($module)).'\', \'myobject\', \'read\') <span class="opacitymedium">(access allowed if user has permission module->object->read)</span>';
5138
5139 print '<tr class="liste_titre">';
5140 print_liste_field_titre("#", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center tdsticky tdstickygray ');
5141 print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
5142 print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center');
5143 print_liste_field_titre("LinkToParentMenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'minwidth100 ');
5144 print_liste_field_titre("mainmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
5145 print_liste_field_titre("leftmenu", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
5146 print_liste_field_titre("URL", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->transnoentitiesnoconv('DetailUrl'));
5147 print_liste_field_titre("LanguageFile", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
5148 print_liste_field_titre("Position", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'right ');
5149 print_liste_field_titre("Enabled", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans('DetailEnabled').'<br><br>'.$htmltextenabled);
5150 print_liste_field_titre("Rights", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailRight').'<br><br>'.$htmltextperms);
5151 print_liste_field_titre("Target", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, '', $langs->trans('DetailTarget'));
5152 print_liste_field_titre("MenuForUsers", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center minwidth100 ', $langs->trans('DetailUser'));
5153 print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, 'center ', $langs->trans(''));
5154 print "</tr>\n";
5155
5156 $r = count($menus) + 1;
5157 // for adding menu on module
5158 print '<tr>';
5159 print '<td class="center tdsticky tdstickygray"><input type="hidden" readonly class="center maxwidth50" name="propenabled" value="#"></td>';
5160 print '<td class="center">';
5161 print '<select class="maxwidth50" name="type">';
5162 print '<option value="">'.$langs->trans("........").'</option><option value="'.dol_escape_htmltag("left").'">left</option><option value="'.dol_escape_htmltag("top").'">top</option>';
5163 print '</select></td>';
5164 print '<td class="left"><input type="text" class="left maxwidth100" name="titre" value="'.dol_escape_htmltag(GETPOST('titre', 'alpha')).'"></td>';
5165 print '<td class="left">';
5166 print '<select name="fk_menu">';
5167 print '<option value="">'.$langs->trans("........").'</option>';
5168 foreach ($menus as $obj) {
5169 if ($obj['type'] == 'left' && !empty($obj['leftmenu'])) {
5170 print "<option value=".strtolower($obj['leftmenu']).">".$obj['leftmenu']."</option>";
5171 }
5172 }
5173 print '</select>';
5174 print '</td>';
5175 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>';
5176 print '<td class="center"><input id="leftmenu" type="text" class="left maxwidth50" name="leftmenu" value="'.dol_escape_htmltag(GETPOST('leftmenu', 'alpha')).'"></td>';
5177 // URL
5178 print '<td class="left"><input id="url" type="text" class="left maxwidth100" name="url" value="'.dol_escape_htmltag(GETPOST('url', 'alpha')).'"></td>';
5179 print '<td class="left"><input type="text" class="left maxwidth75" name="langs" value="'.strtolower($module).'@'.strtolower($module).'" readonly></td>';
5180 // Position
5181 print '<td class="center"><input type="text" class="center maxwidth50 tdstickygray" name="position" value="'.(1000 + $r).'" readonly></td>';
5182 // Enabled
5183 print '<td class="center">';
5184 print '<input type="enabled" class="maxwidth125" value="'.dol_escape_htmltag(GETPOSTISSET('enabled') ? GETPOST('enabled') : 'isModEnabled(\''.$module.'\')').'">';
5185 /*
5186 print '<select class="maxwidth" name="enabled">';
5187 print '<option value="1" selected>'.$langs->trans("Show").'</option>';
5188 print '<option value="0">'.$langs->trans("Hide").'</option>';
5189 print '</select>';
5190 */
5191 print '</td>';
5192 // Perms
5193 print '<td class="left">';
5194 print '<select class="maxwidth" name="objects" id="objects">';
5195 print '<option value=""></option>';
5196 if (is_array($objects)) {
5197 foreach ($objects as $value) {
5198 print '<option value="'.strtolower($value).'">'.dol_escape_htmltag(strtolower($value)).'</option>';
5199 }
5200 }
5201 print '</select>';
5202 print '<select class="maxwidth hideobject" name="perms" id="perms">';
5203 print '</select>';
5204 print '</td>';
5205 print '<td class="center"><input type="text" class="center maxwidth50" name="target" value="'.dol_escape_htmltag(GETPOST('target', 'alpha')).'"></td>';
5206 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>';
5207
5208 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5209 print '<input type="submit" class="button" name="add" value="'.$langs->trans("Add").'">';
5210 print '</td>';
5211 print '</tr>';
5212 // end form for add menu
5213
5214 //var_dump($menus);
5215
5216 // Loop on each menu entry
5217 if (count($menus)) {
5218 $i = 0;
5219 foreach ($menus as $menu) {
5220 $i++;
5221 //for get parent in menu
5222 $string = dol_escape_htmltag($menu['fk_menu']);
5223 $value = substr($string, strpos($string, 'fk_leftmenu=') + strlen('fk_leftmenu='));
5224
5225 $propFk_menu = !empty($menu['fk_menu']) ? $menu['fk_menu'] : GETPOST('fk_menu');
5226 $propTitre = !empty($menu['titre']) ? $menu['titre'] : GETPOST('titre');
5227 $propMainmenu = !empty($menu['mainmenu']) ? $menu['mainmenu'] : GETPOST('mainmenu');
5228 $propLeftmenu = !empty($menu['leftmenu']) ? $menu['leftmenu'] : GETPOST('leftmenu');
5229 $propUrl = !empty($menu['url']) ? $menu['url'] : GETPOST('url', 'alpha');
5230 $propPerms = !empty($menu['perms']) ? $menu['perms'] : GETPOST('perms');
5231 $propUser = !empty($menu['user']) ? $menu['user'] : GETPOST('user');
5232 $propTarget = !empty($menu['target']) ? $menu['target'] : GETPOST('target');
5233 $propEnabled = !empty($menu['enabled']) ? $menu['enabled'] : GETPOST('enabled');
5234
5235 $objPerms = (empty($arguments[1]) ? '' : trim($arguments[1]));
5236 $valPerms = (empty($arguments[2]) ? '' : trim($arguments[2]));
5237
5238 //$tabobject = ''; // We can't know what is $tabobject in most cases
5239
5240 if ($action == 'editmenu' && GETPOSTINT('menukey') == $i) {
5241 //var_dump($propPerms);exit;
5242 print '<tr class="oddeven">';
5243 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5244 print '<input type="hidden" name="token" value="'.newToken().'">';
5245 print '<input type="hidden" name="action" value="update_menu">';
5246 print '<input type="hidden" name="tab" value="menus">';
5247 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5248 print '<input type="hidden" name="menukey" value="'.$i.'"/>';
5249 //print '<input type="hidden" name="tabobject" value="'.dol_escape_htmltag($tabobject).'">';
5250 print '<td class="tdsticky tdstickygray">';
5251 print $i;
5252 print '</td>';
5253 // Position (top, left)
5254 print '<td class="center">
5255 <select class="center maxwidth50" name="type">
5256 <option value="'.dol_escape_htmltag($menu['type']).'">
5257 '.dol_escape_htmltag($menu['type']).'
5258 </option>';
5259 print '<option value="'.($menu['type'] == 'left' ? 'top' : 'left').'">';
5260 if ($menu['type'] == 'left') {
5261 print 'top';
5262 } else {
5263 print 'left';
5264 }
5265 print '</option></select></td>';
5266 // Title
5267 print '<td><input type="text" class="left maxwidth100" name="titre" value="'.dol_escape_htmltag($propTitre).'"></td>';
5268 // Parent menu
5269 print '<td>';
5270 /*print '<select name="fk_menu" class="left maxwidth">';
5271 print '<option value="'.dol_escape_htmltag($propFk_menu).'">'.dol_escape_htmltag($value).'</option>';
5272 foreach ($menus as $obj) {
5273 if ($obj['type'] == 'left' && $obj['leftmenu'] != $value && $obj['leftmenu'] != $menu['leftmenu']) {
5274 print "<option value=".strtolower($obj['leftmenu']).">".$obj['leftmenu']."</option>";
5275 }
5276 }
5277 print '</select>';*/
5278 print '<input type="text" name="fk_menu" class="maxwidth150" value="'.dol_escape_htmltag($propFk_menu).'">';
5279 print '</td>';
5280 print '<td><input type="text" class="left maxwidth50" name="mainmenu" value="'.dol_escape_htmltag($propMainmenu).'" readonly></td>';
5281 print '<td><input type="text" class="left maxwidth50" name="leftmenu" value="'.dol_escape_htmltag($propLeftmenu).'" readonly></td>';
5282 // URL
5283 print '<td><input type="text" class="left maxwidth250" name="url" value="'.dol_escape_htmltag($propUrl).'"></td>';
5284 print '<td><input type="text" class="left maxwidth50" name="langs" value="'.strtolower($module).'@'.strtolower($module).'" readonly></td>';
5285 // Position
5286 print '<td class="center"><input type="text" class="center maxwidth50 tdstickygray" name="position" value="'.($menu['position']).'" readonly></td>';
5287 // Enabled
5288 print '<td class="nowraponall">';
5289 print '<input type="text" class="maxwidth125" name="enabled" value="'.dol_escape_htmltag($propEnabled != '' ? $propEnabled : "isModEnabled('".dol_escape_htmltag($module)."')").'">';
5290 $htmltext = '<u>'.$langs->trans("Examples").':</u><br>';
5291 $htmltext .= '1 <span class="opacitymedium">(always enabled)</span><br>';
5292 $htmltext .= '0 <span class="opacitymedium">(always disabled)</span><br>';
5293 $htmltext .= 'isModEnabled(\''.dol_escape_htmltag($module).'\') <span class="opacitymedium">(enabled when module is enabled)</span><br>';
5294 print $form->textwithpicto('', $htmltext);
5295 /*
5296 print '<select class="maxwidth50" name="enabledselect">';
5297 print '<option value="1">1 (always enabled)</option>';
5298 print '<option value="0">0 (always disabled)</option>';
5299 print '<option value="isModEnabled(\''.dol_escape_htmltag($module).'\')" >isModEnabled(\''.dol_escape_htmltag($module).'\')</option>';
5300 print '</select>';
5301 */
5302 print '</td>';
5303 // Permissions
5304 print '<td class="nowraponall">';
5305 print '<input type="text" name="perms" value="'.dol_escape_htmltag($propPerms).'">';
5306 /*
5307 if (!empty($objPerms)) {
5308 print '<input type="hidden" name="objects" value="'.$objPerms.'" />';
5309 print '<select class="center maxwidth50" name="perms">';
5310 if (!empty($valPerms)) {
5311 print '<option selected value="'.dol_escape_htmltag($valPerms).'">'.dol_escape_htmltag($langs->trans($crud[$valPerms])).'</option>';
5312 foreach ($crud as $key => $val) {
5313 if ($valPerms != $key) {
5314 print '<option value="'.dol_escape_htmltag($key).'">'.dol_escape_htmltag($langs->trans($val)).'</option>';
5315 }
5316 }
5317 }
5318 print '</select>';
5319 } else {
5320 print '<select class="center maxwidth50" name="objects">';
5321 print '<option></option>';
5322 foreach ($objects as $obj) {
5323 print '<option value="'.dol_escape_htmltag(strtolower($obj)).'">'.dol_escape_htmltag($obj).'</option>';
5324 }
5325 print '</select>';
5326 print '<select class="center maxwidth50" name="perms">';
5327 foreach ($crud as $key => $val) {
5328 print '<option value="'.dol_escape_htmltag($key).'">'.dol_escape_htmltag($key).'</option>';
5329 }
5330 print '</select>';
5331 }*/
5332 print '</td>';
5333 // Target
5334 print '<td class="center"><input type="text" class="center maxwidth50" name="target" value="'.dol_escape_htmltag($propTarget).'"></td>';
5335 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>';
5336 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite maxwidth75">';
5337 print '<input class="reposition button smallpaddingimp" type="submit" name="edit" value="'.$langs->trans("Modify").'">';
5338 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'">';
5339 print '</td>';
5340 print '</form>';
5341 print '</tr>';
5342 } else {
5343 print '<tr class="oddeven">';
5344
5345 print '<td class="tdsticky tdstickygray">';
5346 print $i;
5347 print '</td>';
5348
5349 print '<td class="center">';
5350 print dol_escape_htmltag($menu['type']);
5351 print '</td>';
5352
5353 // Title
5354 print '<td>';
5355 print dol_escape_htmltag($menu['titre']);
5356 print '</td>';
5357
5358 // Parent menu
5359 print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($menu['fk_menu']).'">';
5360 print dol_escape_htmltag($menu['fk_menu']);
5361 print '</td>';
5362
5363 print '<td>';
5364 print dol_escape_htmltag($menu['mainmenu']);
5365 print '</td>';
5366
5367 print '<td>';
5368 print dol_escape_htmltag($menu['leftmenu']);
5369 print '</td>';
5370
5371 print '<td class="tdoverflowmax250" title="'.dol_escape_htmltag($menu['url']).'">';
5372 print dol_escape_htmltag($menu['url']);
5373 print '</td>';
5374
5375 print '<td>';
5376 print dol_escape_htmltag($menu['langs']);
5377 print '</td>';
5378
5379 // Position
5380 print '<td class="center">';
5381 print dol_escape_htmltag($menu['position']);
5382 print '</td>';
5383
5384 // Enabled
5385 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($menu['enabled']).'">';
5386 print dol_escape_htmltag($menu['enabled']);
5387 print '</td>';
5388
5389 // Perms
5390 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($menu['perms']).'">';
5391 print dol_escape_htmltag($langs->trans($menu['perms']));
5392 print '</td>';
5393
5394 // Target
5395 print '<td class="center tdoverflowmax200" title="'.dol_escape_htmltag($menu['target']).'">';
5396 print dol_escape_htmltag($menu['target']);
5397 print '</td>';
5398
5399 print '<td class="center">';
5400 if ($menu['user'] == 2) {
5401 print $langs->trans("AllMenus");
5402 } elseif ($menu['user'] == 0) {
5403 print $langs->trans('Internal');
5404 } elseif ($menu['user'] == 1) {
5405 print $langs->trans('External');
5406 } else {
5407 print $menu['user']; // should not happen
5408 }
5409 print '</td>';
5410 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5411 if ($menu['titre'] != 'Module'.$module.'Name') {
5412 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>';
5413 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>';
5414 }
5415 print '</td>';
5416 }
5417 print '</tr>';
5418 }
5419 } else {
5420 print '<tr><td colspan="14"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
5421 }
5422
5423 print '</table>';
5424 print '</div>';
5425 print '</form>';
5426
5427
5428 print '<script>
5429 $(document).ready(function() {
5430 //for fill in auto url
5431 $("#leftmenu").on("input", function() {
5432 var inputLeftMenu = $("#leftmenu").val();
5433 if (inputLeftMenu !== \'\') {
5434 var url = \''.dol_escape_js(strtolower($module)).'\' + inputLeftMenu + \'.php\';
5435 $("#url").val(url);
5436 }else {
5437 $("#url").val("");
5438 }
5439 });
5440
5441 var groupedRights = ' . $groupedRights_json . ';
5442 var objectsSelect = $("select[id=\'objects\']");
5443 var permsSelect = $("select[id=\'perms\']");
5444
5445 objectsSelect.change(function() {
5446 var selectedObject = $(this).val();
5447
5448 permsSelect.empty();
5449
5450 var rights = groupedRights[selectedObject];
5451
5452 if (rights) {
5453 for (var i = 0; i < rights.length; i++) {
5454 var right = rights[i];
5455 var option = $("<option></option>").attr("value", right[5]).text(right[5]);
5456 permsSelect.append(option);
5457 }
5458 } else {
5459 var option = $("<option></option>").attr("value", "read").text("read");
5460 permsSelect.append(option);
5461 }
5462
5463 if (selectedObject !== "" && selectedObject !== null && rights) {
5464 permsSelect.show();
5465 } else {
5466 permsSelect.hide();
5467 }
5468 if (objectsSelect.val() === "" || objectsSelect.val() === null) {
5469 permsSelect.hide();
5470 }
5471 });
5472 });
5473 </script>';
5474
5475 // display permissions for each object
5476 } else {
5477 $fullpathoffile = dol_buildpath($file, 0);
5478
5479 $content = file_get_contents($fullpathoffile);
5480
5481 // New module
5482 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5483 print '<input type="hidden" name="token" value="'.newToken().'">';
5484 print '<input type="hidden" name="action" value="savefile">';
5485 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5486 print '<input type="hidden" name="tab" value="'.$tab.'">';
5487 print '<input type="hidden" name="module" value="'.$module.'">';
5488
5489 $posCursor = (empty($find)) ? array() : array('find'=>$find);
5490 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5491 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5492 print '<br>';
5493 print '<center>';
5494 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5495 print ' &nbsp; ';
5496 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5497 print '</center>';
5498
5499 print '</form>';
5500 }
5501 }
5502
5503 if ($tab == 'permissions') {
5504 print '<!-- tab=permissions -->'."\n";
5505 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
5506
5507 $perms = $moduleobj->rights;
5508
5509 // Get list of existing objects
5510 $dir = $dirread.'/'.$modulelowercase.'/class';
5511 $listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$');
5512 $objects = array('myobject');
5513 $reg = array();
5514 foreach ($listofobject as $fileobj) {
5515 $tmpcontent = file_get_contents($fileobj['fullname']);
5516 if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) {
5517 $objects[$fileobj['fullname']] = $reg[1];
5518 }
5519 }
5520
5521 // declared select list for actions and labels permissions
5522 $crud = array('read' => 'CRUDRead', 'write' => 'CRUDCreateWrite', 'delete' => 'Delete');
5523 $labels = array("Read objects of ".$module, "Create/Update objects of ".$module, "Delete objects of ".$module);
5524
5525 $action = GETPOST('action', 'alpha');
5526
5527 if ($action == 'deleteright') {
5528 $formconfirm = $form->formconfirm(
5529 $_SERVER["PHP_SELF"].'?permskey='.urlencode((string) (GETPOSTINT('permskey'))).'&tab='.urlencode((string) ($tab)).'&module='.urlencode((string) ($module)).'&tabobj='.urlencode((string) ($tabobj)),
5530 $langs->trans('Delete'),
5531 $langs->trans('Confirm Delete Right', GETPOST('permskey', 'alpha')),
5532 'confirm_deleteright',
5533 '',
5534 0,
5535 1
5536 );
5537 print $formconfirm;
5538 }
5539
5540 if ($action != 'editfile' || empty($file)) {
5541 print '<!-- Tab to manage permissions -->'."\n";
5542 print '<span class="opacitymedium">';
5543 $htmlhelp = $langs->trans("PermissionsDefDescTooltip", '{s1}');
5544 $htmlhelp = str_replace('{s1}', '<a target="adminbis" class="nofocusvisible" href="'.DOL_URL_ROOT.'/admin/perms.php">'.$langs->trans('DefaultRights').'</a>', $htmlhelp);
5545 print $form->textwithpicto($langs->trans("PermissionsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
5546 print '</span>';
5547 print '<br>';
5548
5549 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5550 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>';
5551 print '<br>';
5552
5553 print '<br>';
5554 print load_fiche_titre($langs->trans("ListOfPermissionsDefined"), '', '');
5555
5556 print '<!-- form to add permissions -->'."\n";
5557 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5558 print '<input type="hidden" name="token" value="'.newToken().'">';
5559 print '<input type="hidden" name="action" value="addright">';
5560 print '<input type="hidden" name="tab" value="permissions">';
5561 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5562 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
5563
5564 print '<div class="div-table-responsive">';
5565 print '<table class="noborder">';
5566
5567 print '<tr class="liste_titre">';
5568 print_liste_field_titre("ID", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5569 print_liste_field_titre("Object", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5570 print_liste_field_titre("CRUD", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5571 print_liste_field_titre("Label", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5572 print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center");
5573 print "</tr>\n";
5574
5575 //form for add new right
5576 print '<tr class="small">';
5577 print '<td><input type="hidden" readonly name="id" class="width75" value="0"></td>';
5578
5579 print '<td><select class="minwidth100" name="permissionObj" id="permissionObj">';
5580 print '<option value=""></option>';
5581 foreach ($objects as $obj) {
5582 if ($obj != 'myobject') {
5583 print '<option value="'.$obj.'">'.$obj.'</option>';
5584 }
5585 }
5586 print '</select></td>';
5587
5588 print '<td><select class="maxwidth75" name="crud" id="crud">';
5589 print '<option value=""></option>';
5590 foreach ($crud as $key => $val) {
5591 print '<option value="'.$key.'">'.$langs->trans($val).'</option>';
5592 }
5593 print '</td>';
5594
5595 print '<td >';
5596 print '<input type="text" name="label" id="label" class="minwidth200">';
5597 print '</td>';
5598
5599 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5600 print '<input type="submit" class="button" name="add" value="'.$langs->trans("Add").'">';
5601 print '</td>';
5602 print '</tr>';
5603
5604 if (count($perms)) {
5605 $i = 0;
5606 foreach ($perms as $perm) {
5607 $i++;
5608
5609 // section for editing right
5610 if ($action == 'edit_right' && $perm[0] == GETPOSTINT('permskey')) {
5611 print '<tr class="oddeven">';
5612 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="modifPerms">';
5613 print '<input type="hidden" name="token" value="'.newToken().'">';
5614 print '<input type="hidden" name="tab" value="permissions">';
5615 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
5616 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
5617 print '<input type="hidden" name="action" value="update_right">';
5618 print '<input type="hidden" name="counter" value="'.$i.'">';
5619
5620 print '<input type="hidden" name="permskey" value="'.$perm[0].'">';
5621
5622 print '<td class="tdsticky tdstickygray">';
5623 print '<input class="width75" type="text" readonly value="'.dol_escape_htmltag($perm[0]).'"/>';
5624 print '</td>';
5625
5626 print '<td>';
5627 print '<select name="crud">';
5628 print '<option value="'.dol_escape_htmltag($perm[5]).'">'.$langs->trans($perm[5]).'</option>';
5629 foreach ($crud as $i => $x) {
5630 if ($perm[5] != $i) {
5631 print '<option value="'.$i.'">'.$langs->trans(ucfirst($x)).'</option>';
5632 }
5633 }
5634 print '</select>';
5635 print '</td>';
5636
5637 print '<td><select name="permissionObj" >';
5638 print '<option value="'.dol_escape_htmltag($perm[4]).'">'.ucfirst($perm[4]).'</option>';
5639 print '</select></td>';
5640
5641 print '<td>';
5642 print '<input type="text" name="label" value="'.dol_escape_htmltag($perm[1]).'">';
5643 print '</td>';
5644
5645 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5646 print '<input id ="modifyPerm" class="reposition button smallpaddingimp" type="submit" name="modifyright" value="'.$langs->trans("Modify").'"/>';
5647 print '<br>';
5648 print '<input class="reposition button button-cancel smallpaddingimp" type="submit" name="cancel" value="'.$langs->trans("Cancel").'"/>';
5649 print '</td>';
5650
5651 print '</form>';
5652 print '</tr>';
5653 } else {
5654 // $perm can be module->object->crud or module->crud
5655 print '<tr class="oddeven">';
5656
5657 print '<td>';
5658 print dol_escape_htmltag($perm[0]);
5659 print '</td>';
5660
5661 print '<td>';
5662 if (in_array($perm[5], array('lire', 'read', 'creer', 'write', 'effacer', 'delete'))) {
5663 print dol_escape_htmltag(ucfirst($perm[4]));
5664 } else {
5665 print ''; // No particular object
5666 }
5667 print '</td>';
5668
5669 print '<td>';
5670 if (in_array($perm[5], array('lire', 'read', 'creer', 'write', 'effacer', 'delete'))) {
5671 print ucfirst($langs->trans($perm[5]));
5672 } else {
5673 print ucfirst($langs->trans($perm[4]));
5674 }
5675 print '</td>';
5676
5677 print '<td>';
5678 print $langs->trans($perm[1]);
5679 print '</td>';
5680
5681 print '<td class="center minwidth75 tdstickyright tdstickyghostwhite">';
5682 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>';
5683 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>';
5684
5685 print '</td>';
5686
5687 print '</tr>';
5688 }
5689 }
5690 } else {
5691 print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
5692 }
5693
5694 print '</table>';
5695 print '</div>';
5696
5697 print '</form>';
5698 print '<script>
5699 function updateInputField() {
5700 value1 = $("#crud").val();
5701 value2 = $("#permissionObj").val();
5702
5703 // Vérifie si les deux sélections sont faites
5704 if (value1 && value2) {
5705 switch(value1.toLowerCase()){
5706 case "read":
5707 $("#label").val("Read "+value2+" object of '.ucfirst($module).'")
5708 break;
5709 case "write":
5710 $("#label").val("Create/Update "+value2+" object of '.ucfirst($module).'")
5711 break;
5712 case "delete":
5713 $("#label").val("Delete "+value2+" object of '.ucfirst($module).'")
5714 break;
5715 default:
5716 $("#label").val("")
5717 }
5718 }
5719 }
5720
5721 $("#crud, #permissionObj").change(function(){
5722 console.log("We change selection");
5723 updateInputField();
5724 });
5725
5726 </script>';
5727 } else {
5728 $fullpathoffile = dol_buildpath($file, 0);
5729
5730 $content = file_get_contents($fullpathoffile);
5731
5732 // New module
5733 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5734 print '<input type="hidden" name="token" value="'.newToken().'">';
5735 print '<input type="hidden" name="action" value="savefile">';
5736 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5737 print '<input type="hidden" name="tab" value="'.$tab.'">';
5738 print '<input type="hidden" name="module" value="'.$module.'">';
5739
5740 $posCursor = (empty($find)) ? array() : array('find'=>$find);
5741 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5742 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5743 print '<br>';
5744 print '<center>';
5745 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5746 print ' &nbsp; ';
5747 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5748 print '</center>';
5749
5750 print '</form>';
5751 }
5752 }
5753
5754 if ($tab == 'hooks') {
5755 print '<!-- tab=hooks -->'."\n";
5756 if ($action != 'editfile' || empty($file)) {
5757 print '<span class="opacitymedium">'.$langs->trans("HooksDefDesc").'</span><br>';
5758 print '<br>';
5759
5760 print '<table>';
5761
5762 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
5763 print '<tr><td>';
5764 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5765 print '</td><td>';
5766 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>';
5767 print '</td></tr>';
5768
5769 print '<tr><td>';
5770 $pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
5771 print '<span class="fa fa-file-o"></span> '.$langs->trans("HooksFile").' : ';
5772 if (dol_is_file($dirins.'/'.$pathtohook)) {
5773 print '<strong class="wordbreak">'.$pathtohook.'</strong>';
5774 print '</td>';
5775 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> ';
5776 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>';
5777 } else {
5778 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
5779 print '<a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=inithook&format=php&file='.urlencode($pathtohook).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</td>';
5780 print '<td></td>';
5781 }
5782 print '</tr>';
5783 } else {
5784 $fullpathoffile = dol_buildpath($file, 0);
5785
5786 $content = file_get_contents($fullpathoffile);
5787
5788 // New module
5789 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5790 print '<input type="hidden" name="token" value="'.newToken().'">';
5791 print '<input type="hidden" name="action" value="savefile">';
5792 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5793 print '<input type="hidden" name="tab" value="'.$tab.'">';
5794 print '<input type="hidden" name="module" value="'.$module.'">';
5795
5796 $posCursor = (empty($find)) ? array() : array('find'=>$find);
5797 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5798 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5799 print '<br>';
5800 print '<center>';
5801 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5802 print ' &nbsp; ';
5803 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5804 print '</center>';
5805
5806 print '</form>';
5807 }
5808 }
5809
5810 if ($tab == 'triggers') {
5811 print '<!-- tab=triggers -->'."\n";
5812 require_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
5813
5814 $interfaces = new Interfaces($db);
5815 $triggers = $interfaces->getTriggersList(array('/'.strtolower($module).'/core/triggers'));
5816
5817 if ($action != 'editfile' || empty($file)) {
5818 print '<span class="opacitymedium">'.$langs->trans("TriggerDefDesc").'</span><br>';
5819 print '<br>';
5820
5821 print '<table>';
5822
5823 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
5824 print '<tr><td>';
5825 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5826 print '</td><td>';
5827 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>';
5828 print '</td></tr>';
5829
5830 if (!empty($triggers)) {
5831 foreach ($triggers as $trigger) {
5832 $pathtofile = $trigger['relpath'];
5833
5834 print '<tr><td>';
5835 print '<span class="fa fa-file-o"></span> '.$langs->trans("TriggersFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5836 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>';
5837 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>';
5838 print '</tr>';
5839 }
5840 } else {
5841 print '<tr><td>';
5842 print '<span class="fa fa-file-o"></span> '.$langs->trans("TriggersFile");
5843 print ' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
5844 print '<a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=inittrigger&format=php">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
5845 print '<td></td>';
5846 print '</tr>';
5847 }
5848
5849 print '</table>';
5850 } else {
5851 $fullpathoffile = dol_buildpath($file, 0);
5852
5853 $content = file_get_contents($fullpathoffile);
5854
5855 // New module
5856 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5857 print '<input type="hidden" name="token" value="'.newToken().'">';
5858 print '<input type="hidden" name="action" value="savefile">';
5859 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5860 print '<input type="hidden" name="tab" value="'.$tab.'">';
5861 print '<input type="hidden" name="module" value="'.$module.'">';
5862
5863 $posCursor = (empty($find)) ? array() : array('find'=>$find);
5864 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
5865 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5866 print '<br>';
5867 print '<center>';
5868 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5869 print ' &nbsp; ';
5870 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5871 print '</center>';
5872
5873 print '</form>';
5874 }
5875 }
5876
5877 if ($tab == 'css') {
5878 print '<!-- tab=css -->'."\n";
5879 if ($action != 'editfile' || empty($file)) {
5880 print '<span class="opacitymedium">'.$langs->trans("CSSDesc").'</span><br>';
5881 print '<br>';
5882
5883 print '<table>';
5884
5885 print '<tr><td>';
5886 $pathtohook = strtolower($module).'/css/'.strtolower($module).'.css.php';
5887 print '<span class="fa fa-file-o"></span> '.$langs->trans("CSSFile").' : ';
5888 if (dol_is_file($dirins.'/'.$pathtohook)) {
5889 print '<strong class="wordbreak">'.$pathtohook.'</strong>';
5890 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>';
5891 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>';
5892 } else {
5893 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
5894 print '</td><td><a href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initcss&format=php&file='.urlencode($pathtohook).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a></td>';
5895 }
5896 print '</tr>';
5897 } else {
5898 $fullpathoffile = dol_buildpath($file, 0);
5899
5900 $content = file_get_contents($fullpathoffile);
5901
5902 // New module
5903 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5904 print '<input type="hidden" name="token" value="'.newToken().'">';
5905 print '<input type="hidden" name="action" value="savefile">';
5906 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5907 print '<input type="hidden" name="tab" value="'.$tab.'">';
5908 print '<input type="hidden" name="module" value="'.$module.'">';
5909
5910 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
5911 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5912 print '<br>';
5913 print '<center>';
5914 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5915 print ' &nbsp; ';
5916 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5917 print '</center>';
5918
5919 print '</form>';
5920 }
5921 }
5922
5923 if ($tab == 'js') {
5924 print '<!-- tab=js -->'."\n";
5925 if ($action != 'editfile' || empty($file)) {
5926 print '<span class="opacitymedium">'.$langs->trans("JSDesc").'</span><br>';
5927 print '<br>';
5928
5929 print '<table>';
5930
5931 print '<tr><td>';
5932 $pathtohook = strtolower($module).'/js/'.strtolower($module).'.js.php';
5933 print '<span class="fa fa-file-o"></span> '.$langs->trans("JSFile").' : ';
5934 if (dol_is_file($dirins.'/'.$pathtohook)) {
5935 print '<strong class="wordbreak">'.$pathtohook.'</strong>';
5936 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>';
5937 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>';
5938 } else {
5939 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
5940 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>';
5941 }
5942 print '</tr>';
5943 } else {
5944 $fullpathoffile = dol_buildpath($file, 0);
5945
5946 $content = file_get_contents($fullpathoffile);
5947
5948 // New module
5949 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
5950 print '<input type="hidden" name="token" value="'.newToken().'">';
5951 print '<input type="hidden" name="action" value="savefile">';
5952 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
5953 print '<input type="hidden" name="tab" value="'.$tab.'">';
5954 print '<input type="hidden" name="module" value="'.$module.'">';
5955
5956 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
5957 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
5958 print '<br>';
5959 print '<center>';
5960 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
5961 print ' &nbsp; ';
5962 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
5963 print '</center>';
5964
5965 print '</form>';
5966 }
5967 }
5968
5969 if ($tab == 'widgets') {
5970 print '<!-- tab=widgets -->'."\n";
5971 require_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php';
5972
5973 $widgets = ModeleBoxes::getWidgetsList(array('/'.strtolower($module).'/core/boxes'));
5974
5975 if ($action != 'editfile' || empty($file)) {
5976 print '<span class="opacitymedium">'.$langs->trans("WidgetDesc").'</span><br>';
5977 print '<br>';
5978
5979 print '<table>';
5980 if (!empty($widgets)) {
5981 foreach ($widgets as $widget) {
5982 $pathtofile = $widget['relpath'];
5983
5984 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("WidgetFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
5985 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>';
5986 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>';
5987 print '</tr>';
5988 }
5989 } else {
5990 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("WidgetFile").' : <span class="opacitymedium">'.$langs->trans("NoWidget").'</span>';
5991 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>';
5992 print '</td></tr>';
5993 }
5994 print '</table>';
5995 } else {
5996 $fullpathoffile = dol_buildpath($file, 0);
5997
5998 $content = file_get_contents($fullpathoffile);
5999
6000 // New module
6001 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6002 print '<input type="hidden" name="token" value="'.newToken().'">';
6003 print '<input type="hidden" name="action" value="savefile">';
6004 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6005 print '<input type="hidden" name="tab" value="'.$tab.'">';
6006 print '<input type="hidden" name="module" value="'.$module.'">';
6007
6008 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
6009 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6010 print '<br>';
6011 print '<center>';
6012 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6013 print ' &nbsp; ';
6014 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6015 print '</center>';
6016
6017 print '</form>';
6018 }
6019 }
6020
6021 if ($tab == 'emailings') {
6022 print '<!-- tab=emailings -->'."\n";
6023 require_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
6024
6025 $emailingselectors = MailingTargets::getEmailingSelectorsList(array('/'.strtolower($module).'/core/modules/mailings'));
6026
6027 if ($action != 'editfile' || empty($file)) {
6028 print '<span class="opacitymedium">'.$langs->trans("EmailingSelectorDesc").'</span><br>';
6029 print '<br>';
6030
6031 print '<table>';
6032 if (!empty($emailingselectors)) {
6033 foreach ($emailingselectors as $emailingselector) {
6034 $pathtofile = $emailingselector['relpath'];
6035
6036 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("EmailingSelectorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6037 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>';
6038 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>';
6039 print '</tr>';
6040 }
6041 } else {
6042 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("EmailingSelectorFile").' : <span class="opacitymedium">'.$langs->trans("NoEmailingSelector").'</span>';
6043 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>';
6044 print '</td></tr>';
6045 }
6046 print '</table>';
6047 } else {
6048 $fullpathoffile = dol_buildpath($file, 0);
6049
6050 $content = file_get_contents($fullpathoffile);
6051
6052 // New module
6053 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6054 print '<input type="hidden" name="token" value="'.newToken().'">';
6055 print '<input type="hidden" name="action" value="savefile">';
6056 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6057 print '<input type="hidden" name="tab" value="'.$tab.'">';
6058 print '<input type="hidden" name="module" value="'.$module.'">';
6059
6060 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
6061 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6062 print '<br>';
6063 print '<center>';
6064 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6065 print ' &nbsp; ';
6066 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6067 print '</center>';
6068
6069 print '</form>';
6070 }
6071 }
6072
6073 if ($tab == 'exportimport') {
6074 print '<!-- tab=exportimport -->'."\n";
6075 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6076
6077 $exportlist = $moduleobj->export_label;
6078 $importlist = $moduleobj->import_label;
6079
6080 if ($action != 'editfile' || empty($file)) {
6081 print '<span class="opacitymedium">'.$langs->transnoentities('ImportExportProfiles').'</span><br>';
6082 print '<br>';
6083
6084 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' ('.$langs->trans("ExportsArea").') : <strong class="wordbreak">'.$pathtofile.'</strong>';
6085 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>';
6086 print '<br>';
6087 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' ('.$langs->trans("ImportArea").') : <strong class="wordbreak">'.$pathtofile.'</strong>';
6088 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>';
6089 print '<br>';
6090 } else {
6091 $fullpathoffile = dol_buildpath($file, 0);
6092
6093 $content = file_get_contents($fullpathoffile);
6094
6095 // New module
6096 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6097 print '<input type="hidden" name="token" value="'.newToken().'">';
6098 print '<input type="hidden" name="action" value="savefile">';
6099 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6100 print '<input type="hidden" name="tab" value="'.$tab.'">';
6101 print '<input type="hidden" name="module" value="'.$module.'">';
6102
6103 $posCursor = (empty($find)) ? array() : array('find'=>$find);
6104 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
6105 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6106 print '<br>';
6107 print '<center>';
6108 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6109 print ' &nbsp; ';
6110 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6111 print '</center>';
6112
6113 print '</form>';
6114 }
6115 }
6116
6117 if ($tab == 'cli') {
6118 print '<!-- tab=cli -->'."\n";
6119 $clifiles = array();
6120 $i = 0;
6121
6122 $dircli = array('/'.strtolower($module).'/scripts');
6123
6124 foreach ($dircli as $reldir) {
6125 $dir = dol_buildpath($reldir, 0);
6126 $newdir = dol_osencode($dir);
6127
6128 // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call)
6129 if (!is_dir($newdir)) {
6130 continue;
6131 }
6132
6133 $handle = opendir($newdir);
6134
6135 if (is_resource($handle)) {
6136 while (($tmpfile = readdir($handle)) !== false) {
6137 if (is_readable($newdir.'/'.$tmpfile) && preg_match('/^(.+)\.php/', $tmpfile, $reg)) {
6138 if (preg_match('/\.back$/', $tmpfile)) {
6139 continue;
6140 }
6141
6142 $clifiles[$i]['relpath'] = preg_replace('/^\//', '', $reldir).'/'.$tmpfile;
6143
6144 $i++;
6145 }
6146 }
6147 closedir($handle);
6148 }
6149 }
6150
6151 if ($action != 'editfile' || empty($file)) {
6152 print '<span class="opacitymedium">'.$langs->trans("CLIDesc").'</span><br>';
6153 print '<br>';
6154
6155 print '<table>';
6156 if (!empty($clifiles)) {
6157 foreach ($clifiles as $clifile) {
6158 $pathtofile = $clifile['relpath'];
6159
6160 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("CLIFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6161 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>';
6162 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>';
6163 print '</tr>';
6164 }
6165 } else {
6166 print '<tr><td><span class="fa fa-file-o"></span> '.$langs->trans("CLIFile").' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6167 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>';
6168 print '</td></tr>';
6169 }
6170 print '</table>';
6171 } else {
6172 $fullpathoffile = dol_buildpath($file, 0);
6173
6174 $content = file_get_contents($fullpathoffile);
6175
6176 // New module
6177 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6178 print '<input type="hidden" name="token" value="'.newToken().'">';
6179 print '<input type="hidden" name="action" value="savefile">';
6180 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6181 print '<input type="hidden" name="tab" value="'.$tab.'">';
6182 print '<input type="hidden" name="module" value="'.$module.'">';
6183
6184 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
6185 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6186 print '<br>';
6187 print '<center>';
6188 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6189 print ' &nbsp; ';
6190 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6191 print '</center>';
6192
6193 print '</form>';
6194 }
6195 }
6196
6197 if ($tab == 'cron') {
6198 print '<!-- tab=cron -->'."\n";
6199 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6200
6201 $cronjobs = $moduleobj->cronjobs;
6202
6203 if ($action != 'editfile' || empty($file)) {
6204 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>';
6205 print '<br>';
6206
6207 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6208 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>';
6209 print '<br>';
6210
6211 print '<br>';
6212 print load_fiche_titre($langs->trans("CronJobProfiles"), '', '');
6213
6214 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6215 print '<input type="hidden" name="token" value="'.newToken().'">';
6216 print '<input type="hidden" name="action" value="addproperty">';
6217 print '<input type="hidden" name="tab" value="objects">';
6218 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
6219 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
6220
6221 print '<div class="div-table-responsive">';
6222 print '<table class="noborder">';
6223
6224 print '<tr class="liste_titre">';
6225 print_liste_field_titre("CronLabel", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
6226 print_liste_field_titre("CronTask", '', '', "", $param, '', $sortfield, $sortorder);
6227 print_liste_field_titre("CronFrequency", '', "", "", $param, '', $sortfield, $sortorder);
6228 print_liste_field_titre("StatusAtInstall", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
6229 print_liste_field_titre("Comment", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder);
6230 print "</tr>\n";
6231
6232 if (count($cronjobs)) {
6233 foreach ($cronjobs as $cron) {
6234 print '<tr class="oddeven">';
6235
6236 print '<td>';
6237 print $cron['label'];
6238 print '</td>';
6239
6240 print '<td>';
6241 if ($cron['jobtype'] == 'method') {
6242 $text = $langs->trans("CronClass");
6243 $texttoshow = $langs->trans('CronModule').': '.$module.'<br>';
6244 $texttoshow .= $langs->trans('CronClass').': '.$cron['class'].'<br>';
6245 $texttoshow .= $langs->trans('CronObject').': '.$cron['objectname'].'<br>';
6246 $texttoshow .= $langs->trans('CronMethod').': '.$cron['method'];
6247 $texttoshow .= '<br>'.$langs->trans('CronArgs').': '.$cron['parameters'];
6248 $texttoshow .= '<br>'.$langs->trans('Comment').': '.$langs->trans($cron['comment']);
6249 } elseif ($cron['jobtype'] == 'command') {
6250 $text = $langs->trans('CronCommand');
6251 $texttoshow = $langs->trans('CronCommand').': '.dol_trunc($cron['command']);
6252 $texttoshow .= '<br>'.$langs->trans('CronArgs').': '.$cron['parameters'];
6253 $texttoshow .= '<br>'.$langs->trans('Comment').': '.$langs->trans($cron['comment']);
6254 }
6255 print $form->textwithpicto($text, $texttoshow, 1);
6256 print '</td>';
6257
6258 print '<td>';
6259 if ($cron['unitfrequency'] == "60") {
6260 print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes');
6261 }
6262 if ($cron['unitfrequency'] == "3600") {
6263 print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours');
6264 }
6265 if ($cron['unitfrequency'] == "86400") {
6266 print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days');
6267 }
6268 if ($cron['unitfrequency'] == "604800") {
6269 print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks');
6270 }
6271 print '</td>';
6272
6273 print '<td>';
6274 print $cron['status'];
6275 print '</td>';
6276
6277 print '<td>';
6278 if (!empty($cron['comment'])) {
6279 print $cron['comment'];
6280 }
6281 print '</td>';
6282
6283 print '</tr>';
6284 }
6285 } else {
6286 print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
6287 }
6288
6289 print '</table>';
6290 print '</div>';
6291
6292 print '</form>';
6293 } else {
6294 $fullpathoffile = dol_buildpath($file, 0);
6295
6296 $content = file_get_contents($fullpathoffile);
6297
6298 // New module
6299 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6300 print '<input type="hidden" name="token" value="'.newToken().'">';
6301 print '<input type="hidden" name="action" value="savefile">';
6302 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6303 print '<input type="hidden" name="tab" value="'.$tab.'">';
6304 print '<input type="hidden" name="module" value="'.$module.'">';
6305
6306 $posCursor = (empty($find)) ? array() : array('find'=>$find);
6307 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
6308 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6309 print '<br>';
6310 print '<center>';
6311 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6312 print ' &nbsp; ';
6313 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6314 print '</center>';
6315
6316 print '</form>';
6317 }
6318 }
6319
6320 if ($tab == 'specifications') {
6321 print '<!-- tab=specifications -->'."\n";
6322 $specs = dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/'));
6323
6324 if ($action != 'editfile' || empty($file)) {
6325 print '<span class="opacitymedium">'.$langs->trans("SpecDefDesc").'</span><br>';
6326 print '<br>';
6327
6328 print '<table>';
6329 if (is_array($specs) && !empty($specs)) {
6330 foreach ($specs as $spec) {
6331 $pathtofile = $modulelowercase.'/doc/'.$spec['relativename'];
6332 $format = 'asciidoc';
6333 if (preg_match('/\.md$/i', $spec['name'])) {
6334 $format = 'markdown';
6335 }
6336 print '<tr><td>';
6337 print '<span class="fa fa-file-o"></span> '.$langs->trans("SpecificationFile").' : <strong class="wordbreak">'.$pathtofile.'</strong>';
6338 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>';
6339 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>';
6340 print '</tr>';
6341 }
6342 } else {
6343 print '<tr><td>';
6344 print '<span class="fa fa-file-o"></span> '.$langs->trans("SpecificationFile").' : <span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6345 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>';
6346 print '</tr>';
6347 }
6348 print '</table>';
6349 } else {
6350 // Use MD or asciidoc
6351
6352 //print $langs->trans("UseAsciiDocFormat").'<br>';
6353
6354 $fullpathoffile = dol_buildpath($file, 0);
6355
6356 $content = file_get_contents($fullpathoffile);
6357
6358 // New module
6359 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6360 print '<input type="hidden" name="token" value="'.newToken().'">';
6361 print '<input type="hidden" name="action" value="savefile">';
6362 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6363 print '<input type="hidden" name="tab" value="'.$tab.'">';
6364 print '<input type="hidden" name="module" value="'.$module.'">';
6365
6366 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%');
6367 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6368 print '<br>';
6369 print '<center>';
6370 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6371 print ' &nbsp; ';
6372 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6373 print '</center>';
6374
6375 print '</form>';
6376 }
6377
6378 print '<br><br><br>';
6379
6380 $FILENAMEDOC = $modulelowercase.'.html';
6381 $FILENAMEDOCPDF = $modulelowercase.'.pdf';
6382 $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC;
6383 $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC;
6384 $outputfiledocrel = $modulelowercase.'/doc/'.$FILENAMEDOC;
6385 $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF;
6386 $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF;
6387 $outputfiledocrelpdf = $modulelowercase.'/doc/'.$FILENAMEDOCPDF;
6388
6389 // HTML
6390 print '<span class="fa fa-file-o"></span> '.$langs->trans("PathToModuleDocumentation", "HTML").' : ';
6391 if (!dol_is_file($outputfiledoc)) {
6392 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6393 } else {
6394 print '<strong>';
6395 print '<a href="'.$outputfiledocurl.'" target="_blank" rel="noopener noreferrer">';
6396 print $outputfiledoc;
6397 print '</a>';
6398 print '</strong>';
6399 print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledoc), 'dayhour').')</span>';
6400 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>';
6401 }
6402 print '</strong><br>';
6403
6404 // PDF
6405 print '<span class="fa fa-file-o"></span> '.$langs->trans("PathToModuleDocumentation", "PDF").' : ';
6406 if (!dol_is_file($outputfiledocpdf)) {
6407 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6408 } else {
6409 print '<strong>';
6410 print '<a href="'.$outputfiledocurlpdf.'" target="_blank" rel="noopener noreferrer">';
6411 print $outputfiledocpdf;
6412 print '</a>';
6413 print '</strong>';
6414 print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledocpdf), 'dayhour').')</span>';
6415 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>';
6416 }
6417 print '</strong><br>';
6418
6419 print '<br>';
6420
6421 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="generatedoc">';
6422 print '<input type="hidden" name="token" value="'.newToken().'">';
6423 print '<input type="hidden" name="action" value="generatedoc">';
6424 print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
6425 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
6426 print '<input type="submit" class="button" name="generatedoc" value="'.$langs->trans("BuildDocumentation").'"';
6427 if (!is_array($specs) || empty($specs)) {
6428 print ' disabled="disabled"';
6429 }
6430 print '>';
6431 print '</form>';
6432 }
6433
6434 if ($tab == 'buildpackage') {
6435 print '<!-- tab=buildpackage -->'."\n";
6436 print '<span class="opacitymedium">'.$langs->trans("BuildPackageDesc").'</span>';
6437 print '<br>';
6438
6439 if (!class_exists('ZipArchive') && !defined('ODTPHP_PATHTOPCLZIP')) {
6440 print img_warning().' '.$langs->trans("ErrNoZipEngine");
6441 print '<br>';
6442 }
6443
6444 $modulelowercase = strtolower($module);
6445
6446 // Zip file to build
6447 $FILENAMEZIP = '';
6448
6449 // Load module
6450 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6451 dol_include_once($pathtofile);
6452 $class = 'mod'.$module;
6453
6454 if (class_exists($class)) {
6455 try {
6456 $moduleobj = new $class($db);
6457 } catch (Exception $e) {
6458 $error++;
6459 dol_print_error($db, $e->getMessage());
6460 }
6461 } else {
6462 $error++;
6463 $langs->load("errors");
6464 dol_print_error($db, $langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module));
6465 exit;
6466 }
6467
6468 $arrayversion = explode('.', $moduleobj->version, 3);
6469 if (count($arrayversion)) {
6470 $FILENAMEZIP = "module_".$modulelowercase.'-'.$arrayversion[0].(empty($arrayversion[1]) ? '.0' : '.'.$arrayversion[1]).(empty($arrayversion[2]) ? '' : ".".$arrayversion[2]).".zip";
6471 $outputfilezip = dol_buildpath($modulelowercase, 0).'/bin/'.$FILENAMEZIP;
6472 }
6473
6474 print '<br>';
6475
6476 print '<span class="fa fa-file-o"></span> '.$langs->trans("PathToModulePackage").' : ';
6477 if (!dol_is_file($outputfilezip)) {
6478 print '<span class="opacitymedium">'.$langs->trans("FileNotYetGenerated").'</span>';
6479 } else {
6480 $relativepath = $modulelowercase.'/bin/'.$FILENAMEZIP;
6481 print '<strong><a href="'.DOL_URL_ROOT.'/document.php?modulepart=packages&file='.urlencode($relativepath).'">'.$outputfilezip.'</a></strong>';
6482 print ' <span class="opacitymedium">('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfilezip), 'dayhour').')</span>';
6483 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>';
6484 }
6485 print '</strong>';
6486
6487 print '<br>';
6488
6489 print '<br>';
6490
6491 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="generatepackage">';
6492 print '<input type="hidden" name="token" value="'.newToken().'">';
6493 print '<input type="hidden" name="action" value="generatepackage">';
6494 print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
6495 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
6496 print '<input type="submit" class="button" name="generatepackage" value="'.$langs->trans("BuildPackage").'">';
6497 print '</form>';
6498 }
6499
6500 if ($tab == 'tabs') {
6501 $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
6502
6503 $tabs = $moduleobj->tabs;
6504
6505 if ($action != 'editfile' || empty($file)) {
6506 print '<span class="opacitymedium">';
6507 $htmlhelp = $langs->trans("TabsDefDescTooltip", '{s1}');
6508 $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);
6509 print $form->textwithpicto($langs->trans("TabsDefDesc"), $htmlhelp, 1, 'help', '', 0, 2, 'helpondesc').'<br>';
6510 print '</span>';
6511 print '<br>';
6512
6513 print '<span class="fa fa-file-o"></span> '.$langs->trans("DescriptorFile").' : <strong>'.$pathtofile.'</strong>';
6514 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>';
6515 print '<br>';
6516
6517 print '<br>';
6518 print load_fiche_titre($langs->trans("ListOfTabsEntries"), '', '');
6519
6520 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6521 print '<input type="hidden" name="token" value="'.newToken().'">';
6522 print '<input type="hidden" name="action" value="addproperty">';
6523 print '<input type="hidden" name="tab" value="objects">';
6524 print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
6525 print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
6526
6527 print '<div class="div-table-responsive">';
6528 print '<table class="noborder small">';
6529
6530 print '<tr class="liste_titre">';
6531 print_liste_field_titre("ObjectType", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6532 print_liste_field_titre("Tab", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6533 print_liste_field_titre("Title", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6534 print_liste_field_titre("LangFile", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6535 print_liste_field_titre("Condition", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6536 print_liste_field_titre("Path", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
6537 print "</tr>\n";
6538
6539 if (count($tabs)) {
6540 foreach ($tabs as $tab) {
6541 $parts = explode(':', $tab['data']);
6542
6543 $objectType = $parts[0];
6544 $tabName = $parts[1];
6545 $tabTitle = isset($parts[2]) ? $parts[2] : '';
6546 $langFile = isset($parts[3]) ? $parts[3] : '';
6547 $condition = isset($parts[4]) ? $parts[4] : '';
6548 $path = isset($parts[5]) ? $parts[5] : '';
6549
6550 // If we want to remove the tab, then the format is 'objecttype:tabname:optionalcondition'
6551 // See: https://wiki.dolibarr.org/index.php?title=Tabs_system#To_remove_an_existing_tab
6552 if ($tabName[0] === '-') {
6553 $tabTitle = '';
6554 $condition = isset($parts[2]) ? $parts[2] : '';
6555 }
6556
6557 print '<tr class="oddeven">';
6558
6559 print '<td>';
6560 print dol_escape_htmltag($parts[0]);
6561 print '</td>';
6562
6563 print '<td>';
6564 if ($tabName[0] === "+") {
6565 print '<span class="badge badge-status4 badge-status">' . dol_escape_htmltag($tabName) . '</span>';
6566 } else {
6567 print '<span class="badge badge-status8 badge-status">' . dol_escape_htmltag($tabName) . '</span>';
6568 }
6569 print '</td>';
6570
6571 print '<td>';
6572 print dol_escape_htmltag($tabTitle);
6573 print '</td>';
6574
6575 print '<td>';
6576 print dol_escape_htmltag($langFile);
6577 print '</td>';
6578
6579 print '<td>';
6580 print dol_escape_htmltag($condition);
6581 print '</td>';
6582
6583 print '<td>';
6584 print dol_escape_htmltag($path);
6585 print '</td>';
6586
6587 print '</tr>';
6588 }
6589 } else {
6590 print '<tr><td colspan="5"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
6591 }
6592
6593 print '</table>';
6594 print '</div>';
6595
6596 print '</form>';
6597 } else {
6598 $fullpathoffile = dol_buildpath($file, 0);
6599
6600 $content = file_get_contents($fullpathoffile);
6601
6602 // New module
6603 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
6604 print '<input type="hidden" name="token" value="'.newToken().'">';
6605 print '<input type="hidden" name="action" value="savefile">';
6606 print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
6607 print '<input type="hidden" name="tab" value="'.$tab.'">';
6608 print '<input type="hidden" name="module" value="'.$module.'">';
6609
6610 $posCursor = (empty($find)) ? array() : array('find'=>$find);
6611 $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%', 0, $posCursor);
6612 print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html'));
6613 print '<br>';
6614 print '<center>';
6615 print '<input type="submit" class="button buttonforacesave button-save" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
6616 print ' &nbsp; ';
6617 print '<input type="submit" class="button button-cancel" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
6618 print '</center>';
6619
6620 print '</form>';
6621 }
6622 }
6623
6624 if ($tab != 'description') {
6625 print dol_get_fiche_end();
6626 }
6627 }
6628}
6629
6630print dol_get_fiche_end(); // End modules
6631
6632
6633// End of page
6634llxFooter();
6635$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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:456
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:70
print $object position
Definition edit.php:195
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.
llxFooter()
Footer empty.
Definition document.php:107
dol_filemtime($pathoffile)
Return time of a file.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
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).
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.
dolExplodeIntoArray($string, $delimiter=';', $kv='=')
Split a string with 2 keys into key array.
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.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
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.
getDolGlobalString($key, $default='')
Return 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.
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)
Creates 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:143
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:139
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:142
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.