diff --git a/ChangeLog b/ChangeLog index 19859731a6c..797dbaec627 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,14 +19,15 @@ For users: - New: Add object_hour as substitution tag for opendocument generation. - New: Add option MEMBER_PAYONLINE_SENDEMAIL to send email when paypal or paybox payment is done. - New: Implement same rule for return value of all command line scripts (0 when success, <>0 if error). -- New: Clone product/service composition -- New: [ task #926 ] Add extrafield feature on order lines -- New: [ task #927 ] Add extrafield feature on Proposal lines -- New: [ task #928 ] Add extrafield feature on invoice lines -- New: Add option ADHERENT_LOGIN_NOT_REQUIRED +- New: Clone product/service composition. +- New: [ task #926 ] Add extrafield feature on order lines. +- New: [ task #927 ] Add extrafield feature on Proposal lines. +- New: [ task #928 ] Add extrafield feature on invoice lines. +- New: Add option ADHERENT_LOGIN_NOT_REQUIRED. +- New: Add a cron module. For translators: -- Normalized sort order of all languages files with english ref file. +- Normalized sort order of all languages files with english reference files. For developers: - New: DolGraph can build graph with three lines. diff --git a/htdocs/core/lib/cron.lib.php b/htdocs/core/lib/cron.lib.php index 0ba077e1a3b..b66060e3607 100644 --- a/htdocs/core/lib/cron.lib.php +++ b/htdocs/core/lib/cron.lib.php @@ -22,6 +22,7 @@ * \ingroup cron */ + /** * Return array of tabs to used on pages to setup cron module. * @@ -74,3 +75,53 @@ function cron_prepare_head($object) return $head; } + +/** + * Show information with URLs to launch jobs + * + * @return int 0 + */ +function dol_print_cron_urls() +{ + global $conf, $langs, $user; + global $dolibarr_main_url_root; + + // Define $urlwithroot + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + // Cron launch + print ''.$langs->trans("URLToLaunchCronJobs").':
'; + $url=$urlwithroot.'/public/cron/cron_run_jobs.php'.(empty($conf->global->CRON_KEY)?'':'?securitykey='.$conf->global->CRON_KEY.'&').'userlogin='.$user->login; + print img_picto('','object_globe.png').' '.$url."
\n"; + print ' '.$langs->trans("OrToLaunchASpecificJob").'
'; + $url=$urlwithroot.'/public/cron/cron_run_jobs.php'.(empty($conf->global->CRON_KEY)?'':'?securitykey='.$conf->global->CRON_KEY.'&').'userlogin='.$user->login.'&id=cronjobid'; + print img_picto('','object_globe.png').' '.$url."
\n"; + print '
'; + + + print ''.$langs->trans("FileToLaunchCronJobs").':
'; + + $file='/scripts/cron/cron_run_jobs.php'.' '.(empty($conf->global->CRON_KEY)?'securitykey':''.$conf->global->CRON_KEY.'').' '.$user->login.' [cronjobid]'; + print '
\n"; + print '
'; + + // Add note + $linuxlike=1; + if (preg_match('/^win/i',PHP_OS)) $linuxlike=0; + if (preg_match('/^mac/i',PHP_OS)) $linuxlike=0; + print $langs->trans("Note").': '; + if ($linuxlike) + { + print $langs->trans("CronExplainHowToRunUnix"); + } + else + { + print $langs->trans("CronExplainHowToRunWin"); + } + + return 0; +} + + diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index 2080767e00c..80b94a062d0 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -48,7 +48,7 @@ class modCron extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); $this->description = "Enable the Dolibarr cron service"; - $this->version = 'experimental'; // 'experimental' or 'dolibarr' or version + $this->version = 'dolibarr'; // 'experimental' or 'dolibarr' or version // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) diff --git a/htdocs/cron/admin/cron.php b/htdocs/cron/admin/cron.php index 021e4da63e3..14840074b34 100644 --- a/htdocs/cron/admin/cron.php +++ b/htdocs/cron/admin/cron.php @@ -107,39 +107,7 @@ dol_fiche_end(); print '

'; -// Define $urlwithroot -$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); -$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file -//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - -// Cron launch -print ''.$langs->trans("URLToLaunchCronJobs").':
'; -$url=$urlwithroot.'/public/cron/cron_run_jobs.php'.(empty($conf->global->CRON_KEY)?'':'?securitykey='.$conf->global->CRON_KEY.'&').'userlogin='.$user->login; -print img_picto('','object_globe.png').' '.$url."
\n"; -print ' '.$langs->trans("OrToLaunchASpecificJob").'
'; -$url=$urlwithroot.'/public/cron/cron_run_jobs.php'.(empty($conf->global->CRON_KEY)?'':'?securitykey='.$conf->global->CRON_KEY.'&').'userlogin='.$user->login.'&id=cronjobid'; -print img_picto('','object_globe.png').' '.$url."
\n"; -print '
'; - - -$linuxlike=1; -if (preg_match('/^win/i',PHP_OS)) $linuxlike=0; -if (preg_match('/^mac/i',PHP_OS)) $linuxlike=0; - -print '
'; -print ''.$langs->trans("FileToLaunchCronJobs").':
'; - -$file='/scripts/cron/cron_run_jobs.php'.' '.(empty($conf->global->CRON_KEY)?'securitykey':''.$conf->global->CRON_KEY.'').' '.$user->login.' [cronjobid]'; -print '
\n"; -print '
'; -print $langs->trans("Note").': '; -if ($linuxlike) { - print $langs->trans("CronExplainHowToRunUnix"); -} else { - print $langs->trans("CronExplainHowToRunWin"); -} - - +dol_print_cron_urls(); print '
'; diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index 7b7dc26767a..2cdd27862b3 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -1,6 +1,7 @@ + * Copyright (C) 2013 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,55 +44,66 @@ $confirm=GETPOST('confirm','alpha'); $cancel=GETPOST('cancel'); $object = new Cronjob($db); -if (!empty($id)) { +if (!empty($id)) +{ $result=$object->fetch($id); - if ($result < 0) { + if ($result < 0) + { setEventMessage($object->error,'errors'); } } -if(!empty($cancel)) { - if (!empty($id)) { +if(!empty($cancel)) +{ + if (!empty($id)) + { $action=''; - }else { - Header("Location: ".dol_buildpath('/cron/cron/list.php',1).'?status=1'); } - + else + { + Header("Location: ".DOL_URL_ROOT.'/cron/list.php?status=1'); + exit; + } } // Delete jobs -if ($action == 'confirm_delete' && $confirm == "yes" && $user->rights->cron->delete){ - - +if ($action == 'confirm_delete' && $confirm == "yes" && $user->rights->cron->delete) +{ $result = $object->delete($user); - if ($result < 0) { + if ($result < 0) + { setEventMessage($object->error,'errors'); $action='edit'; - }else { - Header("Location: ".dol_buildpath('/cron/cron/list.php',1).'?status=1'); + } + else + { + Header("Location: ".DOL_URL_ROOT.'/cron/list.php?status=1'); + exit; } } // Execute jobs -if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->execute){ - +if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->execute) +{ $result=$object->run_jobs($user->login); - if ($result < 0) { + if ($result < 0) + { setEventMessage($object->error,'errors'); $action=''; - }else { + } + else + { if ($object->lastresult > 0) setEventMessage($langs->trans("JobFinished"),'warnings'); else setEventMessage($langs->trans("JobFinished"),'mesgs'); $action=''; } - } -if ($action=='add') { - +if ($action=='add') +{ $object->jobtype=GETPOST('jobtype','alpha'); $object->label=GETPOST('label','alpha'); $object->command=GETPOST('command','alpha'); @@ -123,7 +135,8 @@ if ($action=='add') { } // Save parameters -if ($action=='update') { +if ($action=='update') +{ $object->id=$id; $object->jobtype=GETPOST('jobtype'); $object->label=GETPOST('label'); @@ -155,7 +168,8 @@ if ($action=='update') { } } -if ($action=='activate') { +if ($action=='activate') +{ $object->status=1; //Ajout de la tache cron @@ -172,7 +186,8 @@ if ($action=='activate') { } } -if ($action=='inactive') { +if ($action=='inactive') +{ $object->status=0; //Ajout de la tache cron $result = $object->update($user); @@ -199,7 +214,7 @@ llxHeader('',$langs->trans("CronAdd")); if ($action=='edit' || empty($action) || $action=='delete' || $action=='execute') { $head=cron_prepare_head($object); - dol_fiche_head($head, 'card', $langs->trans("CronTask"), 0, 'bill'); + print dol_get_fiche_head($head, 'card', $langs->trans("CronTask"), 0, 'bill'); } elseif ($action=='create') { @@ -441,16 +456,12 @@ if (($action=="create") || ($action=="edit")) print ""; print "\n"; + print ''; - print ''; - print "trans("Save")."\">"; - print "trans("Cancel")."\">"; - print ""; - print ""; - print ""; - print "\n"; - - print ''; + print '

'; + print ''; + print ''; + print ""; print "\n"; @@ -608,5 +619,8 @@ if (($action=="create") || ($action=="edit")) print '

'; } + +llxFooter(); + $db->close(); -llxFooter(); \ No newline at end of file +?> \ No newline at end of file diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index f75fcb5754b..0ae8f71b3a5 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -25,8 +25,6 @@ require '../main.inc.php'; require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); - -// librairie jobs require_once DOL_DOCUMENT_ROOT."/cron/class/cronjob.class.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/cron.lib.php'; @@ -99,6 +97,8 @@ if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->ex setEventMessage($object->error,'errors'); } + header("Location: ".DOL_URL_ROOT.'/cron/list.php?status=-1'); // Make a call to avoid to run twice job when using back + exit; } @@ -141,8 +141,8 @@ if ($result < 0) { print "

"; -if (count($object->lines)>0) { - +if (count($object->lines)>0) +{ print ''; print ''; $arg_url='&page='.$page.'&status='.$status.'&search_label='.$search_label; @@ -156,7 +156,7 @@ if (count($object->lines)>0) { print_liste_field_titre($langs->trans("CronNbRun"),$_SERVEUR['PHP_SELF'],"t.nbrun","",$arg_url,'',$sortfield,$sortorder); print_liste_field_titre($langs->trans("CronLastResult"),$_SERVEUR['PHP_SELF'],"t.lastresult","",$arg_url,'',$sortfield,$sortorder); print_liste_field_titre($langs->trans("CronLastOutput"),$_SERVEUR['PHP_SELF'],"t.lastoutput","",$arg_url,'',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Active"),$_SERVEUR['PHP_SELF'],"t.status","",$arg_url,'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Enabled"),$_SERVEUR['PHP_SELF'],"t.status","",$arg_url,'align="center"',$sortfield,$sortorder); print ''; print ''; @@ -303,6 +303,10 @@ print ''; print '
'; + +dol_print_cron_urls(); + + llxFooter(); $db->close(); diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang index 567b541c7cd..b24339f0b5f 100644 --- a/htdocs/langs/en_US/cron.lang +++ b/htdocs/langs/en_US/cron.lang @@ -21,12 +21,12 @@ Permission23104 = Execute Scheduled task # # Admin # -CronSetup= Configuration Scheduled task management +CronSetup= Scheduled job management setup URLToLaunchCronJobs=URL to launch cron jobs OrToLaunchASpecificJob=Or to launch a specific job KeyForCronAccess=Security key for URL to launch cron jobs -FileToLaunchCronJobs=Command to launch cron jobs -CronExplainHowToRunUnix=On Unix environement you should use crontab to run Command line each minutes +FileToLaunchCronJobs=Command line to launch cron jobs +CronExplainHowToRunUnix=On Unix environment you should use crontab to run Command line each minutes CronExplainHowToRunWin=On Microsoft(tm) Windows environement you can use Scheduled task tools to run Command line each minutes @@ -48,15 +48,15 @@ CronListOfCronJobs=List of scheduled jobs CronCommand=Command CronList= Job list CronDelete= Delete cron jobs -CronConfirmDelete= Are you sure to delete this cron jobs ? -CronExecute=Launch task +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 -CronTask=Task +CronTask=Job CronNone= None CronDtStart=Start date -CronDtEnd=End fin +CronDtEnd=End date CronDtNextLaunch=Next execution CronDtLastLaunch=Last execution CronFrequency=Frequancy @@ -65,12 +65,14 @@ CronMethod=Method CronModule=Module CronAction=Action CronStatus=Status -CronStatusActive=Active -CronStatusInactive=Inactive +CronStatusActive=Enabled +CronStatusInactive=Disabled CronNoJobs=No jobs registered CronPriority=Priority CronLabel=Description CronNbRun=Nb. launch +CronEach=Every +JobFinished=Job launched and finished # #Page card @@ -84,12 +86,12 @@ CronSaveSucess=Save succesfully CronNote=Comment CronFieldMandatory=Fields %s is mandatory CronErrEndDateStartDt=End date cannot be before start date -CronStatusActiveBtn=Active -CronStatusInactiveBtn=Inactive -CronTaskInactive=This task is inactive +CronStatusActiveBtn=Enable +CronStatusInactiveBtn=Disable +CronTaskInactive=This job is disabled CronDtLastResult=Last result date CronId=Id -CronClassFile=Classes (file name) +CronClassFile=Classes (filename.class.php) CronModuleHelp=Name of Dolibarr module directory (also work with external Dolibarr module).
For exemple to fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value of module is product CronClassFileHelp=The file name to load.
For exemple to fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value of class file name is product.class.php CronObjectHelp=The object name to load.
For exemple to fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value of class file name is Product diff --git a/htdocs/langs/fr_FR/cron.lang b/htdocs/langs/fr_FR/cron.lang index 95c1546e4af..6e68fb659de 100644 --- a/htdocs/langs/fr_FR/cron.lang +++ b/htdocs/langs/fr_FR/cron.lang @@ -1,7 +1,7 @@ # Dolibarr language file - en_US - cron CHARSET=UTF-8 Module2310Name=Cron -Module2310Desc=Gestion des tâches programmées +Module2310Desc=Gestion des travaux programmées # # About page @@ -13,20 +13,20 @@ CronAboutPage = Page à propos de Cron # # Right # -Permission23101 = Voir la tâche planifiée -Permission23102 = Créer/modifier la tâche planifiée -Permission23103 = Supprimer la tâche planifiée -Permission23104 = Lancer la tâche planifiée +Permission23101 = Voir les travaux planifiés +Permission23102 = Créer/modifier des travaux planifiés +Permission23103 = Supprimer un travail planifiée +Permission23104 = Lancer un travail planifié # # Admin # -CronSetup= Page de configuration du module - Gestion des tâches planifiées -URLToLaunchCronJobs=URL pour lancer les travaux cron -OrToLaunchASpecificJob=Ou pour lancer un travail spécifique -KeyForCronAccess=Clé de sécurité pour l'URL de lancement des travaux cron -FileToLaunchCronJobs=Commande pour lancer les travaux cron -CronExplainHowToRunUnix=Sur un environnement Unix vous devez utiliser crontab pour exécuter une commande toute les minutes +CronSetup= Page de configuration du module - Gestion des travaux planifiées +URLToLaunchCronJobs=URL pour lancer les travaux planifiés actifs +OrToLaunchASpecificJob=Ou pour lancer un travail planifié spécifique +KeyForCronAccess=Clé de sécurité pour l'URL de lancement des travaux planifiés +FileToLaunchCronJobs=Commande pour lancer les travaux planifiés actifs +CronExplainHowToRunUnix=Sur un environnement Unix vous pouvez utiliser 'crontab' pour exécuter une commande toute les minutes CronExplainHowToRunWin=Sur un environement Microsoft(tm) Windows vous pouvez utiliser le planificateur de tâche pour lancer une commande toute les minutes @@ -71,6 +71,8 @@ CronNoJobs=Aucun travail enregistré CronPriority=Priorité CronLabel=Description CronNbRun=Nb. exec. +CronEach=Tous les +JobFinished=Tache lancée et terminée # #Page card diff --git a/htdocs/public/cron/cron_run_jobs.php b/htdocs/public/cron/cron_run_jobs.php index 7f25cfaf63c..79eaf5e7013 100644 --- a/htdocs/public/cron/cron_run_jobs.php +++ b/htdocs/public/cron/cron_run_jobs.php @@ -1,6 +1,7 @@ + * Copyright (C) 2013 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,9 +41,20 @@ if (! $res) die("Include of master.inc.php fails"); // librarie jobs dol_include_once("/cron/class/cronjob.class.php"); - global $langs, $conf; +// Language Management +$langs->load("admin"); +$langs->load("cron"); + + + + + +/* + * View + */ + // Check the key, avoid that a stranger starts cron $key = $_GET['securitykey']; if (empty($key)) { @@ -55,80 +67,101 @@ if($key != $conf->global->CRON_KEY) exit; } // Check the key, avoid that a stranger starts cron -$userlogin = $_GET['userlogin']; -if (empty($userlogin)) { +$userlogin = GETPOST('userlogin'); +if (empty($userlogin)) +{ echo 'userlogin is require'; exit; } require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; $user=new User($db); $result=$user->fetch('',$userlogin); -if ($result<0) { +if ($result < 0) +{ echo "User Error:".$user->error; - dol_syslog("cron_run_jobs.php:: User Error:".$user->error, LOG_ERR); + dol_syslog("cron_run_jobs.php:: User Error:".$user->error, LOG_WARNING); exit; -}else { - if (empty($user->id)) { +} +else +{ + if (empty($user->id)) + { echo " User user login:".$userlogin." do not exists"; - dol_syslog(" User user login:".$userlogin." do not exists", LOG_ERR); + dol_syslog(" User user login:".$userlogin." do not exists", LOG_WARNING); exit; } } -$id = $_GET['id']; - -// Language Management -$langs->load("admin"); -$langs->load("cron@cron"); +$id = GETPOST('id'); // create a jobs object $object = new Cronjob($db); $filter=array(); -if (empty($id)) { +if (! empty($id)) +{ + if (! is_numeric($id)) + { + echo "Error: Bad value for parameter job id"; + dol_syslog("cron_run_jobs.php Bad value for parameter job id", LOG_WARNING); + exit; + } $filter=array(); $filter['t.rowid']=$id; } $result = $object->fetch_all('DESC','t.rowid', 0, 0, 1, $filter); -if ($result<0) { - echo "Error:".$cronjob->error; - dol_syslog("cron_run_jobs.php:: fetch Error".$cronjob->error, LOG_ERR); +if ($result<0) +{ + echo "Error: ".$cronjob->error; + dol_syslog("cron_run_jobs.php fetch Error".$cronjob->error, LOG_WARNING); exit; } // current date $now=dol_now(); +$nbofjobs=count($object->lines); +$nbofjobslaunchedok=0; +$nbofjobslaunchedko=0; -if(is_array($object->lines) && (count($object->lines)>0)){ +if (is_array($object->lines) && (count($object->lines)>0)) +{ // Loop over job - foreach($object->lines as $line){ - - dol_syslog("cron_run_jobs.php:: fetch cronjobid:".$line->id, LOG_ERR); + foreach($object->lines as $line) + { + dol_syslog("cron_run_jobs.php fetch cronjobid: ".$line->id, LOG_WARNING); //If date_next_jobs is less of current dat, execute the program, and store the execution time of the next execution in database if ((($line->datenextrun <= $now) && $line->dateend < $now) - || ((empty($line->datenextrun)) && (empty($line->dateend)))){ + || ((empty($line->datenextrun)) && (empty($line->dateend)))) + { - dol_syslog("cron_run_jobs.php:: torun line->datenextrun:".dol_print_date($line->datenextrun,'dayhourtext')." line->dateend:".dol_print_date($line->dateend,'dayhourtext')." now:".dol_print_date($now,'dayhourtext'), LOG_ERR); + dol_syslog("cron_run_jobs.php:: torun line->datenextrun:".dol_print_date($line->datenextrun,'dayhourtext')." line->dateend:".dol_print_date($line->dateend,'dayhourtext')." now:".dol_print_date($now,'dayhourtext')); $cronjob=new Cronjob($db); $result=$cronjob->fetch($line->id); - if ($result<0) { + if ($result<0) + { echo "Error:".$cronjob->error; dol_syslog("cron_run_jobs.php:: fetch Error".$cronjob->error, LOG_ERR); exit; } - // execute methode + // Execut job $result=$cronjob->run_jobs($userlogin); - if ($result<0) { + if ($result<0) + { echo "Error:".$cronjob->error; dol_syslog("cron_run_jobs.php:: run_jobs Error".$cronjob->error, LOG_ERR); - exit; + $nbofjobslaunchedko++; + } + else + { + $nbofjobslaunchedok++; } - // we re-program the next execution and stores the last execution time for this job + // We re-program the next execution and stores the last execution time for this job $result=$cronjob->reprogram_jobs($userlogin); - if ($result<0) { + if ($result<0) + { echo "Error:".$cronjob->error; dol_syslog("cron_run_jobs.php:: reprogram_jobs Error".$cronjob->error, LOG_ERR); exit; @@ -136,7 +169,12 @@ if(is_array($object->lines) && (count($object->lines)>0)){ } } - echo "OK"; -} else { - echo "No Jobs to run"; + echo "Result: ".($nbofjobs)." jobs - ".($nbofjobslaunchedok+$nbofjobslaunchedko)." launched = ".$nbofjobslaunchedok." OK + ".$nbofjobslaunchedko." KO"; } +else +{ + echo "No active jobs found"; +} + +$db->close(); +?> \ No newline at end of file