NEW Can install an external module from admin pages, if web server has

permission for and if setup is ok for.
This commit is contained in:
Laurent Destailleur 2015-04-04 00:19:03 +02:00
parent 106a393054
commit 2ec5595277
4 changed files with 150 additions and 30 deletions

View File

@ -29,6 +29,8 @@ include_once DOL_DOCUMENT_ROOT . '/core/lib/geturl.lib.php';
$langs->load("admin"); $langs->load("admin");
$langs->load("other"); $langs->load("other");
$action=GETPOST('action','alpha');
if (! $user->admin) accessforbidden(); if (! $user->admin) accessforbidden();
if (GETPOST('msg','alpha')) { if (GETPOST('msg','alpha')) {
@ -43,14 +45,18 @@ $dolibarrroot=preg_replace('/([\\/]+)$/i','',DOL_DOCUMENT_ROOT);
$dolibarrroot=preg_replace('/([^\\/]+)$/i','',$dolibarrroot); $dolibarrroot=preg_replace('/([^\\/]+)$/i','',$dolibarrroot);
$dolibarrdataroot=preg_replace('/([\\/]+)$/i','',DOL_DATA_ROOT); $dolibarrdataroot=preg_replace('/([\\/]+)$/i','',DOL_DATA_ROOT);
$dirins=DOL_DOCUMENT_ROOT.'/custom';
/* /*
* Actions * Actions
*/ */
if (GETPOST('action','alpha')=='install') if ($action=='install')
{ {
$error=0; $error=0;
// $original_file should match format module_modulename-x.y[.z].zip
$original_file=basename($_FILES["fileinstall"]["name"]); $original_file=basename($_FILES["fileinstall"]["name"]);
$newfile=$conf->admin->dir_temp.'/'.$original_file.'/'.$original_file; $newfile=$conf->admin->dir_temp.'/'.$original_file.'/'.$original_file;
@ -72,33 +78,87 @@ if (GETPOST('action','alpha')=='install')
if (! $error) if (! $error)
{ {
@dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$original_file); if ($original_file)
dol_mkdir($conf->admin->dir_temp.'/'.$original_file); {
@dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$original_file);
dol_mkdir($conf->admin->dir_temp.'/'.$original_file);
}
$tmpdir=preg_replace('/\.zip$/','',$original_file).'.dir';
if ($tmpdir)
{
@dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$tmpdir);
dol_mkdir($conf->admin->dir_temp.'/'.$tmpdir);
}
$result=dol_move_uploaded_file($_FILES['fileinstall']['tmp_name'],$newfile,1,0,$_FILES['fileinstall']['error']); $result=dol_move_uploaded_file($_FILES['fileinstall']['tmp_name'],$newfile,1,0,$_FILES['fileinstall']['error']);
if ($result > 0) if ($result > 0)
{ {
$documentrootalt=DOL_DOCUMENT_ROOT.'/extensions'; $result=dol_uncompress($newfile,$conf->admin->dir_temp.'/'.$tmpdir);
$result=dol_uncompress($newfile,$documentrootalt);
if (! empty($result['error'])) if (! empty($result['error']))
{ {
$langs->load("errors"); $langs->load("errors");
setEventMessage($langs->trans($result['error'],$original_file), 'errors'); setEventMessage($langs->trans($result['error'],$original_file), 'errors');
$error++;
} }
else else
{ {
setEventMessage($langs->trans("SetupIsReadyForUse")); // Now we move the dir of the module
$modulename=preg_replace('/module_/', '', $original_file);
$modulename=preg_replace('/\-[\d]+\.[\d]+.*$/', '', $modulename);
// Search dir $modulename
$modulenamedir=$conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulename;
//var_dump($modulenamedir);
if (! dol_is_dir($modulenamedir))
{
$modulenamedir=$conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulename;
//var_dump($modulenamedir);
if (! dol_is_dir($modulenamedir))
{
setEventMessage($langs->trans("ErrorModuleFileSeemsToHaveAWrongFormat"), 'errors');
$error++;
}
}
if (! $error)
{
//var_dump($dirins);
@dol_delete_dir_recursive($dirins.'/'.$modulename);
$result=dolCopyDir($modulenamedir, $dirins.'/'.$modulename, '0444', 1);
if ($result <= 0)
{
setEventMessage($langs->trans("ErrorFailedToCopy"), 'errors');
$error++;
}
}
} }
} }
else
{
$error++;
}
}
if (! $error)
{
setEventMessage($langs->trans("SetupIsReadyForUse"));
} }
} }
/* /*
* View * View
*/ */
$dirins=DOL_DOCUMENT_ROOT.'/extensions';
$dirins_ok=(is_dir($dirins));
// Set dir where external modules are installed
if (! dol_is_dir($dirins))
{
dol_mkdir($dirins);
}
$dirins_ok=(dol_is_dir($dirins));
$wikihelp='EN:Installation_-_Upgrade|FR:Installation_-_Mise_à_jour|ES:Instalación_-_Actualización'; $wikihelp='EN:Installation_-_Upgrade|FR:Installation_-_Mise_à_jour|ES:Instalación_-_Actualización';
llxHeader('',$langs->trans("Upgrade"),$wikihelp); llxHeader('',$langs->trans("Upgrade"),$wikihelp);
@ -143,6 +203,8 @@ else
} }
print '<br>'; print '<br>';
// Upgrade
print $langs->trans("Upgrade").'<br>'; print $langs->trans("Upgrade").'<br>';
print '<hr>'; print '<hr>';
print $langs->trans("ThisIsProcessToFollow").'<br>'; print $langs->trans("ThisIsProcessToFollow").'<br>';
@ -162,20 +224,76 @@ print $langs->trans("RestoreLock",$dolibarrdataroot.'/install.lock').'<br>';
print '<br>'; print '<br>';
print '<br>'; print '<br>';
// Install external module
$allowonlineinstall=true;
$allowfromweb=1;
if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) $allowonlineinstall=false;
$fullurl='<a href="'.$urldolibarrmodules.'" target="_blank">'.$urldolibarrmodules.'</a>'; $fullurl='<a href="'.$urldolibarrmodules.'" target="_blank">'.$urldolibarrmodules.'</a>';
$message='';
if (! empty($allowonlineinstall))
{
if (! in_array('/custom',explode(',',$dolibarr_main_url_root_alt)))
{
$message=info_admin($langs->trans("ConfFileMuseContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT));
$allowfromweb=-1;
}
else
{
if ($dirins_ok)
{
if (! is_writable(dol_osencode($dirins)))
{
$langs->load("errors");
$message=info_admin($langs->trans("ErrorFailedToWriteInDir",$dirins));
$allowfromweb=0;
}
}
else
{
$message=info_admin($langs->trans("NotExistsDirect",$dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample"));
$allowfromweb=0;
}
}
}
else
{
$message=info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile",$dolibarrdataroot.'/installmodules.lock'));
$allowfromweb=0;
}
print $langs->trans("AddExtensionThemeModuleOrOther").'<br>'; print $langs->trans("AddExtensionThemeModuleOrOther").'<br>';
print '<hr>'; print '<hr>';
print $langs->trans("ThisIsProcessToFollow").'<br>';
print '<b>'.$langs->trans("StepNb",1).'</b>: '; if ($allowfromweb < 1)
print $langs->trans("FindPackageFromWebSite",$fullurl).'<br>';
print '<b>'.$langs->trans("StepNb",2).'</b>: ';
print $langs->trans("DownloadPackageFromWebSite",$fullurl).'<br>';
print '<b>'.$langs->trans("StepNb",3).'</b>: ';
print $langs->trans("UnpackPackageInDolibarrRoot",$dolibarrroot).'<br>';
if (! empty($conf->global->MAIN_ONLINE_INSTALL_MODULE))
{ {
if ($dirins_ok) print $langs->trans("SomethingMakeInstallFromWebNotPossible");
print $message;
//print $langs->trans("SomethingMakeInstallFromWebNotPossible2");
print '<br>';
}
if ($allowfromweb >= 0)
{
if ($allowfromweb == 1) print $langs->trans("ThisIsProcessToFollow").'<br>';
else print $langs->trans("ThisIsAlternativeProcessToFollow").'<br>';
print '<b>'.$langs->trans("StepNb",1).'</b>: ';
print $langs->trans("FindPackageFromWebSite",$fullurl).'<br>';
print '<b>'.$langs->trans("StepNb",2).'</b>: ';
print $langs->trans("DownloadPackageFromWebSite",$fullurl).'<br>';
print '<b>'.$langs->trans("StepNb",3).'</b>: ';
if ($allowfromweb == 1)
{ {
print $langs->trans("UnpackPackageInDolibarrRoot",$dirins).'<br>';
print '<form enctype="multipart/form-data" method="POST" class="noborder" action="'.$_SERVER["PHP_SELF"].'" name="forminstall">'; print '<form enctype="multipart/form-data" method="POST" class="noborder" action="'.$_SERVER["PHP_SELF"].'" name="forminstall">';
print '<input type="hidden" name="action" value="install">'; print '<input type="hidden" name="action" value="install">';
print $langs->trans("YouCanSubmitFile").' <input type="file" name="fileinstall"> '; print $langs->trans("YouCanSubmitFile").' <input type="file" name="fileinstall"> ';
@ -184,16 +302,12 @@ if (! empty($conf->global->MAIN_ONLINE_INSTALL_MODULE))
} }
else else
{ {
$message=info_admin($langs->trans("NotExistsDirect",$dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample")); print $langs->trans("UnpackPackageInDolibarrRoot",$dirins).'<br>';
setEventMessage($message, 'warnings'); print '<b>'.$langs->trans("StepNb",4).'</b>: ';
print $langs->trans("SetupIsReadyForUse").'<br>';
} }
} }
else
{
print '<b>'.$langs->trans("StepNb",4).'</b>: ';
print $langs->trans("SetupIsReadyForUse").'<br>';
}
print '</form>';
if (! empty($result['return'])) if (! empty($result['return']))
{ {

View File

@ -3728,9 +3728,10 @@ function get_exdir($num,$level=3,$alpha=0,$withoutslash=0)
* *
* @param string $dir Directory to create (Separator must be '/'. Example: '/mydir/mysubdir') * @param string $dir Directory to create (Separator must be '/'. Example: '/mydir/mysubdir')
* @param string $dataroot Data root directory (To avoid having the data root in the loop. Using this will also lost the warning on first dir PHP has no permission when open_basedir is used) * @param string $dataroot Data root directory (To avoid having the data root in the loop. Using this will also lost the warning on first dir PHP has no permission when open_basedir is used)
* @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0444'
* @return int < 0 if KO, 0 = already exists, > 0 if OK * @return int < 0 if KO, 0 = already exists, > 0 if OK
*/ */
function dol_mkdir($dir, $dataroot='') function dol_mkdir($dir, $dataroot='', $newmask=0)
{ {
global $conf; global $conf;
@ -3767,8 +3768,8 @@ function dol_mkdir($dir, $dataroot='')
dol_syslog("functions.lib::dol_mkdir: Directory '".$ccdir."' does not exists or is outside open_basedir PHP setting.",LOG_DEBUG); dol_syslog("functions.lib::dol_mkdir: Directory '".$ccdir."' does not exists or is outside open_basedir PHP setting.",LOG_DEBUG);
umask(0); umask(0);
$dirmaskdec=octdec('0755'); $dirmaskdec=octdec($newmask);
if (! empty($conf->global->MAIN_UMASK)) $dirmaskdec=octdec($conf->global->MAIN_UMASK); if (empty($newmask) && ! empty($conf->global->MAIN_UMASK)) $dirmaskdec=octdec($conf->global->MAIN_UMASK);
$dirmaskdec |= octdec('0111'); // Set x bit required for directories $dirmaskdec |= octdec('0111'); // Set x bit required for directories
if (! @mkdir($ccdir_osencoded, $dirmaskdec)) if (! @mkdir($ccdir_osencoded, $dirmaskdec))
{ {

View File

@ -55,7 +55,7 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface
set_include_path($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH); set_include_path($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH);
//print 'rrrrr'.get_include_path(); //print 'rrrrr'.get_include_path();
$res = include_once('ChromePhp.php'); $res = @include_once('ChromePhp.php');
if (! $res) $res=@include_once('ChromePhp.class.php'); if (! $res) $res=@include_once('ChromePhp.class.php');
restore_include_path(); restore_include_path();

View File

@ -297,10 +297,11 @@ MenuHandlers=Menu handlers
MenuAdmin=Menu editor MenuAdmin=Menu editor
DoNotUseInProduction=Do not use in production DoNotUseInProduction=Do not use in production
ThisIsProcessToFollow=This is setup to process: ThisIsProcessToFollow=This is setup to process:
ThisIsAlternativeProcessToFollow=This is an alternative setup to process:
StepNb=Step %s StepNb=Step %s
FindPackageFromWebSite=Find a package that provides feature you want (for example on official web site %s). FindPackageFromWebSite=Find a package that provides feature you want (for example on official web site %s).
DownloadPackageFromWebSite=Download package %s. DownloadPackageFromWebSite=Download package %s.
UnpackPackageInDolibarrRoot=Unpack package file into Dolibarr's root directory <b>%s</b> UnpackPackageInDolibarrRoot=Unpack package file into directory dedicated to external modules: <b>%s</b>
SetupIsReadyForUse=Install is finished and Dolibarr is ready to use with this new component. SetupIsReadyForUse=Install is finished and Dolibarr is ready to use with this new component.
NotExistsDirect=The alternative root directory is not defined.<br> NotExistsDirect=The alternative root directory is not defined.<br>
InfDirAlt=Since version 3 it is possible to define an alternative root directory.This allows you to store, same place, plug-ins and custom templates.<br>Just create a directory at the root of Dolibarr (eg: custom).<br> InfDirAlt=Since version 3 it is possible to define an alternative root directory.This allows you to store, same place, plug-ins and custom templates.<br>Just create a directory at the root of Dolibarr (eg: custom).<br>
@ -1617,3 +1618,7 @@ ListOfFixedNotifications=List of fixed notifications
GoOntoContactCardToAddMore=Go on the tab "Notifications" of a thirdparty contact to add or remove notifications for contacts/addresses GoOntoContactCardToAddMore=Go on the tab "Notifications" of a thirdparty contact to add or remove notifications for contacts/addresses
Threshold=Threshold Threshold=Threshold
BackupDumpWizard=Wizard to build database backup dump file BackupDumpWizard=Wizard to build database backup dump file
SomethingMakeInstallFromWebNotPossible=Installation of external module is not possible from the web interface for the following reason:
SomethingMakeInstallFromWebNotPossible2=For this reason, process to upgrade described here is only manual steps a privileged user can do.
InstallModuleFromWebHasBeenDisabledByFile=Install of external module from application has been disabled by your administrator. You must ask him to remove the file <strong>%s</strong> to allow this feature.
ConfFileMuseContainCustom=Installing an external module from application save the module files into directory <strong>%s</strong>. To have this directory processed by Dolibarr, you must setup your <strong>conf/conf.php</strong> to have option<br>- <strong>$dolibarr_main_url_root_alt</strong> enabled to value <strong>$dolibarr_main_url_root_alt="/custom"</strong><br>- <strong>$dolibarr_main_document_root_alt</strong> enabled to value <strong>"%s/custom"</strong>