mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°5279 - PHP 8.1: Migrate usages of deprecated strftime() function
In the end we made an adapter to keep using the strftime() format (https://www.php.net/manual/fr/function.strftime.php); not to ease migration but because we couldn't use \DateTime::format(). We can't use \DateTime::format() directly on the whole filename as it would also format characters that are not supposed to be. eg. "__DB__-Y-m-d-production" would become "itopdb-2023-02-09-+01:00Thu, 09 Feb 2023 11:34:01 +0100202309", mind the "production" part being converted.
This commit is contained in:
@@ -874,11 +874,50 @@ class utils
|
||||
*/
|
||||
public static function DateTimeFormatToPHP($sOldDateTimeFormat)
|
||||
{
|
||||
$aSearch = array('%d', '%m', '%y', '%Y', '%H', '%i', '%s');
|
||||
$aReplacement = array('d', 'm', 'y', 'Y', 'H', 'i', 's');
|
||||
$aSearch = ['%d', '%m', '%y', '%Y', '%H', '%i', '%s'];
|
||||
$aReplacement = ['d', 'm', 'y', 'Y', 'H', 'i', 's'];
|
||||
return str_replace($aSearch, $aReplacement, $sOldDateTimeFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an old strtime() date/time format specification {@link https://www.php.net/manual/fr/function.strftime.php}
|
||||
* to a format compatible with \DateTime::format {@link https://www.php.net/manual/fr/datetime.format.php}
|
||||
*
|
||||
* Example: '%Y-%m-%d %H:%M:%S' => 'Y-m-d H:i:s'
|
||||
*
|
||||
* Note: Not all strftime() formats can be converted, in which case they will be present in the returned string (eg. '%U' or '%W')
|
||||
*
|
||||
* @param string $sOldStrftimeFormat
|
||||
*
|
||||
* @return string
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public static function StrftimeFormatToDateTimeFormat(string $sOldStrftimeFormat): string
|
||||
{
|
||||
$aSearch = [
|
||||
'%d', '%m', '%y', '%Y', '%H', '%M', '%S', // Most popular formats
|
||||
'%a', '%A', '%e', '%j', '%u', '%w', // Day formats
|
||||
'%U', '%V', '%W', // Week formats
|
||||
'%b', '%B', '%h', // Month formats
|
||||
'%C', '%g', '%G', // Year formats
|
||||
'%k', '%I', '%l', '%p', '%P', '%r', '%R', '%T', '%X', '%z', '%Z', // Time formats
|
||||
'%c', '%D', '%F', '%s', '%x', // Datetime formats
|
||||
'%n', '%t', '%%', // Misc. formats
|
||||
];
|
||||
$aReplacement = [
|
||||
'd', 'm', 'y', 'Y', 'H', 'i', 's',
|
||||
'D', 'l', 'j', 'z', 'N', 'w',
|
||||
'%U', 'W', '%W',
|
||||
'M', 'F', 'M',
|
||||
'%C', 'y', 'Y',
|
||||
'G', 'h', 'g', 'A', 'a', 'h:i:s A', 'H:i', 'H:i:s', '%X', 'O', 'T',
|
||||
'%c', 'm/d/y', 'Y-m-d', 'U', '%x',
|
||||
'%n', '%t', '%',
|
||||
];
|
||||
|
||||
return str_replace($aSearch, $aReplacement, $sOldStrftimeFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to set cached config. Useful when running with {@link Parameters} for example.
|
||||
* @param \Config $oConfig
|
||||
|
||||
@@ -551,6 +551,12 @@ class LogChannels
|
||||
*/
|
||||
public const NOTIFICATIONS = 'notifications';
|
||||
|
||||
/**
|
||||
* @var string Everything related to the backup / restore
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public const BACKUP = 'backup';
|
||||
|
||||
/**
|
||||
* @since 3.0.0
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,7 @@ auth_pwd = admin
|
||||
# Full path or relative to current directory
|
||||
#
|
||||
# Formatting rules:
|
||||
# %Y-%m-%d => 2011-01-25... see PHP documentation of strftime()
|
||||
# %Y-%m-%d => 2011-01-25... see PHP documentation of strftime() (https://www.php.net/manual/fr/function.strftime.php)
|
||||
# Placeholders:
|
||||
# __HOST__ MySQL server
|
||||
# __DB__ Database name
|
||||
|
||||
@@ -69,7 +69,7 @@ function Usage($oP)
|
||||
$oP->p('auth_user: login, must be administrator');
|
||||
$oP->p('auth_pwd: ...');
|
||||
}
|
||||
$oP->p('backup_file [optional]: name of the file to store the backup into. Follows the PHP strftime format spec. The following placeholders are available: __HOST__, __DB__, __SUBNAME__');
|
||||
$oP->p('backup_file [optional]: name of the file to store the backup into. Follows the PHP strftime() format spec (https://www.php.net/manual/fr/function.strftime.php). The following placeholders are available: __HOST__, __DB__, __SUBNAME__');
|
||||
$oP->p('simulate [optional]: set to check the name of the file that would be created');
|
||||
$oP->p('mysql_bindir [optional]: specify the path for mysqldump');
|
||||
|
||||
|
||||
@@ -108,20 +108,9 @@ function MakeArchiveFileName($iRefTime = null)
|
||||
$sDefaultBackupFileName = sys_get_temp_dir().'/'."__DB__-%Y-%m-%d";
|
||||
$sBackupFile = utils::ReadParam('backup_file', $sDefaultBackupFileName, true, 'raw_data');
|
||||
|
||||
$oConfig = GetConfig();
|
||||
|
||||
$sBackupFile = str_replace('__HOST__', $oConfig->Get('db_host'), $sBackupFile);
|
||||
$sBackupFile = str_replace('__DB__', $oConfig->Get('db_name'), $sBackupFile);
|
||||
$sBackupFile = str_replace('__SUBNAME__', $oConfig->Get('db_subname'), $sBackupFile);
|
||||
|
||||
if (is_null($iRefTime))
|
||||
{
|
||||
$sBackupFile = strftime($sBackupFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sBackupFile = strftime($sBackupFile, $iRefTime);
|
||||
}
|
||||
$oBackup = new DBBackup();
|
||||
$oDateTime = $iRefTime !== null ? new DateTime($iRefTime) : new DateTime();
|
||||
$sBackupFile = $oBackup->MakeName($sBackupFile, $oDateTime);
|
||||
|
||||
return $sBackupFile;
|
||||
}
|
||||
|
||||
@@ -163,8 +163,7 @@ class BackupExec extends AbstractWeeklyScheduledProcess
|
||||
//
|
||||
$oBackup->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting($this->GetModuleName(), 'mysql_bindir', ''));
|
||||
|
||||
$sBackupFileFormat = MetaModel::GetConfig()->GetModuleSetting($this->GetModuleName(), 'file_name_format',
|
||||
'__DB__-%Y-%m-%d_%H_%M');
|
||||
$sBackupFileFormat = MetaModel::GetConfig()->GetModuleSetting($this->GetModuleName(), 'file_name_format', '__DB__-%Y-%m-%d_%H_%M');
|
||||
$sName = $oBackup->MakeName($sBackupFileFormat);
|
||||
if ($sName == '')
|
||||
{
|
||||
|
||||
@@ -69,7 +69,7 @@ function Usage($oP)
|
||||
$oP->p('auth_user: login, must be administrator');
|
||||
$oP->p('auth_pwd: ...');
|
||||
}
|
||||
$oP->p('backup_file [optional]: name of the file to store the backup into. Follows the PHP strftime format spec. The following placeholders are available: __HOST__, __DB__, __SUBNAME__');
|
||||
$oP->p('backup_file [optional]: name of the file to store the backup into. Follows the PHP strftime() (https://www.php.net/manual/fr/function.strftime.php) format spec. The following placeholders are available: __HOST__, __DB__, __SUBNAME__');
|
||||
$oP->p('mysql_bindir [optional]: specify the path for mysql executable');
|
||||
|
||||
if (utils::IsModeCLI())
|
||||
@@ -131,7 +131,7 @@ function ExecuteMainOperation($oP){
|
||||
exit;
|
||||
}
|
||||
|
||||
// Interpret strftime specifications (like %Y) and database placeholders
|
||||
// Interpret strftime() specifications (like %Y) and database placeholders
|
||||
$oRestore = new MyCliRestore($oP);
|
||||
$oRestore->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', ''));
|
||||
|
||||
|
||||
@@ -146,18 +146,35 @@ class DBBackup
|
||||
/**
|
||||
* Create a normalized backup name, depending on the current date/time and Database
|
||||
*
|
||||
* @param string sNameSpec Name and path, eventually containing itop placeholders + time formatting specs
|
||||
* @param string sNameSpec Name and path, eventually containing itop placeholders + time formatting following the strftime() format {@link https://www.php.net/manual/fr/function.strftime.php}
|
||||
* @param \DateTime|null $oDateTime Date time to use for the name
|
||||
*
|
||||
* @return string
|
||||
* @since 3.1.0 N°5279 Add $oDtaeaTime parameter
|
||||
*/
|
||||
public function MakeName($sNameSpec = "__DB__-%Y-%m-%d")
|
||||
public function MakeName($sNameSpec = "__DB__-%Y-%m-%d", DateTime $oDateTime = null)
|
||||
{
|
||||
if ($oDateTime === null) {
|
||||
$oDateTime = new DateTime();
|
||||
}
|
||||
|
||||
$sFileName = $sNameSpec;
|
||||
$sFileName = str_replace('__HOST__', $this->sDBHost, $sFileName);
|
||||
$sFileName = str_replace('__DB__', $this->sDBName, $sFileName);
|
||||
$sFileName = str_replace('__SUBNAME__', $this->sDBSubName, $sFileName);
|
||||
// Transform %Y, etc.
|
||||
$sFileName = strftime($sFileName);
|
||||
|
||||
// Transform date/time placeholders (%Y, %m, etc)
|
||||
// N°5279 - As of PHP 8.1 strftime() is deprecated so we use \DateTime::format() instead
|
||||
//
|
||||
// IMPORTANT: We can't use \DateTime::format() directly on the whole filename as it would also format characters that are not supposed to be. eg. "__DB__-Y-m-d-production" would become "itopdb-2023-02-09-+01:00Thu, 09 Feb 2023 11:34:01 +0100202309"
|
||||
$sFileName = preg_replace_callback(
|
||||
'/(%[a-zA-Z])/',
|
||||
function ($aMatches) use ($oDateTime) {
|
||||
$sDateTimeFormatPlaceholder = utils::StrftimeFormatToDateTimeFormat($aMatches[0]);
|
||||
return $oDateTime->format($sDateTimeFormatPlaceholder);
|
||||
},
|
||||
$sFileName,
|
||||
);
|
||||
|
||||
return $sFileName;
|
||||
}
|
||||
|
||||
@@ -423,6 +423,35 @@ class utilsTest extends ItopTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider StrftimeFormatToDateTimeFormatProvider
|
||||
* @covers \utils::StrftimeFormatToDateTimeFormat
|
||||
*
|
||||
* @param string $sInput
|
||||
* @param string $sExpectedFormat
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testStrftimeFormatToDateTimeFormat(string $sInput, string $sExpectedFormat)
|
||||
{
|
||||
$sTestedFormat = utils::StrftimeFormatToDateTimeFormat($sInput);
|
||||
$this->assertEquals($sExpectedFormat, $sTestedFormat, "DateTime format transformation for '$sInput' doesn't match. Got '$sTestedFormat', expected '$sExpectedFormat'.");
|
||||
}
|
||||
|
||||
public function StrftimeFormatToDateTimeFormatProvider(): array
|
||||
{
|
||||
return [
|
||||
'Standard date time' => [
|
||||
'%Y-%m-%d %H:%M:%S',
|
||||
'Y-m-d H:i:s',
|
||||
],
|
||||
'All placeholders' => [
|
||||
'%d | %m | %y | %Y | %H | %M | %S | %a | %A | %e | %j | %u | %w | %U | %V | %W | %b | %B | %h | %C | %g | %G | %k | %I | %l | %p | %P | %r | %R | %T | %X | %z | %Z | %c | %D | %F | %s | %x | %n | %t | %%',
|
||||
'd | m | y | Y | H | i | s | D | l | j | z | N | w | %U | W | %W | M | F | M | %C | y | Y | G | h | g | A | a | h:i:s A | H:i | H:i:s | %X | O | T | %c | m/d/y | Y-m-d | U | %x | %n | %t | %',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ToCamelCaseProvider
|
||||
* @covers utils::ToCamelCase
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Combodo\iTop\Test\UnitTest\Setup;
|
||||
|
||||
use CMDBSource;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use DateTime;
|
||||
use DBBackup;
|
||||
use utils;
|
||||
|
||||
@@ -102,4 +103,45 @@ class DBBackupTest extends ItopTestCase
|
||||
}
|
||||
$this->assertStringEndsWith('--ssl-ca='.DBBackup::EscapeShellArg($sTestCa), $sCliArgsCapathCfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider MakeNameProvider
|
||||
* @covers \DBBackup::MakeName
|
||||
*
|
||||
* @param string $sInputFormat
|
||||
* @param \DateTime $oBackupDateTime
|
||||
* @param string $sExpectedFilename
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testMakeName(string $sInputFormat, DateTime $oBackupDateTime, string $sExpectedFilename): void
|
||||
{
|
||||
$oBackup = new DBBackup(utils::GetConfig());
|
||||
$sTestedFilename = $oBackup->MakeName($sInputFormat, $oBackupDateTime);
|
||||
|
||||
$this->assertEquals($sExpectedFilename, $sTestedFilename, "Backup filename for '$sInputFormat' format doesn't match. Got '$sTestedFilename', expected '$sExpectedFilename'.");
|
||||
}
|
||||
|
||||
public function MakeNameProvider(): array
|
||||
{
|
||||
$oBackupDateTime = DateTime::createFromFormat('Y-m-d H:i:s', '1985-07-30 15:30:59');
|
||||
|
||||
return [
|
||||
'Default format' => [
|
||||
'itopdb-%Y-%m-%d',
|
||||
$oBackupDateTime,
|
||||
'itopdb-1985-07-30',
|
||||
],
|
||||
'With time which is a placeholder that needs to be translated (minutes defined by "%M" when its actually "i" in the transformation matrix)' => [
|
||||
'itopdb-%Y-%m-%d_%H:%M:%S',
|
||||
$oBackupDateTime,
|
||||
'itopdb-1985-07-30_15:30:59',
|
||||
],
|
||||
'With user defined string that would be translated if using \DateTime::format() directly' => [
|
||||
'itopdb-%Y-%m-%d-production',
|
||||
$oBackupDateTime,
|
||||
'itopdb-1985-07-30-production',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user