diff --git a/e107_handlers/Shims/Internal/ReadfileTrait.php b/e107_handlers/Shims/Internal/ReadfileTrait.php
new file mode 100644
index 000000000..8d1858337
--- /dev/null
+++ b/e107_handlers/Shims/Internal/ReadfileTrait.php
@@ -0,0 +1,64 @@
+ '%m/%d/%y', '%T' => '%H:%M:%S',);
+ static $map_r = array(
+ '%S' => 'tm_sec',
+ '%M' => 'tm_min',
+ '%H' => 'tm_hour',
+ '%I' => 'tm_hour',
+ '%d' => 'tm_mday',
+ '%m' => 'tm_mon',
+ '%Y' => 'tm_year',
+ '%y' => 'tm_year',
+ '%W' => 'tm_wday',
+ '%D' => 'tm_yday',
+ '%u' => 'unparsed',
+ );
+
+ $fullmonth = array();
+ $abrevmonth = array();
+
+ for ($i = 1; $i <= 12; $i++)
+ {
+ $k = strftime('%B', mktime(0, 0, 0, $i));
+ $fullmonth[$k] = $i;
+
+ $j = strftime('%b', mktime(0, 0, 0, $i));
+ $abrevmonth[$j] = $i;
+ }
+
+
+ #-- transform $format into extraction regex
+ $format = str_replace(array_keys($expand), array_values($expand), $format);
+ $preg = preg_replace('/(%\w)/', '(\w+)', preg_quote($format));
+
+ #-- record the positions of all STRFCMD-placeholders
+ preg_match_all('/(%\w)/', $format, $positions);
+ $positions = $positions[1];
+
+ $vals = array();
+
+ #-- get individual values
+ if (preg_match("#$preg#", $date, $extracted))
+ {
+ #-- get values
+ foreach ($positions as $pos => $strfc)
+ {
+ $v = $extracted[$pos + 1];
+ #-- add
+ if (isset($map_r[$strfc]))
+ {
+ $n = $map_r[$strfc];
+ $vals[$n] = ($v > 0) ? (int)$v : $v;
+ }
+ else
+ {
+ if (!isset($vals['unparsed'])) $vals['unparsed'] = '';
+ $vals['unparsed'] .= $v . ' ';
+ }
+ }
+
+ #-- fixup some entries
+ //$vals["tm_wday"] = $names[ substr($vals["tm_wday"], 0, 3) ];
+ if ($vals['tm_year'] >= 1900)
+ {
+ $vals['tm_year'] -= 1900;
+ }
+ elseif ($vals['tm_year'] > 0)
+ {
+ $vals['tm_year'] += 100;
+ }
+
+ if ($vals['tm_mon'])
+ {
+ $vals['tm_mon'] -= 1;
+ }
+
+ if (!isset($vals['tm_sec']))
+ {
+ $vals['tm_sec'] = 0;
+ }
+
+ if (!isset($vals['tm_min']))
+ {
+ $vals['tm_min'] = 0;
+ }
+
+ if (!isset($vals['tm_hour']))
+ {
+ $vals['tm_hour'] = 0;
+ }
+
+
+ if (!isset($vals['unparsed']))
+ {
+ $vals['unparsed'] = '';
+ }
+
+ $unxTimestamp = mktime($vals['tm_hour'], $vals['tm_min'], $vals['tm_sec'], ($vals['tm_mon'] + 1), $vals['tm_mday'], ($vals['tm_year'] + 1900));
+
+ $vals['tm_wday'] = (int)strftime('%w', $unxTimestamp); // Days since Sunday (0-6)
+ $vals['tm_yday'] = (strftime('%j', $unxTimestamp) - 1); // Days since January 1 (0-365)
+ }
+
+ return !empty($vals) ? $vals : false;
+
+ }
+}
\ No newline at end of file
diff --git a/e107_handlers/Shims/InternalShims.php b/e107_handlers/Shims/InternalShims.php
index 676b87255..207868a20 100644
--- a/e107_handlers/Shims/InternalShims.php
+++ b/e107_handlers/Shims/InternalShims.php
@@ -2,7 +2,7 @@
/**
* e107 website system
*
- * Copyright (C) 2008-2018 e107 Inc (e107.org)
+ * Copyright (C) 2008-2020 e107 Inc (e107.org)
* Released under the terms and conditions of the
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
*
diff --git a/e107_handlers/Shims/InternalShimsTrait.php b/e107_handlers/Shims/InternalShimsTrait.php
index dfaaf6b15..9ae20ceb3 100644
--- a/e107_handlers/Shims/InternalShimsTrait.php
+++ b/e107_handlers/Shims/InternalShimsTrait.php
@@ -2,7 +2,7 @@
/**
* e107 website system
*
- * Copyright (C) 2008-2018 e107 Inc (e107.org)
+ * Copyright (C) 2008-2020 e107 Inc (e107.org)
* Released under the terms and conditions of the
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
*
@@ -13,51 +13,6 @@ namespace e107\Shims;
trait InternalShimsTrait
{
- /**
- * Outputs a file
- *
- * Resilient replacement for PHP internal readfile()
- *
- * @see https://github.com/e107inc/e107/issues/3528 Why this method was implemented
- * @param string $filename The filename being read.
- * @param bool $use_include_path You can use the optional second parameter and set it to TRUE,
- * if you want to search for the file in the include_path, too.
- * @param resource $context A context stream resource.
- * @return int|bool Returns the number of bytes read from the file.
- * If an error occurs, FALSE is returned.
- */
- public static function readfile($filename, $use_include_path = FALSE, $context = NULL)
- {
- $output = @readfile($filename, $use_include_path, $context);
- if ($output === NULL)
- {
- return self::readfile_alt($filename, $use_include_path, $context);
- }
- return $output;
- }
-
- /**
- * Outputs a file
- *
- * Alternative implementation using file streams
- *
- * @param $filename
- * @param bool $use_include_path
- * @param resource $context
- * @return bool|int
- */
- public static function readfile_alt($filename, $use_include_path = FALSE, $context = NULL)
- {
- // fopen() silently returns false if there is no context
- if (!is_resource($context)) $context = stream_context_create();
-
- $handle = @fopen($filename, 'rb', $use_include_path, $context);
- if ($handle === FALSE) return FALSE;
- while (!feof($handle))
- {
- echo(fread($handle, 8192));
- }
- fclose($handle);
- return filesize($filename);
- }
+ use Internal\ReadfileTrait;
+ use Internal\StrptimeTrait;
}
\ No newline at end of file
diff --git a/e107_handlers/date_handler.php b/e107_handlers/date_handler.php
index 0a6ef9b53..ea47fe9f5 100644
--- a/e107_handlers/date_handler.php
+++ b/e107_handlers/date_handler.php
@@ -770,184 +770,22 @@ class e_date
/**
- * This work of Lionel SAURON (http://sauron.lionel.free.fr:80) is licensed under the
- * Creative Commons Attribution-Noncommercial-Share Alike 2.0 France License.
- * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/fr/
- * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
- *
- * http://snipplr.com/view/4964/emulate-php-5-for-backwards-compatibility/
- *
- * Parse a date generated with strftime().
- *
- * @author Lionel SAURON and reworked by e107 Inc. for month names.
- * @version 1.0
- * @public
+ * Parse a time/date generated with strftime()
+ * With extra output keys for localized month
*
+ * @deprecated Use eShims::strptime() instead
+ * @see eShims::strptime()
* @param string $str date string to parse (e.g. returned from strftime()).
* @param $format
* @return array|bool Returns an array with the $str
parsed, or false
on error.
*/
public function strptime($str, $format)
{
- if(STRPTIME_COMPAT !== TRUE && function_exists('strptime')) // Unix Only.
- {
- $vals = strptime($str,$format); // PHP5 is more accurate than below.
- $vals['tm_amon'] = strftime('%b', mktime(0,0,0, $vals['tm_mon'] +1) );
- $vals['tm_fmon'] = strftime('%B', mktime(0,0,0, $vals['tm_mon'] +1) );
- return $vals;
- }
-
- // Below is for Windows machines. (XXX TODO - Currently not as accurate as Linux PHP5 strptime() function above. )
-
- static $expand = array('%D'=>'%m/%d/%y', '%T'=>'%H:%M:%S', );
-
- $ampm = (preg_match("/%l|%I|%p|%P/",$format)) ? 'true' : 'false';
-
- static $map_r = array(
- '%S' =>'tm_sec',
- '%M' =>'tm_min',
- '%H' =>'tm_hour',
- '%I' =>'tm_hour',
- '%d' =>'tm_mday',
- '%m' =>'tm_mon',
- '%Y' =>'tm_year',
- '%y' =>'tm_year',
- '%W' =>'tm_wday',
- '%D' =>'tm_yday',
- '%B' =>'tm_fmon', // full month-name
- '%b' =>'tm_amon', // abrev. month-name
- '%p' =>'tm_AMPM', // AM/PM
- '%P' =>'tm_ampm', // am/pm
- '%u' =>'unparsed',
-
- );
-
- $fullmonth = array();
- $abrevmonth = array();
-
- for ($i = 1; $i <= 12; $i++)
- {
- $k = strftime('%B',mktime(0,0,0,$i));
- $fullmonth[$k] = $i;
-
- $j = strftime('%b',mktime(0,0,0,$i));
- $abrevmonth[$j] = $i;
- }
-
-
-
- #-- transform $format into extraction regex
- $format = str_replace(array_keys($expand), array_values($expand), $format);
- $preg = preg_replace('/(%\w)/', '(\w+)', preg_quote($format));
-
- #-- record the positions of all STRFCMD-placeholders
- preg_match_all('/(%\w)/', $format, $positions);
- $positions = $positions[1];
-
- $vals = array();
-
- #-- get individual values
- if (preg_match("#$preg#", $str, $extracted))
- {
- #-- get values
- foreach ($positions as $pos => $strfc)
- {
- $v = $extracted[$pos + 1];
- #-- add
- if (isset($map_r[$strfc]))
- {
- $n = $map_r[$strfc];
- $vals[$n] = ($v > 0) ? (int) $v : $v;
- }
- else
- {
- $vals['unparsed'] .= $v.' ';
- }
- }
-
- #-- fixup some entries
- //$vals["tm_wday"] = $names[ substr($vals["tm_wday"], 0, 3) ];
- if ($vals['tm_year'] >= 1900)
- {
- $vals['tm_year'] -= 1900;
- }
- elseif ($vals['tm_year'] > 0)
- {
- $vals['tm_year'] += 100;
- }
-
- if ($vals['tm_mon'])
- {
- $vals['tm_mon'] -= 1;
- }
- else
- {
-
- if(isset($fullmonth[$vals['tm_fmon']]))
- {
- $vals['tm_mon'] = $fullmonth[$vals['tm_fmon']];
- }
- elseif(isset($abrevmonth[$vals['tm_amon']]))
- {
- $vals['tm_mon'] = $abrevmonth[$vals['tm_amon']];
- }
-
- }
-
- if($ampm && isset($vals['tm_hour']))
- {
- if($vals['tm_hour'] == 12 && ($vals['tm_AMPM'] == 'AM' || $vals['tm_ampm'] == 'am'))
- {
- $vals['tm_hour'] = 0;
- }
-
- if($vals['tm_hour'] < 12 && ($vals['tm_AMPM'] == 'PM' || $vals['tm_ampm'] == 'pm'))
- {
- $vals['tm_hour'] = intval($vals['tm_hour']) + 12;
- }
-
- }
-
- //$vals['tm_sec'] -= 1; always increasing tm_sec + 1 ??????
-
- #-- calculate wday/yday
- //$vals['tm_mon'] = $vals['tm_mon'] + 1; // returns months from 0 - 11 so we need to +1
-
- if (!isset($vals['tm_sec']))
- {
- $vals['tm_sec'] = 0;
- }
-
- if (!isset($vals['tm_min']))
- {
- $vals['tm_min'] = 0;
- }
-
- if (!isset($vals['tm_hour']))
- {
- $vals['tm_hour'] = 0;
- }
-
-
- if (!isset($vals['unparsed']))
- {
- $vals['unparsed'] = '';
- }
-
- $unxTimestamp = mktime($vals['tm_hour'], $vals['tm_min'], $vals['tm_sec'], ($vals['tm_mon'] + 1), $vals['tm_mday'], ($vals['tm_year'] + 1900));
-
- $vals['tm_amon'] = strftime('%b', mktime($vals['tm_hour'], $vals['tm_min'], $vals['tm_sec'], $vals['tm_mon'] + 1));
- $vals['tm_fmon'] = strftime('%B', mktime($vals['tm_hour'], $vals['tm_min'], $vals['tm_sec'], $vals['tm_mon'] + 1));
- $vals['tm_wday'] = (int) strftime('%w', $unxTimestamp); // Days since Sunday (0-6)
- $vals['tm_yday'] = (strftime('%j', $unxTimestamp) - 1); // Days since January 1 (0-365)
-
-
- //var_dump($vals, $str, strftime($format, $unxTimestamp), $unxTimestamp);
- }
-
- return !empty($vals) ? $vals : false;
-
- }
+ $vals = eShims::strptime($str, $format); // PHP5 is more accurate than below.
+ $vals['tm_amon'] = strftime('%b', mktime(0, 0, 0, $vals['tm_mon'] + 1));
+ $vals['tm_fmon'] = strftime('%B', mktime(0, 0, 0, $vals['tm_mon'] + 1));
+ return $vals;
+ }
diff --git a/e107_handlers/php_compatibility_handler.php b/e107_handlers/php_compatibility_handler.php
index e26abfe77..21eac532e 100644
--- a/e107_handlers/php_compatibility_handler.php
+++ b/e107_handlers/php_compatibility_handler.php
@@ -26,17 +26,12 @@ if (!defined('e107_INIT'))
*/
-
-
if (!function_exists('strptime'))
{
-
- define('STRPTIME_COMPAT', true);
- function strptime($str, $format)
+ function strptime($date, $format)
{
- return e107::getDate()->strptime($str,$format);
- }
-
+ return eShims::strptime($date, $format);
+ }
}
//PHP < 5.2 compatibility
diff --git a/e107_tests/tests/unit/e107/Shims/StrptimeTest.php b/e107_tests/tests/unit/e107/Shims/StrptimeTest.php
new file mode 100644
index 000000000..0623d6922
--- /dev/null
+++ b/e107_tests/tests/unit/e107/Shims/StrptimeTest.php
@@ -0,0 +1,94 @@
+testStrptimeImplementation([\e107\Shims\InternalShims::class, 'strptime']);
+ }
+
+ public function testStrptimeDefaultLegacy()
+ {
+ $this->testStrptimeImplementation([\eShims::class, 'strptime']);
+ }
+
+ public function testStrptimeAlt()
+ {
+ $this->testStrptimeImplementation([\e107\Shims\InternalShims::class, 'strptime_alt']);
+ }
+
+ protected function testStrptimeImplementation($implementation)
+ {
+ $this->testStrptimeDateOnly($implementation);
+ $this->testStrptimeDateTime($implementation);
+ $this->testStrptimeUnparsed($implementation);
+ $this->testStrptimeInvalid($implementation);
+ }
+
+ protected function testStrptimeDateOnly($implementation)
+ {
+ $actual = call_user_func($implementation, '2018/05/13', '%Y/%m/%d');
+ $expected = array(
+ 'tm_year' => 118,
+ 'tm_mon' => 4,
+ 'tm_mday' => 13,
+ 'tm_sec' => 0,
+ 'tm_min' => 0,
+ 'tm_hour' => 0,
+ 'unparsed' => '',
+ 'tm_wday' => 0,
+ 'tm_yday' => 132,
+ );
+ $this->assertEquals($expected, $actual);
+ }
+
+ protected function testStrptimeDateTime($implementation)
+ {
+ $actual = call_user_func($implementation, '2018/05/13 20:10', '%Y/%m/%d %H:%M');
+ $expected = array(
+ 'tm_year' => 118,
+ 'tm_mon' => 4,
+ 'tm_mday' => 13,
+ 'tm_hour' => 20,
+ 'tm_min' => 10,
+ 'tm_sec' => 0,
+ 'unparsed' => '',
+ 'tm_wday' => 0,
+ 'tm_yday' => 132,
+ );
+ $this->assertEquals($expected, $actual);
+ }
+
+ protected function testStrptimeUnparsed($implementation)
+ {
+ $actual = call_user_func($implementation, '1607-09-04 08:10 PM', '%Y-%m-%d %l:%M %P');
+ $expected = array(
+ 'tm_year' => 1707,
+ 'tm_mon' => 8,
+ 'tm_mday' => 4,
+ 'tm_hour' => 0,
+ 'tm_min' => 10,
+ 'tm_sec' => 0,
+ 'unparsed' => '08 PM ',
+ 'tm_wday' => 2,
+ 'tm_yday' => 246,
+ );
+ $this->assertEquals($expected, $actual);
+ }
+
+ protected function testStrptimeInvalid($implementation)
+ {
+ $actual = call_user_func($implementation, 'garbage', '%Y-%m-%d');
+ $this->assertFalse($actual);
+ }
+}
\ No newline at end of file