From 5ecb5e3bd0617b0c291d9ce3b3c59eebd6c3704f Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 4 Jun 2013 17:08:26 -0400 Subject: [PATCH 1/7] Fixed Formatter doc. --- framework/yii/i18n/Formatter.php | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/framework/yii/i18n/Formatter.php b/framework/yii/i18n/Formatter.php index d688a15..4a93397 100644 --- a/framework/yii/i18n/Formatter.php +++ b/framework/yii/i18n/Formatter.php @@ -30,19 +30,28 @@ class Formatter extends \yii\base\Formatter */ public $locale; /** - * @var string the default format string to be used to format a date using PHP date() function. + * @var string the default format string to be used to format a date. + * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. + * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). */ public $dateFormat = 'short'; /** - * @var string the default format string to be used to format a time using PHP date() function. + * @var string the default format string to be used to format a time. + * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. + * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). */ public $timeFormat = 'short'; /** - * @var string the default format string to be used to format a date and time using PHP date() function. + * @var string the default format string to be used to format a date and time. + * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. + * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). */ public $datetimeFormat = 'short'; /** * @var array the options to be set for the NumberFormatter objects. Please refer to + * [PHP manual](http://php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatattribute) + * for the possible options. This property is used by [[createNumberFormatter]] when + * creating a new number formatter to format decimals, currencies, etc. */ public $numberFormatOptions = array(); @@ -81,8 +90,11 @@ class Formatter extends \yii\base\Formatter * - a PHP DateTime object * * @param string $format the format used to convert the value into a date string. - * If null, [[dateFormat]] will be used. The format string should be the one - * that can be recognized by the PHP `date()` function. + * If null, [[dateFormat]] will be used. + * + * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. + * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). + * * @return string the formatted result * @see dateFormat */ @@ -111,8 +123,11 @@ class Formatter extends \yii\base\Formatter * - a PHP DateTime object * * @param string $format the format used to convert the value into a date string. - * If null, [[dateFormat]] will be used. The format string should be the one - * that can be recognized by the PHP `date()` function. + * If null, [[dateFormat]] will be used. + * + * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. + * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). + * * @return string the formatted result * @see timeFormat */ @@ -141,8 +156,11 @@ class Formatter extends \yii\base\Formatter * - a PHP DateTime object * * @param string $format the format used to convert the value into a date string. - * If null, [[dateFormat]] will be used. The format string should be the one - * that can be recognized by the PHP `date()` function. + * If null, [[dateFormat]] will be used. + * + * This can be "short", "medium", "long", or "full", which represents a preset format of different lengths. + * It can also be a custom format as specified in the [ICU manual](http://userguide.icu-project.org/formatparse/datetime). + * * @return string the formatted result * @see datetimeFormat */ @@ -213,7 +231,7 @@ class Formatter extends \yii\base\Formatter /** * Creates a number formatter based on the given type and format. * @param integer $type the type of the number formatter - * @param string $format the format to be used + * @param string $format the format to be used. Please refer to [ICU manual](http://www.icu-project.org/apiref/icu4c/classDecimalFormat.html#_details) * @return NumberFormatter the created formatter instance */ protected function createNumberFormatter($type, $format) From cbf642d93147442daffdd5eb4e8b184480ab1313 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 4 Jun 2013 17:21:40 -0400 Subject: [PATCH 2/7] Added support for locale-dependent decimal and grouping separators. --- framework/yii/base/Formatter.php | 18 +++++++++++++----- framework/yii/i18n/Formatter.php | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/framework/yii/base/Formatter.php b/framework/yii/base/Formatter.php index d15e5f2..e62039e 100644 --- a/framework/yii/base/Formatter.php +++ b/framework/yii/base/Formatter.php @@ -39,17 +39,19 @@ class Formatter extends Component public $datetimeFormat = 'Y/m/d h:i:s A'; /** * @var array the text to be displayed when formatting a boolean value. The first element corresponds - * to the text display for false, the second element for true. Defaults to array('No', 'Yes'). + * to the text display for false, the second element for true. Defaults to `array('No', 'Yes')`. */ public $booleanFormat; /** * @var string the character displayed as the decimal point when formatting a number. + * If not set, "." will be used. */ - public $decimalSeparator = '.'; + public $decimalSeparator; /** * @var string the character displayed as the thousands separator character when formatting a number. + * If not set, "," will be used. */ - public $thousandSeparator = ','; + public $thousandSeparator; /** @@ -273,7 +275,11 @@ class Formatter extends Component */ public function asDouble($value, $decimals = 2) { - return str_replace('.', $this->decimalSeparator, sprintf("%.{$decimals}f", $value)); + if ($this->decimalSeparator === null) { + return sprintf("%.{$decimals}f", $value); + } else { + return str_replace('.', $this->decimalSeparator, sprintf("%.{$decimals}f", $value)); + } } /** @@ -287,6 +293,8 @@ class Formatter extends Component */ public function asNumber($value, $decimals = 0) { - return number_format($value, $decimals, $this->decimalSeparator, $this->thousandSeparator); + $ds = isset($this->decimalSeparator) ? $this->decimalSeparator: '.'; + $ts = isset($this->thousandSeparator) ? $this->thousandSeparator: ','; + return number_format($value, $decimals, $ds, $ts); } } diff --git a/framework/yii/i18n/Formatter.php b/framework/yii/i18n/Formatter.php index 4a93397..8fa29dd 100644 --- a/framework/yii/i18n/Formatter.php +++ b/framework/yii/i18n/Formatter.php @@ -54,6 +54,16 @@ class Formatter extends \yii\base\Formatter * creating a new number formatter to format decimals, currencies, etc. */ public $numberFormatOptions = array(); + /** + * @var string the character displayed as the decimal point when formatting a number. + * If not set, the decimal separator corresponding to [[locale]] will be used. + */ + public $decimalSeparator; + /** + * @var string the character displayed as the thousands separator character when formatting a number. + * If not set, the thousand separator corresponding to [[locale]] will be used. + */ + public $thousandSeparator; /** @@ -70,6 +80,16 @@ class Formatter extends \yii\base\Formatter if ($this->locale === null) { $this->locale = Yii::$app->language; } + if ($this->decimalSeparator === null || $this->thousandSeparator === null) { + $formatter = new NumberFormatter($this->locale, NumberFormatter::DECIMAL); + if ($this->decimalSeparator === null) { + $this->decimalSeparator = $formatter->getSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL); + } + if ($this->thousandSeparator === null) { + $this->thousandSeparator = $formatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); + } + } + parent::init(); } From 23767304527a989c2e664f2522c0acacc857b615 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 4 Jun 2013 18:11:50 -0400 Subject: [PATCH 3/7] better check of existence of tables. --- framework/yii/db/ActiveRecord.php | 8 +++++++- framework/yii/db/mysql/Schema.php | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/framework/yii/db/ActiveRecord.php b/framework/yii/db/ActiveRecord.php index 58411f0..6faebbf 100644 --- a/framework/yii/db/ActiveRecord.php +++ b/framework/yii/db/ActiveRecord.php @@ -275,10 +275,16 @@ class ActiveRecord extends Model /** * Returns the schema information of the DB table associated with this AR class. * @return TableSchema the schema information of the DB table associated with this AR class. + * @throws InvalidConfigException if the table for the AR class does not exist. */ public static function getTableSchema() { - return static::getDb()->getTableSchema(static::tableName()); + $schema = static::getDb()->getTableSchema(static::tableName()); + if ($schema !== null) { + return $schema; + } else { + throw new InvalidConfigException("The table does not exist: " . static::tableName()); + } } /** diff --git a/framework/yii/db/mysql/Schema.php b/framework/yii/db/mysql/Schema.php index 501149a..e7b34e0 100644 --- a/framework/yii/db/mysql/Schema.php +++ b/framework/yii/db/mysql/Schema.php @@ -181,12 +181,12 @@ class Schema extends \yii\db\Schema */ protected function findColumns($table) { - $sql = 'SHOW FULL COLUMNS FROM ' . $this->quoteSimpleTableName($table->name); - try { - $columns = $this->db->createCommand($sql)->queryAll(); - } catch (\Exception $e) { + $rows = $this->db->createCommand("SHOW TABLES LIKE " . $this->quoteValue($table->name))->queryAll(); + if (count($rows) === 0) { return false; } + $sql = 'SHOW FULL COLUMNS FROM ' . $this->quoteSimpleTableName($table->name); + $columns = $this->db->createCommand($sql)->queryAll(); foreach ($columns as $info) { $column = $this->loadColumnSchema($info); $table->columns[$column->name] = $column; From b311b6ecf3b0168024dbe0241faa6c5dea9184fd Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 4 Jun 2013 18:13:32 -0400 Subject: [PATCH 4/7] typo fix. --- framework/yii/i18n/Formatter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/yii/i18n/Formatter.php b/framework/yii/i18n/Formatter.php index 8fa29dd..948e277 100644 --- a/framework/yii/i18n/Formatter.php +++ b/framework/yii/i18n/Formatter.php @@ -83,10 +83,10 @@ class Formatter extends \yii\base\Formatter if ($this->decimalSeparator === null || $this->thousandSeparator === null) { $formatter = new NumberFormatter($this->locale, NumberFormatter::DECIMAL); if ($this->decimalSeparator === null) { - $this->decimalSeparator = $formatter->getSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL); + $this->decimalSeparator = $formatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); } if ($this->thousandSeparator === null) { - $this->thousandSeparator = $formatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL); + $this->thousandSeparator = $formatter->getSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL); } } From 9d6f11d5d524afeacd9cb702612d8667c15a6e3c Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 4 Jun 2013 19:34:51 -0400 Subject: [PATCH 5/7] new way of detecting if table exists. --- framework/yii/db/mysql/Schema.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/framework/yii/db/mysql/Schema.php b/framework/yii/db/mysql/Schema.php index e7b34e0..b42ef15 100644 --- a/framework/yii/db/mysql/Schema.php +++ b/framework/yii/db/mysql/Schema.php @@ -178,15 +178,21 @@ class Schema extends \yii\db\Schema * Collects the metadata of table columns. * @param TableSchema $table the table metadata * @return boolean whether the table exists in the database + * @throws \Exception if DB query fails */ protected function findColumns($table) { - $rows = $this->db->createCommand("SHOW TABLES LIKE " . $this->quoteValue($table->name))->queryAll(); - if (count($rows) === 0) { - return false; - } $sql = 'SHOW FULL COLUMNS FROM ' . $this->quoteSimpleTableName($table->name); - $columns = $this->db->createCommand($sql)->queryAll(); + try { + $columns = $this->db->createCommand($sql)->queryAll(); + } catch (\Exception $e) { + $previous = $e->getPrevious(); + if ($previous instanceof \PDOException && $previous->getCode() == '42S02') { + // table does not exist + return false; + } + throw $e; + } foreach ($columns as $info) { $column = $this->loadColumnSchema($info); $table->columns[$column->name] = $column; From 7e111e92e2865a94359962fe323b5b759441b4f6 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 5 Jun 2013 06:15:31 -0400 Subject: [PATCH 6/7] Fixes issue #496 --- framework/yii/logging/Target.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/framework/yii/logging/Target.php b/framework/yii/logging/Target.php index fac8b53..7be7001 100644 --- a/framework/yii/logging/Target.php +++ b/framework/yii/logging/Target.php @@ -204,11 +204,9 @@ abstract class Target extends Component if ($matched) { foreach ($this->except as $category) { $prefix = rtrim($category, '*'); - foreach ($messages as $i => $message) { - if (strpos($message[2], $prefix) === 0 && ($message[2] === $category || $prefix !== $category)) { - $matched = false; - break; - } + if (strpos($message[2], $prefix) === 0 && ($message[2] === $category || $prefix !== $category)) { + $matched = false; + break; } } } From b7c1f949776bb9f4b55b0ac2d55429e8ab3a681a Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Wed, 5 Jun 2013 08:28:36 -0400 Subject: [PATCH 7/7] Fixed bug about setting default path aliases. --- framework/yii/base/Application.php | 62 +++++++++++++++++--------------------- framework/yii/base/Module.php | 3 ++ 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/framework/yii/base/Application.php b/framework/yii/base/Application.php index 495c1f8..09951bd 100644 --- a/framework/yii/base/Application.php +++ b/framework/yii/base/Application.php @@ -67,10 +67,20 @@ class Application extends Module * Constructor. * @param array $config name-value pairs that will be used to initialize the object properties. * Note that the configuration must contain both [[id]] and [[basePath]]. + * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing. */ public function __construct($config = array()) { Yii::$app = $this; + if (!isset($config['id'])) { + throw new InvalidConfigException('The "id" configuration is required.'); + } + if (isset($config['basePath'])) { + $this->setBasePath($config['basePath']); + unset($config['basePath']); + } else { + throw new InvalidConfigException('The "basePath" configuration is required.'); + } $this->preInit($config); @@ -83,37 +93,24 @@ class Application extends Module /** * Pre-initializes the application. * This method is called at the beginning of the application constructor. - * When this method is called, none of the application properties are initialized yet. - * The default implementation will initialize a few important properties - * that may be referenced during the initialization of the rest of the properties. * @param array $config the application configuration - * @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing. */ - public function preInit($config) + public function preInit(&$config) { - if (!isset($config['id'])) { - throw new InvalidConfigException('The "id" configuration is required.'); - } - if (!isset($config['basePath'])) { - throw new InvalidConfigException('The "basePath" configuration is required.'); - } - - $this->setBasePath($config['basePath']); - Yii::setAlias('@app', $this->getBasePath()); - unset($config['basePath']); - - if (isset($config['vendor'])) { - $this->setVendorPath($config['vendor']); + if (isset($config['vendorPath'])) { + $this->setVendorPath($config['vendorPath']); unset($config['vendorPath']); + } else { + // set "@vendor" + $this->getVendorPath(); } - Yii::setAlias('@vendor', $this->getVendorPath()); - - if (isset($config['runtime'])) { - $this->setRuntimePath($config['runtime']); - unset($config['runtime']); + if (isset($config['runtimePath'])) { + $this->setRuntimePath($config['runtimePath']); + unset($config['runtimePath']); + } else { + // set "@runtime" + $this->getRuntimePath(); } - Yii::setAlias('@runtime', $this->getRuntimePath()); - if (isset($config['timeZone'])) { $this->setTimeZone($config['timeZone']); unset($config['timeZone']); @@ -202,7 +199,8 @@ class Application extends Module /** * Returns the directory that stores runtime files. - * @return string the directory that stores runtime files. Defaults to 'protected/runtime'. + * @return string the directory that stores runtime files. + * Defaults to the "runtime" subdirectory under [[basePath]]. */ public function getRuntimePath() { @@ -215,16 +213,11 @@ class Application extends Module /** * Sets the directory that stores runtime files. * @param string $path the directory that stores runtime files. - * @throws InvalidConfigException if the directory does not exist or is not writable */ public function setRuntimePath($path) { - $path = Yii::getAlias($path); - if (is_dir($path) && is_writable($path)) { - $this->_runtimePath = $path; - } else { - throw new InvalidConfigException("Runtime path must be a directory writable by the Web server process: $path"); - } + $this->_runtimePath = Yii::getAlias($path); + Yii::setAlias('@runtime', $this->_runtimePath); } private $_vendorPath; @@ -232,7 +225,7 @@ class Application extends Module /** * Returns the directory that stores vendor files. * @return string the directory that stores vendor files. - * Defaults to 'vendor' directory under applications [[basePath]]. + * Defaults to "vendor" directory under [[basePath]]. */ public function getVendorPath() { @@ -249,6 +242,7 @@ class Application extends Module public function setVendorPath($path) { $this->_vendorPath = Yii::getAlias($path); + Yii::setAlias('@vendor', $this->_vendorPath); } /** diff --git a/framework/yii/base/Module.php b/framework/yii/base/Module.php index fac4164..5f5c376 100644 --- a/framework/yii/base/Module.php +++ b/framework/yii/base/Module.php @@ -236,6 +236,9 @@ abstract class Module extends Component $p = realpath($path); if ($p !== false && is_dir($p)) { $this->_basePath = $p; + if ($this instanceof Application) { + Yii::setAlias('@app', $p); + } } else { throw new InvalidParamException("The directory does not exist: $path"); }