diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php
index 8262e315540..d7dce8613db 100644
--- a/htdocs/core/class/interfaces.class.php
+++ b/htdocs/core/class/interfaces.class.php
@@ -262,6 +262,8 @@ class Interfaces
{
if (is_readable($newdir.'/'.$file) && preg_match('/^interface_([0-9]+)_([^_]+)_(.+)\.class\.php/',$file,$reg))
{
+ if (preg_match('/\.back$/',$file)) continue;
+
$part1=$reg[1];
$part2=$reg[2];
$part3=$reg[3];
diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php
index 32ad3283d44..71f834a56d7 100644
--- a/htdocs/core/modules/DolibarrModules.class.php
+++ b/htdocs/core/modules/DolibarrModules.class.php
@@ -617,7 +617,8 @@ class DolibarrModules // Can not be abstract, because we need to insta
* Gives the long description of a module. First check README-la_LA.md then README.md
* If not markdown files found, it return translated value of the key ->descriptionlong.
*
- * @return string Long description of a module
+ * @param int $checkonly
+ * @return string Long description of a module from README of from property.
*/
function getDescLong()
{
@@ -627,25 +628,9 @@ class DolibarrModules // Can not be abstract, because we need to insta
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
- $filefound= false;
+ $pathoffile = $this->getDescLongReadmeFound();
- // Define path to file README.md.
- // First check README-la_LA.md then README.md
- $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$langs->defaultlang.'.md', 0);
- if (dol_is_file($pathoffile))
- {
- $filefound = true;
- }
- if (! $filefound)
- {
- $pathoffile = dol_buildpath(strtolower($this->name).'/README.md', 0);
- if (dol_is_file($pathoffile))
- {
- $filefound = true;
- }
- }
-
- if ($filefound) // Mostly for external modules
+ if ($pathoffile) // Mostly for external modules
{
$content = file_get_contents($pathoffile);
@@ -683,6 +668,35 @@ class DolibarrModules // Can not be abstract, because we need to insta
return $content;
}
+ /**
+ * Return path of file if a README file was found.
+ *
+ * @return string Path of file if a README file was found.
+ */
+ function getDescLongReadmeFound()
+ {
+ $filefound= false;
+
+ // Define path to file README.md.
+ // First check README-la_LA.md then README.md
+ $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$langs->defaultlang.'.md', 0);
+ if (dol_is_file($pathoffile))
+ {
+ $filefound = true;
+ }
+ if (! $filefound)
+ {
+ $pathoffile = dol_buildpath(strtolower($this->name).'/README.md', 0);
+ if (dol_is_file($pathoffile))
+ {
+ $filefound = true;
+ }
+ }
+
+ return ($filefound?$pathoffile:'');
+ }
+
+
/**
* Gives the changelog. First check ChangeLog-la_LA.md then ChangeLog.md
*
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 8b1c0df7f40..58028423a35 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -72,8 +72,10 @@ SeeHere=See here
Apply=Apply
BackgroundColorByDefault=Default background color
FileRenamed=The file was successfully renamed
-FileUploaded=The file was successfully uploaded
FileGenerated=The file was successfully generated
+FileSaved=The file was successfully saved
+FileUploaded=The file was successfully uploaded
+FileTransferComplete=File(s) was uploaded successfuly
FileWasNotUploaded=A file is selected for attachment but was not yet uploaded. Click on "Attach file" for this.
NbOfEntries=Nb of entries
GoToWikiHelpPage=Read online help (Internet access needed)
@@ -519,7 +521,6 @@ MonthShort10=Oct
MonthShort11=Nov
MonthShort12=Dec
AttachedFiles=Attached files and documents
-FileTransferComplete=File was uploaded successfuly
DateFormatYYYYMM=YYYY-MM
DateFormatYYYYMMDD=YYYY-MM-DD
DateFormatYYYYMMDDHHMM=YYYY-MM-DD HH:SS
diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
index 4037b727ee4..2547b893055 100644
--- a/htdocs/modulebuilder/index.php
+++ b/htdocs/modulebuilder/index.php
@@ -20,6 +20,8 @@
* \brief Home page for module builder module
*/
+if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
+
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
@@ -30,6 +32,7 @@ $langs->load("other");
$action=GETPOST('action','aZ09');
$confirm=GETPOST('confirm','alpha');
+$cancel=GETPOST('cancel','alpha');
$module=GETPOST('module','alpha');
$tab=GETPOST('tab','aZ09');
@@ -375,26 +378,42 @@ if ($dirins && $action == 'generatepackage')
}
}
-if ($action == 'savefile')
+
+// Save file
+if ($action == 'savefile' && empty($cancel))
{
- $pathoftrigger=dol_buildpath($file, 0);
- $pathoftriggerbackup=dol_buildpath($file.'.back', 0);
+ $relofcustom = basename($dirins);
- dol_move($pathoftrigger, $pathoftriggerbackup, 0, 1, 0, 0);
-
- $content = GETPOST('triggerfilecontent');
-
- // Save file on disk
- $newmask = 0;
-
- file_put_contents($pathoftrigger, $content);
- if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
- if (empty($newmask)) // This should no happen
+ if ($relofcustom)
{
- $newmask='0664';
- }
+ // Check that relative path ($file) start with name 'custom'
+ if (! preg_match('/^'.$relofcustom.'/', $file)) $file=$relofcustom.'/'.$file;
- @chmod($pathoftrigger, octdec($newmask));
+ $pathoffile=dol_buildpath($file, 0);
+ $pathoffilebackup=dol_buildpath($file.'.back', 0);
+
+ // Save old version
+ if (dol_is_file($pathoffile))
+ {
+ dol_move($pathoffile, $pathoffilebackup, 0, 1, 0, 0);
+ }
+
+ $content = GETPOST('editfilecontent');
+
+ // Save file on disk
+ $newmask = 0;
+
+ file_put_contents($pathoffile, $content);
+ if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
+ if (empty($newmask)) // This should no happen
+ {
+ $newmask='0664';
+ }
+
+ @chmod($pathoffile, octdec($newmask));
+
+ setEventMessages($langs->trans("FileSaved"), null);
+ }
}
@@ -438,7 +457,7 @@ if (!empty($conf->modulebuilder->enabled) && $mainmenu == 'modulebuilder') // En
if (dol_is_file($fullname.'/'.$FILEFLAG))
{
// Get real name of module (MyModule instead of mymodule)
- $descriptorfiles = dol_dir_list($fullname.'/core/modules/', 'files', 0, 'mod.*\.class\.php');
+ $descriptorfiles = dol_dir_list($fullname.'/core/modules/', 'files', 0, 'mod.*\.class\.php$');
$modulenamewithcase='';
foreach($descriptorfiles as $descriptorcursor)
{
@@ -654,80 +673,155 @@ elseif (! empty($module))
if ($tab == 'description')
{
$pathtofile = $modulelowercase.'/core/modules/mod'.$module.'.class.php';
+ $pathtofilereadme = $modulelowercase.'/README.md';
- print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.'
';
- print '
';
+ if ($action != 'editfile' || empty($file))
+ {
+ print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.'';
+ print ' '.img_picto($langs->trans("Edit"), 'edit').'';
+ print '
';
- print '
| '; - print $langs->trans("Parameter"); - print ' | '; - print $langs->trans("Value"); - print ' |
| '; - print $langs->trans("Numero"); - print ' ('.$langs->trans("SeeHere").')'; - print ' | '; - print $moduleobj->numero; - print ' |
| '; - print $langs->trans("Name"); - print ' | '; - print $moduleobj->getName(); - print ' |
| '; - print $langs->trans("Version"); - print ' | '; - print $moduleobj->getVersion(); - print ' |
| '; + print $langs->trans("Parameter"); + print ' | '; + print $langs->trans("Value"); + print ' |
| ';
- print $langs->trans("Family");
- //print " 'crm','financial','hr','projects','products','ecm','technic','interface','other'"; - print ' | '; - print $moduleobj->family; - print ' |
| '; + print $langs->trans("Numero"); + print ' ('.$langs->trans("SeeHere").')'; + print ' | '; + print $moduleobj->numero; + print ' |
| '; - print $langs->trans("EditorName"); - print ' | '; - print $moduleobj->editor_name; - print ' |
| '; + print $langs->trans("Name"); + print ' | '; + print $moduleobj->getName(); + print ' |
| '; - print $langs->trans("EditorUrl"); - print ' | '; - print $moduleobj->editor_url; - print ' |
| '; + print $langs->trans("Version"); + print ' | '; + print $moduleobj->getVersion(); + print ' |
| '; - print $langs->trans("Description"); - print ' | '; - print $moduleobj->getDesc(); - print ' |
| ';
+ print $langs->trans("Family");
+ //print " 'crm','financial','hr','projects','products','ecm','technic','interface','other'"; + print ' | '; + print $moduleobj->family; + print ' |
| '; - print $langs->trans("DescriptionLong"); - print ' | '; - print $moduleobj->getDescLong(); - print ' |
| '; + print $langs->trans("EditorName"); + print ' | '; + print $moduleobj->editor_name; + print ' |
| '.$langs->trans("File").' | -'.$langs->trans("Active").' | -- | - | |
| '.$trigger['picto'].' | '; - print ''.$trigger['relpath'].' | '; - print ''.(empty($trigger['status'])?$langs->trans("No"):$trigger['status']).' | '; - print '';
- $text=$trigger['info'];
- $text.=" \n".$langs->trans("File").": \n".$trigger['relpath']; - //$text.="\n".$langs->trans("ExternalModule",$trigger['isocreorexternal']); - print $form->textwithpicto('', $text); - print ' | ';
- print ''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ' | '; - print '