Merge pull request #17309 from atm-john/new/check_update_for_module
NEW : Check update for externals modules using button on module page
This commit is contained in:
commit
35e3c32b14
@ -520,9 +520,11 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
|
||||
$moreforfilter = '<div class="valignmiddle">';
|
||||
|
||||
$moreforfilter .= '<div class="floatright right pagination"><ul><li>';
|
||||
$moreforfilter .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=commonkanban'.$param, '', 1, array('morecss'=>'reposition'.($mode == 'common' ? '' : ' btnTitleSelected')));
|
||||
$moreforfilter .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-list-alt imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.$param, '', 1, array('morecss'=>'reposition'.($mode == 'commonkanban' ? '' : ' btnTitleSelected')));
|
||||
$moreforfilter .= '<div class="floatright right pagination --module-list"><ul><li>';
|
||||
$moreforfilter .= dolGetButtonTitle($langs->trans('CheckForModuleUpdate'), $langs->trans('CheckForModuleUpdateHelp'), 'fa fa-check-double ', $_SERVER["PHP_SELF"].'?action=checklastversion&token='.newToken().'&mode='.$mode.$param, '', 1, array('morecss'=>'reposition'));
|
||||
$moreforfilter .= '</li><li>'.dolGetButtonTitleSeparator();
|
||||
$moreforfilter .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=commonkanban'.$param, '', ($mode == 'commonkanban' ? 2 : 1), array('morecss'=>'reposition'));
|
||||
$moreforfilter .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-list-alt imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.$param, '', ($mode == 'common' ? 2 : 1), array('morecss'=>'reposition'));
|
||||
$moreforfilter .= '</li></ul></div>';
|
||||
|
||||
//$moreforfilter .= '<div class="floatright center marginrightonly hideonsmartphone" style="padding-top: 3px"><span class="paddingright">'.$moreinfo.'</span> '.$moreinfo2.'</div>';
|
||||
@ -583,7 +585,6 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
// Show list of modules
|
||||
$oldfamily = '';
|
||||
$linenum = 0;
|
||||
|
||||
foreach ($orders as $key => $value) {
|
||||
$linenum++;
|
||||
$tab = explode('_', $value);
|
||||
@ -591,6 +592,8 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
$module_position = $tab[2];
|
||||
|
||||
$modName = $filename[$key];
|
||||
|
||||
/** @var DolibarrModules $objMod */
|
||||
$objMod = $modules[$modName];
|
||||
|
||||
//print $objMod->name." - ".$key." - ".$objMod->version."<br>";
|
||||
@ -719,6 +722,22 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
$versiontrans .= $objMod->getVersion(1);
|
||||
}
|
||||
|
||||
if ($objMod->isCoreOrExternalModule() == 'external'
|
||||
&& (
|
||||
$action == 'checklastversion'
|
||||
// This is a bad practice to activate a synch external access during building of a page. 1 external module can hang the application.
|
||||
// Adding a cron job could be a good idea see DolibarrModules::checkForUpdate()
|
||||
|| !empty($conf->global->CHECKLASTVERSION_EXTERNALMODULE)
|
||||
)
|
||||
) {
|
||||
$checkRes = $objMod->checkForUpdate();
|
||||
if ($checkRes > 0) {
|
||||
setEventMessage($objMod->getName().' : '.$versiontrans.' -> '.$objMod->lastVersion);
|
||||
} elseif ($checkRes < 0) {
|
||||
setEventMessage($objMod->getName().' '.$langs->trans('CheckVersionFail'), 'warnings');
|
||||
}
|
||||
}
|
||||
|
||||
// Define imginfo
|
||||
$imginfo = "info";
|
||||
if ($objMod->isCoreOrExternalModule() == 'external') {
|
||||
@ -893,17 +912,11 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
|
||||
// Version
|
||||
print '<td class="center nowrap" width="120px">';
|
||||
print $versiontrans;
|
||||
if (!empty($conf->global->CHECKLASTVERSION_EXTERNALMODULE)) { // This is a bad practice to activate a synch external access during building of a page. 1 external module can hang the application.
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
if (!empty($objMod->url_last_version)) {
|
||||
$newversion = getURLContent($objMod->url_last_version, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only
|
||||
if (isset($newversion['content'])) {
|
||||
if (version_compare($newversion['content'], $versiontrans) > 0) {
|
||||
print " <span class='butAction' title='".$langs->trans('LastStableVersion')."'>".$newversion['content']."</span>";
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($objMod->needUpdate) {
|
||||
$versionTitle = $langs->trans('ModuleUpdateAvailable').' : '.$objMod->lastVersion;
|
||||
print '<span class="badge badge-warning classfortooltip" title="'.dol_escape_htmltag($versionTitle).'">'.$versiontrans.'</span>';
|
||||
} else {
|
||||
print $versiontrans;
|
||||
}
|
||||
print "</td>\n";
|
||||
|
||||
|
||||
@ -9710,6 +9710,17 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url =
|
||||
return '<div class="inline-block divButAction"><'.$tag.' '.$compiledAttributes.'>'.$html.'</'.$tag.'></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add space between dolGetButtonTitle
|
||||
*
|
||||
* @param string $moreClass more css class label
|
||||
* @return string html of title separator
|
||||
*/
|
||||
function dolGetButtonTitleSeparator($moreClass = "")
|
||||
{
|
||||
return '<span class="button-title-separator '.$moreClass.'" ></span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function dolGetButtonTitle : this kind of buttons are used in title in list
|
||||
*
|
||||
@ -9718,7 +9729,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url =
|
||||
* @param string $iconClass class for icon element (Example: 'fa fa-file')
|
||||
* @param string $url the url for link
|
||||
* @param string $id attribute id of button
|
||||
* @param int $status 0 no user rights, 1 active, -1 Feature Disabled, -2 disable Other reason use helpText as tooltip
|
||||
* @param int $status 0 no user rights, 1 active, 2 current action or selected, -1 Feature Disabled, -2 disable Other reason use helpText as tooltip
|
||||
* @param array $params various params for future : recommended rather than adding more function arguments
|
||||
* @return string html button
|
||||
*/
|
||||
@ -9753,7 +9764,9 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u
|
||||
$useclassfortooltip = 0;
|
||||
}
|
||||
|
||||
if ($status <= 0) {
|
||||
if ($status == 2) {
|
||||
$attr['class'] .= ' btnTitleSelected';
|
||||
} elseif ($status <= 0) {
|
||||
$attr['class'] .= ' refused';
|
||||
|
||||
$attr['href'] = '';
|
||||
|
||||
@ -192,6 +192,18 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
|
||||
*/
|
||||
public $version;
|
||||
|
||||
/**
|
||||
* Module last version
|
||||
* @var string $lastVersion
|
||||
*/
|
||||
public $lastVersion = '';
|
||||
|
||||
/**
|
||||
* true indicate this module need update
|
||||
* @var bool $needUpdate
|
||||
*/
|
||||
public $needUpdate = false;
|
||||
|
||||
/**
|
||||
* @var string Module description (short text)
|
||||
*
|
||||
@ -2240,7 +2252,11 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
|
||||
}
|
||||
|
||||
print '
|
||||
<div class="box-flex-item info-box-module'.(empty($conf->global->$const_name) ? ' info-box-module-disabled' : '').($this->isCoreOrExternalModule() == 'external' ? ' info-box-module-external' : '').'">
|
||||
<div class="box-flex-item info-box-module'
|
||||
.(empty($conf->global->$const_name) ? ' --disabled' : '')
|
||||
.($this->isCoreOrExternalModule() == 'external' ? ' --external' : '')
|
||||
.($this->needUpdate ? ' --need-update' : '')
|
||||
.'">
|
||||
<div class="info-box info-box-sm info-box-module">
|
||||
<div class="info-box-icon'.(empty($conf->global->$const_name) ? '' : ' info-box-icon-module-enabled'.($versiontrans ? ' info-box-icon-module-warning' : '')).'">';
|
||||
|
||||
@ -2258,7 +2274,12 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
|
||||
}
|
||||
|
||||
if ($this->isCoreOrExternalModule() == 'external' || preg_match('/development|experimental|deprecated/i', $version)) {
|
||||
print '<span class="info-box-icon-version'.($versiontrans ? ' '.$versiontrans : '').'" title="'.$langs->trans("Version").' '.$this->getVersion(1).'">';
|
||||
$versionTitle = $langs->trans("Version").' '.$this->getVersion(1);
|
||||
if ($this->needUpdate) {
|
||||
$versionTitle.= '<br/>'.$langs->trans('ModuleUpdateAvailable').' : '.$this->lastVersion;
|
||||
}
|
||||
|
||||
print '<span class="info-box-icon-version'.($versiontrans ? ' '.$versiontrans : '').' classfortooltip" title="'.dol_escape_js($versionTitle).'" >';
|
||||
print $this->getVersion(1);
|
||||
print '</span>';
|
||||
}
|
||||
@ -2287,4 +2308,33 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
|
||||
</div><!-- /.info-box -->
|
||||
</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* check for module update
|
||||
* TODO : store results for $this->url_last_version and $this->needUpdate
|
||||
* Add a cron task to monitor for updates
|
||||
*
|
||||
* @return int <0 if Error, 0 == no update needed, >0 if need update
|
||||
*/
|
||||
public function checkForUpdate()
|
||||
{
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
if (!empty($this->url_last_version)) {
|
||||
$lastVersion = getURLContent($this->url_last_version, 'GET', '', 1, array(), array('http', 'https'), 0); // Accept http or https links on external remote server only
|
||||
if (isset($lastVersion['content']) && strlen($lastVersion['content']) < 30) {
|
||||
// Security warning : be careful with remote data content, the module editor could be hacked (or evil) so limit to a-z A-Z 0-9 _ . -
|
||||
$this->lastVersion = preg_replace("/[^a-zA-Z0-9_\.\-]+/", "", $lastVersion['content']);
|
||||
if (version_compare($this->lastVersion, $this->version) > 0) {
|
||||
$this->needUpdate = true;
|
||||
return 1;
|
||||
} else {
|
||||
$this->needUpdate = false;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2122,4 +2122,7 @@ IfCLINotRequiredYouShouldDisablePHPFunctions=Except if you need to run system co
|
||||
NoWritableFilesFoundIntoRootDir=No writable files or directories of the common programs were found into your root directory (Good)
|
||||
RecommendedValueIs=Recommended: %s
|
||||
ARestrictedPath=A restricted path
|
||||
SwaggerDescriptionFile=Swagger API description file (for use with redoc for example)
|
||||
CheckForModuleUpdate=Check for modules updates
|
||||
CheckForModuleUpdateHelp=Check for modules updates.<br/>This action will connect to modules editors to check if a new version is available.
|
||||
ModuleUpdateAvailable=An update is available for this module
|
||||
SwaggerDescriptionFile=Swagger API description file (for use with redoc for example)
|
||||
|
||||
@ -297,3 +297,4 @@ WarningAvailableOnlyForHTTPSServers=Available only if using HTTPS secured connec
|
||||
WarningModuleXDisabledSoYouMayMissEventHere=Module %s has not been enabled. So you may miss a lot of event here.
|
||||
ErrorActionCommPropertyUserowneridNotDefined=User's owner is required
|
||||
ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary
|
||||
CheckVersionFail=Version check fail
|
||||
|
||||
@ -279,6 +279,11 @@ div.pagination li:first-child a.btnTitle{
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.button-title-separator{
|
||||
display: inline-block;
|
||||
clear: both;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.imgforviewmode {
|
||||
color: #aaa;
|
||||
|
||||
@ -9,10 +9,14 @@ if (!defined('ISLOADEDBYSTEELSHEET')) {
|
||||
* -------------------
|
||||
*/
|
||||
|
||||
.info-box-module-external span.info-box-icon-version {
|
||||
.info-box-module.--external span.info-box-icon-version {
|
||||
background: #bbb;
|
||||
}
|
||||
|
||||
.info-box-module.--external.--need-update span.info-box-icon-version{
|
||||
background: #bc9525;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
display: block;
|
||||
position: relative;
|
||||
@ -153,7 +157,7 @@ a.info-box-text-a i.fa.fa-exclamation-triangle {
|
||||
-webkit-transition: opacity 0.5s, visibility 0s 0.5s;
|
||||
transition: opacity 0.5s, visibility 0s 0.5s;
|
||||
}
|
||||
.box-flex-item.info-box-module.info-box-module-disabled {
|
||||
.box-flex-item.info-box-module.--disabled {
|
||||
/* opacity: 0.6; */
|
||||
}
|
||||
|
||||
|
||||
@ -119,7 +119,7 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) {
|
||||
}
|
||||
|
||||
|
||||
.info-box-module-external span.info-box-icon-version {
|
||||
.info-box-module.--external span.info-box-icon-version {
|
||||
background: #bbb;
|
||||
}
|
||||
|
||||
@ -250,7 +250,7 @@ a.info-box-text-a i.fa.fa-exclamation-triangle {
|
||||
transition: opacity 0.5s, visibility 0s 0.5s;
|
||||
}
|
||||
|
||||
.box-flex-item.info-box-module.info-box-module-disabled {
|
||||
.box-flex-item.info-box-module.--disabled {
|
||||
/* opacity: 0.6; */
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user