diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php
index df7054ca162..de5a1e75d0a 100644
--- a/htdocs/api/class/api.class.php
+++ b/htdocs/api/class/api.class.php
@@ -216,7 +216,7 @@ class DolibarrApi
*
* @param string $resource element to check
* @param int $resource_id Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional).
- * @param type $dbtablename 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity. Not used if objectid is null (optional)
+ * @param string $dbtablename 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity. Not used if objectid is null (optional)
* @param string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'.
* @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional)
* @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional)
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 3aec931714b..463cf828b29 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -855,7 +855,7 @@ Download=Download
DownloadDocument=Download document
ActualizeCurrency=Update currency rate
Fiscalyear=Fiscal year
-ModuleBuilder=Module Builder
+ModuleBuilder=Module and Application Builder
SetMultiCurrencyCode=Set currency
BulkActions=Bulk actions
ClickToShowHelp=Click to show tooltip help
diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang
index 8e2d57a03fc..5cb927dc8b7 100644
--- a/htdocs/langs/en_US/modulebuilder.lang
+++ b/htdocs/langs/en_US/modulebuilder.lang
@@ -1,5 +1,5 @@
# Dolibarr language file - Source file is en_US - loan
-ModuleBuilderDesc=This tool must be used only by experienced users or developers. It provides utilities to build or edit your own module.
Documentation for alternative manual development is here.
+ModuleBuilderDesc=This tool must be used only by experienced users or developers. It provides utilities to build or edit your own module. Documentation for alternative manual development is here.
EnterNameOfModuleDesc=Enter name of the module/application to create with no spaces. Use uppercase to separate words (For example: MyModule, EcommerceForShop, SyncWithMySystem...)
EnterNameOfObjectDesc=Enter name of the object to create with no spaces. Use uppercase to separate words (For example: MyObject, Student, Teacher...). The CRUD class file, but also API file, pages to list/add/edit/delete object and SQL files will be generated.
ModuleBuilderDesc2=Path where modules are generated/edited (first directory for external modules defined into %s): %s
@@ -21,13 +21,14 @@ ModuleBuilderDesctriggers=This is the view of triggers provided by your module.
ModuleBuilderDeschooks=This tab is dedicated to hooks.
ModuleBuilderDescwidgets=This tab is dedicated to manage/build widgets.
ModuleBuilderDescbuildpackage=You can generate here a "ready to distribute" package file (a normalized .zip file) of your module and a "ready to distribute" documentation file. Just click on button to build the package or documentation file.
-EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: ALL files of module AND structured data and documentation will be deleted!
-EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All files related to object will be deleted!
+EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: All coding files of module (generated or created manually) AND structured data and documentation will be deleted!
+EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All coding files (generated or created manually) related to object will be deleted!
DangerZone=Danger zone
BuildPackage=Build package
+BuildPackageDesc=You can generate a zip package or your application so your are ready to distribute it on any Dolibarr. You can also distribute it or sell it on marketplace like DoliStore.com.
BuildDocumentation=Build documentation
ModuleIsNotActive=This module is not activated yet. Go to %s to make it live or click here:
-ModuleIsLive=This module has been activated. Any change on it may break a current active feature.
+ModuleIsLive=This module has been activated. Any change may break a current live feature.
DescriptionLong=Long description
EditorName=Name of editor
EditorUrl=URL of editor
@@ -43,10 +44,11 @@ PathToModulePackage=Path to zip of module/application package
PathToModuleDocumentation=Path to file of module/application documentation (%s)
SpaceOrSpecialCharAreNotAllowed=Spaces or special characters are not allowed.
FileNotYetGenerated=File not yet generated
-RegenerateClassAndSql=Erase and regenerate class and sql files
+RegenerateClassAndSql=Force update of .class and .sql files
RegenerateMissingFiles=Generate missing files
SpecificationFile=File of documentation
LanguageFile=File for language
+ObjectProperties=Object Properties
ConfirmDeleteProperty=Are you sure you want to delete the property %s? This will change code in PHP class but also remove column from table definition of object.
NotNull=Not NULL
NotNullDesc=1=Set database to NOT NULL. -1=Allow null values and force value to NULL if empty ('' or 0).
@@ -62,7 +64,8 @@ ReadmeFile=Readme file
ChangeLog=ChangeLog file
TestClassFile=File for PHP Unit Test class
SqlFile=Sql file
-PageForLib=File for PHP libraries
+PageForLib=File for PHP library
+PageForObjLib=File for PHP library dedicated to object
SqlFileExtraFields=Sql file for complementary attributes
SqlFileKey=Sql file for keys
AnObjectAlreadyExistWithThisNameAndDiffCase=An object already exists with this name and a different case
@@ -81,8 +84,10 @@ IsAMeasureDesc=Can the value of field be cumulated to get a total into list? (Ex
SearchAllDesc=Is the field used to make a search from the quick search tool? (Examples: 1 or 0)
SpecDefDesc=Enter here all documentation you want to provide with your module that is not already defined by other tabs. You can use .md or better, the rich .asciidoc syntax.
LanguageDefDesc=Enter in this files, all the key and the translation for each language file.
-MenusDefDesc=Define here the menus provided by your module (once defined, they are visible into the menu editor %s)
-PermissionsDefDesc=Define here the new permissions provided by your module (once defined, they are visible into the default permissions setup %s)
+MenusDefDesc=Define here the menus provided by your module
+PermissionsDefDesc=Define here the new permissions provided by your module
+MenusDefDescTooltip=The menus provided by your module/application are defined into the array $this->menus into the module descriptor file. You can edit manually this file or use the embedded editor.
Note: Once defined (and module re-activated), menus are also visible into the menu editor available to administrator users on %s.
+PermissionsDefDescTooltip=The permissions provided by your module/application are defined into the array $this->rights into the module descriptor file. You can edit manually this file or use the embedded editor.
Note: Once defined (and module re-activated), permissions are visible into the default permissions setup %s.
HooksDefDesc=Define in the module_parts['hooks'] property, in the module descriptor, the context of hooks you want to manage (list of contexts can be found by a search on 'initHooks(' in core code).
Edit the hook file to add code of your hooked functions (hookable functions can be found by a search on 'executeHooks' in core code).
TriggerDefDesc=Define in the trigger file the code you want to execute for each business event executed.
SeeIDsInUse=See IDs in use in your installation
@@ -109,4 +114,5 @@ UseSpecificEditorName = Use a specific editor name
UseSpecificEditorURL = Use a specific editor URL
UseSpecificFamily = Use a specific family
UseSpecificAuthor = Use a specific author
-UseSpecificVersion = Use a specific initial version
\ No newline at end of file
+UseSpecificVersion = Use a specific initial version
+ModuleMustBeEnabled=The module/application must be enabled first
\ No newline at end of file
diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
index 0e80c0ba4ac..0ad297221be 100644
--- a/htdocs/modulebuilder/index.php
+++ b/htdocs/modulebuilder/index.php
@@ -156,8 +156,7 @@ if ($dirins && $action == 'initmodule' && $modulename)
dol_delete_file($destdir.'/scripts/'.strtolower($modulename).'.php');
dol_delete_dir($destdir.'/scripts');
-
- // Delete some files related to Object (because the dolCopyDir has copied everything)
+ // Delete some files related to Object (because the previous dolCopyDir has copied everything)
dol_delete_file($destdir.'/myobject_card.php');
dol_delete_file($destdir.'/myobject_note.php');
dol_delete_file($destdir.'/myobject_document.php');
@@ -222,6 +221,39 @@ if ($dirins && $action == 'initmodule' && $modulename)
}
}
+if ($dirins && $action == 'initapi' && !empty($module))
+{
+ dol_mkdir($dirins.'/'.strtolower($module).'/class');
+ $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
+ $srcfile = $srcdir.'/class/api_mymodule.class.php';
+ $destfile = $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php';
+ //var_dump($srcfile);var_dump($destfile);
+ $result = dol_copy($srcfile, $destfile, 0, 0);
+
+ if ($result > 0)
+ {
+ $modulename = ucfirst($module); // Force first letter in uppercase
+ $objectname = $tabobj;
+
+ //var_dump($phpfileval['fullname']);
+ $arrayreplacement=array(
+ 'mymodule'=>strtolower($modulename),
+ 'MyModule'=>$modulename,
+ 'MYMODULE'=>strtoupper($modulename),
+ 'My module'=>$modulename,
+ 'my module'=>$modulename,
+ 'Mon module'=>$modulename,
+ 'mon module'=>$modulename,
+ 'htdocs/modulebuilder/template'=>strtolower($modulename),
+ 'myobject'=>strtolower($objectname),
+ 'MyObject'=>$objectname,
+ 'MYOBJECT'=>strtoupper($objectname),
+ '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':'')
+ );
+
+ dolReplaceInFile($destfile, $arrayreplacement);
+ }
+}
if ($dirins && $action == 'inithook' && !empty($module))
{
dol_mkdir($dirins.'/'.strtolower($module).'/class');
@@ -230,6 +262,26 @@ if ($dirins && $action == 'inithook' && !empty($module))
$destfile = $dirins.'/'.strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
//var_dump($srcfile);var_dump($destfile);
$result = dol_copy($srcfile, $destfile, 0, 0);
+
+ if ($result > 0)
+ {
+ $modulename = ucfirst($module); // Force first letter in uppercase
+
+ //var_dump($phpfileval['fullname']);
+ $arrayreplacement=array(
+ 'mymodule'=>strtolower($modulename),
+ 'MyModule'=>$modulename,
+ 'MYMODULE'=>strtoupper($modulename),
+ 'My module'=>$modulename,
+ 'my module'=>$modulename,
+ 'Mon module'=>$modulename,
+ 'mon module'=>$modulename,
+ 'htdocs/modulebuilder/template'=>strtolower($modulename),
+ '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':'')
+ );
+
+ dolReplaceInFile($destfile, $arrayreplacement);
+ }
}
if ($dirins && $action == 'inittrigger' && !empty($module))
{
@@ -500,10 +552,10 @@ if ($dirins && $action == 'initobject' && $module && $objectname)
'sql/llx_mymodule_myobject.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql',
'sql/llx_mymodule_myobject_extrafields.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'_extrafields.sql',
'sql/llx_mymodule_myobject.key.sql'=>'sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql',
- 'scripts/myobject.php'=>'scripts/'.strtolower($objectname).'.php',
+ //'scripts/mymodule.php'=>'scripts/'.strtolower($objectname).'.php',
'img/object_myobject.png'=>'img/object_'.strtolower($objectname).'.png',
'class/myobject.class.php'=>'class/'.strtolower($objectname).'.class.php',
- 'class/api_mymodule.class.php'=>'class/api_'.strtolower($module).'.class.php'
+ //'class/api_mymodule.class.php'=>'class/api_'.strtolower($module).'.class.php'
);
foreach($filetogenerate as $srcfile => $destfile)
@@ -524,8 +576,8 @@ if ($dirins && $action == 'initobject' && $module && $objectname)
}
}
- if (! $error)
- {
+ //if (! $error) // If there is error copying 1 file, we still have to make the replacement
+ //{
// Scan for object class files
$listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$');
@@ -536,6 +588,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname)
if (preg_match('/^actions_/', $fileobj['name'])) continue;
$tmpcontent=file_get_contents($fileobj['fullname']);
+ $reg=array();
if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg))
{
$objectnameloop = $reg[1];
@@ -587,7 +640,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname)
// TODO
}
- }
+ //}
}
if (! $error)
@@ -730,11 +783,11 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj))
}
}
- if (GETPOST('regeneratemissing'))
+ /*if (GETPOST('regeneratemissing'))
{
setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings');
$error++;
- }
+ }*/
// Edit the class file to write properties
if (! $error)
@@ -760,7 +813,7 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj))
clearstatcache(true);
// Make a redirect to reload all data
- header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.'&tabobj='.$objectname.'&nocache='.time());
+ header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname.'&nocache='.time());
exit;
}
@@ -795,7 +848,7 @@ if ($dirins && $action == 'confirm_deleteproperty' && $propertykey)
clearstatcache(true);
// Make a redirect to reload all data
- header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.'&tabobj='.$objectname);
+ header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname);
exit;
}
@@ -1030,9 +1083,9 @@ if ($action == 'savefile' && empty($cancel))
if ($action == 'set' && $user->admin)
{
$param='';
- if ($module) $param.='&module='.$module;
- if ($tab) $param.='&tab='.$tab;
- if ($tabobj) $param.='&tabobj='.$tabobj;
+ if ($module) $param.='&module='.urlencode($module);
+ if ($tab) $param.='&tab='.urlencode($tab);
+ if ($tabobj) $param.='&tabobj='.urlencode($tabobj);
$value = GETPOST('value', 'alpha');
$resarray = activateModule($value);
@@ -1065,9 +1118,9 @@ if ($action == 'set' && $user->admin)
if ($action == 'reset' && $user->admin)
{
$param='';
- if ($module) $param.='&module='.$module;
- if ($tab) $param.='&tab='.$tab;
- if ($tabobj) $param.='&tabobj='.$tabobj;
+ if ($module) $param.='&module='.urlencode($module);
+ if ($tab) $param.='&tab='.urlencode($tab);
+ if ($tabobj) $param.='&tabobj='.urlencode($tabobj);
$value = GETPOST('value', 'alpha');
$result=unActivateModule($value);
@@ -1105,7 +1158,7 @@ $text=$langs->trans("ModuleBuilder");
print load_fiche_titre($text, '', 'title_setup');
-print $langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'
';
+print ''.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'
';
$dirsrootforscan=array($dirread);
if ($dirread != DOL_DOCUMENT_ROOT && $conf->global->MAIN_FEATURES_LEVEL >=2) { $dirsrootforscan[]=DOL_DOCUMENT_ROOT; }
@@ -1310,9 +1363,9 @@ elseif (! empty($module))
$const_name = 'MAIN_MODULE_'.strtoupper($module);
$param='';
- if ($tab) $param.= '&tab='.$tab;
- if ($module) $param.='&module='.$module;
- if ($tabobj) $param.='&tabobj='.$tabobj;
+ if ($tab) $param.='&tab='.urlencode($tab);
+ if ($module) $param.='&module='.urlencode($module);
+ if ($tabobj) $param.='&tabobj='.urlencode($tabobj);
$urltomodulesetup=''.$langs->trans('Home').'-'.$langs->trans("Setup").'-'.$langs->trans("Modules").'';
$linktoenabledisable='';
@@ -1595,8 +1648,8 @@ elseif (! empty($module))
{
$pathtofile = $modulelowercase.'/langs/'.$langfile['relativename'];
print '