Continue work started on module builder

This commit is contained in:
Laurent Destailleur 2017-06-18 12:30:18 +02:00
parent 862b12abfd
commit 787d6946b2
5 changed files with 294 additions and 151 deletions

View File

@ -1,24 +1,25 @@
# Dolibarr language file - Source file is en_US - loan
ModuleBuilderDesc=This tools give you utilites to build or edit your own module.
ModuleBuilderDesc=This tools give you utilites to build or edit your own module (<a href="%s" target="_blank">More information here</a>).
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...)
ModuleBuilderDesc2=Path were modules are generated/edited (first alternative directory defined into %s): <strong>%s</strong>
ModuleBuilderDesc3=Generated/editable modules found: <strong>%s</strong> (they are detected as editable when the file <strong>%s</strong> exists in root of module directory).
NewModule=New module
NewObject=New object
ModuleKey=Key for new module
ObjectKey=Key for new object
ModuleKey=Module key
ObjectKey=Object key
ModuleInitialized=Module initialized
FilesForObjectInitialized=Files for new object initialized
ModuleBuilderDescdescription=Enter here all general information that describe your module
ModuleBuilderDescobjects=Define here the new objects you want to manage with your module. A page to list them and a page to create/edit/view a card will be generated.
ModuleBuilderDescobjects=Define here the objects you want to manage with your module. A sql file, a page to list them, to create/edit/view a card and an API will be generated.
ModuleBuilderDescmenus=This tab is dedicated to define menu entries provided by your module.
ModuleBuilderDescpermissions=This tab is dedicated to define the new permissions you want to provide with your module.
ModuleBuilderDesctriggers=This is the view of triggers provided by your module. To include code executed when a triggered business event is launched, just edit this file with your IDE.
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. Just click on button to build the module package file.
ModuleBuilderDescdangerzone=You can delete your module. WARNING: All files of module will be definetly lost !
EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: All files of module will be definitly lost !
EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All files related to object will be definitly lost !
DangerZone=Danger zone
BuildPackage=Build package
ModuleIsNotActive=This module was not activated yet (go into Home-Setup-Module to make it live)
@ -31,4 +32,5 @@ ClassFile=File for PHP class
ApiClassFile=File for PHP API class
PageForList=PHP page for list of record
PageForCreateEditView=PHP page to create/edit/view a record
PathToModulePackage=Path to zip of module/application package
PathToModulePackage=Path to zip of module/application package
SpaceOrSpecialCharAreNotAllowed=Spaces or special characters are not allowed.

View File

@ -58,41 +58,50 @@ $FILEFLAG='modulebuilder.txt';
if ($dirins && $action == 'initmodule' && $modulename)
{
$srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
$destdir = $dirins.'/'.strtolower($modulename);
$arrayreplacement=array(
'mymodule'=>strtolower($modulename),
'MyModule'=>$modulename
);
$result = dolCopyDir($srcdir, $destdir, 0, 0, $arrayreplacement);
//dol_mkdir($destfile);
if ($result <= 0)
if (preg_match('/\s/', $modulename))
{
if ($result < 0)
{
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorFailToCopyDir", $srcdir, $destdir), null, 'errors');
}
else // $result == 0
{
setEventMessages($langs->trans("AllFilesDidAlreadyExist", $srcdir, $destdir), null, 'warnings');
}
$error++;
setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
}
// Delete some files
dol_delete_file($destdir.'/myobject_card.php');
dol_delete_file($destdir.'/myobject_list.php');
dol_delete_file($destdir.'/test/phpunit/MyObjectTest.php');
dol_delete_file($destdir.'/sql/llx_myobject.key.sql');
dol_delete_file($destdir.'/sql/llx_myobject.sql');
dol_delete_file($destdir.'/scripts/myobject.php');
dol_delete_file($destdir.'/img/object_myobject.png');
dol_delete_file($destdir.'/class/myobject.class.php');
dol_delete_file($destdir.'/class/api_myobject.class.php');
dol_delete_file($destdir.'/class/MyObject.txt');
if (! $error)
{
$srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
$destdir = $dirins.'/'.strtolower($modulename);
$arrayreplacement=array(
'mymodule'=>strtolower($modulename),
'MyModule'=>$modulename
);
$result = dolCopyDir($srcdir, $destdir, 0, 0, $arrayreplacement);
//dol_mkdir($destfile);
if ($result <= 0)
{
if ($result < 0)
{
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorFailToCopyDir", $srcdir, $destdir), null, 'errors');
}
else // $result == 0
{
setEventMessages($langs->trans("AllFilesDidAlreadyExist", $srcdir, $destdir), null, 'warnings');
}
}
// Delete some files
dol_delete_file($destdir.'/myobject_card.php');
dol_delete_file($destdir.'/myobject_list.php');
dol_delete_file($destdir.'/test/phpunit/MyObjectTest.php');
dol_delete_file($destdir.'/sql/llx_myobject.key.sql');
dol_delete_file($destdir.'/sql/llx_myobject.sql');
dol_delete_file($destdir.'/scripts/myobject.php');
dol_delete_file($destdir.'/img/object_myobject.png');
dol_delete_file($destdir.'/class/myobject.class.php');
dol_delete_file($destdir.'/class/api_myobject.class.php');
dol_delete_file($destdir.'/class/MyObject.txt');
}
// Edit PHP files
if (! $error)
@ -129,74 +138,86 @@ if ($dirins && $action == 'initmodule' && $modulename)
if ($dirins && $action == 'initobject' && $module && $objectname)
{
$srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
$destdir = $dirins.'/'.strtolower($module);
$arrayreplacement=array(
'mymodule'=>strtolower($module),
'MyModule'=>$module,
'myobject'=>strtolower($objectname),
'MyObject'=>$objectname
);
// Delete some files
$filetogenerate = array(
'myobject_card.php'=>strtolower($objectname).'_card.php',
'myobject_list.php'=>strtolower($objectname).'_list.php',
'test/phpunit/MyObjectTest.php'=>'test/phpunit/'.$objectname.'Test.php',
'sql/llx_myobject.key.sql'=>'sql/llx_'.strtolower($objectname).'.key.sql',
'sql/llx_myobject.sql'=>'sql/llx_'.strtolower($objectname).'.sql',
'scripts/myobject.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_myobject.class.php'=>'class/api_'.strtolower($objectname).'.class.php',
'class/MyObject.txt'=>'class/'.$objectname.'.txt'
);
foreach($filetogenerate as $srcfile => $destfile)
if (preg_match('/\s/', $objectname))
{
$result = dol_copy($srcdir.'/'.$srcfile, $destdir.'/'.$destfile);
if ($result <= 0)
{
if ($result < 0)
{
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorFailToCopyFile", $srcdir.'/'.$srcfile, $destdir.'/'.$destfile), null, 'errors');
}
else // $result == 0
{
setEventMessages($langs->trans("FileAlreadyExists", $srcdir.'/'.$srcfile, $destdir.'/'.$destfile), null, 'warnings');
}
}
else
{
// Copy is ok
}
$error++;
setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
}
// Edit PHP files
foreach($filetogenerate as $destfile)
if (! $error)
{
$phpfileval['fullname'] = $destdir.'/'.$destfile;
$srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template';
$destdir = $dirins.'/'.strtolower($module);
//var_dump($phpfileval['fullname']);
$arrayreplacement=array(
'mymodule'=>strtolower($modulename),
'MyModule'=>$modulename,
'MYMODULE'=>strtoupper($modulename),
'My module'=>$modulename,
'htdocs/modulebuilder/template/'=>'',
'mymodule'=>strtolower($module),
'MyModule'=>$module,
'myobject'=>strtolower($objectname),
'MyObject'=>$objectname
);
$result=dolReplaceInFile($phpfileval['fullname'], $arrayreplacement);
//var_dump($result);
if ($result < 0)
// Delete some files
$filetogenerate = array(
'myobject_card.php'=>strtolower($objectname).'_card.php',
'myobject_list.php'=>strtolower($objectname).'_list.php',
'test/phpunit/MyObjectTest.php'=>'test/phpunit/'.$objectname.'Test.php',
'sql/llx_myobject.key.sql'=>'sql/llx_'.strtolower($objectname).'.key.sql',
'sql/llx_myobject.sql'=>'sql/llx_'.strtolower($objectname).'.sql',
'scripts/myobject.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_myobject.class.php'=>'class/api_'.strtolower($objectname).'.class.php',
'class/MyObject.txt'=>'class/'.$objectname.'.txt'
);
foreach($filetogenerate as $srcfile => $destfile)
{
setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
$result = dol_copy($srcdir.'/'.$srcfile, $destdir.'/'.$destfile);
if ($result <= 0)
{
if ($result < 0)
{
$error++;
$langs->load("errors");
setEventMessages($langs->trans("ErrorFailToCopyFile", $srcdir.'/'.$srcfile, $destdir.'/'.$destfile), null, 'errors');
}
else // $result == 0
{
setEventMessages($langs->trans("FileAlreadyExists", $srcdir.'/'.$srcfile, $destdir.'/'.$destfile), null, 'warnings');
}
}
else
{
// Copy is ok
}
}
}
if (! $error)
{
// Edit PHP files
foreach($filetogenerate as $destfile)
{
$phpfileval['fullname'] = $destdir.'/'.$destfile;
//var_dump($phpfileval['fullname']);
$arrayreplacement=array(
'mymodule'=>strtolower($modulename),
'MyModule'=>$modulename,
'MYMODULE'=>strtoupper($modulename),
'My module'=>$modulename,
'htdocs/modulebuilder/template/'=>'',
'myobject'=>strtolower($objectname),
'MyObject'=>$objectname
);
$result=dolReplaceInFile($phpfileval['fullname'], $arrayreplacement);
//var_dump($result);
if ($result < 0)
{
setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
}
}
}
@ -206,18 +227,90 @@ if ($dirins && $action == 'initobject' && $module && $objectname)
}
}
if ($dirins && $action == 'confirm_delete')
{
$modulelowercase=strtolower($module);
if (preg_match('/\s/', $module))
{
$error++;
setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
}
// Dir for module
$dir = $dirins.'/'.$modulelowercase;
if (! $error)
{
$modulelowercase=strtolower($module);
dol_delete_dir_recursive($dir);
// Dir for module
$dir = $dirins.'/'.$modulelowercase;
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?module=initmodule');
exit;
$result = dol_delete_dir_recursive($dir);
if ($result > 0)
{
setEventMessages($langs->trans("DirDeleted"), null);
}
else
{
setEventMessages($langs->trans("NothingDeleted"), null, 'warnings');
}
}
//header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?module=initmodule');
//exit;
$action = '';
$module = 'deletemodule';
}
if ($dirins && $action == 'confirm_deleteobject' && $objectname)
{
if (preg_match('/\s/', $objectname))
{
$error++;
setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
}
if (! $error)
{
$modulelowercase=strtolower($module);
$objectlowercase=strtolower($objectname);
// Dir for module
$dir = $dirins.'/'.$modulelowercase;
// Delete some files
$filetogenerate = array(
'myobject_card.php'=>strtolower($objectname).'_card.php',
'myobject_list.php'=>strtolower($objectname).'_list.php',
'test/phpunit/MyObjectTest.php'=>'test/phpunit/'.$objectname.'Test.php',
'sql/llx_myobject.key.sql'=>'sql/llx_'.strtolower($objectname).'.key.sql',
'sql/llx_myobject.sql'=>'sql/llx_'.strtolower($objectname).'.sql',
'scripts/myobject.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_myobject.class.php'=>'class/api_'.strtolower($objectname).'.class.php',
'class/MyObject.txt'=>'class/'.$objectname.'.txt'
);
$resultko = 0;
foreach($filetogenerate as $filetodelete)
{
$resulttmp = dol_delete_file($dir.'/'.$filetodelete, 0, 0, 1);
if (! $resulttmp) $resultko++;
}
if ($resultko == 0)
{
setEventMessages($langs->trans("FilesDeleted"), null);
}
else
{
setEventMessages($langs->trans("ErrorSomeFilesCouldNotBeDeleted"), null, 'warnings');
}
}
//header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?module=initmodule');
//exit;
$action = '';
$tabobj = 'deleteobject';
}
if ($dirins && $action == 'generatepackage')
@ -341,7 +434,7 @@ if (!empty($conf->modulebuilder->enabled) && $mainmenu == 'modulebuilder') // En
// Show description of content
$newdircustom=$dirins;
if (empty($newdircustom)) $newdircustom=img_warning();
print $langs->trans("ModuleBuilderDesc").'<br>';
print $langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'<br>';
print $langs->trans("ModuleBuilderDesc2", 'conf/conf.php', $newdircustom).'<br>';
$message='';
@ -381,7 +474,7 @@ print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'<br
$error=0;
$moduleobj = null;
if (! empty($module) && $module != 'initmodule')
if (! empty($module) && $module != 'initmodule' && $module != 'deletemodule')
{
$modulelowercase=strtolower($module);
@ -428,6 +521,10 @@ foreach($listofmodules as $tmpmodule => $tmpmodulewithcase)
$h++;
}
$head[$h][0] = $_SERVER["PHP_SELF"].'?module=deletemodule';
$head[$h][1] = $langs->trans("DangerZone");
$head[$h][2] = 'deletemodule';
$h++;
dol_fiche_head($head, $module, $langs->trans("Modules"), -1, 'generic');
@ -446,6 +543,19 @@ if ($module == 'initmodule')
print '<input type="submit" class="button" name="create" value="'.dol_escape_htmltag($langs->trans("Create")).'"'.($dirins?'':' disabled="disabled"').'>';
print '</form>';
}
elseif ($module == 'deletemodule')
{
print '<form name="delete">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="confirm_delete">';
print '<input type="hidden" name="module" value="deletemodule">';
print $langs->trans("EnterNameOfModuleToDeleteDesc").'<br><br>';
print '<input type="text" name="module" placeholder="'.dol_escape_htmltag($langs->trans("ModuleKey")).'" value="">';
print '<input type="submit" class="buttonDelete" value="'.$langs->trans("Delete").'"'.($dirins?'':' disabled="disabled"').'>';
print '</form>';
}
elseif (! empty($module))
{
// Tabs for module
@ -502,11 +612,6 @@ elseif (! empty($module))
$head2[$h][2] = 'buildpackage';
$h++;
$head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=dangerzone&module='.$module;
$head2[$h][1] = $langs->trans("DangerZone");
$head2[$h][2] = 'dangerzone';
$h++;
print $modulestatusinfo.'<br><br>';
dol_fiche_head($head2, $tab, '', -1, '');
@ -532,6 +637,7 @@ elseif (! empty($module))
print '<tr><td>';
print $langs->trans("Numero");
print ' (<a href="https://wiki.dolibarr.org/index.php/List_of_modules_id" target="_blank">'.$langs->trans("SeeHere").'</a>)';
print '</td><td>';
print $moduleobj->numero;
print '</td></tr>';
@ -608,6 +714,12 @@ elseif (! empty($module))
$h++;
}
$head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.'&tabobj=deleteobject';
$head3[$h][1] = $langs->trans("DangerZone");
$head3[$h][2] = 'deleteobject';
$h++;
dol_fiche_head($head3, $tabobj, '', -1, '');
if ($tabobj == 'newobject')
@ -625,6 +737,21 @@ elseif (! empty($module))
print '<input type="submit" class="button" name="create" value="'.dol_escape_htmltag($langs->trans("Create")).'"'.($dirins?'':' disabled="disabled"').'>';
print '</form>';
}
elseif ($tabobj == 'deleteobject')
{
// New module
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="confirm_deleteobject">';
print '<input type="hidden" name="tab" value="objects">';
print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
print $langs->trans("EnterNameOfObjectToDeleteDesc").'<br><br>';
print '<input type="text" name="objectname" value="'.dol_escape_htmltag($modulename).'" placeholder="'.dol_escape_htmltag($langs->trans("ObjectKey")).'">';
print '<input type="submit" class="buttonDelete" name="delete" value="'.dol_escape_htmltag($langs->trans("Delete")).'"'.($dirins?'':' disabled="disabled"').'>';
print '</form>';
}
else
{
try {
@ -641,8 +768,9 @@ elseif (! empty($module))
$tmpobjet = new $tabobj($db);
$reflector = new ReflectionClass($tabobj);
$properties = $reflector->getProperties();
$propdefault = $reflector->getDefaultProperties();
$properties = $reflector->getProperties(); // Can also use get_object_vars
$propdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars
//$propstat = $reflector->getStaticProperties();
print load_fiche_titre($langs->trans("Properties"), '', '');
@ -655,8 +783,10 @@ elseif (! empty($module))
print '<table class="noborder">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Property").'</td>';
print '<td>'.$langs->trans("Description").'</td>';
print '<td>'.$langs->trans("Property");
print ' (<a href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank">'.$langs->trans("Example").'</a>)';
print '</td>';
print '<td>'.$langs->trans("Comment").'</td>';
print '<td>'.$langs->trans("Type").'</td>';
print '<td>'.$langs->trans("DefaultValue").'</td>';
print '<td></td>';
@ -676,7 +806,7 @@ elseif (! empty($module))
$propname=$propval->getName();
// Discard generic properties
if (in_array($propname, array('element', 'table_element', 'table_element_line', 'class_element_line', 'ismultientitymanaged'))) continue;
if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue;
// Keep or not lines
if (in_array($propname, array('fk_element', 'lines'))) continue;
@ -686,11 +816,10 @@ elseif (! empty($module))
print $propname;
print '</td>';
print '<td>';
print $propval->getDocComment();
print '</td>';
print '<td>';
print gettype($tmpobjet->$propname);
print '</td>';
print '<td>';
@ -836,16 +965,6 @@ elseif (! empty($module))
print '</form>';
}
if ($tab == 'dangerzone')
{
print '<form name="delete">';
print '<input type="hidden" name="action" value="confirm_delete">';
print '<input type="hidden" name="tab" value="'.dol_escape_htmltag($tab).'">';
print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
print '<input type="submit" class="buttonDelete" value="'.$langs->trans("Delete").'"'.($dirins?'':' disabled="disabled"').'>';
print '</form>';
}
dol_fiche_end();
}
}

View File

@ -1 +1,2 @@
# If this file exists, it means the class and file for object MyOjbect was generated by ModuleBuilder.
# DO NOT DELETE THIS FILE MANUALLY
# If this file exists, it means the class and file for object MyOjbect was generated by ModuleBuilder. Use ModuleBuilder if you want to delete object.

View File

@ -36,43 +36,63 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
class MyObject extends CommonObject
{
/**
* @var string Id to identify managed object
* @var string ID to identify managed object
*/
public $element = 'myobject';
/**
* @var string Name of table without prefix where object is stored
*/
public $table_element = 'myobject';
/**
* @var array Array with all fields and their property
/**
* @var array Does this field is linked to a thirdparty ?
*/
protected $isnolinkedbythird=1;
/**
* @var array Does myobject support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
*/
protected $ismultientitymanaged = 1;
/**
* @var string String with name of icon for myobject
*/
public $picto = 'myobject';
/**
* @var array Array with all fields and their property
/**
* @var int Entity Id
*/
public $entity;
/**
* @var array Array with all fields and their property
*/
public $fields;
// If this object has a subtable with lines
/**
* @var mixed Sample property 1
* @var int Name of subtable line
*/
public $prop1;
//public $table_element_line = 'myobjectdet';
/**
* @var mixed Sample property 2
* @var int Field with ID of parent key if this field has a parent
*/
public $prop2;
//...
protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
public $table_element_line = 'myobjectdet';
public $class_element_line = 'MyObjectline';
public $fk_element = 'fk_myobject';
/**
* @var MyObjectLine[] Lines
//public $fk_element = 'fk_myobject';
/**
* @var int Name of subtable class that manage subtable lines
*/
public $lines = array();
//public $class_element_line = 'MyObjectline';
/**
* @var array Array of child tables (child tables to delete before deleting a record)
*/
//protected $childtables=array('myobjectdet');
/**
* @var MyObjectLine[] Array of subtable lines
*/
//public $lines = array();

View File

@ -1,2 +1,3 @@
File to flag module built using official module template.
When this file is present into a module directory, you can edit it with the module builder tool.
# DO NOT DELETE THIS FILE MANUALLY
# File to flag module built using official module template.
# When this file is present into a module directory, you can edit it with the module builder tool. Use ModuleBuilder if you want to delete module.