Commit 4a837deb by Alexander Makarov

Merge branch 'master'

parents 76705b43 9aa006e5
...@@ -2,5 +2,5 @@ Contributing to Yii2 ...@@ -2,5 +2,5 @@ Contributing to Yii2
==================== ====================
- [Report an issue](docs/internals/report-an-issue.md) - [Report an issue](docs/internals/report-an-issue.md)
- [Traslate documentation or messages](docs/internals/translations.md) - [Translate documentation or messages](docs/internals/translations.md)
- [Contribute to the core code or fix bugs](docs/internals/getting-started.md) - [Contribute to the core code or fix bugs](docs/internals/getting-started.md)
...@@ -5,7 +5,7 @@ use yii\widgets\ActiveForm; ...@@ -5,7 +5,7 @@ use yii\widgets\ActiveForm;
/** /**
* @var yii\web\View $this * @var yii\web\View $this
* @var yii\widgets\ActiveForm $form * @var yii\widgets\ActiveForm $form
* @var app\models\LoginForm $model * @var common\models\LoginForm $model
*/ */
$this->title = 'Login'; $this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
......
...@@ -126,12 +126,16 @@ class SiteController extends Controller ...@@ -126,12 +126,16 @@ class SiteController extends Controller
public function actionResetPassword($token) public function actionResetPassword($token)
{ {
if (empty($token) || is_array($token)) {
throw new BadRequestHttpException('Invalid password reset token.');
}
$model = User::find([ $model = User::find([
'password_reset_token' => $token, 'password_reset_token' => $token,
'status' => User::STATUS_ACTIVE, 'status' => User::STATUS_ACTIVE,
]); ]);
if (!$model) { if ($model === null) {
throw new BadRequestHttpException('Wrong password reset token.'); throw new BadRequestHttpException('Wrong password reset token.');
} }
......
...@@ -6,7 +6,7 @@ use yii\captcha\Captcha; ...@@ -6,7 +6,7 @@ use yii\captcha\Captcha;
/** /**
* @var yii\web\View $this * @var yii\web\View $this
* @var yii\widgets\ActiveForm $form * @var yii\widgets\ActiveForm $form
* @var app\models\ContactForm $model * @var frontend\models\ContactForm $model
*/ */
$this->title = 'Contact'; $this->title = 'Contact';
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
......
...@@ -5,7 +5,7 @@ use yii\widgets\ActiveForm; ...@@ -5,7 +5,7 @@ use yii\widgets\ActiveForm;
/** /**
* @var yii\web\View $this * @var yii\web\View $this
* @var yii\widgets\ActiveForm $form * @var yii\widgets\ActiveForm $form
* @var app\models\LoginForm $model * @var common\models\LoginForm $model
*/ */
$this->title = 'Login'; $this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
"ext-mbstring": "*", "ext-mbstring": "*",
"lib-pcre": "*", "lib-pcre": "*",
"yiisoft/yii2-composer": "*", "yiisoft/yii2-composer": "*",
"yiisoft/jquery": "2.0.*", "yiisoft/jquery": "~2.0 | ~1.10",
"phpspec/php-diff": ">=1.0.2", "phpspec/php-diff": ">=1.0.2",
"ezyang/htmlpurifier": "4.6.*", "ezyang/htmlpurifier": "4.6.*",
"michelf/php-markdown": "1.3.*" "michelf/php-markdown": "1.3.*"
......
...@@ -210,7 +210,7 @@ assets file like the following: ...@@ -210,7 +210,7 @@ assets file like the following:
'components' => [ 'components' => [
// ... // ...
'assetManager' => [ 'assetManager' => [
'bundles' => require /path/to/myapp/config/assets_compressed.php, 'bundles' => require '/path/to/myapp/config/assets_compressed.php',
], ],
], ],
``` ```
......
...@@ -118,7 +118,7 @@ in cache and we should regenerate it: ...@@ -118,7 +118,7 @@ in cache and we should regenerate it:
public function getCachedData() public function getCachedData()
{ {
$key = /* generate unique key here */; $key = /* generate unique key here */;
$value = Yii::$app->getCache()->get($key); $value = Yii::$app->cache->get($key);
if ($value === false) { if ($value === false) {
$value = /* regenerate value because it is not found in cache and then save it in cache for later use */; $value = /* regenerate value because it is not found in cache and then save it in cache for later use */;
Yii::$app->cache->set($key, $value); Yii::$app->cache->set($key, $value);
......
...@@ -24,7 +24,7 @@ Adding more packages to your project ...@@ -24,7 +24,7 @@ Adding more packages to your project
The act of [installing a Yii application](installation.md) creates the `composer.json` file in the root directory of your project. The act of [installing a Yii application](installation.md) creates the `composer.json` file in the root directory of your project.
In this file you list the packages that your application requires. For Yii sites, the most important part of the file is the `require` section: In this file you list the packages that your application requires. For Yii sites, the most important part of the file is the `require` section:
``` ```json
{ {
"require": { "require": {
"Michelf/php-markdown": ">=1.3", "Michelf/php-markdown": ">=1.3",
...@@ -63,6 +63,25 @@ In both cases, after some waiting, the required packages will be installed and r ...@@ -63,6 +63,25 @@ In both cases, after some waiting, the required packages will be installed and r
No additional configuration of those packages will be required. No additional configuration of those packages will be required.
Using a specifc version of a package
------------------------------------
Yii always comes with the latest version of a required library that it is compatible with but allows you to use an
older version if you need to.
A good example for this is jQuery which has [dropped old IE browser support](http://jquery.com/browser-support/) in version 2.x.
When installing Yii via composer the installed jQuery version will be the latest 2.x release. When you want to use jQuery 1.10
because of IE browser support you can adjust your composer.json by requiring a specific version of jQuery like this:
```json
{
"require": {
...
"yiisoft/jquery": "1.10.*"
}
}
```
FAQ FAQ
--- ---
......
...@@ -48,6 +48,7 @@ Extensions and 3rd party libraries ...@@ -48,6 +48,7 @@ Extensions and 3rd party libraries
- [Composer](composer.md) - How to manage applications dependencies via composer - [Composer](composer.md) - How to manage applications dependencies via composer
- [Extending Yii](extensions.md) - [Extending Yii](extensions.md)
- [Template engines](template.md) - Using template engines such as Smarty or Twig - [Template engines](template.md) - Using template engines such as Smarty or Twig
- [Using Yii together with 3rd-Party Systems](using-3rd-party-libraries.md) - Using Yii in 3rd-Party Systems and using Yii 1 and 2 together
Security and access control Security and access control
=========================== ===========================
......
...@@ -525,3 +525,8 @@ up to date updating it semi-automatically and manages autoloading for third part ...@@ -525,3 +525,8 @@ up to date updating it semi-automatically and manages autoloading for third part
these are using. these are using.
In order to learn more refer to [composer](composer.md) and [installation](installation.md) sections of the guide. In order to learn more refer to [composer](composer.md) and [installation](installation.md) sections of the guide.
Using Yii 1.1 and 2.x together
------------------------------
Check the guide on [using Yii together with 3rd-Party Systems](using-3rd-party-libraries.md) on this topic.
Using 3rd-Party Libraries
=========================
Yii is carefully designed so that third-party libraries can be
easily integrated to further extend Yii's functionalities.
TODO: namespaces and composer explanations
Using Yii in 3rd-Party Systems
------------------------------
Yii can also be used as a self-contained library to support developing and enhancing
existing 3rd-party systems, such as WordPress, Joomla, etc. To do so, include
the following code in the bootstrap code of the 3rd-party system:
```php
$yiiConfig = require(__DIR__ . '/../config/yii/web.php');
new yii\web\Application($yiiConfig); // No 'run()' invocation!
```
The above code is very similar to the bootstrap code used by a typical Yii application
except one thing: it does not call the `run()` method after creating the Web application
instance.
Now we can use most features offered by Yii when developing 3rd-party enhancements. For example,
we can use `Yii::$app` to access the application instance; we can use the database features
such as ActiveRecord; we can use the model and validation feature; and so on.
Using Yii2 with Yii1
--------------------
Yii2 can be used along with Yii1 at the same project.
Since Yii2 uses namespaced class names they will not conflict with any class from Yii1.
However there is single class, which name is used both in Yii1 and Yii2, it named 'Yii'.
In order to use both Yii1 and Yii2 you need to resolve this collision.
To do so you need to define your own 'Yii' class, which will combine content of 'Yii' from 1.x
and 'Yii' from 2.x.
When using composer you add the following to your composer.json in order to add both versions of yii to your project:
```json
"require": {
"yiisoft/yii": "*",
"yiisoft/yii2": "*",
},
```
Start from defining your own descendant of [[\yii\BaseYii]]:
```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php');
class Yii extends \yii\BaseYii
{
}
Yii::$classMap = include($yii2path . '/classes.php');
```
Now we have a class, which suites Yii2, but causes fatal errors for Yii1.
So, first of all, we need to include [[\YiiBase]] of Yii1 source code to our 'Yii' class
definition file:
```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php'); // Yii 2.x
$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php'); // Yii 1.x
class Yii extends \yii\BaseYii
{
}
Yii::$classMap = include($yii2path . '/classes.php');
```
Using this, defines all necessary constants and autoloader of Yii1.
Now we need to add all fields and methods from [[\YiiBase]] of Yii1 to our 'Yii' class.
Unfortunally, there is no way to do so but copy-paste:
```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php');
$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php');
class Yii extends \yii\BaseYii
{
public static $classMap = [];
public static $enableIncludePath = true;
private static $_aliases = ['system'=>YII_PATH,'zii'=>YII_ZII_PATH];
private static $_imports = [];
private static $_includePaths;
private static $_app;
private static $_logger;
public static function getVersion()
{
return '1.1.15-dev';
}
public static function createWebApplication($config=null)
{
return self::createApplication('CWebApplication',$config);
}
public static function app()
{
return self::$_app;
}
// Rest of \YiiBase internal code placed here
...
}
Yii::$classMap = include($yii2path . '/classes.php');
Yii::registerAutoloader(['Yii', 'autoload']); // Register Yii2 autoloader via Yii1
```
Note: while copying methods you should NOT copy method "autoload()"!
Also you may avoid copying "log()", "trace()", "beginProfile()", "endProfile()"
in case you want to use Yii2 logging instead of Yii1 one.
Now we have 'Yii' class, which suites both Yii 1.x and Yii 2.x.
So bootstrap code used by your application will looks like following:
```php
require(__DIR__ . '/../components/my/Yii.php'); // include created 'Yii' class
$yii2Config = require(__DIR__ . '/../config/yii2/web.php');
new yii\web\Application($yii2Config); // create Yii 2.x application
$yii1Config = require(__DIR__ . '/../config/yii1/main.php');
Yii::createWebApplication($yii1Config)->run(); // create Yii 1.x application
```
Then in any part of your program ```Yii::$app``` refers to Yii 2.x application,
while ```Yii::app()``` refers to Yii 1.x application:
```php
echo get_class(Yii::app()); // outputs 'CWebApplication'
echo get_class(Yii::$app); // outputs 'yii\web\Application'
```
\ No newline at end of file
...@@ -44,6 +44,9 @@ class RenderController extends Controller ...@@ -44,6 +44,9 @@ class RenderController extends Controller
} }
$renderer = $this->findRenderer(); $renderer = $this->findRenderer();
if ($renderer === false) {
return 1;
}
$renderer->targetDir = $targetDir; $renderer->targetDir = $targetDir;
$this->stdout('Searching files to process... '); $this->stdout('Searching files to process... ');
...@@ -103,15 +106,11 @@ class RenderController extends Controller ...@@ -103,15 +106,11 @@ class RenderController extends Controller
*/ */
protected function findRenderer() protected function findRenderer()
{ {
$file = Yii::getAlias('@yii/apidoc/templates/' . $this->template . '/Renderer.php'); $rendererClass = 'yii\\apidoc\\templates\\' . $this->template . '\\Renderer';
$reflection = new FileReflector($file, true); if (!class_exists($rendererClass)) {
$reflection->process();
$classes = $reflection->getClasses();
if (empty($classes)) {
$this->stderr('Renderer not found.' . PHP_EOL); $this->stderr('Renderer not found.' . PHP_EOL);
return false;
} }
$rendererClass = reset($classes)->getName();
require($file);
return new $rendererClass(); return new $rendererClass();
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace yii\debug; namespace yii\debug;
use Yii; use Yii;
use yii\base\InvalidConfigException;
use yii\log\Target; use yii\log\Target;
/** /**
...@@ -45,15 +46,10 @@ class LogTarget extends Target ...@@ -45,15 +46,10 @@ class LogTarget extends Target
if (!is_dir($path)) { if (!is_dir($path)) {
mkdir($path); mkdir($path);
} }
$indexFile = "$path/index.data";
if (!is_file($indexFile)) {
$manifest = [];
} else {
$manifest = unserialize(file_get_contents($indexFile));
}
$request = Yii::$app->getRequest(); $request = Yii::$app->getRequest();
$response = Yii::$app->getResponse(); $response = Yii::$app->getResponse();
$manifest[$this->tag] = $summary = [ $summary = [
'tag' => $this->tag, 'tag' => $this->tag,
'url' => $request->getAbsoluteUrl(), 'url' => $request->getAbsoluteUrl(),
'ajax' => $request->getIsAjax(), 'ajax' => $request->getIsAjax(),
...@@ -63,7 +59,6 @@ class LogTarget extends Target ...@@ -63,7 +59,6 @@ class LogTarget extends Target
'statusCode' => $response->statusCode, 'statusCode' => $response->statusCode,
'sqlCount' => $this->getSqlTotalCount(), 'sqlCount' => $this->getSqlTotalCount(),
]; ];
$this->gc($manifest);
$dataFile = "$path/{$this->tag}.data"; $dataFile = "$path/{$this->tag}.data";
$data = []; $data = [];
...@@ -72,7 +67,38 @@ class LogTarget extends Target ...@@ -72,7 +67,38 @@ class LogTarget extends Target
} }
$data['summary'] = $summary; $data['summary'] = $summary;
file_put_contents($dataFile, serialize($data)); file_put_contents($dataFile, serialize($data));
file_put_contents($indexFile, serialize($manifest));
$indexFile = "$path/index.data";
$this->updateIndexFile($indexFile, $summary);
}
private function updateIndexFile($indexFile, $summary)
{
touch($indexFile);
if (($fp = @fopen($indexFile, 'r+')) === false) {
throw new InvalidConfigException("Unable to open debug data index file: $indexFile");
}
@flock($fp, LOCK_EX);
$manifest = '';
while (($buffer = fgets($fp)) !== false) {
$manifest .= $buffer;
}
if (!feof($fp) || empty($manifest)) {
// error while reading index data, ignore and create new
$manifest = [];
} else {
$manifest = unserialize($manifest);
}
$manifest[$this->tag] = $summary;
$this->gc($manifest);
ftruncate($fp, 0);
rewind($fp);
fwrite($fp, serialize($manifest));
@flock($fp, LOCK_UN);
@fclose($fp);
} }
/** /**
......
<?php <?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\mongodb; namespace yii\mongodb;
use Yii; use Yii;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\test\BaseActiveFixture;
class ActiveFixture extends \yii\test\BaseActiveFixture /**
* ActiveFixture represents a fixture backed up by a [[modelClass|MongoDB ActiveRecord class]] or a [[collectionName|MongoDB collection]].
*
* Either [[modelClass]] or [[collectionName]] must be set. You should also provide fixture data in the file
* specified by [[dataFile]] or overriding [[getData()]] if you want to use code to generate the fixture data.
*
* When the fixture is being loaded, it will first call [[resetCollection()]] to remove any existing data in the collection.
* It will then populate the table with the data returned by [[getData()]].
*
* After the fixture is loaded, you can access the loaded data via the [[data]] property. If you set [[modelClass]],
* you will also be able to retrieve an instance of [[modelClass]] with the populated data via [[getModel()]].
*
* @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0
*/
class ActiveFixture extends BaseActiveFixture
{ {
/** /**
* @var Connection|string the DB connection object or the application component ID of the DB connection. * @var Connection|string the DB connection object or the application component ID of the DB connection.
...@@ -55,6 +76,7 @@ class ActiveFixture extends \yii\test\BaseActiveFixture ...@@ -55,6 +76,7 @@ class ActiveFixture extends \yii\test\BaseActiveFixture
if ($this->collectionName) { if ($this->collectionName) {
return $this->collectionName; return $this->collectionName;
} else { } else {
/** @var ActiveRecord $modelClass */
$modelClass = $this->modelClass; $modelClass = $this->modelClass;
return $modelClass::collectionName(); return $modelClass::collectionName();
} }
...@@ -74,16 +96,13 @@ class ActiveFixture extends \yii\test\BaseActiveFixture ...@@ -74,16 +96,13 @@ class ActiveFixture extends \yii\test\BaseActiveFixture
*/ */
protected function getData() protected function getData()
{ {
if ($this->dataFile === false) { if ($this->dataFile === null) {
return [];
}
if ($this->dataFile !== null) {
$dataFile = Yii::getAlias($this->dataFile);
} else {
$class = new \ReflectionClass($this); $class = new \ReflectionClass($this);
$dataFile = dirname($class->getFileName()) . '/data/' . $this->getCollectionName() . '.php'; $dataFile = dirname($class->getFileName()) . '/data/' . $this->getCollectionName() . '.php';
}
return is_file($dataFile) ? require($dataFile) : []; return is_file($dataFile) ? require($dataFile) : [];
} else {
return parent::getData();
}
} }
/** /**
......
...@@ -716,7 +716,7 @@ class QueryBuilder extends Object ...@@ -716,7 +716,7 @@ class QueryBuilder extends Object
return "$column $operator (" . implode(', ', $values) . ')'; return "$column $operator (" . implode(', ', $values) . ')';
} else { } else {
$operator = $operator === 'IN' ? '=' : '<>'; $operator = $operator === 'IN' ? '=' : '<>';
return "$column$operator{$values[0]}"; return $column . $operator . reset($values);
} }
} }
......
...@@ -4,6 +4,7 @@ Yii Framework 2 Change Log ...@@ -4,6 +4,7 @@ Yii Framework 2 Change Log
2.0.0 beta under development 2.0.0 beta under development
---------------------------- ----------------------------
- Bug #1265: AssetController does not override 'js' and 'css' for compressed bundles (klimov-paul)
- Bug #1326: The `visible` setting for `DetailView` doesn't work as expected (qiangxue) - Bug #1326: The `visible` setting for `DetailView` doesn't work as expected (qiangxue)
- Bug #1446: Logging while logs are processed causes infinite loop (qiangxue) - Bug #1446: Logging while logs are processed causes infinite loop (qiangxue)
- Bug #1497: Localized view files are not correctly returned (mintao) - Bug #1497: Localized view files are not correctly returned (mintao)
...@@ -34,6 +35,8 @@ Yii Framework 2 Change Log ...@@ -34,6 +35,8 @@ Yii Framework 2 Change Log
- Bug #1992: In module scenario that use 'site/captcha' will get wrong refreshUrl (callmez) - Bug #1992: In module scenario that use 'site/captcha' will get wrong refreshUrl (callmez)
- Bug #1993: afterFind event in AR is now called after relations have been populated (cebe, creocoder) - Bug #1993: afterFind event in AR is now called after relations have been populated (cebe, creocoder)
- Bug #1998: Unchecked required checkbox never pass client validation (klevron) - Bug #1998: Unchecked required checkbox never pass client validation (klevron)
- Bug #2084: AssetController adjusting CSS URLs declared at same line fixed (klimov-paul)
- Bug #2091: `QueryBuilder::buildInCondition()` fails to handle array not starting with index 0 (qiangxue)
- Bug: Fixed `Call to a member function registerAssetFiles() on a non-object` in case of wrong `sourcePath` for an asset bundle (samdark) - Bug: Fixed `Call to a member function registerAssetFiles() on a non-object` in case of wrong `sourcePath` for an asset bundle (samdark)
- Bug: Fixed incorrect event name for `yii\jui\Spinner` (samdark) - Bug: Fixed incorrect event name for `yii\jui\Spinner` (samdark)
- Bug: Json::encode() did not handle objects that implement JsonSerializable interface correctly (cebe) - Bug: Json::encode() did not handle objects that implement JsonSerializable interface correctly (cebe)
...@@ -56,6 +59,7 @@ Yii Framework 2 Change Log ...@@ -56,6 +59,7 @@ Yii Framework 2 Change Log
- Enh #1572: Added `yii\web\Controller::createAbsoluteUrl()` (samdark) - Enh #1572: Added `yii\web\Controller::createAbsoluteUrl()` (samdark)
- Enh #1579: throw exception when the given AR relation name does not match in a case sensitive manner (qiangxue) - Enh #1579: throw exception when the given AR relation name does not match in a case sensitive manner (qiangxue)
- Enh #1581: Added `ActiveQuery::joinWith()` and `ActiveQuery::innerJoinWith()` to support joining with relations (qiangxue) - Enh #1581: Added `ActiveQuery::joinWith()` and `ActiveQuery::innerJoinWith()` to support joining with relations (qiangxue)
- Enh #1585: added schema parameter to createAbsoluteUrl() to force 'http' or 'https' (cebe)
- Enh #1601: Added support for tagName and encodeLabel parameters in ButtonDropdown (omnilight) - Enh #1601: Added support for tagName and encodeLabel parameters in ButtonDropdown (omnilight)
- Enh #1611: Added `BaseActiveRecord::markAttributeDirty()` (qiangxue) - Enh #1611: Added `BaseActiveRecord::markAttributeDirty()` (qiangxue)
- Enh #1633: Advanced application template now works with MongoDB by default (samdark) - Enh #1633: Advanced application template now works with MongoDB by default (samdark)
...@@ -109,6 +113,7 @@ Yii Framework 2 Change Log ...@@ -109,6 +113,7 @@ Yii Framework 2 Change Log
`index-test.php` and `yii` files to point to the new location of `Yii.php` (qiangxue, cebe) `index-test.php` and `yii` files to point to the new location of `Yii.php` (qiangxue, cebe)
- Chg: Advanced app template: moved database connection DSN, login and password to `-local` config not to expose it to VCS (samdark) - Chg: Advanced app template: moved database connection DSN, login and password to `-local` config not to expose it to VCS (samdark)
- Chg: Renamed `yii\web\Request::acceptedLanguages` to `acceptableLanguages` (qiangxue) - Chg: Renamed `yii\web\Request::acceptedLanguages` to `acceptableLanguages` (qiangxue)
- Chg: Removed implementation of `Arrayable` from `yii\Object` (qiangxue)
- New #66: [Auth client library](https://github.com/yiisoft/yii2-authclient) OpenId, OAuth1, OAuth2 clients (klimov-paul) - New #66: [Auth client library](https://github.com/yiisoft/yii2-authclient) OpenId, OAuth1, OAuth2 clients (klimov-paul)
- New #1393: [Codeception testing framework integration](https://github.com/yiisoft/yii2-codeception) (Ragazzo) - New #1393: [Codeception testing framework integration](https://github.com/yiisoft/yii2-codeception) (Ragazzo)
- New #1438: [MongoDB integration](https://github.com/yiisoft/yii2-mongodb) ActiveRecord and Query (klimov-paul) - New #1438: [MongoDB integration](https://github.com/yiisoft/yii2-mongodb) ActiveRecord and Query (klimov-paul)
......
...@@ -52,7 +52,7 @@ use yii\validators\Validator; ...@@ -52,7 +52,7 @@ use yii\validators\Validator;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class Model extends Component implements IteratorAggregate, ArrayAccess class Model extends Component implements IteratorAggregate, ArrayAccess, Arrayable
{ {
/** /**
* The name of the default scenario. * The name of the default scenario.
......
...@@ -17,7 +17,7 @@ use Yii; ...@@ -17,7 +17,7 @@ use Yii;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class Object implements Arrayable class Object
{ {
/** /**
* @return string the fully qualified name of this class. * @return string the fully qualified name of this class.
...@@ -227,14 +227,4 @@ class Object implements Arrayable ...@@ -227,14 +227,4 @@ class Object implements Arrayable
{ {
return method_exists($this, $name); return method_exists($this, $name);
} }
/**
* Converts the object into an array.
* The default implementation will return all public property values as an array.
* @return array the array representation of the object
*/
public function toArray()
{
return Yii::getObjectVars($this);
}
} }
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
"ext-mbstring": "*", "ext-mbstring": "*",
"lib-pcre": "*", "lib-pcre": "*",
"yiisoft/yii2-composer": "*", "yiisoft/yii2-composer": "*",
"yiisoft/jquery": "2.0.*", "yiisoft/jquery": "~2.0 | ~1.10",
"phpspec/php-diff": ">=1.0.2", "phpspec/php-diff": ">=1.0.2",
"ezyang/htmlpurifier": "4.6.*", "ezyang/htmlpurifier": "4.6.*",
"michelf/php-markdown": "1.3.*" "michelf/php-markdown": "1.3.*"
......
...@@ -80,7 +80,7 @@ class AssetController extends Controller ...@@ -80,7 +80,7 @@ class AssetController extends Controller
* Default value relies on usage of "YUI Compressor" * Default value relies on usage of "YUI Compressor"
* @see https://github.com/yui/yuicompressor/ * @see https://github.com/yui/yuicompressor/
*/ */
public $cssCompressor = 'java -jar yuicompressor.jar {from} -o {to}'; public $cssCompressor = 'java -jar yuicompressor.jar -o --type css {from} {to}';
/** /**
* @var array|\yii\web\AssetManager [[yii\web\AssetManager]] instance or its array configuration, which will be used * @var array|\yii\web\AssetManager [[yii\web\AssetManager]] instance or its array configuration, which will be used
...@@ -585,7 +585,7 @@ return [ ...@@ -585,7 +585,7 @@ return [
], ],
// Asset bundle for compression output: // Asset bundle for compression output:
'targets' => [ 'targets' => [
'app\config\AllAsset' => [ 'app\assets\AllAsset' => [
'basePath' => 'path/to/web', 'basePath' => 'path/to/web',
'baseUrl' => '', 'baseUrl' => '',
'js' => 'js/all-{ts}.js', 'js' => 'js/all-{ts}.js',
......
...@@ -592,7 +592,8 @@ class MigrateController extends Controller ...@@ -592,7 +592,8 @@ class MigrateController extends Controller
*/ */
protected function createMigrationHistoryTable() protected function createMigrationHistoryTable()
{ {
echo 'Creating migration history table "' . $this->migrationTable . '"...'; $tableName = $this->db->schema->getRawTableName($this->migrationTable);
echo "Creating migration history table \"$tableName\"...";
$this->db->createCommand()->createTable($this->migrationTable, [ $this->db->createCommand()->createTable($this->migrationTable, [
'version' => 'varchar(180) NOT NULL PRIMARY KEY', 'version' => 'varchar(180) NOT NULL PRIMARY KEY',
'apply_time' => 'integer', 'apply_time' => 'integer',
......
...@@ -988,7 +988,7 @@ class QueryBuilder extends \yii\base\Object ...@@ -988,7 +988,7 @@ class QueryBuilder extends \yii\base\Object
return "$column $operator (" . implode(', ', $values) . ')'; return "$column $operator (" . implode(', ', $values) . ')';
} else { } else {
$operator = $operator === 'IN' ? '=' : '<>'; $operator = $operator === 'IN' ? '=' : '<>';
return "$column$operator{$values[0]}"; return $column . $operator . reset($values);
} }
} }
......
...@@ -283,7 +283,7 @@ SQL; ...@@ -283,7 +283,7 @@ SQL;
// Index is an expression like "lower(colname::text)" // Index is an expression like "lower(colname::text)"
$indexColumns = preg_replace("/.*\(([^\:]+).*/mi", "$1", $index['indexcolumns']); $indexColumns = preg_replace("/.*\(([^\:]+).*/mi", "$1", $index['indexcolumns']);
} else { } else {
$indexColumns = array_map('trim', explode(',', str_replace(['{', '}'], '', $index['indexcolumns']))); $indexColumns = array_map('trim', explode(',', str_replace(['{', '}', '"', '\\'], '', $index['indexcolumns'])));
} }
$uniqueIndexes[$indexName] = $indexColumns; $uniqueIndexes[$indexName] = $indexColumns;
......
...@@ -167,12 +167,14 @@ class Controller extends \yii\base\Controller ...@@ -167,12 +167,14 @@ class Controller extends \yii\base\Controller
* *
* @param string $route the route. This can be either an absolute route or a relative route. * @param string $route the route. This can be either an absolute route or a relative route.
* @param array $params the parameters (name-value pairs) to be included in the generated URL * @param array $params the parameters (name-value pairs) to be included in the generated URL
* @param string $schema the schema to use for the url. e.g. 'http' or 'https'. If not specified
* the schema of the current request will be used.
* @return string the created absolute URL * @return string the created absolute URL
*/ */
public function createAbsoluteUrl($route, $params = []) public function createAbsoluteUrl($route, $params = [], $schema = null)
{ {
$route = $this->getNormalizedRoute($route); $route = $this->getNormalizedRoute($route);
return Yii::$app->getUrlManager()->createAbsoluteUrl($route, $params); return Yii::$app->getUrlManager()->createAbsoluteUrl($route, $params, $schema);
} }
/** /**
......
...@@ -9,6 +9,7 @@ namespace yii\web; ...@@ -9,6 +9,7 @@ namespace yii\web;
use Yii; use Yii;
use ArrayIterator; use ArrayIterator;
use yii\base\Arrayable;
use yii\base\InvalidCallException; use yii\base\InvalidCallException;
use yii\base\Object; use yii\base\Object;
...@@ -22,7 +23,7 @@ use yii\base\Object; ...@@ -22,7 +23,7 @@ use yii\base\Object;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class CookieCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable class CookieCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
{ {
/** /**
* @var boolean whether this collection is read only. * @var boolean whether this collection is read only.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace yii\web; namespace yii\web;
use Yii; use Yii;
use yii\base\Arrayable;
use yii\base\Object; use yii\base\Object;
use ArrayIterator; use ArrayIterator;
...@@ -21,7 +22,7 @@ use ArrayIterator; ...@@ -21,7 +22,7 @@ use ArrayIterator;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class HeaderCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable class HeaderCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
{ {
/** /**
* @var array the headers in this collection (indexed by the header names) * @var array the headers in this collection (indexed by the header names)
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace yii\web; namespace yii\web;
use Yii; use Yii;
use yii\base\Arrayable;
use yii\base\Component; use yii\base\Component;
use yii\base\InvalidConfigException; use yii\base\InvalidConfigException;
use yii\base\InvalidParamException; use yii\base\InvalidParamException;
...@@ -71,7 +72,7 @@ use yii\base\InvalidParamException; ...@@ -71,7 +72,7 @@ use yii\base\InvalidParamException;
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Countable class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
{ {
/** /**
* @var boolean whether the session should be automatically started when the session component is initialized. * @var boolean whether the session should be automatically started when the session component is initialized.
......
...@@ -277,17 +277,21 @@ class UrlManager extends Component ...@@ -277,17 +277,21 @@ class UrlManager extends Component
* This method prepends the URL created by [[createUrl()]] with the [[hostInfo]]. * This method prepends the URL created by [[createUrl()]] with the [[hostInfo]].
* @param string $route the route * @param string $route the route
* @param array $params the parameters (name-value pairs) * @param array $params the parameters (name-value pairs)
* @param string $schema the schema to use for the url. e.g. 'http' or 'https'. If not specified
* the schema of the current request will be used.
* @return string the created URL * @return string the created URL
* @see createUrl() * @see createUrl()
*/ */
public function createAbsoluteUrl($route, $params = []) public function createAbsoluteUrl($route, $params = [], $schema = null)
{ {
$url = $this->createUrl($route, $params); $url = $this->createUrl($route, $params);
if (strpos($url, '://') !== false) { if (strpos($url, '://') === false) {
return $url; $url = $this->getHostInfo($schema) . $url;
} else {
return $this->getHostInfo() . $url;
} }
if ($schema !== null && ($pos = strpos($url, '://')) !== false) {
$url = $schema . substr($url, $pos);
}
return $url;
} }
/** /**
......
...@@ -239,7 +239,6 @@ class FileValidatorTest extends TestCase ...@@ -239,7 +239,6 @@ class FileValidatorTest extends TestCase
$val->validateAttribute($m, 'attr_err_part'); $val->validateAttribute($m, 'attr_err_part');
$this->assertTrue($m->hasErrors('attr_err_part')); $this->assertTrue($m->hasErrors('attr_err_part'));
$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_part'))); $this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_part')));
$log = Yii::$app->getLog()->toArray();
} }
public function testValidateAttributeErrCantWrite() public function testValidateAttributeErrCantWrite()
...@@ -249,7 +248,6 @@ class FileValidatorTest extends TestCase ...@@ -249,7 +248,6 @@ class FileValidatorTest extends TestCase
$val->validateAttribute($m, 'attr_err_write'); $val->validateAttribute($m, 'attr_err_write');
$this->assertTrue($m->hasErrors('attr_err_write')); $this->assertTrue($m->hasErrors('attr_err_write'));
$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_write'))); $this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_write')));
$log = Yii::$app->getLog()->toArray();
} }
public function testValidateAttributeErrExtension() public function testValidateAttributeErrExtension()
...@@ -259,7 +257,6 @@ class FileValidatorTest extends TestCase ...@@ -259,7 +257,6 @@ class FileValidatorTest extends TestCase
$val->validateAttribute($m, 'attr_err_ext'); $val->validateAttribute($m, 'attr_err_ext');
$this->assertTrue($m->hasErrors('attr_err_ext')); $this->assertTrue($m->hasErrors('attr_err_ext'));
$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_ext'))); $this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_ext')));
$log = Yii::$app->getLog()->toArray();
} }
public function testValidateAttributeErrNoTmpDir() public function testValidateAttributeErrNoTmpDir()
...@@ -269,6 +266,5 @@ class FileValidatorTest extends TestCase ...@@ -269,6 +266,5 @@ class FileValidatorTest extends TestCase
$val->validateAttribute($m, 'attr_err_tmp'); $val->validateAttribute($m, 'attr_err_tmp');
$this->assertTrue($m->hasErrors('attr_err_tmp')); $this->assertTrue($m->hasErrors('attr_err_tmp'));
$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_tmp'))); $this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_tmp')));
$log = Yii::$app->getLog()->toArray();
} }
} }
...@@ -124,6 +124,13 @@ class UrlManagerTest extends TestCase ...@@ -124,6 +124,13 @@ class UrlManagerTest extends TestCase
]); ]);
$url = $manager->createAbsoluteUrl('post/view', ['id' => 1, 'title' => 'sample post']); $url = $manager->createAbsoluteUrl('post/view', ['id' => 1, 'title' => 'sample post']);
$this->assertEquals('http://www.example.com?r=post/view&id=1&title=sample+post', $url); $this->assertEquals('http://www.example.com?r=post/view&id=1&title=sample+post', $url);
$url = $manager->createAbsoluteUrl('post/view', ['id' => 1, 'title' => 'sample post'], 'https');
$this->assertEquals('https://www.example.com?r=post/view&id=1&title=sample+post', $url);
$manager->hostInfo = 'https://www.example.com';
$url = $manager->createAbsoluteUrl('post/view', ['id' => 1, 'title' => 'sample post'], 'http');
$this->assertEquals('http://www.example.com?r=post/view&id=1&title=sample+post', $url);
} }
public function testParseRequest() public function testParseRequest()
......
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