From 19d119d3a41407bd6b26d7f49e4294bd02f8323d Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@destailleur.fr>
Date: Sat, 30 Jan 2016 02:51:26 +0100
Subject: [PATCH] Debug cron module. Task to delete temporary files older than
 24 is on by default.

---
 htdocs/core/class/utils.class.php             |  20 ++-
 htdocs/core/modules/DolibarrModules.class.php |   3 +-
 htdocs/core/modules/modCron.class.php         |   6 +
 htdocs/cron/card.php                          |   6 +-
 htdocs/cron/class/cronjob.class.php           | 151 ++++++++++--------
 htdocs/cron/list.php                          |  46 +++---
 htdocs/langs/en_US/admin.lang                 |   1 +
 7 files changed, 135 insertions(+), 98 deletions(-)

diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php
index 23827a31b94..3132423d614 100644
--- a/htdocs/core/class/utils.class.php
+++ b/htdocs/core/class/utils.class.php
@@ -43,21 +43,33 @@ class Utils
 	/**
 	 *  Purge files into directory of data files.
 	 *
-	 *  @param	string		$choice		Choice of purge mode ('tempfiles', 'allfiles', 'logfiles')
+	 *  @param	string		$choice		Choice of purge mode ('tempfiles', 'tempfilesold' to purge temp older than 24h, 'allfiles', 'logfiles')
 	 *  @return	int						Nb of files deleted 
 	 */
-	function purgeFiles($choice)
+	function purgeFiles($choice='tempfilesold')
 	{
 		global $conf, $dolibarr_main_data_root;
 		
+		dol_syslog("Utils::purgeFiles choice=".$choice, LOG_DEBUG);
+		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
+		
 		$filesarray=array();
+		if (empty($choice)) $choice='tempfilesold';
 		
-		if ($choice=='tempfiles')
+		if ($choice=='tempfiles' || $choice=='tempfilesold')
 		{
 			// Delete temporary files
 			if ($dolibarr_main_data_root)
 			{
-				$filesarray=dol_dir_list($dolibarr_main_data_root,"directories",1,'^temp$');
+				$filesarray=dol_dir_list($dolibarr_main_data_root,"directories",1,'^temp$','','','',2);
+				if ($choice == 'tempfilesold')
+				{
+					$now = dol_now();
+					foreach($filesarray as $key => $val)
+					{
+						if ($val['date'] > ($now - (24 * 3600))) unset($filesarray[$key]);	// Discard files not older than 24h
+					}
+				}
 			}
 		}
 	
diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php
index 11d904f58d4..06b3bc89860 100644
--- a/htdocs/core/modules/DolibarrModules.class.php
+++ b/htdocs/core/modules/DolibarrModules.class.php
@@ -936,10 +936,11 @@ class DolibarrModules           // Can not be abstract, because we need to insta
 
                         if (! $err)
                         {
-                            $sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, label, jobtype, classesname, objectname, methodename, command, params, note, frequency, unitfrequency, entity)";
+                            $sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note, frequency, unitfrequency, entity)";
                             $sql.= " VALUES (";
                             $sql.= "'".$this->db->escape($this->rights_class)."', ";
                             $sql.= "'".$this->db->idate($now)."', ";
+                            $sql.= "'".$this->db->idate($now)."', ";
                             $sql.= "'".$this->db->escape($label)."', ";
                             $sql.= "'".$this->db->escape($jobtype)."', ";
                             $sql.= ($class?"'".$this->db->escape($class)."'":"null").",";
diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php
index aefb599a9b7..4981eeb0089 100644
--- a/htdocs/core/modules/modCron.class.php
+++ b/htdocs/core/modules/modCron.class.php
@@ -99,6 +99,12 @@ class modCron extends DolibarrModules
 		$this->rights_class = 'cron';
 		$r=0;
 
+		// Cronjobs
+		$this->cronjobs = array(
+			0=>array('label'=>'PurgeDeleteTemporaryFilesShort', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'purgeFiles', 'parameters'=>'', 'comment'=>'PurgeDeleteTemporaryFiles', 'frequency'=>1, 'unitfrequency'=>3600 * 24 * 7),
+			// 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24)
+		);
+		
 		$this->rights[$r][0] = 23001;
 		$this->rights[$r][1] = 'Read cron jobs';
 		$this->rights[$r][3] = 1;
diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php
index e91b359ed98..76781d6645e 100644
--- a/htdocs/cron/card.php
+++ b/htdocs/cron/card.php
@@ -1,7 +1,7 @@
 <?php
 /* Copyright (C) 2012      Nicolas Villa aka Boyquotes http://informetic.fr
  * Copyright (C) 2013      Florian Henry <florian.henry@open-concpt.pro>
- * Copyright (C) 2013-2015 Laurent Destailleur <eldy@users.sourceforge.net>
+ * Copyright (C) 2013-2016 Laurent Destailleur <eldy@users.sourceforge.net>
  *
  * 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
@@ -539,7 +539,7 @@ else
 
 	print '<tr><td>';
 	print $langs->trans('CronLabel')."</td>";
-	print "<td>".$object->label;
+	print "<td>".$langs->trans($object->label);
 	print "</td></tr>";
 
 	print "<tr><td>";
@@ -579,7 +579,7 @@ else
 
 	print '<tr><td>';
 	print $langs->trans('CronNote')."</td><td>";
-	print $object->note;
+	print $langs->trans($object->note);
 	print "</td></tr>";
 
 	print '<tr><td>';
diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php
index a66fcd9597c..a22b4aa21c0 100644
--- a/htdocs/cron/class/cronjob.class.php
+++ b/htdocs/cron/class/cronjob.class.php
@@ -500,7 +500,6 @@ class Cronjob extends CommonObject
 		$error=0;
 
 		// Clean parameters
-
 		if (isset($this->label)) $this->label=trim($this->label);
 		if (isset($this->jobtype)) $this->jobtype=trim($this->jobtype);
 		if (isset($this->command)) $this->command=trim($this->command);
@@ -524,7 +523,7 @@ class Cronjob extends CommonObject
 		// Check parameters
 		// Put here code to add a control on parameters values
 		if (dol_strlen($this->datestart)==0) {
-			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->trans('CronDtStart'));
+			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->transnoentitiesnoconv('CronDtStart'));
 			$error++;
 		}
 		if ((dol_strlen($this->datestart)!=0) && (dol_strlen($this->dateend)!=0) && ($this->dateend<$this->datestart)) {
@@ -532,32 +531,32 @@ class Cronjob extends CommonObject
 			$error++;
 		}
 		if (empty($this->label)) {
-			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->trans('CronLabel'));
+			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->transnoentitiesnoconv('CronLabel'));
 			$error++;
 		}
 		if (empty($this->unitfrequency)) {
-			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->trans('CronFrequency'));
+			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->transnoentitiesnoconv('CronFrequency'));
 			$error++;
 		}
 		if (($this->jobtype=='command') && (empty($this->command))) {
-			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->trans('CronCommand'));
+			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->transnoentitiesnoconv('CronCommand'));
 			$error++;
 		}
 		if (($this->jobtype=='method') && (empty($this->classesname))) {
-			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->trans('CronClass'));
+			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->transnoentitiesnoconv('CronClass'));
 			$error++;
 		}
 		if (($this->jobtype=='method' || $this->jobtype == 'function') && (empty($this->methodename))) {
-			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->trans('CronMethod'));
+			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->transnoentitiesnoconv('CronMethod'));
 			$error++;
 		}
 		if (($this->jobtype=='method') && (empty($this->objectname))) {
-			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->trans('CronObject'));
+			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->transnoentitiesnoconv('CronObject'));
 			$error++;
 		}
 
 		if (($this->jobtype=='function') && (empty($this->libname))) {
-			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->trans('CronLib'));
+			$this->errors[]=$langs->trans('CronFieldMandatory',$langs->transnoentitiesnoconv('CronLib'));
 			$error++;
 		}
 
@@ -592,7 +591,7 @@ class Cronjob extends CommonObject
 		$sql.= " libname=".(isset($this->libname)?"'".$this->db->escape($this->libname)."'":"null");
         $sql.= " WHERE rowid=".$this->id;
 
-		$this->db->begin();
+        $this->db->begin();
 
 		dol_syslog(get_class($this)."::update", LOG_DEBUG);
         $resql = $this->db->query($sql);
@@ -841,6 +840,8 @@ class Cronjob extends CommonObject
 		global $langs, $conf;
 
 		$now=dol_now();
+		$error = 0;
+		$retval = '';
 
 		$langs->load('cron');
 
@@ -889,7 +890,7 @@ class Cronjob extends CommonObject
 		}
 
 
-		// Update last run date (to track launch)
+		// Update last run date (to track running jobs)
 		$this->datelastrun=$now;
 		$this->lastoutput='';
 		$this->lastresult='';
@@ -904,49 +905,63 @@ class Cronjob extends CommonObject
 		if ($this->jobtype=='method')
 		{
 			// load classes
-			$file = "/".$this->module_name."/class/".$this->classesname;
-			$ret=dol_include_once($file,$this->objectname);
-			if ($ret===false)
+			$ret=dol_include_once($this->classesname,$this->objectname);
+			if (! $error && $ret===false)
 			{
-				$this->error=$langs->trans('CronCannotLoadClass',$file,$this->objectname);
+				$this->error=$langs->trans('CronCannotLoadClass',$this->classesname,$this->objectname);
 				dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
-				return -1;
+				$this->lastoutput = $this->error;
+				$this->lastresult = -1;
+                $retval = $this->lastresult;
+                $error++;
 			}
 
 			// Load langs
-			$result=$langs->load($this->module_name.'@'.$this->module_name);
-			if ($result<0)
+			if (! $error)
 			{
-				dol_syslog(get_class($this)."::run_jobs Cannot load module langs".$langs->error, LOG_ERR);
-				return -1;
-			}
-
-			dol_syslog(get_class($this)."::run_jobs ".$this->objectname."->".$this->methodename."(".$this->params.");", LOG_DEBUG);
-
-			// Create Object for the call module
-			$object = new $this->objectname($this->db);
-
-			$params_arr = explode(", ",$this->params);
-			if (!is_array($params_arr))
-			{
-				$result = call_user_func(array($object, $this->methodename), $this->params);
-			}
-			else
-			{
-				$result = call_user_func_array(array($object, $this->methodename), $params_arr);
-			}
-
-			if ($result===false)
-			{
-				dol_syslog(get_class($this)."::run_jobs ".$object->error, LOG_ERR);
-				return -1;
+				$result=$langs->load($this->module_name.'@'.$this->module_name);
+				if ($result<0)
+				{
+					dol_syslog(get_class($this)."::run_jobs Cannot load module lang file - ".$langs->error, LOG_ERR);
+					$this->lastoutput = $langs->error;
+					$this->lastresult = -1;
+	                $retval = $this->lastresult;
+	                $error++;
+				}
 			}
-			else
+			
+			if (! $error)
 			{
-				$this->lastoutput=var_export($result,true);
-				$this->lastresult=var_export($result,true);
-			}
-
+				dol_syslog(get_class($this)."::run_jobs ".$this->objectname."->".$this->methodename."(".$this->params.");", LOG_DEBUG);
+	
+				// Create Object for the call module
+				$object = new $this->objectname($this->db);
+	
+				$params_arr = explode(", ",$this->params);
+				if (!is_array($params_arr))
+				{
+					$result = call_user_func(array($object, $this->methodename), $this->params);
+				}
+				else
+				{
+					$result = call_user_func_array(array($object, $this->methodename), $params_arr);
+				}
+			
+				if ($result===false)
+				{
+					dol_syslog(get_class($this)."::run_jobs ".$object->error, LOG_ERR);
+					$this->lastoutput = $object->error;
+					$this->lastresult = -1;
+		            $retval = $this->lastresult;
+		            $error++;
+				}
+				else
+				{
+					$this->lastoutput='NA';
+					$this->lastresult=var_export($result,true);
+					$retval = $this->lastresult;
+				}
+			}		
 		}
 
 		if($this->jobtype == 'function')
@@ -981,12 +996,16 @@ class Cronjob extends CommonObject
 			if ($result === false)
 			{
 				dol_syslog(get_class($this) . "::run_jobs " . $object->error, LOG_ERR);
-				return -1;
+				
+				$this->lastoutput = $object->error;
+				$this->lastresult = -1;
+                $retval = $this->lastresult;
 			}
 			else
 			{
                 $this->lastoutput=var_export($result,true);
-                $this->lastresult=var_export($result,true);
+                $this->lastresult=var_export($result,true);	// Return code
+                $retval = $this->lastresult;
 			}
 		}
 
@@ -1029,9 +1048,7 @@ class Cronjob extends CommonObject
 
 		dol_syslog(get_class($this)."::run_jobs output_arr:".var_export($output_arr,true), LOG_DEBUG);
 
-
 		// Update with result
-		$this->lastoutput='';
 		if (is_array($output_arr) && count($output_arr)>0)
 		{
 			foreach($output_arr as $val)
@@ -1049,7 +1066,7 @@ class Cronjob extends CommonObject
 		}
 		else
 		{
-			return 1;
+			return $error?-1:1;
 		}
 
 	}
@@ -1089,26 +1106,26 @@ class Cronjob extends CommonObject
 		
 		if (empty($this->datenextrun)) 
 		{
-			$this->datenextrun = $now + ($this->frequency * $this->unitfrequency);
+			if (empty($this->datestart)) $this->datenextrun = $now + ($this->frequency * $this->unitfrequency);
+			else $this->datenextrun = $this->datestart + ($this->frequency * $this->unitfrequency);
+		}
+
+		if ($this->datenextrun < $now && $this->frequency > 0 && $this->unitfrequency > 0) 
+		{
+		    // Loop until date is after future
+		    while ($this->datenextrun < $now)
+		    {
+		        $this->datenextrun += ($this->frequency * $this->unitfrequency);
+		        
+		        // TODO For exact frequency (every month, every year, ...), use instead a dol_time_plus_duree($time, $duration_value, $duration_unit)
+		    }
 		}
 		else 
 		{
-			if ($this->datenextrun < $now && $this->frequency > 0) 
-			{
-			    // Loop until date is after future
-			    while ($this->datenextrun < $now)
-			    {
-			        $this->datenextrun += ($this->frequency * $this->unitfrequency);
-			        
-			        // TODO For exact frequency (every month, every year, ...), use instead a dol_time_plus_duree($time, $duration_value, $duration_unit)
-			    }
-			}
-			else 
-			{
-				//$this->datenextrun=$this->datenextrun + ($this->frequency * $this->unitfrequency);
-			}
+			//$this->datenextrun=$this->datenextrun + ($this->frequency * $this->unitfrequency);
 		}
 
+
 		// Archive job
 		if ($this->autodelete == 2)
 		{
@@ -1116,7 +1133,7 @@ class Cronjob extends CommonObject
 		        || ($this->dateend && ($this->datenextrun > $this->dateend)))
 		    {
 		        $this->status = 2;
-		        dol_syslog(get_class($this)."::reprogram_jobs Job must be set to archived", LOG_ERR);
+		        dol_syslog(get_class($this)."::reprogram_jobs Job will be set to archived", LOG_ERR);
 		    }
 		}
 		
diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php
index 867695cade6..3ff7e974408 100644
--- a/htdocs/cron/list.php
+++ b/htdocs/cron/list.php
@@ -54,7 +54,7 @@ if ($status == '') $status=-2;
 $search_label=GETPOST("search_label",'alpha');
 
 if (empty($sortorder)) $sortorder="DESC";
-if (empty($sortfield)) $sortfield="t.datenextrun";
+if (empty($sortfield)) $sortfield="t.status";
 if (empty($arch)) $arch = 0;
 if ($page == -1) {
 	$page = 0 ;
@@ -99,24 +99,26 @@ if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->ex
 
     $now = dol_now();   // Date we start
 
-    $result = $object->run_jobs($user->login);
-	if ($result < 0) {
+    $resrunjob = $object->run_jobs($user->login);
+	if ($resrunjob < 0) {
 		setEventMessages($object->error, $object->errors, 'errors');
 	}
-	else
+
+	// Programm next run
+	$res = $object->reprogram_jobs($user->login, $now);
+	if ($res > 0)
 	{
-		$res = $object->reprogram_jobs($user->login, $now);
-		if ($res > 0)
+		if ($resrunjob >= 0)	// We add result of reprogram ony if no error message already reported 
 		{
 			if ($object->lastresult > 0) setEventMessages($langs->trans("JobFinished"), null, 'warnings');
 			else setEventMessages($langs->trans("JobFinished"), null, 'mesgs');
-			$action='';
-		}
-		else
-		{
-			setEventMessages($object->error, $object->errors, 'errors');
-			$action='';
 		}
+		$action='';
+	}
+	else
+	{
+		setEventMessages($object->error, $object->errors, 'errors');
+		$action='';
 	}
 
 	header("Location: ".DOL_URL_ROOT.'/cron/list.php?status=-2');		// Make a call to avoid to run twice job when using back
@@ -246,21 +248,19 @@ if ($num > 0)
 		if ($line->jobtype=='method')
 		{
 		    $text=$langs->trans("CronClass");
-			$texttoshow=$langs->trans('CronModule').':'.$line->module_name.'<br>';
-			$texttoshow.=$langs->trans('CronClass').':'. $line->classesname.'<br>';
-			$texttoshow.=$langs->trans('CronObject').':'. $line->objectname.'<br>';
-			$texttoshow.=$langs->trans('CronMethod').':'. $line->methodename;
-			if(!empty($line->params)) {
-				$texttoshow.='<br>'.$langs->trans('CronArgs').':'. $line->params;
-			}
+			$texttoshow=$langs->trans('CronModule').': '.$line->module_name.'<br>';
+			$texttoshow.=$langs->trans('CronClass').': '. $line->classesname.'<br>';
+			$texttoshow.=$langs->trans('CronObject').': '. $line->objectname.'<br>';
+			$texttoshow.=$langs->trans('CronMethod').': '. $line->methodename;
+			$texttoshow.='<br>'.$langs->trans('CronArgs').':'. $line->params;
+			$texttoshow.='<br>'.$langs->trans('Comment').':'. $line->note;
 		}
 		elseif ($line->jobtype=='command') 
 		{
 			$text=$langs->trans('CronCommand');
 			$texttoshow=$langs->trans('CronCommand').': '.dol_trunc($line->command);
-			if(!empty($line->params)) {
-				$texttoshow='<br>'.$langs->trans('CronArgs').':'. $line->params;
-			}
+			$texttoshow.='<br>'.$langs->trans('CronArgs').':'. $line->params;
+			$texttoshow.='<br>'.$langs->trans('Comment').':'. $line->note;
 		}
 		print $form->textwithpicto($text, $texttoshow, 1);
 		print '</td>';
@@ -297,7 +297,7 @@ if ($num > 0)
 		print '</td>';
 
 		print '<td class="center">';
-		if(!empty($line->lastresult)) {print dol_trunc($line->lastresult);}
+		if ($line->lastresult != '') {print dol_trunc($line->lastresult);}
 		print '</td>';
 
 		print '<td>';
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 13368cbfc06..55eb22f0aee 100755
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -154,6 +154,7 @@ Purge=Purge
 PurgeAreaDesc=This page allows you to delete all files built or stored by Dolibarr (temporary files or all files in <b>%s</b> directory). Using this feature is not necessary. It is provided for users whose Dolibarr is hosted by a provider that does not offer permissions to delete files built by the web server.
 PurgeDeleteLogFile=Delete log file <b>%s</b> defined for Syslog module (no risk to loose data)
 PurgeDeleteTemporaryFiles=Delete all temporary files (no risk to loose data)
+PurgeDeleteTemporaryFilesShort=Delete temporary files
 PurgeDeleteAllFilesInDocumentsDir=Delete all files in directory <b>%s</b>. Temporary files but also database backup dumps, files attached to elements (third parties, invoices, ...) and uploaded into the ECM module will be deleted.
 PurgeRunNow=Purge now
 PurgeNothingToDelete=No directory or file to delete.
-- 
GitLab