Commit d9a3f399 by Alexander Makarov

Merge branch 'master'

Conflicts: framework/CHANGELOG.md
parents 1122da95 ee2b968b
......@@ -19,6 +19,8 @@ Thumbs.db
composer.phar
# composer.lock should not be committed as we always want the latest versions
/composer.lock
# composer.lock in applications is ignored in dev repo, will be committed in checked out app repos
/apps/*/composer.lock
# Mac DS_Store Files
.DS_Store
......
......@@ -5,14 +5,16 @@ php:
- 5.5
- 5.6
- hhvm
- hhvm-nightly
# run build against PHP 5.6 and hhvm but allow them to fail
# http://docs.travis-ci.com/user/build-configuration/#Rows-That-are-Allowed-To-Fail
matrix:
fast_finish: true
allow_failures:
- php: hhvm
- php: 5.6
- php: hhvm
- php: hhvm-nightly
services:
- redis-server
......
......@@ -227,8 +227,8 @@ return [
'app\config\AllAsset' => [
'basePath' => 'path/to/web',
'baseUrl' => '',
'js' => 'js/all-{ts}.js',
'css' => 'css/all-{ts}.css',
'js' => 'js/all-{hash}.js',
'css' => 'css/all-{hash}.css',
],
],
// Asset manager configuration:
......@@ -246,8 +246,8 @@ everything to `path/to/web` that can be accessed like `http://example.com/` i.e.
> Note: in the console environment some path aliases like '@webroot' and '@web' may not exist,
so corresponding paths inside the configuration should be specified directly.
JavaScript files are combined, compressed and written to `js/all-{ts}.js` where {ts} is replaced with current UNIX
timestamp.
JavaScript files are combined, compressed and written to `js/all-{hash}.js` where {hash} is replaced with the hash of
the resulting file.
`jsCompressor` and `cssCompressor` are console commands or PHP callbacks, which should perform JavaScript and CSS files
compression correspondingly. You should adjust these values according to your environment.
......
......@@ -28,10 +28,12 @@ Yii Framework 2 Change Log
- Bug #3431: Allow using extended ErrorHandler class from the app namespace (cebe)
- Bug #3436: Fixed the issue that `ServiceLocator` still returns the old component after calling `set()` with a new definition (qiangxue)
- Bug #3458: Fixed the bug that the image rendered by `CaptchaAction` was using a wrong content type (MDMunir, qiangxue)
- Bug #3473: Allow postgreSQL to specify timestamp precision via abstract types in QueryBuilder (cebe)
- Bug #3522: Fixed BaseFileHelper::normalizePath to allow a (.) for the current path. (skotos)
- Bug #3548: Fixed the bug that X-Rate-Limit-Remaining header is always zero when using RateLimiter (qiangxue)
- Bug #3564: Fixed the bug that primary key columns should not take default values from schema (qiangxue)
- Bug #3567: Fixed the bug that smallint was treated as string for PostgreSQL (qiangxue)
- Bug #3578: Fixed postgreSQL column type detection, added missing types (MDMunir, cebe)
- Bug: Fixed inconsistent return of `\yii\console\Application::runAction()` (samdark)
- Enh #2264: `CookieCollection::has()` will return false for expired or removed cookies (qiangxue)
- Enh #2435: `yii\db\IntegrityException` is now thrown on database integrity errors instead of general `yii\db\Exception` (samdark)
......@@ -55,6 +57,7 @@ Yii Framework 2 Change Log
- Enh #3518: `yii\helpers\Html::encode()` now replaces invalid code sequences with "?" (DaSourcerer)
- Enh #3521: Added `yii\filters\HttpCache::sessionCacheLimiter` (qiangxue)
- Enh #3542: Removed requirement to specify `extensions` in application config (samdark)
- Enh #3574: Add integrity check support for SQLite (zeeke)
- Enh: Added support for using sub-queries when building a DB query with `IN` condition (qiangxue)
- Enh: Supported adding a new response formatter without the need to reconfigure existing formatters (qiangxue)
- Enh: Added `yii\web\UrlManager::addRules()` to simplify adding new URL rules (qiangxue)
......@@ -67,11 +70,13 @@ Yii Framework 2 Change Log
- Enh: Added support for using path alias with `FileDependency::fileName` (qiangxue)
- Enh: Added param `hideOnSinglePage` to `yii\widgets\LinkPager` (arturf)
- Enh: Added support for array attributes in `in` validator (creocoder)
- Chg #2898: `yii\console\controllers\AssetController` is now using hashes instead of timestamps (samdark)
- Chg #2913: RBAC `DbManager` is now initialized via migration (samdark)
- Chg #3036: Upgraded Twitter Bootstrap to 3.1.x (qiangxue)
- Chg #3175: InvalidCallException, InvalidParamException, UnknownMethodException are now extended from SPL BadMethodCallException (samdark)
- Chg #3383: Added `$type` parameter to `IdentityInterface::findIdentityByAccessToken()` (qiangxue)
- Chg #3531: \yii\grid\GridView now allows any character (except ":") in the attribute part of the shorthand syntax for columns (rawtaz)
- Chg #3544: Added `$key` as a parameter to the callable specified via `yii\grid\DataColumn::value` (mdmunir)
- Chg: Replaced `clearAll()` and `clearAllAssignments()` in `yii\rbac\ManagerInterface` with `removeAll()`, `removeAllRoles()`, `removeAllPermissions()`, `removeAllRules()` and `removeAllAssignments()` (qiangxue)
- Chg: Added `$user` as the first parameter of `yii\rbac\Rule::execute()` (qiangxue)
- Chg: `yii\grid\DataColumn::getDataCellValue()` visibility is now `public` to allow accessing the value from a GridView directly (cebe)
......
......@@ -37,3 +37,10 @@ Upgrade from Yii 2.0 Beta
* If you are using `dropDownList()`, `listBox()`, `activeDropDownList()`, or `activeListBox()`
of `yii\helpers\Html`, and your list options use multiple blank spaces to format and align
option label texts, you need to specify the option `encodeSpaces` to be true.
* If you are using `yii\grid\GridView` and have configured a data column to use a PHP callable
to return cell values (via `yii\grid\DataColumn::value`), you may need to adjust the signature
of the callable to be `function ($model, $key, $index, $widget)`. The `$key` parameter was newly added
in this release.
* `yii\console\controllers\AssetController` is now using hashes instead of timestamps. Replace all `{ts}` with `{hash}`.
\ No newline at end of file
......@@ -10,6 +10,7 @@ namespace yii\console\controllers;
use Yii;
use yii\console\Exception;
use yii\console\Controller;
use yii\helpers\StringHelper;
use yii\helpers\VarDumper;
/**
......@@ -52,14 +53,13 @@ class AssetController extends Controller
*
* ~~~
* 'app\config\AllAsset' => [
* 'js' => 'js/all-{ts}.js',
* 'css' => 'css/all-{ts}.css',
* 'js' => 'js/all-{hash}.js',
* 'css' => 'css/all-{hash}.css',
* 'depends' => [ ... ],
* ]
* ~~~
*
* File names can contain placeholder "{ts}", which will be filled by current timestamp, while
* file creation.
* File names can contain placeholder "{hash}", which will be filled by the hash of the resulting file.
*/
public $targets = [];
/**
......@@ -138,14 +138,13 @@ class AssetController extends Controller
$this->loadConfiguration($configFile);
$bundles = $this->loadBundles($this->bundles);
$targets = $this->loadTargets($this->targets, $bundles);
$timestamp = time();
foreach ($targets as $name => $target) {
echo "Creating output bundle '{$name}':\n";
if (!empty($target->js)) {
$this->buildTarget($target, 'js', $bundles, $timestamp);
$this->buildTarget($target, 'js', $bundles);
}
if (!empty($target->css)) {
$this->buildTarget($target, 'css', $bundles, $timestamp);
$this->buildTarget($target, 'css', $bundles);
}
echo "\n";
}
......@@ -282,14 +281,11 @@ class AssetController extends Controller
* @param \yii\web\AssetBundle $target output asset bundle
* @param string $type either 'js' or 'css'.
* @param \yii\web\AssetBundle[] $bundles source asset bundles.
* @param integer $timestamp current timestamp.
* @throws Exception on failure.
*/
protected function buildTarget($target, $type, $bundles, $timestamp)
protected function buildTarget($target, $type, $bundles)
{
$outputFile = strtr($target->$type, [
'{ts}' => $timestamp,
]);
$tempFile = $target->basePath . '/' . strtr($target->$type, ['{hash}' => 'temp']);
$inputFiles = [];
foreach ($target->depends as $name) {
......@@ -302,10 +298,13 @@ class AssetController extends Controller
}
}
if ($type === 'js') {
$this->compressJsFiles($inputFiles, $target->basePath . '/' . $outputFile);
$this->compressJsFiles($inputFiles, $tempFile);
} else {
$this->compressCssFiles($inputFiles, $target->basePath . '/' . $outputFile);
$this->compressCssFiles($inputFiles, $tempFile);
}
$outputFile = $target->basePath . '/' . strtr($target->$type, ['{hash}' => md5_file($tempFile)]);
rename($tempFile, $outputFile);
$target->$type = [$outputFile];
}
......@@ -599,8 +598,8 @@ return [
'app\assets\AllAsset' => [
'basePath' => 'path/to/web',
'baseUrl' => '',
'js' => 'js/all-{ts}.js',
'css' => 'css/all-{ts}.css',
'js' => 'js/all-{hash}.js',
'css' => 'css/all-{hash}.css',
],
],
// Asset manager configuration:
......
......@@ -30,9 +30,9 @@ class QueryBuilder extends \yii\db\QueryBuilder
Schema::TYPE_BIGINT => 'bigint',
Schema::TYPE_FLOAT => 'double precision',
Schema::TYPE_DECIMAL => 'numeric(10,0)',
Schema::TYPE_DATETIME => 'timestamp',
Schema::TYPE_TIMESTAMP => 'timestamp',
Schema::TYPE_TIME => 'time',
Schema::TYPE_DATETIME => 'timestamp(0)',
Schema::TYPE_TIMESTAMP => 'timestamp(0)',
Schema::TYPE_TIME => 'time(0)',
Schema::TYPE_DATE => 'date',
Schema::TYPE_BINARY => 'bytea',
Schema::TYPE_BOOLEAN => 'boolean',
......
......@@ -26,49 +26,83 @@ class Schema extends \yii\db\Schema
/**
* @var array mapping from physical column types (keys) to abstract
* column types (values)
* @see http://www.postgresql.org/docs/current/static/datatype.html#DATATYPE-TABLE
*/
public $typeMap = [
'abstime' => self::TYPE_TIMESTAMP,
'bit' => self::TYPE_STRING,
'bit varying' => self::TYPE_STRING,
'varbit' => self::TYPE_STRING,
'bool' => self::TYPE_BOOLEAN,
'boolean' => self::TYPE_BOOLEAN,
'box' => self::TYPE_STRING,
'circle' => self::TYPE_STRING,
'point' => self::TYPE_STRING,
'line' => self::TYPE_STRING,
'lseg' => self::TYPE_STRING,
'polygon' => self::TYPE_STRING,
'path' => self::TYPE_STRING,
'character' => self::TYPE_STRING,
'bytea' => self::TYPE_BINARY,
'char' => self::TYPE_STRING,
'character varying' => self::TYPE_STRING,
'varchar' => self::TYPE_STRING,
'text' => self::TYPE_TEXT,
'bytea' => self::TYPE_BINARY,
'cidr' => self::TYPE_STRING,
'circle' => self::TYPE_STRING,
'date' => self::TYPE_DATE,
'inet' => self::TYPE_STRING,
'macaddr' => self::TYPE_STRING,
'real' => self::TYPE_FLOAT,
'float4' => self::TYPE_FLOAT,
'double precision' => self::TYPE_FLOAT,
'float8' => self::TYPE_FLOAT,
'decimal' => self::TYPE_DECIMAL,
'double precision' => self::TYPE_DECIMAL,
'inet' => self::TYPE_STRING,
'numeric' => self::TYPE_DECIMAL,
'money' => self::TYPE_MONEY,
'smallint' => self::TYPE_SMALLINT,
'int2' => self::TYPE_INTEGER,
'int2' => self::TYPE_SMALLINT,
'int4' => self::TYPE_INTEGER,
'int8' => self::TYPE_BIGINT,
'int' => self::TYPE_INTEGER,
'integer' => self::TYPE_INTEGER,
'bigint' => self::TYPE_BIGINT,
'interval' => self::TYPE_STRING,
'json' => self::TYPE_STRING,
'line' => self::TYPE_STRING,
'macaddr' => self::TYPE_STRING,
'money' => self::TYPE_MONEY,
'name' => self::TYPE_STRING,
'numeric' => self::TYPE_STRING,
'int8' => self::TYPE_BIGINT,
'oid' => self::TYPE_BIGINT, // should not be used. it's pg internal!
'path' => self::TYPE_STRING,
'point' => self::TYPE_STRING,
'polygon' => self::TYPE_STRING,
'text' => self::TYPE_TEXT,
'smallserial' => self::TYPE_SMALLINT,
'serial2' => self::TYPE_SMALLINT,
'serial4' => self::TYPE_INTEGER,
'serial' => self::TYPE_INTEGER,
'bigserial' => self::TYPE_BIGINT,
'serial8' => self::TYPE_BIGINT,
'pg_lsn' => self::TYPE_BIGINT,
'date' => self::TYPE_DATE,
'interval' => self::TYPE_STRING,
'time without time zone' => self::TYPE_TIME,
'time' => self::TYPE_TIME,
'time with time zone' => self::TYPE_TIME,
'timetz' => self::TYPE_TIME,
'timestamp without time zone' => self::TYPE_TIMESTAMP,
'timestamp' => self::TYPE_TIMESTAMP,
'timestamp with time zone' => self::TYPE_TIMESTAMP,
'time with time zone' => self::TYPE_TIMESTAMP,
'timestamptz' => self::TYPE_TIMESTAMP,
'abstime' => self::TYPE_TIMESTAMP,
'tsquery' => self::TYPE_STRING,
'tsvector' => self::TYPE_STRING,
'txid_snapshot' => self::TYPE_STRING,
'unknown' => self::TYPE_STRING,
'uuid' => self::TYPE_STRING,
'bit varying' => self::TYPE_STRING,
'character varying' => self::TYPE_STRING,
'json' => self::TYPE_STRING,
'jsonb' => self::TYPE_STRING,
'xml' => self::TYPE_STRING
];
......
......@@ -139,7 +139,7 @@ class QueryBuilder extends \yii\db\QueryBuilder
*/
public function checkIntegrity($check = true, $schema = '', $table = '')
{
throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.');
return 'PRAGMA foreign_keys='.(int)$check;
}
/**
......
......@@ -51,7 +51,7 @@ class DataColumn extends Column
public $label;
/**
* @var string|\Closure an anonymous function that returns the value to be displayed for every data model.
* The signature of this function is `function ($model, $index, $widget)`.
* The signature of this function is `function ($model, $key, $index, $widget)`.
* If this is not set, `$model[$attribute]` will be used to obtain the value.
*
* You may also set this property to a string representing the attribute name to be displayed in this column.
......@@ -176,7 +176,7 @@ class DataColumn extends Column
if (is_string($this->value)) {
return ArrayHelper::getValue($model, $this->value);
} else {
return call_user_func($this->value, $model, $index, $this);
return call_user_func($this->value, $model, $key, $index, $this);
}
} elseif ($this->attribute !== null) {
return ArrayHelper::getValue($model, $this->attribute);
......
......@@ -129,7 +129,6 @@ class BaseHtml
public static function tag($name, $content = '', $options = [])
{
$html = "<$name" . static::renderTagAttributes($options) . '>';
return isset(static::$voidElements[strtolower($name)]) ? $html : "$html$content</$name>";
}
......@@ -337,7 +336,6 @@ class BaseHtml
if ($url !== null) {
$options['href'] = Url::to($url);
}
return static::tag('a', $text, $options);
}
......@@ -357,7 +355,6 @@ class BaseHtml
public static function mailto($text, $email = null, $options = [])
{
$options['href'] = 'mailto:' . ($email === null ? $text : $email);
return static::tag('a', $text, $options);
}
......@@ -376,7 +373,6 @@ class BaseHtml
if (!isset($options['alt'])) {
$options['alt'] = '';
}
return static::tag('img', '', $options);
}
......@@ -396,7 +392,6 @@ class BaseHtml
public static function label($content, $for = null, $options = [])
{
$options['for'] = $for;
return static::tag('label', $content, $options);
}
......@@ -430,7 +425,6 @@ class BaseHtml
public static function submitButton($content = 'Submit', $options = [])
{
$options['type'] = 'submit';
return static::button($content, $options);
}
......@@ -448,7 +442,6 @@ class BaseHtml
public static function resetButton($content = 'Reset', $options = [])
{
$options['type'] = 'reset';
return static::button($content, $options);
}
......@@ -468,7 +461,6 @@ class BaseHtml
$options['type'] = $type;
$options['name'] = $name;
$options['value'] = $value === null ? null : (string) $value;
return static::tag('input', '', $options);
}
......@@ -485,7 +477,6 @@ class BaseHtml
{
$options['type'] = 'button';
$options['value'] = $label;
return static::tag('input', '', $options);
}
......@@ -502,7 +493,6 @@ class BaseHtml
{
$options['type'] = 'submit';
$options['value'] = $label;
return static::tag('input', '', $options);
}
......@@ -518,7 +508,6 @@ class BaseHtml
{
$options['type'] = 'reset';
$options['value'] = $label;
return static::tag('input', '', $options);
}
......@@ -598,7 +587,6 @@ class BaseHtml
public static function textarea($name, $value = '', $options = [])
{
$options['name'] = $name;
return static::tag('textarea', static::encode($value), $options);
}
......@@ -992,7 +980,6 @@ class BaseHtml
$results[] = static::tag('li', $encode ? static::encode($item) : $item, $itemOptions);
}
}
return static::tag($tag, "\n" . implode("\n", $results) . "\n", $options);
}
......@@ -1022,7 +1009,6 @@ class BaseHtml
public static function ol($items, $options = [])
{
$options['tag'] = 'ol';
return static::ul($items, $options);
}
......@@ -1051,7 +1037,6 @@ class BaseHtml
$attribute = static::getAttributeName($attribute);
$label = isset($options['label']) ? $options['label'] : static::encode($model->getAttributeLabel($attribute));
unset($options['label'], $options['for']);
return static::label($label, $for, $options);
}
......@@ -1118,7 +1103,6 @@ class BaseHtml
$error = $model->getFirstError($attribute);
$tag = isset($options['tag']) ? $options['tag'] : 'div';
unset($options['tag']);
return Html::tag($tag, Html::encode($error), $options);
}
......@@ -1142,7 +1126,6 @@ class BaseHtml
if (!array_key_exists('id', $options)) {
$options['id'] = static::getInputId($model, $attribute);
}
return static::input($type, $name, $value, $options);
}
......@@ -1235,7 +1218,6 @@ class BaseHtml
if (!array_key_exists('id', $options)) {
$options['id'] = static::getInputId($model, $attribute);
}
return static::textarea($name, $value, $options);
}
......@@ -1518,7 +1500,6 @@ class BaseHtml
if (!array_key_exists('id', $options)) {
$options['id'] = static::getInputId($model, $attribute);
}
return static::$type($name, $selection, $items, $options);
}
......@@ -1775,7 +1756,6 @@ class BaseHtml
$result[trim($property[0])] = trim($property[1]);
}
}
return $result;
}
......@@ -1899,7 +1879,6 @@ class BaseHtml
public static function getInputId($model, $attribute)
{
$name = strtolower(static::getInputName($model, $attribute));
return str_replace(['[]', '][', '[', ']', ' '], ['', '-', '-', '', '-'], $name);
return str_replace(['[]', '][', '[', ']', ' ', '.'], ['', '-', '-', '', '-', '-'], $name);
}
}
......@@ -20,7 +20,7 @@
<?php if ($method !== null): ?>
<span class="call">
<?php if ($file !== null) echo '&ndash;' ?>
<?= $class !== null ? $handler->addTypeLinks("$class::$method(" . $handler->argumentsToString($args) . ")") : $handler->htmlEncode($method) . '(' . $handler->argumentsToString($args) . ')' ?>
<?= ($class !== null ? $handler->addTypeLinks("$class::$method") : $handler->htmlEncode($method)) . '(' . $handler->argumentsToString($args) . ')' ?>
</span>
<?php endif; ?>
<span class="at"><?php if ($line !== null) echo 'at line'; ?></span>
......
......@@ -156,11 +156,10 @@ class ErrorHandler extends \yii\base\ErrorHandler
*/
public function addTypeLinks($code)
{
if (preg_match('/(.*?)::([^(]+)\((.*)\)/', $code, $matches)) {
if (preg_match('/(.*?)::([^(]+)/', $code, $matches)) {
$class = $matches[1];
$method = $matches[2];
$args = $matches[3];
$text = $this->htmlEncode($class) . '::' . $this->htmlEncode($method) . '(' . $args . ')';
$text = $this->htmlEncode($class) . '::' . $this->htmlEncode($method);
} else {
$class = $code;
$text = $this->htmlEncode($class);
......
......@@ -3,6 +3,7 @@
namespace yiiunit\framework\helpers;
use Yii;
use yii\base\DynamicModel;
use yii\helpers\Html;
use yiiunit\TestCase;
......@@ -157,6 +158,13 @@ class HtmlTest extends TestCase
$this->assertEquals('<button type="reset" class="t" name="test" value="value">content<></button>', Html::resetButton('content<>', ['name' => 'test', 'value' => 'value', 'class' => 't']));
}
public function testInputId()
{
$model = new DynamicModel(['test', 'relation.name']);
$this->assertEquals('<input type="text" id="dynamicmodel-test" name="DynamicModel[test]">', Html::activeTextInput($model, 'test'));
$this->assertEquals('<input type="text" id="dynamicmodel-relation-name" name="DynamicModel[relation.name]">', Html::activeTextInput($model, 'relation.name'));
}
public function testInput()
{
$this->assertEquals('<input type="text">', Html::input('text'));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment