Merge remote-tracking branch 'origin/3.7' into develop
This commit is contained in:
commit
ab739e162c
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
/* Copyright (C) 2005-2013 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
/* Copyright (C) 2005-2015 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
*
|
||||
* This file is a modified version of datepicker.php from phpBSM to fix some
|
||||
* bugs, to add new features and to dramatically increase speed.
|
||||
|
||||
@ -36,9 +36,6 @@
|
||||
function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest=1)
|
||||
{
|
||||
global $db,$conf,$langs;
|
||||
global $mc;
|
||||
|
||||
dol_syslog("functions_dolibarr::check_user_password_dolibarr usertotest=".$usertotest);
|
||||
|
||||
// Force master entity in transversal mode
|
||||
$entity=$entitytotest;
|
||||
@ -48,6 +45,8 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest=
|
||||
|
||||
if (! empty($usertotest))
|
||||
{
|
||||
dol_syslog("functions_dolibarr::check_user_password_dolibarr usertotest=".$usertotest." passwordtotest=".preg_replace('/./','*',$passwordtotest)." entitytotest=".$entitytotest);
|
||||
|
||||
// If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko
|
||||
$table = MAIN_DB_PREFIX."user";
|
||||
$usernamecol1 = 'login';
|
||||
@ -60,7 +59,6 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest=
|
||||
if (preg_match('/@/',$usertotest)) $sql.=' OR '.$usernamecol2." = '".$db->escape($usertotest)."'";
|
||||
$sql.=') AND '.$entitycol." IN (0," . ($entity ? $entity : 1) . ")";
|
||||
|
||||
dol_syslog("functions_dolibarr::check_user_password_dolibarr", LOG_DEBUG);
|
||||
$resql=$db->query($sql);
|
||||
if ($resql)
|
||||
{
|
||||
@ -99,12 +97,6 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest=
|
||||
}
|
||||
}
|
||||
|
||||
if ($passok && ! empty($obj->entity) && (! empty($conf->multicompany->enabled) && ! empty($conf->multicompany->transverse_mode)))
|
||||
{
|
||||
$ret=$mc->checkRight($obj->rowid, $entitytotest); // The module multicompany check here user belong to at least one group into company. This is a bugged behaviour, so you must hack module to make thing working.
|
||||
if ($ret < 0) $passok=false;
|
||||
}
|
||||
|
||||
// Password ok ?
|
||||
if ($passok)
|
||||
{
|
||||
@ -112,12 +104,24 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest=
|
||||
}
|
||||
else
|
||||
{
|
||||
dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko bad password pour '".$usertotest."'");
|
||||
dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko bad password for '".$usertotest."'");
|
||||
sleep(1);
|
||||
$langs->load('main');
|
||||
$langs->load('errors');
|
||||
$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
|
||||
}
|
||||
|
||||
if ($passok && ! empty($conf->multicompany->enabled)) // We must check entity
|
||||
{
|
||||
global $mc;
|
||||
|
||||
$ret=$mc->checkRight($obj->rowid, $entitytotest);
|
||||
if ($ret < 0)
|
||||
{
|
||||
dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko entity '".$entitytotest."' not allowed for user '".$obj->rowid."'");
|
||||
$login=''; // force authentication failure
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -34,7 +34,8 @@
|
||||
*/
|
||||
function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest)
|
||||
{
|
||||
global $_POST,$db,$conf,$langs;
|
||||
global $db,$conf,$langs;
|
||||
global $_POST;
|
||||
global $dolibarr_main_auth_ldap_host,$dolibarr_main_auth_ldap_port;
|
||||
global $dolibarr_main_auth_ldap_version,$dolibarr_main_auth_ldap_servertype;
|
||||
global $dolibarr_main_auth_ldap_login_attribute,$dolibarr_main_auth_ldap_dn;
|
||||
@ -42,6 +43,13 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest)
|
||||
global $dolibarr_main_auth_ldap_filter;
|
||||
global $dolibarr_main_auth_ldap_debug;
|
||||
|
||||
// Force master entity in transversal mode
|
||||
$entity=$entitytotest;
|
||||
if (! empty($conf->multicompany->enabled) && ! empty($conf->multicompany->transverse_mode)) $entity=1;
|
||||
|
||||
$login='';
|
||||
$resultFetchUser='';
|
||||
|
||||
if (! function_exists("ldap_connect"))
|
||||
{
|
||||
dol_syslog("functions_ldap::check_user_password_ldap Authentification ko failed to connect to LDAP. LDAP functions are disabled on this PHP");
|
||||
@ -52,11 +60,10 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest)
|
||||
return;
|
||||
}
|
||||
|
||||
$login='';
|
||||
$resultFetchUser='';
|
||||
|
||||
if (!empty($_POST["username"]) || $usertotest)
|
||||
if ($usertotest)
|
||||
{
|
||||
dol_syslog("functions_ldap::check_user_password_ldap usertotest=".$usertotest." passwordtotest=".preg_replace('/./','*',$passwordtotest)." entitytotest=".$entitytotest);
|
||||
|
||||
// If test username/password asked, we define $test=false and $login var if ok, set $_SESSION["dol_loginmesg"] if ko
|
||||
$ldaphost=$dolibarr_main_auth_ldap_host;
|
||||
$ldapport=$dolibarr_main_auth_ldap_port;
|
||||
@ -80,7 +87,6 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest)
|
||||
$ldap->searchUser=$ldapadminlogin;
|
||||
$ldap->searchPassword=$ldapadminpass;
|
||||
|
||||
dol_syslog("functions_ldap::check_user_password_ldap usertotest=".$usertotest);
|
||||
if ($ldapdebug)
|
||||
{
|
||||
dol_syslog("functions_ldap::check_user_password_ldap Server:".join(',',$ldap->server).", Port:".$ldap->serverPort.", Protocol:".$ldap->ldapProtocolVersion.", Type:".$ldap->serverType);
|
||||
@ -146,52 +152,56 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest)
|
||||
$login=$usertotest;
|
||||
|
||||
// ldap2dolibarr synchronisation
|
||||
if ($login && ! empty($conf->ldap->enabled) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr')
|
||||
if ($login && ! empty($conf->ldap->enabled) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') // ldap2dolibarr synchronisation
|
||||
{
|
||||
dol_syslog("functions_ldap::check_user_password_ldap Sync ldap2dolibarr");
|
||||
dol_syslog("functions_ldap::check_user_password_ldap Sync ldap2dolibarr");
|
||||
|
||||
// On charge les attributs du user ldap
|
||||
if ($ldapdebug) print "DEBUG: login ldap = ".$login."<br>\n";
|
||||
$resultFetchLdapUser = $ldap->fetch($login,$userSearchFilter);
|
||||
// On charge les attributs du user ldap
|
||||
if ($ldapdebug) print "DEBUG: login ldap = ".$login."<br>\n";
|
||||
$resultFetchLdapUser = $ldap->fetch($login,$userSearchFilter);
|
||||
|
||||
if ($ldapdebug) print "DEBUG: UACF = ".join(',',$ldap->uacf)."<br>\n";
|
||||
if ($ldapdebug) print "DEBUG: pwdLastSet = ".dol_print_date($ldap->pwdlastset,'day')."<br>\n";
|
||||
if ($ldapdebug) print "DEBUG: badPasswordTime = ".dol_print_date($ldap->badpwdtime,'day')."<br>\n";
|
||||
if ($ldapdebug) print "DEBUG: UACF = ".join(',',$ldap->uacf)."<br>\n";
|
||||
if ($ldapdebug) print "DEBUG: pwdLastSet = ".dol_print_date($ldap->pwdlastset,'day')."<br>\n";
|
||||
if ($ldapdebug) print "DEBUG: badPasswordTime = ".dol_print_date($ldap->badpwdtime,'day')."<br>\n";
|
||||
|
||||
// On recherche le user dolibarr en fonction de son SID ldap
|
||||
$sid = $ldap->getObjectSid($login);
|
||||
if ($ldapdebug) print "DEBUG: sid = ".$sid."<br>\n";
|
||||
// On recherche le user dolibarr en fonction de son SID ldap
|
||||
$sid = $ldap->getObjectSid($login);
|
||||
if ($ldapdebug) print "DEBUG: sid = ".$sid."<br>\n";
|
||||
|
||||
$user=new User($db);
|
||||
$resultFetchUser=$user->fetch('',$login,$sid);
|
||||
if ($resultFetchUser > 0)
|
||||
{
|
||||
dol_syslog("functions_ldap::check_user_password_ldap Sync user found id=".$user->id);
|
||||
// On verifie si le login a change et on met a jour les attributs dolibarr
|
||||
|
||||
if ($conf->multicompany->enabled)
|
||||
$usertmp=new User($db);
|
||||
$resultFetchUser=$usertmp->fetch('',$login,$sid);
|
||||
if ($resultFetchUser > 0)
|
||||
{
|
||||
global $mc;
|
||||
dol_syslog("functions_ldap::check_user_password_ldap Sync user found user id=".$usertmp->id);
|
||||
// On verifie si le login a change et on met a jour les attributs dolibarr
|
||||
|
||||
$ret=$mc->checkRight($user->id, $entitytotest, $user); // The module multicompany check here user belong to at least one group into company. This is a bugged behaviour, so you must hack module to make thing working.
|
||||
if ($ret < 0)
|
||||
if ($usertmp->login != $ldap->login && $ldap->login)
|
||||
{
|
||||
dol_syslog("Failed to checkRight by module multicompany for user id = ".$user->id." into entity ".$entitytotest);
|
||||
$login=false; // force error of authentication
|
||||
$usertmp->login = $ldap->login;
|
||||
$usertmp->update($usertmp);
|
||||
// TODO Que faire si update echoue car on update avec un login deja existant.
|
||||
}
|
||||
|
||||
//$resultUpdate = $usertmp->update_ldap2dolibarr($ldap);
|
||||
}
|
||||
|
||||
|
||||
if ($user->login != $ldap->login && $ldap->login)
|
||||
{
|
||||
$user->login = $ldap->login;
|
||||
$user->update($user);
|
||||
// TODO Que faire si update echoue car on update avec un login deja existant.
|
||||
}
|
||||
|
||||
//$resultUpdate = $user->update_ldap2dolibarr($ldap);
|
||||
}
|
||||
unset($usertmp);
|
||||
}
|
||||
|
||||
if (! empty($conf->multicompany->enabled)) // We must check entity (even if sync is not active)
|
||||
{
|
||||
global $mc;
|
||||
|
||||
$usertmp=new User($db);
|
||||
$usertmp->fetch('',$login);
|
||||
$ret=$mc->checkRight($usertmp->id, $entitytotest);
|
||||
if ($ret < 0)
|
||||
{
|
||||
dol_syslog("functions_ldap::check_user_password_ldap Authentification ko entity '".$entitytotest."' not allowed for user '".$usertmp->id."'");
|
||||
$login=''; // force authentication failure
|
||||
}
|
||||
unset($usertmp);
|
||||
}
|
||||
|
||||
}
|
||||
if ($result == 1)
|
||||
{
|
||||
|
||||
@ -218,18 +218,42 @@ class MenuManager
|
||||
}
|
||||
foreach($submenu->liste as $key2 => $val2) // $val['url','titre','level','enabled'=0|1|2,'target','mainmenu','leftmenu'
|
||||
{
|
||||
$relurl2=dol_buildpath($val2['url'],1);
|
||||
$relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2);
|
||||
$relurl2=preg_replace('/__USERID__/',$user->id,$relurl2);
|
||||
$canonurl2=preg_replace('/\?.*$/','',$val2['url']);
|
||||
//var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']);
|
||||
if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2='';
|
||||
if ($val2['level']==0) print str_pad('',$val2['level']+1).'<li'.($val2['level']==0?' data-role="list-dividerxxx"':'').' class="lilevel'.($val2['level']+1).' ui-btn-icon-right ui-btn">'; // ui-btn to highlight on clic
|
||||
else print str_pad('',$val2['level']+1).'<li class="lilevel'.($val2['level']+1).'">'; // ui-btn to highlight on clic
|
||||
if ($relurl2) print '<a href="'.$relurl2.'">';
|
||||
print $val2['titre'];
|
||||
if ($relurl2) print '</a>';
|
||||
print '</li>'."\n";
|
||||
$showmenu=true;
|
||||
if (! empty($conf->global->MAIN_MENU_HIDE_UNAUTHORIZED) && empty($val2['enabled'])) $showmenu=false;
|
||||
|
||||
if ($showmenu) // Visible (option to hide when not allowed is off or allowed)
|
||||
{
|
||||
$relurl2=dol_buildpath($val2['url'],1);
|
||||
$relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2);
|
||||
$relurl2=preg_replace('/__USERID__/',$user->id,$relurl2);
|
||||
$canonurl2=preg_replace('/\?.*$/','',$val2['url']);
|
||||
//var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']);
|
||||
if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2='';
|
||||
if ($val2['level']==0) print str_pad('',$val2['level']+1).'<li'.($val2['level']==0?' data-role="list-dividerxxx"':'').' class="lilevel'.($val2['level']+1).' ui-btn-icon-right ui-btn">'; // ui-btn to highlight on clic
|
||||
else print str_pad('',$val2['level']+1).'<li class="lilevel'.($val2['level']+1).'">'; // ui-btn to highlight on clic
|
||||
if ($relurl2)
|
||||
{
|
||||
if ($val2['enabled']) // Allowed
|
||||
{
|
||||
print '<a href="'.$relurl2.'"';
|
||||
//print ' data-ajax="false"';
|
||||
print '>';
|
||||
}
|
||||
else // Not allowed but visible (greyed)
|
||||
{
|
||||
print '<a href="#" class="vsmenudisabled">';
|
||||
}
|
||||
}
|
||||
print $val2['titre'];
|
||||
if ($relurl2)
|
||||
{
|
||||
if ($val2['enabled']) // Allowed
|
||||
print '</a>';
|
||||
else
|
||||
print '</a>';
|
||||
}
|
||||
print '</li>'."\n";
|
||||
}
|
||||
}
|
||||
//var_dump($submenu);
|
||||
print '</ul>';
|
||||
|
||||
@ -150,6 +150,7 @@ class MenuManager
|
||||
{
|
||||
print '<ul class="ulmenu" data-role="listview" data-inset="true">';
|
||||
print '<li data-role="list-dividerxxx" class="lilevel0">';
|
||||
|
||||
if ($val['enabled'] == 1)
|
||||
{
|
||||
$relurl=dol_buildpath($val['url'],1);
|
||||
@ -184,23 +185,42 @@ class MenuManager
|
||||
}
|
||||
foreach($submenu->liste as $key2 => $val2) // $val['url','titre','level','enabled'=0|1|2,'target','mainmenu','leftmenu']
|
||||
{
|
||||
$relurl2=dol_buildpath($val2['url'],1);
|
||||
$relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2);
|
||||
$relurl2=preg_replace('/__USERID__/',$user->id,$relurl2);
|
||||
$canonurl2=preg_replace('/\?.*$/','',$val2['url']);
|
||||
//var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']);
|
||||
if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2='';
|
||||
if ($val2['level']==0) print str_pad('',$val2['level']+1).'<li'.($val2['level']==0?' data-role="list-dividerxxx"':'').' class="lilevel'.($val2['level']+1).' ui-btn-icon-right ui-btn">'; // ui-btn to highlight on clic
|
||||
else print str_pad('',$val2['level']+1).'<li class="lilevel'.($val2['level']+1).'">'; // ui-btn to highlight on clic
|
||||
if ($relurl2)
|
||||
{
|
||||
print '<a href="'.$relurl2.'"';
|
||||
//print ' data-ajax="false"';
|
||||
print '>';
|
||||
}
|
||||
print $val2['titre'];
|
||||
if ($relurl2) print '</a>';
|
||||
print '</li>'."\n";
|
||||
$showmenu=true;
|
||||
if (! empty($conf->global->MAIN_MENU_HIDE_UNAUTHORIZED) && empty($val2['enabled'])) $showmenu=false;
|
||||
|
||||
if ($showmenu) // Visible (option to hide when not allowed is off or allowed)
|
||||
{
|
||||
$relurl2=dol_buildpath($val2['url'],1);
|
||||
$relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2);
|
||||
$relurl2=preg_replace('/__USERID__/',$user->id,$relurl2);
|
||||
$canonurl2=preg_replace('/\?.*$/','',$val2['url']);
|
||||
//var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']);
|
||||
if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2='';
|
||||
if ($val2['level']==0) print str_pad('',$val2['level']+1).'<li'.($val2['level']==0?' data-role="list-dividerxxx"':'').' class="lilevel'.($val2['level']+1).' ui-btn-icon-right ui-btn">'; // ui-btn to highlight on clic
|
||||
else print str_pad('',$val2['level']+1).'<li class="lilevel'.($val2['level']+1).'">'; // ui-btn to highlight on clic
|
||||
if ($relurl2)
|
||||
{
|
||||
if ($val2['enabled']) // Allowed
|
||||
{
|
||||
print '<a href="'.$relurl2.'"';
|
||||
//print ' data-ajax="false"';
|
||||
print '>';
|
||||
}
|
||||
else // Not allowed but visible (greyed)
|
||||
{
|
||||
print '<a href="#" class="vsmenudisabled">';
|
||||
}
|
||||
}
|
||||
print $val2['titre'];
|
||||
if ($relurl2)
|
||||
{
|
||||
if ($val2['enabled']) // Allowed
|
||||
print '</a>';
|
||||
else
|
||||
print '</a>';
|
||||
}
|
||||
print '</li>'."\n";
|
||||
}
|
||||
}
|
||||
//var_dump($submenu);
|
||||
print '</ul>';
|
||||
|
||||
@ -100,7 +100,7 @@ if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->ex
|
||||
if ($result < 0) {
|
||||
setEventMessage($object->error,'errors');
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
$res = $object->reprogram_jobs($user->login);
|
||||
if ($res > 0)
|
||||
@ -314,11 +314,11 @@ print "\n<div class=\"tabsAction\">\n";
|
||||
|
||||
if (! $user->rights->cron->create)
|
||||
{
|
||||
print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("New").'</a>';
|
||||
print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("CronCreateJob").'</a>';
|
||||
}
|
||||
else
|
||||
{
|
||||
print '<a class="butAction" href="'.DOL_URL_ROOT.'/cron/card.php?action=create">'.$langs->trans("New").'</a>';
|
||||
print '<a class="butAction" href="'.DOL_URL_ROOT.'/cron/card.php?action=create">'.$langs->trans("CronCreateJob").'</a>';
|
||||
}
|
||||
|
||||
print '</div>';
|
||||
|
||||
@ -517,7 +517,7 @@ Module2000Desc=Allow to edit some text area using an advanced editor
|
||||
Module2200Name=Dynamic Prices
|
||||
Module2200Desc=Enable the usage of math expressions for prices
|
||||
Module2300Name=Cron
|
||||
Module2300Desc=Scheduled task management
|
||||
Module2300Desc=Scheduled job management
|
||||
Module2400Name=Agenda
|
||||
Module2400Desc=Events/tasks and agenda management
|
||||
Module2500Name=Electronic Content Management
|
||||
@ -765,10 +765,10 @@ Permission1237=Export supplier orders and their details
|
||||
Permission1251=Run mass imports of external data into database (data load)
|
||||
Permission1321=Export customer invoices, attributes and payments
|
||||
Permission1421=Export customer orders and attributes
|
||||
Permission23001 = Read Scheduled task
|
||||
Permission23002 = Create/update Scheduled task
|
||||
Permission23003 = Delete Scheduled task
|
||||
Permission23004 = Execute Scheduled task
|
||||
Permission23001=Read Scheduled job
|
||||
Permission23002=Create/update Scheduled job
|
||||
Permission23003=Delete Scheduled job
|
||||
Permission23004=Execute Scheduled job
|
||||
Permission2401=Read actions (events or tasks) linked to his account
|
||||
Permission2402=Create/modify actions (events or tasks) linked to his account
|
||||
Permission2403=Delete actions (events or tasks) linked to his account
|
||||
|
||||
@ -26,15 +26,15 @@ CronLastOutput=Last run output
|
||||
CronLastResult=Last result code
|
||||
CronListOfCronJobs=List of scheduled jobs
|
||||
CronCommand=Command
|
||||
CronList=Jobs list
|
||||
CronDelete= Delete cron jobs
|
||||
CronConfirmDelete= Are you sure you want to delete this cron job ?
|
||||
CronExecute=Launch job
|
||||
CronConfirmExecute= Are you sure to execute this job now
|
||||
CronInfo= Jobs allow to execute task that have been planned
|
||||
CronWaitingJobs=Wainting jobs
|
||||
CronList=Scheduled job
|
||||
CronDelete=Delete scheduled jobs
|
||||
CronConfirmDelete=Are you sure you want to delete this scheduled jobs ?
|
||||
CronExecute=Launch scheduled jobs
|
||||
CronConfirmExecute=Are you sure to execute this scheduled jobs now ?
|
||||
CronInfo=Scheduled job module allow to execute job that have been planned
|
||||
CronWaitingJobs=Waiting jobs
|
||||
CronTask=Job
|
||||
CronNone= None
|
||||
CronNone=None
|
||||
CronDtStart=Start date
|
||||
CronDtEnd=End date
|
||||
CronDtNextLaunch=Next execution
|
||||
@ -75,6 +75,7 @@ CronObjectHelp=The object name to load. <BR> For exemple to fetch method of Doli
|
||||
CronMethodHelp=The object method to launch. <BR> For exemple to fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value of method is is <i>fecth</i>
|
||||
CronArgsHelp=The method arguments. <BR> For exemple to fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value of paramters can be <i>0, ProductRef</i>
|
||||
CronCommandHelp=The system command line to execute.
|
||||
CronCreateJob=Create new Scheduled Job
|
||||
# Info
|
||||
CronInfoPage=Information
|
||||
# Common
|
||||
|
||||
Loading…
Reference in New Issue
Block a user