Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve #22 by using contributed new function from BohwaZ to fix depr… #23

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4']
php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1']

steps:
- uses: actions/checkout@v2
Expand Down
51 changes: 50 additions & 1 deletion Log.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
define('PEAR_LOG_TYPE_DEBUG', 2); /* Use PHP's debugging connection */
define('PEAR_LOG_TYPE_FILE', 3); /* Append to a file */
define('PEAR_LOG_TYPE_SAPI', 4); /* Use the SAPI logging handler */

if (!function_exists('PHP81_BC\strftime')) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit overkill?
There is no other way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@williamdes I think previously I found that if someone had pulled in https://packagist.org/packages/php81_bc/strftime via composer then without this if there were errors

require_once 'php-8.1-strftime.php';
}
use function PHP81_BC\strftime;
/**
* The Log:: class implements both an abstraction for various logging
* mechanisms and the Subject end of a Subject-Observer pattern.
Expand Down Expand Up @@ -111,6 +114,14 @@ class Log
'%{class}' => '%8$s',
'%\{' => '%%{');

/**
* Locale to be passed to strftime when formatting
*
* @var string
* @access protected
*/
var $_locale = 'en_US';

public function __construct()
{
}
Expand Down Expand Up @@ -869,4 +880,42 @@ function getIdent()
{
return $this->_ident;
}

/**
* Set the current locale
* @param string $locale The new locale
*
* @access public
* @since
*/
function setLocale($locale)
{
$this->_locale = $locale;
}

/**
* Returns the current locale
* @return string
*
* @access public
* @since
*/
function getLocale()
{
return $this->_locale;
}

/**
* Returns formatted time string using the PHP81_BC\strftime function to avoid deprecation errors
* @param string $format the format of the string to return
*
* @return string
*
* @access public
* @since 1.13.4
*/
public function formatTime($format)
{
return strftime($format, NULL, $this->_locale);
}
}
2 changes: 1 addition & 1 deletion Log/console.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ function log($message, $priority = null)

/* Build the string containing the complete log line. */
$line = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$this->formatTime($this->_timeFormat),
$priority, $message) . "\n";

/*
Expand Down
2 changes: 1 addition & 1 deletion Log/display.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ function log($message, $priority = null)

/* Build and output the complete log line. */
echo $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$this->formatTime($this->_timeFormat),
$priority,
$message);

Expand Down
2 changes: 1 addition & 1 deletion Log/error_log.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function log($message, $priority = null)

/* Build the string containing the complete log line. */
$line = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$this->formatTime($this->_timeFormat),
$priority, $message);

/* Pass the log line and parameters to the error_log() function. */
Expand Down
2 changes: 1 addition & 1 deletion Log/file.php
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ function log($message, $priority = null)

/* Build the string containing the complete log line. */
$line = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$this->formatTime($this->_timeFormat),
$priority, $message) . $this->_eol;

/* If locking is enabled, acquire an exclusive lock on the file. */
Expand Down
2 changes: 1 addition & 1 deletion Log/firebug.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ function log($message, $priority = null)

/* Build the string containing the complete log line. */
$line = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$this->formatTime($this->_timeFormat),
$priority,
$message);

Expand Down
2 changes: 1 addition & 1 deletion Log/mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ function log($message, $priority = null)

/* Append the string containing the complete log line. */
$this->_message .= $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$this->formatTime($this->_timeFormat),
$priority, $message) . "\r\n";
$this->_shouldSend = true;

Expand Down
2 changes: 1 addition & 1 deletion Log/sqlite.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ function log($message, $priority = null)
$q = sprintf('INSERT INTO [%s] (logtime, ident, priority, message) ' .
"VALUES ('%s', '%s', %d, '%s')",
$this->_table,
strftime('%Y-%m-%d %H:%M:%S', time()),
$this->formatTime('%Y-%m-%d %H:%M:%S', time()),
sqlite_escape_string($this->_ident),
$priority,
sqlite_escape_string($message));
Expand Down
2 changes: 1 addition & 1 deletion Log/syslog.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ function log($message, $priority = null)

/* Apply the configured line format to the message string. */
$message = $this->_format($this->_lineFormat,
strftime($this->_timeFormat),
$this->formatTime($this->_timeFormat),
$priority, $message);

/* Split the string into parts based on our maximum length setting. */
Expand Down
2 changes: 1 addition & 1 deletion Log/win.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ function log($message, $priority = null)
/* Build the output line that contains the log entry row. */
$line = '<tr>';
$line .= sprintf('<td>%s.%s</td>',
strftime('%H:%M:%S', $sec), substr($usec, 2, 2));
$this->formatTime('%H:%M:%S', $sec), substr($usec, 2, 2));
if (!empty($this->_ident)) {
$line .= '<td>' . $this->_ident . '</td>';
}
Expand Down
217 changes: 217 additions & 0 deletions php-8.1-strftime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<?php
namespace PHP81_BC;

use DateTime;
use DateTimeZone;
use DateTimeInterface;
use Exception;
use IntlDateFormatter;
use IntlGregorianCalendar;
use InvalidArgumentException;

// PHP5.6 compatability.
if (!defined('PHP_INT_MIN')) {
define('PHP_INT_MIN', ~PHP_INT_MAX);
}

/**
* Locale-formatted strftime using IntlDateFormatter (PHP 8.1 compatible)
* This provides a cross-platform alternative to strftime() for when it will be removed from PHP.
* Note that output can be slightly different between libc sprintf and this function as it is using ICU.
*
* Usage:
* use function \PHP81_BC\strftime;
* echo strftime('%A %e %B %Y %X', new \DateTime('2021-09-28 00:00:00'), 'fr_FR');
*
* Original use:
* \setlocale(LC_TIME, 'fr_FR.UTF-8');
* echo \strftime('%A %e %B %Y %X', strtotime('2021-09-28 00:00:00'));
*
* @param string $format Date format
* @param integer|string|DateTime $timestamp Timestamp
* @return string
* @author BohwaZ <https://bohwaz.net/>
*/
function strftime ($format, $timestamp = null, $locale = null) {
if (!($timestamp instanceof DateTimeInterface)) {
$timestamp = is_int($timestamp) ? '@' . $timestamp : (string) $timestamp;

try {
$timestamp = new DateTime($timestamp);
} catch (Exception $e) {
throw new InvalidArgumentException('$timestamp argument is neither a valid UNIX timestamp, a valid date-time string or a DateTime object.', 0, $e);
}
}

$timestamp->setTimezone(new DateTimeZone(date_default_timezone_get()));

$locale = substr((string) $locale, 0, 5);

$intl_formats = [
'%a' => 'EEE', // An abbreviated textual representation of the day Sun through Sat
'%A' => 'EEEE', // A full textual representation of the day Sunday through Saturday
'%b' => 'MMM', // Abbreviated month name, based on the locale Jan through Dec
'%B' => 'MMMM', // Full month name, based on the locale January through December
'%h' => 'MMM', // Abbreviated month name, based on the locale (an alias of %b) Jan through Dec
];

$intl_formatter = function (DateTimeInterface $timestamp, $format) use ($intl_formats, $locale) {
$tz = $timestamp->getTimezone();
$date_type = IntlDateFormatter::FULL;
$time_type = IntlDateFormatter::FULL;
$pattern = '';

switch ($format) {
// %c = Preferred date and time stamp based on locale
// Example: Tue Feb 5 00:45:10 2009 for February 5, 2009 at 12:45:10 AM
case '%c':
$date_type = IntlDateFormatter::LONG;
$time_type = IntlDateFormatter::SHORT;
break;

// %x = Preferred date representation based on locale, without the time
// Example: 02/05/09 for February 5, 2009
case '%x':
$date_type = IntlDateFormatter::SHORT;
$time_type = IntlDateFormatter::NONE;
break;

// Localized time format
case '%X':
$date_type = IntlDateFormatter::NONE;
$time_type = IntlDateFormatter::MEDIUM;
break;

default:
$pattern = $intl_formats[$format];
}

// In October 1582, the Gregorian calendar replaced the Julian in much of Europe, and
// the 4th October was followed by the 15th October.
// ICU (including IntlDateFormattter) interprets and formats dates based on this cutover.
// Posix (including strftime) and timelib (including DateTimeImmutable) instead use
// a "proleptic Gregorian calendar" - they pretend the Gregorian calendar has existed forever.
// This leads to the same instants in time, as expressed in Unix time, having different representations
// in formatted strings.
// To adjust for this, a custom calendar can be supplied with a cutover date arbitrarily far in the past.
$calendar = IntlGregorianCalendar::createInstance();
$calendar->setGregorianChange(PHP_INT_MIN);

return (new IntlDateFormatter($locale, $date_type, $time_type, $tz, $calendar, $pattern))->format($timestamp);
};

// Same order as https://www.php.net/manual/en/function.strftime.php
$translation_table = [
// Day
'%a' => $intl_formatter,
'%A' => $intl_formatter,
'%d' => 'd',
'%e' => function ($timestamp) {
return sprintf('% 2u', $timestamp->format('j'));
},
'%j' => function ($timestamp) {
// Day number in year, 001 to 366
return sprintf('%03d', $timestamp->format('z')+1);
},
'%u' => 'N',
'%w' => 'w',

// Week
'%U' => function ($timestamp) {
// Number of weeks between date and first Sunday of year
$day = new DateTime(sprintf('%d-01 Sunday', $timestamp->format('Y')));
return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
},
'%V' => 'W',
'%W' => function ($timestamp) {
// Number of weeks between date and first Monday of year
$day = new DateTime(sprintf('%d-01 Monday', $timestamp->format('Y')));
return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
},

// Month
'%b' => $intl_formatter,
'%B' => $intl_formatter,
'%h' => $intl_formatter,
'%m' => 'm',

// Year
'%C' => function ($timestamp) {
// Century (-1): 19 for 20th century
return floor($timestamp->format('Y') / 100);
},
'%g' => function ($timestamp) {
return substr($timestamp->format('o'), -2);
},
'%G' => 'o',
'%y' => 'y',
'%Y' => 'Y',

// Time
'%H' => 'H',
'%k' => function ($timestamp) {
return sprintf('% 2u', $timestamp->format('G'));
},
'%I' => 'h',
'%l' => function ($timestamp) {
return sprintf('% 2u', $timestamp->format('g'));
},
'%M' => 'i',
'%p' => 'A', // AM PM (this is reversed on purpose!)
'%P' => 'a', // am pm
'%r' => 'h:i:s A', // %I:%M:%S %p
'%R' => 'H:i', // %H:%M
'%S' => 's',
'%T' => 'H:i:s', // %H:%M:%S
'%X' => $intl_formatter, // Preferred time representation based on locale, without the date

// Timezone
'%z' => 'O',
'%Z' => 'T',

// Time and Date Stamps
'%c' => $intl_formatter,
'%D' => 'm/d/Y',
'%F' => 'Y-m-d',
'%s' => 'U',
'%x' => $intl_formatter,
];

$out = preg_replace_callback('/(?<!%)%([_#-]?)([a-zA-Z])/', function ($match) use ($translation_table, $timestamp) {
$prefix = $match[1];
$char = $match[2];
$pattern = '%'.$char;
if ($pattern == '%n') {
return "\n";
} elseif ($pattern == '%t') {
return "\t";
}

if (!isset($translation_table[$pattern])) {
throw new InvalidArgumentException(sprintf('Format "%s" is unknown in time format', $pattern));
}

$replace = $translation_table[$pattern];

if (is_string($replace)) {
$result = $timestamp->format($replace);
} else {
$result = $replace($timestamp, $pattern);
}

switch ($prefix) {
case '_':
// replace leading zeros with spaces but keep last char if also zero
return preg_replace('/\G0(?=.)/', ' ', $result);
case '#':
case '-':
// remove leading zeros but keep last char if also zero
return preg_replace('/^0+(?=.)/', '', $result);
}

return $result;
}, $format);

$out = str_replace('%%', '%', $out);
return $out;
}
Loading