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