Browse Source

Merge branch 'master' into 3.next

Conflicts:
	.travis.yml
ADmad 9 years ago
parent
commit
138f50ff48
5 changed files with 42 additions and 234 deletions
  1. 4 4
      .travis.yml
  2. 1 62
      src/I18n/DateFormatTrait.php
  3. 2 6
      src/I18n/RelativeTimeFormatter.php
  4. 32 15
      src/ORM/Query.php
  5. 3 147
      tests/TestCase/I18n/TimeTest.php

+ 4 - 4
.travis.yml

@@ -1,9 +1,9 @@
 language: php
 
 php:
+  - 7.0
   - 5.5
   - 5.6
-  - 7.0
 
 dist: trusty
 
@@ -45,7 +45,7 @@ matrix:
     - php: hhvm
 
 before_install:
-  - if [ $HHVM != 1 ]; then phpenv config-rm xdebug.ini; fi
+  - if [ $HHVM != 1 && $TRAVIS_PHP_VERSION != 7.* ]; then phpenv config-rm xdebug.ini; fi
 
   - if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi;
 
@@ -66,7 +66,6 @@ before_install:
   - if [[ $TRAVIS_PHP_VERSION != 'hhvm' ]] ; then echo 'apc.enable_cli = 1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi
   - if [[ $TRAVIS_PHP_VERSION =~ 5.[56] ]] ; then echo yes | pecl install apcu-4.0.10; fi
   - if [[ $TRAVIS_PHP_VERSION = 7.* ]] ; then echo yes | pecl install apcu; fi
-  - if [[ $TRAVIS_PHP_VERSION = 7.* ]] ; then pecl config-set preferred_state beta; echo yes | pecl install apcu_bc; fi
   - if [[ $TRAVIS_PHP_VERSION = 'hhvm' ]] ; then composer require lorenzo/multiple-iterator=~1.0; fi
 
   - phpenv rehash
@@ -76,7 +75,8 @@ before_script:
   - composer install --prefer-dist --no-interaction
 
 script:
-  - if [[ $DEFAULT = 1 ]]; then vendor/bin/phpunit; fi
+  - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.* ]]; then export CODECOVERAGE=1; vendor/bin/phpunit --coverage-clover=clover.xml; fi
+  - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION != 7.* ]]; then vendor/bin/phpunit; fi
 
   - if [[ $PHPCS = 1 ]]; then vendor/bin/phpcs -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests; fi
 

+ 1 - 62
src/I18n/DateFormatTrait.php

@@ -16,10 +16,7 @@ namespace Cake\I18n;
 
 use Cake\Chronos\Date as ChronosDate;
 use Cake\Chronos\MutableDate;
-use DateTimeZone;
 use IntlDateFormatter;
-use InvalidArgumentException;
-use RuntimeException;
 
 /**
  * Trait for date formatting methods shared by both Time & Date.
@@ -38,14 +35,6 @@ trait DateFormatTrait
     public static $defaultLocale;
 
     /**
-     * The \DateTimeZone default output timezone used by Time and FrozenTime.
-     *
-     * @var \DateTimeZone|null
-     * @see http://php.net/manual/en/timezones.php
-     */
-    protected static $_defaultOutputTimezone;
-
-    /**
      * In-memory cache of date formatters
      *
      * @var array
@@ -76,43 +65,6 @@ trait DateFormatTrait
     protected static $_isDateInstance;
 
     /**
-     * Gets the default output timezone used by Time and FrozenTime.
-     *
-     * @return \DateTimeZone|null DateTimeZone object in which the date will be displayed or null.
-     * @throws \RuntimeException When being executed on Date/FrozenDate.
-     */
-    public static function getDefaultOutputTimezone()
-    {
-        if (is_subclass_of(static::class, ChronosDate::class) || is_subclass_of(static::class, MutableDate::class)) {
-            throw new RuntimeException('Timezone conversion is not supported by Date/FrozenDate.');
-        }
-        return static::$_defaultOutputTimezone;
-    }
-
-    /**
-     * Sets the default output timezone used by Time and FrozenTime.
-     *
-     * @param string|\DateTimeZone $timezone Timezone string or DateTimeZone object
-     * in which the date will be displayed.
-     * @return void
-     * @throws \RuntimeException When being executed on Date/FrozenDate.
-     * @throws \InvalidArgumentException When $timezone is neither a valid DateTimeZone string nor a \DateTimeZone object.
-     */
-    public static function setDefaultOutputTimezone($timezone)
-    {
-        if (is_subclass_of(static::class, ChronosDate::class) || is_subclass_of(static::class, MutableDate::class)) {
-            throw new RuntimeException('Timezone conversion is not supported by Date/FrozenDate.');
-        }
-        if (is_string($timezone)) {
-            static::$_defaultOutputTimezone = new DateTimeZone($timezone);
-        } elseif ($timezone instanceof DateTimeZone) {
-            static::$_defaultOutputTimezone = $timezone;
-        } else {
-            throw new InvalidArgumentException('Expected valid DateTimeZone string or \DateTimeZone object.');
-        }
-    }
-
-    /**
      * Gets the default locale.
      *
      * @return string|null The default locale string to be used or null.
@@ -205,22 +157,9 @@ trait DateFormatTrait
     {
         $time = $this;
 
-        if ($time instanceof Time || $time instanceof FrozenTime) {
-            $timezone = $timezone ?: static::getDefaultOutputTimezone();
-        }
-        // Detect and prevent null timezone transitions, as datefmt_create will
-        // doubly apply the TZ offset.
-        $currentTimezone = $time->getTimezone();
-        if ($timezone && (
-            (is_string($timezone) && $currentTimezone->getName() === $timezone) ||
-            ($timezone instanceof DateTimeZone && $currentTimezone->getName() === $timezone->getName())
-        )) {
-            $timezone = null;
-        }
-
         if ($timezone) {
             // Handle the immutable and mutable object cases.
-            $time = clone $time;
+            $time = clone $this;
             $time = $time->timezone($timezone);
         }
 

+ 2 - 6
src/I18n/RelativeTimeFormatter.php

@@ -93,12 +93,8 @@ class RelativeTimeFormatter
     public function timeAgoInWords(DatetimeInterface $time, array $options = [])
     {
         $options = $this->_options($options, FrozenTime::class);
-
-        $timezone = null;
         if ($options['timezone']) {
-            $timezone = $options['timezone'];
-        } elseif ($time instanceof Time || $time instanceof FrozenTime) {
-            $timezone = $time->getDefaultOutputTimezone();
+            $time = $time->timezone($options['timezone']);
         }
 
         $now = $options['from']->format('U');
@@ -118,7 +114,7 @@ class RelativeTimeFormatter
         }
 
         if ($diff > abs($now - (new FrozenTime($options['end']))->format('U'))) {
-            return sprintf($options['absoluteString'], $time->i18nFormat($options['format'], $timezone));
+            return sprintf($options['absoluteString'], $time->i18nFormat($options['format']));
         }
 
         $diffData = $this->_diffData($futureTime, $pastTime, $backwards, $options);

+ 32 - 15
src/ORM/Query.php

@@ -289,20 +289,37 @@ class Query extends DatabaseQuery implements JsonSerializable, QueryInterface
      * Each association might define special options when eager loaded, the allowed
      * options that can be set per association are:
      *
-     * - foreignKey: Used to set a different field to match both tables, if set to false
+     * - `foreignKey`: Used to set a different field to match both tables, if set to false
      *   no join conditions will be generated automatically. `false` can only be used on
      *   joinable associations and cannot be used with hasMany or belongsToMany associations.
-     * - fields: An array with the fields that should be fetched from the association
-     * - queryBuilder: Equivalent to passing a callable instead of an options array
+     * - `fields`: An array with the fields that should be fetched from the association.
+     * - `finder`: The finder to use when loading associated records. Either the name of the
+     *   finder as a string, or an array to define options to pass to the finder.
+     * - `queryBuilder`: Equivalent to passing a callable instead of an options array.
      *
      * ### Example:
      *
      * ```
      * // Set options for the hasMany articles that will be eagerly loaded for an author
      * $query->contain([
-     *   'Articles' => [
-     *     'fields' => ['title', 'author_id']
-     *   ]
+     *     'Articles' => [
+     *         'fields' => ['title', 'author_id']
+     *     ]
+     * ]);
+     * ```
+     *
+     * Finders can be configured to use options.
+     *
+     * ```
+     * // Retrieve translations for the articles, but only those for the `en` and `es` locales
+     * $query->contain([
+     *     'Articles' => [
+     *         'finder' => [
+     *             'translations' => [
+     *                 'locales' => ['en', 'es']
+     *             ]
+     *         ]
+     *     ]
      * ]);
      * ```
      *
@@ -312,12 +329,12 @@ class Query extends DatabaseQuery implements JsonSerializable, QueryInterface
      * ```
      * // Use special join conditions for getting an Articles's belongsTo 'authors'
      * $query->contain([
-     *   'Authors' => [
-     *     'foreignKey' => false,
-     *     'queryBuilder' => function ($q) {
-     *       return $q->where(...); // Add full filtering conditions
-     *     }
-     *   ]
+     *     'Authors' => [
+     *         'foreignKey' => false,
+     *         'queryBuilder' => function ($q) {
+     *             return $q->where(...); // Add full filtering conditions
+     *         }
+     *     ]
      * ]);
      * ```
      *
@@ -325,11 +342,11 @@ class Query extends DatabaseQuery implements JsonSerializable, QueryInterface
      * with the list of previously configured associations to be contained in the
      * result.
      *
-     * If called with an empty first argument and $override is set to true, the
+     * If called with an empty first argument and `$override` is set to true, the
      * previous list will be emptied.
      *
-     * @param array|string|null $associations list of table aliases to be queried
-     * @param bool $override whether override previous list with the one passed
+     * @param array|string|null $associations List of table aliases to be queried.
+     * @param bool $override Whether override previous list with the one passed
      * defaults to merging previous list with the new one.
      * @return array|$this
      */

+ 3 - 147
tests/TestCase/I18n/TimeTest.php

@@ -38,10 +38,6 @@ class TimeTest extends TestCase
         $this->locale = Time::getDefaultLocale();
         Time::setDefaultLocale('en_US');
         FrozenTime::setDefaultLocale('en_US');
-
-        date_default_timezone_set('UTC');
-        Time::setDefaultOutputTimezone('UTC');
-        FrozenTime::setDefaultOutputTimezone('UTC');
     }
 
     /**
@@ -59,12 +55,8 @@ class TimeTest extends TestCase
         FrozenTime::setTestNow($this->frozenNow);
         FrozenTime::setDefaultLocale($this->locale);
         FrozenTime::resetToStringFormat();
-
-        I18n::locale(I18n::DEFAULT_LOCALE);
-
         date_default_timezone_set('UTC');
-        Time::setDefaultOutputTimezone('UTC');
-        FrozenTime::setDefaultOutputTimezone('UTC');
+        I18n::locale(I18n::DEFAULT_LOCALE);
     }
 
     /**
@@ -200,7 +192,6 @@ class TimeTest extends TestCase
             ],
         ];
     }
-
     /**
      * test the timezone option for timeAgoInWords
      *
@@ -209,37 +200,7 @@ class TimeTest extends TestCase
      */
     public function testTimeAgoInWordsTimezone($class)
     {
-        $time = new $class('1990-07-31 20:33:00 UTC');
-        $result = $time->timeAgoInWords(
-            [
-                'timezone' => 'America/Vancouver',
-                'end' => '+1month',
-                'format' => 'dd-MM-YYYY HH:mm:ss'
-            ]
-        );
-        $this->assertEquals('on 31-07-1990 13:33:00', $result);
-    }
-
-    /**
-     * test the timezone option for timeAgoInWords
-     *
-     * @dataProvider classNameProvider
-     * @return void
-     */
-    public function testTimeAgoInWordsTimezoneOutputDefaultTimezone($class)
-    {
-        $class::setDefaultOutputTimezone('Europe/Paris');
-        $time = new $class('1990-07-31 20:33:00 UTC');
-        $result = $time->timeAgoInWords(
-            [
-                'end' => '+1month',
-                'format' => 'dd-MM-YYYY HH:mm:ss'
-            ]
-        );
-        $this->assertEquals('on 31-07-1990 22:33:00', $result);
-
-        $class::setDefaultOutputTimezone('Europe/Berlin');
-        $time = new $class('1990-07-31 20:33:00 UTC');
+        $time = new FrozenTime('1990-07-31 20:33:00 UTC');
         $result = $time->timeAgoInWords(
             [
                 'timezone' => 'America/Vancouver',
@@ -461,29 +422,6 @@ class TimeTest extends TestCase
     }
 
     /**
-     * testNiceWithDefaultOutputTimezone method
-     *
-     * @dataProvider classNameProvider
-     * @return void
-     */
-    public function testNiceWithDefaultOutputTimezone($class)
-    {
-        $class::setDefaultOutputTimezone('America/Vancouver');
-        $time = new $class('2014-04-20 20:00', 'UTC');
-
-        $this->assertTimeFormat('Apr 20, 2014, 1:00 PM', $time->nice());
-
-        $result = $time->nice('America/New_York');
-        $this->assertTimeFormat('Apr 20, 2014, 4:00 PM', $result);
-        $this->assertEquals('UTC', $time->getTimezone()->getName());
-
-        $class::setDefaultOutputTimezone('Europe/Paris');
-        $time = new $class('2014-04-20 20:00', 'UTC');
-        $this->assertTimeFormat('20 avr. 2014 22:00', $time->nice(null, 'fr-FR'));
-        $this->assertTimeFormat('20 avr. 2014 16:00', $time->nice('America/New_York', 'fr-FR'));
-    }
-
-    /**
      * test formatting dates taking in account preferred i18n locale file
      *
      * @dataProvider classNameProvider
@@ -544,61 +482,24 @@ class TimeTest extends TestCase
     }
 
     /**
-     * test formatting dates taking in account default output timezones.
-     *
-     * @dataProvider classNameProvider
-     * @return void
-     */
-    public function testI18nFormatWithDefaultOutputTimezone($class)
-    {
-        $time = new $class('Thu Jan 14 13:59:28 2010');
-
-        $class::setDefaultLocale('en-US');
-        $class::setDefaultOutputTimezone('America/Vancouver');
-
-        $result = $time->i18nFormat();
-        $expected = '1/14/10 5:59 AM';
-        $this->assertTimeFormat($expected, $result);
-
-        $result = $time->i18nFormat(null, 'America/Toronto');
-        $expected = '1/14/10 8:59 AM';
-        $this->assertTimeFormat($expected, $result);
-
-
-        $class::setDefaultLocale('de-DE');
-        $class::setDefaultOutputTimezone('Europe/Berlin');
-
-        $result = $time->i18nFormat();
-        $expected = '14.01.10 14:59';
-        $this->assertTimeFormat($expected, $result);
-
-        $result = $time->i18nFormat(null, 'Europe/London');
-        $expected = '14.01.10 13:59';
-        $this->assertTimeFormat($expected, $result);
-    }
-
-    /**
      * test formatting dates with offset style timezone
      *
      * @dataProvider classNameProvider
-     * @return void
      * @see https://github.com/facebook/hhvm/issues/3637
+     * @return void
      */
     public function testI18nFormatWithOffsetTimezone($class)
     {
-        // Default output format is in UTC
         $time = new $class('2014-01-01T00:00:00+00');
         $result = $time->i18nFormat(\IntlDateFormatter::FULL);
         $expected = 'Wednesday January 1 2014 12:00:00 AM GMT';
         $this->assertTimeFormat($expected, $result);
 
-        $class::setDefaultOutputTimezone('GMT+09:00');
         $time = new $class('2014-01-01T00:00:00+09');
         $result = $time->i18nFormat(\IntlDateFormatter::FULL);
         $expected = 'Wednesday January 1 2014 12:00:00 AM GMT+09:00';
         $this->assertTimeFormat($expected, $result);
 
-        $class::setDefaultOutputTimezone('GMT-01:30');
         $time = new $class('2014-01-01T00:00:00-01:30');
         $result = $time->i18nFormat(\IntlDateFormatter::FULL);
         $expected = 'Wednesday January 1 2014 12:00:00 AM GMT-01:30';
@@ -606,34 +507,6 @@ class TimeTest extends TestCase
     }
 
     /**
-     * test formatting dates with offset style timezone and defaultOutputTimezone
-     *
-     * @dataProvider classNameProvider
-     * @return void
-     * @see https://github.com/facebook/hhvm/issues/3637
-     */
-    public function testI18nFormatWithOffsetTimezoneWithDefaultOutputTimezone($class)
-    {
-        // America/Vancouver is GMT-8 in the winter
-        $class::setDefaultOutputTimezone('America/Vancouver');
-
-        $time = new $class('2014-01-01T00:00:00+00');
-        $result = $time->i18nFormat(\IntlDateFormatter::FULL);
-        $expected = 'Tuesday December 31 2013 4:00:00 PM Pacific Standard Time';
-        $this->assertTimeFormat($expected, $result, 'GMT to GMT-8 should be 8 hours');
-
-        $time = new $class('2014-01-01T00:00:00+09:00');
-        $result = $time->i18nFormat(\IntlDateFormatter::FULL);
-        $expected = 'Tuesday December 31 2013 7:00:00 AM Pacific Standard Time';
-        $this->assertTimeFormat($expected, $result, 'GMT+9 to GMT-8 should be 17hrs');
-
-        $time = new $class('2014-01-01T00:00:00-01:30');
-        $result = $time->i18nFormat(\IntlDateFormatter::FULL);
-        $expected = 'Tuesday December 31 2013 5:30:00 PM Pacific Standard Time';
-        $this->assertTimeFormat($expected, $result, 'GMT-1:30 to GMT-8 is 6.5hrs');
-    }
-
-    /**
      * testListTimezones
      *
      * @dataProvider classNameProvider
@@ -681,21 +554,6 @@ class TimeTest extends TestCase
     }
 
     /**
-     * Tests that __toString uses the i18n formatter and works with OutputTimezones
-     *
-     * @dataProvider classNameProvider
-     * @return void
-     */
-    public function testToStringWithDefaultOutputTimezone($class)
-    {
-        $class::setDefaultOutputTimezone('America/Vancouver');
-        $time = new $class('2014-04-20 22:10 UTC');
-        $class::setDefaultLocale('fr-FR');
-        $class::setToStringFormat(\IntlDateFormatter::FULL);
-        $this->assertTimeFormat('dimanche 20 avril 2014 15:10:00 heure d’été du Pacifique', (string)$time);
-    }
-
-    /**
      * Tests that __toString uses the i18n formatter
      *
      * @dataProvider classNameProvider
@@ -1029,12 +887,10 @@ class TimeTest extends TestCase
     {
         $expected = str_replace([',', '(', ')', ' at', ' م.', ' ه‍.ش.', ' AP', ' AH', ' SAKA', 'à '], '', $expected);
         $expected = str_replace(['  '], ' ', $expected);
-        $expected = str_replace("d’été", 'avancée', $expected);
 
         $result = str_replace([',', '(', ')', ' at', ' م.', ' ه‍.ش.', ' AP', ' AH', ' SAKA', 'à '], '', $result);
         $result = str_replace(['گرینویچ'], 'GMT', $result);
         $result = str_replace(['  '], ' ', $result);
-        $expected = str_replace("d’été", 'avancée', $result);
 
         return $this->assertSame($expected, $result, $message);
     }