diff --git a/core/backgroundprocess.inc.php b/core/backgroundprocess.inc.php
index 625385f59..ba23b7030 100644
--- a/core/backgroundprocess.inc.php
+++ b/core/backgroundprocess.inc.php
@@ -56,8 +56,9 @@ interface iBackgroundProcess extends iProcess
* interface iScheduledProcess
* A variant of process that must be called at specific times
*
- * @copyright Copyright (C) 2013 Combodo SARL
+ * @see \AbstractWeeklyScheduledProcess for a bootstrap implementation
* @license http://opensource.org/licenses/AGPL-3.0
+ * @copyright Copyright (C) 2013 Combodo SARL
*/
interface iScheduledProcess extends iProcess
{
@@ -67,14 +68,189 @@ interface iScheduledProcess extends iProcess
public function GetNextOccurrence();
}
+
/**
- * Class ProcessException
- * Exception for iProcess implementations.
+ * Implementation of {@link iScheduledProcess}, using config parameters for module
+ *
+ * Use these parameters :
+ *
+ * * enabled
+ * * week_days
+ * * time
+ *
+ * Param names and some of their default values are in constant that can be overriden.
+ *
+ * Other info (module name and time default value) should be provided using a method that needs to be implemented.
+ *
+ * @since 2.7.0
+ */
+abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
+{
+ // param have default names/values but can be overriden
+ const MODULE_SETTING_ENABLED = 'enabled';
+ const DEFAULT_MODULE_SETTING_ENABLED = true;
+ const MODULE_SETTING_WEEKDAYS = 'week_days';
+ const DEFAULT_MODULE_SETTING_WEEKDAYS = 'monday, tuesday, wednesday, thursday, friday, saturday, sunday';
+ const MODULE_SETTING_TIME = 'time';
+
+ /**
+ * Module must be declared in each implementation
+ *
+ * @return string
+ */
+ abstract protected function GetModuleName();
+
+ /**
+ * @return string default value for {@link MODULE_SETTING_TIME} config param.
+ * example '23:30'
+ */
+ abstract protected function GetDefaultModuleSettingTime();
+
+ /**
+ * Interpret current setting for the week days
+ *
+ * @returns int[] (monday = 1)
+ * @throws ProcessInvalidConfigException
+ */
+ public function InterpretWeekDays()
+ {
+ static $aWEEKDAYTON = array(
+ 'monday' => 1,
+ 'tuesday' => 2,
+ 'wednesday' => 3,
+ 'thursday' => 4,
+ 'friday' => 5,
+ 'saturday' => 6,
+ 'sunday' => 7,
+ );
+ $aDays = array();
+ $sWeekDays = MetaModel::GetConfig()->GetModuleSetting(
+ $this->GetModuleName(),
+ static::MODULE_SETTING_WEEKDAYS,
+ static::DEFAULT_MODULE_SETTING_WEEKDAYS
+ );
+
+ if ($sWeekDays !== '')
+ {
+ $aWeekDaysRaw = explode(',', $sWeekDays);
+ foreach ($aWeekDaysRaw as $sWeekDay)
+ {
+ $sWeekDay = strtolower(trim($sWeekDay));
+ if (array_key_exists($sWeekDay, $aWEEKDAYTON))
+ {
+ $aDays[] = $aWEEKDAYTON[$sWeekDay];
+ }
+ else
+ {
+ throw new ProcessInvalidConfigException($this->GetModuleName().": wrong format for setting '".static::MODULE_SETTING_WEEKDAYS."' (found '$sWeekDay')");
+ }
+ }
+ }
+ if (count($aDays) === 0)
+ {
+ throw new ProcessInvalidConfigException($this->GetModuleName().': missing setting \''.static::MODULE_SETTING_WEEKDAYS.'\'');
+ }
+ $aDays = array_unique($aDays);
+ sort($aDays);
+
+ return $aDays;
+ }
+
+ /**
+ * Gives the exact time at which the process must be run next time
+ *
+ * @return DateTime
+ * @throws Exception
+ */
+ public function GetNextOccurrence()
+ {
+ $bEnabled = MetaModel::GetConfig()->GetModuleSetting(
+ $this->GetModuleName(),
+ static::MODULE_SETTING_ENABLED,
+ static::DEFAULT_MODULE_SETTING_ENABLED
+ );
+ if (!$bEnabled)
+ {
+ return new DateTime('3000-01-01');
+ }
+
+ // 1st - Interpret the list of days as ordered numbers (monday = 1)
+ //
+ $aDays = $this->InterpretWeekDays();
+
+ // 2nd - Find the next active week day
+ //
+ $sProcessTime = MetaModel::GetConfig()->GetModuleSetting(
+ $this->GetModuleName(),
+ static::MODULE_SETTING_TIME,
+ static::DEFAULT_MODULE_SETTING_TIME
+ );
+ if (!preg_match('/[0-2][0-9]:[0-5][0-9]/', $sProcessTime))
+ {
+ throw new ProcessInvalidConfigException($this->GetModuleName().": wrong format for setting '".static::MODULE_SETTING_TIME."' (found '$sProcessTime')");
+ }
+ $oNow = new DateTime();
+ $iNextPos = false;
+ for ($iDay = $oNow->format('N'); $iDay <= 7; $iDay++)
+ {
+ $iNextPos = array_search($iDay, $aDays, true);
+ if ($iNextPos !== false)
+ {
+ if (($iDay > $oNow->format('N')) || ($oNow->format('H:i') < $sProcessTime))
+ {
+ break;
+ }
+ $iNextPos = false; // necessary on sundays
+ }
+ }
+
+ // 3rd - Compute the result
+ //
+ if ($iNextPos === false)
+ {
+ // Jump to the first day within the next week
+ $iFirstDayOfWeek = $aDays[0];
+ $iDayMove = $oNow->format('N') - $iFirstDayOfWeek;
+ $oRet = clone $oNow;
+ $oRet->modify('-'.$iDayMove.' days');
+ $oRet->modify('+1 weeks');
+ }
+ else
+ {
+ $iNextDayOfWeek = $aDays[$iNextPos];
+ $iMove = $iNextDayOfWeek - $oNow->format('N');
+ $oRet = clone $oNow;
+ $oRet->modify('+'.$iMove.' days');
+ }
+ list($sHours, $sMinutes) = explode(':', $sProcessTime);
+ $oRet->setTime((int)$sHours, (int)$sMinutes);
+
+ return $oRet;
+ }
+
+ /**
+ * @see \iProcess
+ *
+ * @param int $iUnixTimeLimit
+ *
+ * @return string
+ */
+ abstract public function Process($iUnixTimeLimit);
+}
+
+/**
+ * Exception for {@link iProcess} implementations.
* An error happened during the processing but we can go on with the next implementations.
*/
class ProcessException extends CoreException
{
+}
+/**
+ * @since 2.7.0
+ */
+class ProcessInvalidConfigException extends ProcessException
+{
}
/**
@@ -84,5 +260,4 @@ class ProcessException extends CoreException
*/
class ProcessFatalException extends CoreException
{
-
}
diff --git a/datamodels/2.x/itop-backup/main.itop-backup.php b/datamodels/2.x/itop-backup/main.itop-backup.php
index 698bfc70b..d53d37cbf 100644
--- a/datamodels/2.x/itop-backup/main.itop-backup.php
+++ b/datamodels/2.x/itop-backup/main.itop-backup.php
@@ -85,16 +85,26 @@ class DBBackupScheduled extends DBBackup
}
}
-class BackupExec implements iScheduledProcess
+class BackupExec extends AbstractWeeklyScheduledProcess
{
protected $sBackupDir;
protected $iRetentionCount;
+ protected function GetModuleName()
+ {
+ return 'itop-backup';
+ }
+
+ protected function GetDefaultModuleSettingTime()
+ {
+ return '23:30';
+ }
+
/**
- * Constructor
- * @param sBackupDir string Target directory, defaults to APPROOT/data/backups/auto
- * @param iRetentionCount int Rotation (default to the value given in the configuration file 'retentation_count') set to 0 to disable this feature
- */
+ * @param string $sBackupDir Target directory, defaults to APPROOT/data/backups/auto
+ * @param int $iRetentionCount default to the value given in the configuration file 'retentation_count'
+ * set to 0 to disable this feature
+ */
public function __construct($sBackupDir = null, $iRetentionCount = null)
{
if (is_null($sBackupDir))
@@ -107,7 +117,7 @@ class BackupExec implements iScheduledProcess
}
if (is_null($iRetentionCount))
{
- $this->iRetentionCount = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'retention_count', 5);
+ $this->iRetentionCount = MetaModel::GetConfig()->GetModuleSetting($this->GetModuleName(), 'retention_count', 5);
}
else
{
@@ -151,9 +161,10 @@ class BackupExec implements iScheduledProcess
// Do execute the backup
//
- $oBackup->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', ''));
-
- $sBackupFileFormat = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'file_name_format', '__DB__-%Y-%m-%d_%H_%M');
+ $oBackup->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting($this->GetModuleName(), 'mysql_bindir', ''));
+
+ $sBackupFileFormat = MetaModel::GetConfig()->GetModuleSetting($this->GetModuleName(), 'file_name_format',
+ '__DB__-%Y-%m-%d_%H_%M');
$sName = $oBackup->MakeName($sBackupFileFormat);
if ($sName == '')
{
@@ -179,101 +190,4 @@ class BackupExec implements iScheduledProcess
return "Created the backup: $sBackupFile";
}
- /**
- * Interpret current setting for the week days
- * @returns array of int (monday = 1)
- * @throws Exception
- */
- public function InterpretWeekDays()
- {
- static $aWEEKDAYTON = array('monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6, 'sunday' => 7);
- $aDays = array();
- $sWeekDays = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'week_days', 'monday, tuesday, wednesday, thursday, friday');
- if ($sWeekDays != '')
- {
- $aWeekDaysRaw = explode(',', $sWeekDays);
- foreach ($aWeekDaysRaw as $sWeekDay)
- {
- $sWeekDay = strtolower(trim($sWeekDay));
- if (array_key_exists($sWeekDay, $aWEEKDAYTON))
- {
- $aDays[] = $aWEEKDAYTON[$sWeekDay];
- }
- else
- {
- throw new Exception("'itop-backup: wrong format for setting 'week_days' (found '$sWeekDay')");
- }
- }
- }
- if (count($aDays) == 0)
- {
- throw new Exception("'itop-backup: missing setting 'week_days'");
- }
- $aDays = array_unique($aDays);
- sort($aDays);
- return $aDays;
- }
-
- /** Gives the exact time at which the process must be run next time
- * @return DateTime
- * @throws Exception
- */
- public function GetNextOccurrence()
- {
- $bEnabled = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'enabled', true);
- if (!$bEnabled)
- {
- $oRet = new DateTime('3000-01-01');
- }
- else
- {
- // 1st - Interpret the list of days as ordered numbers (monday = 1)
- //
- $aDays = $this->InterpretWeekDays();
-
- // 2nd - Find the next active week day
- //
- $sBackupTime = MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'time', '23:30');
- if (!preg_match('/[0-2][0-9]:[0-5][0-9]/', $sBackupTime))
- {
- throw new Exception("'itop-backup: wrong format for setting 'time' (found '$sBackupTime')");
- }
- $oNow = new DateTime();
- $iNextPos = false;
- for ($iDay = $oNow->format('N') ; $iDay <= 7 ; $iDay++)
- {
- $iNextPos = array_search($iDay, $aDays);
- if ($iNextPos !== false)
- {
- if (($iDay > $oNow->format('N')) || ($oNow->format('H:i') < $sBackupTime))
- {
- break;
- }
- $iNextPos = false; // necessary on sundays
- }
- }
-
- // 3rd - Compute the result
- //
- if ($iNextPos === false)
- {
- // Jump to the first day within the next week
- $iFirstDayOfWeek = $aDays[0];
- $iDayMove = $oNow->format('N') - $iFirstDayOfWeek;
- $oRet = clone $oNow;
- $oRet->modify('-'.$iDayMove.' days');
- $oRet->modify('+1 weeks');
- }
- else
- {
- $iNextDayOfWeek = $aDays[$iNextPos];
- $iMove = $iNextDayOfWeek - $oNow->format('N');
- $oRet = clone $oNow;
- $oRet->modify('+'.$iMove.' days');
- }
- list($sHours, $sMinutes) = explode(':', $sBackupTime);
- $oRet->setTime((int)$sHours, (int) $sMinutes);
- }
- return $oRet;
- }
}
diff --git a/webservices/cron.php b/webservices/cron.php
index dc4e866fc..e7544878d 100644
--- a/webservices/cron.php
+++ b/webservices/cron.php
@@ -528,6 +528,10 @@ $aProcesses = array();
foreach (get_declared_classes() as $sPHPClass)
{
$oRefClass = new ReflectionClass($sPHPClass);
+ if ($oRefClass->isAbstract())
+ {
+ continue;
+ }
$oExtensionInstance = null;
if ($oRefClass->implementsInterface('iProcess'))
{