Browse Source

Merge branch 'master' of github.com:yiisoft/yii2

* 'master' of github.com:yiisoft/yii2:
  Make code coverage work
  Note about  embedded documents added to mongodb extension readme
  yii\mongodb\file\Collection::ensureMongoId() fixed to suppress exception on invalid _id format.
  yii\mongodb\file\ActiveRecord::update() fixed to save the attributes while updating file.
  Fixes #2661: Added boolean column type support for SQLite
  Refactored controller creation process.
  Added back some toArray() implementations.
  Fixed test break.
  Update console-migrate.md
  Fixes #2655: Arrayable and ArrayableTrait are incompatible for some PHP versions.
  Fixes #2659
  Minor code style fixes for apidoc
  Changed assertions
  fix tests
tags/2.0.0-beta
Carsten Brandt 11 years ago
parent
commit
c815d0cef7
  1. 2
      .travis.yml
  2. 20
      apps/advanced/backend/tests/acceptance/LoginCept.php
  3. 15
      apps/advanced/backend/tests/functional/LoginCept.php
  4. 20
      apps/advanced/frontend/tests/acceptance/ContactCept.php
  5. 20
      apps/advanced/frontend/tests/acceptance/LoginCept.php
  6. 18
      apps/advanced/frontend/tests/acceptance/SignupCest.php
  7. 20
      apps/advanced/frontend/tests/functional/ContactCept.php
  8. 15
      apps/advanced/frontend/tests/functional/LoginCept.php
  9. 24
      apps/advanced/frontend/tests/functional/SignupCest.php
  10. 6
      apps/advanced/frontend/tests/unit/models/ContactFormTest.php
  11. 2
      docs/guide/console-migrate.md
  12. 4
      extensions/apidoc/commands/ApiController.php
  13. 6
      extensions/apidoc/commands/GuideController.php
  14. 2
      extensions/apidoc/components/BaseController.php
  15. 4
      extensions/gii/generators/crud/Generator.php
  16. 8
      extensions/mongodb/Collection.php
  17. 31
      extensions/mongodb/README.md
  18. 10
      extensions/mongodb/file/ActiveRecord.php
  19. 1
      framework/CHANGELOG.md
  20. 73
      framework/base/Arrayable.php
  21. 4
      framework/base/ArrayableTrait.php
  22. 30
      framework/base/ErrorException.php
  23. 31
      framework/base/ErrorHandler.php
  24. 30
      framework/base/Exception.php
  25. 7
      framework/base/Module.php
  26. 16
      framework/data/Pagination.php
  27. 2
      framework/db/sqlite/Schema.php
  28. 6
      framework/helpers/BaseJson.php
  29. 7
      framework/i18n/I18N.php
  30. 25
      framework/rest/Serializer.php
  31. 6
      framework/web/CookieCollection.php
  32. 3
      framework/web/HeaderCollection.php
  33. 11
      framework/web/HttpException.php
  34. 12
      framework/web/Link.php
  35. 12
      framework/web/Session.php
  36. 20
      tests/unit/extensions/mongodb/CollectionTest.php
  37. 1
      tests/unit/extensions/mongodb/file/ActiveRecordTest.php
  38. 23
      tests/unit/framework/base/ExceptionTest.php
  39. 9
      tests/unit/framework/i18n/I18NTest.php

2
.travis.yml

@ -45,5 +45,7 @@ script:
- cd apps/basic && php vendor/bin/codecept run
after_script:
- cd ../..
- pwd
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover

20
apps/advanced/backend/tests/acceptance/LoginCept.php

@ -10,21 +10,23 @@ $loginPage = LoginPage::openBy($I);
$I->amGoingTo('submit login form with no data');
$loginPage->login('', '');
$I->expectTo('see validations errors');
$I->see('Username cannot be blank.');
$I->see('Password cannot be blank.');
$I->see('Username cannot be blank.', '.help-block');
$I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('try to login with wrong credentials');
$I->expectTo('see validations errors');
$loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors');
$I->see('Incorrect username or password.');
$I->see('Incorrect username or password.', '.help-block');
$I->amGoingTo('try to login with correct credentials');
$loginPage->login('erau', 'password_0');
$I->expectTo('see that user is logged');
$I->see('Logout (erau)');
$I->dontSee('Login');
$I->dontSee('Signup');
$I->click('Logout (erau)');
$I->dontSee('Logout (erau)');
$I->see('Login');
$I->seeLink('Logout (erau)');
$I->dontSeeLink('Login');
$I->dontSeeLink('Signup');
/** Uncomment if using WebDriver
* $I->click('Logout (erau)');
* $I->dontSeeLink('Logout (erau)');
* $I->seeLink('Login');
*/

15
apps/advanced/backend/tests/functional/LoginCept.php

@ -10,21 +10,18 @@ $loginPage = LoginPage::openBy($I);
$I->amGoingTo('submit login form with no data');
$loginPage->login('', '');
$I->expectTo('see validations errors');
$I->see('Username cannot be blank.');
$I->see('Password cannot be blank.');
$I->see('Username cannot be blank.', '.help-block');
$I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('try to login with wrong credentials');
$I->expectTo('see validations errors');
$loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors');
$I->see('Incorrect username or password.');
$I->see('Incorrect username or password.', '.help-block');
$I->amGoingTo('try to login with correct credentials');
$loginPage->login('erau', 'password_0');
$I->expectTo('see that user is logged');
$I->see('Logout (erau)');
$I->dontSee('Login');
$I->dontSee('Signup');
$I->click('Logout (erau)');
$I->dontSee('Logout (erau)');
$I->see('Login');
$I->seeLink('Logout (erau)');
$I->dontSeeLink('Login');
$I->dontSeeLink('Signup');

20
apps/advanced/frontend/tests/acceptance/ContactCept.php

@ -13,11 +13,11 @@ $I->amGoingTo('submit contact form with no data');
$contactPage->submit([]);
$I->expectTo('see validations errors');
$I->see('Contact', 'h1');
$I->see('Name cannot be blank');
$I->see('Email cannot be blank');
$I->see('Subject cannot be blank');
$I->see('Body cannot be blank');
$I->see('The verification code is incorrect');
$I->see('Name cannot be blank', '.help-block');
$I->see('Email cannot be blank', '.help-block');
$I->see('Subject cannot be blank', '.help-block');
$I->see('Body cannot be blank', '.help-block');
$I->see('The verification code is incorrect', '.help-block');
$I->amGoingTo('submit contact form with not correct email');
$contactPage->submit([
@ -28,11 +28,11 @@ $contactPage->submit([
'verifyCode' => 'testme',
]);
$I->expectTo('see that email adress is wrong');
$I->dontSee('Name cannot be blank', '.help-inline');
$I->see('Email is not a valid email address.');
$I->dontSee('Subject cannot be blank', '.help-inline');
$I->dontSee('Body cannot be blank', '.help-inline');
$I->dontSee('The verification code is incorrect', '.help-inline');
$I->dontSee('Name cannot be blank', '.help-block');
$I->see('Email is not a valid email address.', '.help-block');
$I->dontSee('Subject cannot be blank', '.help-block');
$I->dontSee('Body cannot be blank', '.help-block');
$I->dontSee('The verification code is incorrect', '.help-block');
$I->amGoingTo('submit contact form with correct data');
$contactPage->submit([

20
apps/advanced/frontend/tests/acceptance/LoginCept.php

@ -10,21 +10,23 @@ $loginPage = LoginPage::openBy($I);
$I->amGoingTo('submit login form with no data');
$loginPage->login('', '');
$I->expectTo('see validations errors');
$I->see('Username cannot be blank.');
$I->see('Password cannot be blank.');
$I->see('Username cannot be blank.', '.help-block');
$I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('try to login with wrong credentials');
$I->expectTo('see validations errors');
$loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors');
$I->see('Incorrect username or password.');
$I->see('Incorrect username or password.', '.help-block');
$I->amGoingTo('try to login with correct credentials');
$loginPage->login('erau', 'password_0');
$I->expectTo('see that user is logged');
$I->see('Logout (erau)');
$I->dontSee('Login');
$I->dontSee('Signup');
$I->click('Logout (erau)');
$I->dontSee('Logout (erau)');
$I->see('Login');
$I->seeLink('Logout (erau)');
$I->dontSeeLink('Login');
$I->dontSeeLink('Signup');
/** Uncomment if using WebDriver
* $I->click('Logout (erau)');
* $I->dontSeeLink('Logout (erau)');
* $I->seeLink('Login');
*/

18
apps/advanced/frontend/tests/acceptance/SignupCest.php

@ -9,7 +9,7 @@ class SignupCest
{
/**
* This method is called after each cest class test method
* This method is called before each cest class test method
* @param \Codeception\Event\Test $event
*/
public function _before($event)
@ -37,7 +37,6 @@ class SignupCest
}
/**
*
* @param \WebGuy $I
* @param \Codeception\Scenario $scenario
*/
@ -46,6 +45,7 @@ class SignupCest
$I->wantTo('ensure that signup works');
$signupPage = SignupPage::openBy($I);
$I->see('Signup', 'h1');
$I->see('Please fill out the following fields to signup:');
$I->amGoingTo('submit signup form with no data');
@ -53,9 +53,9 @@ class SignupCest
$signupPage->submit([]);
$I->expectTo('see validation errors');
$I->see('Username cannot be blank.');
$I->see('Email cannot be blank.');
$I->see('Password cannot be blank.');
$I->see('Username cannot be blank.', '.help-block');
$I->see('Email cannot be blank.', '.help-block');
$I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('submit signup form with not correct email');
$signupPage->submit([
@ -64,9 +64,9 @@ class SignupCest
'password' => 'tester_password',
]);
$I->expectTo('see that email adress is wrong');
$I->dontSee('Username cannot be blank.', '.help-inline');
$I->dontSee('Password cannot be blank.', '.help-inline');
$I->expectTo('see that email address is wrong');
$I->dontSee('Username cannot be blank.', '.help-block');
$I->dontSee('Password cannot be blank.', '.help-block');
$I->see('Email is not a valid email address.', '.help-block');
$I->amGoingTo('submit signup form with correct email');
@ -77,6 +77,6 @@ class SignupCest
]);
$I->expectTo('see that user logged in');
$I->see('Logout (tester)');
$I->seeLink('Logout (tester)');
}
}

20
apps/advanced/frontend/tests/functional/ContactCept.php

@ -13,11 +13,11 @@ $I->amGoingTo('submit contact form with no data');
$contactPage->submit([]);
$I->expectTo('see validations errors');
$I->see('Contact', 'h1');
$I->see('Name cannot be blank');
$I->see('Email cannot be blank');
$I->see('Subject cannot be blank');
$I->see('Body cannot be blank');
$I->see('The verification code is incorrect');
$I->see('Name cannot be blank', '.help-block');
$I->see('Email cannot be blank', '.help-block');
$I->see('Subject cannot be blank', '.help-block');
$I->see('Body cannot be blank', '.help-block');
$I->see('The verification code is incorrect', '.help-block');
$I->amGoingTo('submit contact form with not correct email');
$contactPage->submit([
@ -28,11 +28,11 @@ $contactPage->submit([
'verifyCode' => 'testme',
]);
$I->expectTo('see that email adress is wrong');
$I->dontSee('Name cannot be blank', '.help-inline');
$I->see('Email is not a valid email address.');
$I->dontSee('Subject cannot be blank', '.help-inline');
$I->dontSee('Body cannot be blank', '.help-inline');
$I->dontSee('The verification code is incorrect', '.help-inline');
$I->dontSee('Name cannot be blank', '.help-block');
$I->see('Email is not a valid email address.', '.help-block');
$I->dontSee('Subject cannot be blank', '.help-block');
$I->dontSee('Body cannot be blank', '.help-block');
$I->dontSee('The verification code is incorrect', '.help-block');
$I->amGoingTo('submit contact form with correct data');
$contactPage->submit([

15
apps/advanced/frontend/tests/functional/LoginCept.php

@ -10,21 +10,18 @@ $loginPage = LoginPage::openBy($I);
$I->amGoingTo('submit login form with no data');
$loginPage->login('', '');
$I->expectTo('see validations errors');
$I->see('Username cannot be blank.');
$I->see('Password cannot be blank.');
$I->see('Username cannot be blank.', '.help-block');
$I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('try to login with wrong credentials');
$I->expectTo('see validations errors');
$loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors');
$I->see('Incorrect username or password.');
$I->see('Incorrect username or password.', '.help-block');
$I->amGoingTo('try to login with correct credentials');
$loginPage->login('erau', 'password_0');
$I->expectTo('see that user is logged');
$I->see('Logout (erau)');
$I->dontSee('Login');
$I->dontSee('Signup');
$I->click('Logout (erau)');
$I->dontSee('Logout (erau)');
$I->see('Login');
$I->seeLink('Logout (erau)');
$I->dontSeeLink('Login');
$I->dontSeeLink('Signup');

24
apps/advanced/frontend/tests/functional/SignupCest.php

@ -9,7 +9,7 @@ class SignupCest
{
/**
* This method is called after each cest class test method
* This method is called before each cest class test method
* @param \Codeception\Event\Test $event
*/
public function _before($event)
@ -34,6 +34,7 @@ class SignupCest
*/
public function _fail($event)
{
}
/**
@ -46,6 +47,7 @@ class SignupCest
$I->wantTo('ensure that signup works');
$signupPage = SignupPage::openBy($I);
$I->see('Signup', 'h1');
$I->see('Please fill out the following fields to signup:');
$I->amGoingTo('submit signup form with no data');
@ -53,9 +55,9 @@ class SignupCest
$signupPage->submit([]);
$I->expectTo('see validation errors');
$I->see('Username cannot be blank.');
$I->see('Email cannot be blank.');
$I->see('Password cannot be blank.');
$I->see('Username cannot be blank.', '.help-block');
$I->see('Email cannot be blank.', '.help-block');
$I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('submit signup form with not correct email');
$signupPage->submit([
@ -64,9 +66,9 @@ class SignupCest
'password' => 'tester_password',
]);
$I->expectTo('see that email adress is wrong');
$I->dontSee('Username cannot be blank.', '.help-inline');
$I->dontSee('Password cannot be blank.', '.help-inline');
$I->expectTo('see that email address is wrong');
$I->dontSee('Username cannot be blank.', '.help-block');
$I->dontSee('Password cannot be blank.', '.help-block');
$I->see('Email is not a valid email address.', '.help-block');
$I->amGoingTo('submit signup form with correct email');
@ -76,7 +78,13 @@ class SignupCest
'password' => 'tester_password',
]);
$I->expectTo('see that user is created');
$I->seeRecord('common\models\User', [
'username' => 'tester',
'email' => 'tester.email@example.com',
]);
$I->expectTo('see that user logged in');
$I->see('Logout (tester)');
$I->seeLink('Logout (tester)');
}
}

6
apps/advanced/frontend/tests/unit/models/ContactFormTest.php

@ -4,6 +4,7 @@ namespace frontend\tests\unit\models;
use Yii;
use frontend\tests\unit\TestCase;
use frontend\models\ContactForm;
class ContactFormTest extends TestCase
{
@ -26,8 +27,7 @@ class ContactFormTest extends TestCase
public function testContact()
{
$model = $this->getMock('frontend\models\ContactForm', ['validate']);
$model->expects($this->once())->method('validate')->will($this->returnValue(true));
$model = new ContactForm();
$model->attributes = [
'name' => 'Tester',
@ -36,7 +36,7 @@ class ContactFormTest extends TestCase
'body' => 'body of current message',
];
$model->contact('admin@example.com');
$model->sendEmail('admin@example.com');
$this->specify('email should be send', function () {
expect('email file should exist', file_exists($this->getMessageFile()))->true();

2
docs/guide/console-migrate.md

@ -322,7 +322,7 @@ the console application's configuration file like the following,
```php
'controllerMap' => [
'migrate' => [
'class' => 'yii\console\MigrateController',
'class' => 'yii\console\controllers\MigrateController',
'migrationTable' => 'my_custom_migrate_table',
],
]

4
extensions/apidoc/commands/ApiController.php

@ -112,6 +112,9 @@ class ApiController extends BaseController
}
}
/**
* @inheritdoc
*/
protected function findFiles($path, $except = [])
{
if (empty($except)) {
@ -135,6 +138,7 @@ class ApiController extends BaseController
}
/**
* @inheritdoc
* @return ApiRenderer
*/
protected function findRenderer($template)

6
extensions/apidoc/commands/GuideController.php

@ -9,7 +9,6 @@ namespace yii\apidoc\commands;
use yii\apidoc\components\BaseController;
use yii\apidoc\models\Context;
use yii\apidoc\renderers\BaseRenderer;
use yii\apidoc\renderers\GuideRenderer;
use yii\helpers\Console;
use yii\helpers\FileHelper;
@ -77,6 +76,9 @@ class GuideController extends BaseController
file_put_contents($targetDir . '/guide-references.txt', implode("\n", $references));
}
/**
* @inheritdoc
*/
protected function findFiles($path, $except = [])
{
if (empty($except)) {
@ -89,7 +91,9 @@ class GuideController extends BaseController
];
return FileHelper::findFiles($path, $options);
}
/**
* @inheritdoc
* @return GuideRenderer
*/
protected function findRenderer($template)

2
extensions/apidoc/components/BaseController.php

@ -78,7 +78,6 @@ abstract class BaseController extends Controller
protected abstract function findFiles($dir, $except = []);
protected function loadContext($location)
{
$context = new Context();
@ -114,6 +113,7 @@ abstract class BaseController extends Controller
}
/**
* @inheritdoc
* @return BaseRenderer
*/
protected abstract function findRenderer($template);

4
extensions/gii/generators/crud/Generator.php

@ -105,8 +105,8 @@ class Generator extends \yii\gii\Generator
If not set, it means the controller will belong to the application.',
'indexWidgetType' => 'This is the widget type to be used in the index page to display list of the models.
You may choose either <code>GridView</code> or <code>ListView</code>',
'searchModelClass' => 'This is the class representing the data being collected in the search form.
A fully qualified namespaced class name is required, e.g., <code>app\models\search\PostSearch</code>.',
'searchModelClass' => 'This is the name of the search model class to be generated. You should provide a fully
qualified namespaced class name, e.g., <code>app\models\search\PostSearch</code>.',
];
}

8
extensions/mongodb/Collection.php

@ -733,7 +733,13 @@ class Collection extends Object
$rawId = (string)$rawId;
}
}
return new \MongoId($rawId);
try {
$mongoId = new \MongoId($rawId);
} catch (\MongoException $e) {
// invalid id format
$mongoId = $rawId;
}
return $mongoId;
}
/**

31
extensions/mongodb/README.md

@ -184,6 +184,37 @@ $models = $provider->getModels();
```
Working with embedded documents
-------------------------------
This extension does not provide any special way to work with embedded documents (sub-documents).
General recommendation is avoiding it if possible.
For example: instead of:
```
{
content: "some content",
author: {
name: author1,
email: author1@domain.com
}
}
```
use following:
```
{
content: "some content",
author_name: author1,
author_email: author1@domain.com
}
```
Yii Model designed assuming single attribute is a scalar. Validation and attribute processing based on this suggestion.
Still any attribute can be an array of any depth and complexity, however you should handle its validation on your own.
Using GridFS
------------

10
extensions/mongodb/file/ActiveRecord.php

@ -178,6 +178,16 @@ abstract class ActiveRecord extends \yii\mongodb\ActiveRecord
unset($values['file']);
}
if (isset($newFileContent) || isset($newFile)) {
$fileAssociatedAttributeNames = [
'filename',
'uploadDate',
'length',
'chunkSize',
'md5',
'file',
'newFileContent'
];
$values = array_merge($this->getAttributes(null, $fileAssociatedAttributeNames), $values);
$rows = $this->deleteInternal();
$insertValues = $values;
$insertValues['_id'] = $this->getAttribute('_id');

1
framework/CHANGELOG.md

@ -135,6 +135,7 @@ Yii Framework 2 Change Log
- Enh #2525: Added support for formatting file sizes with `yii\base\Formatter` (VinceG)
- Enh #2526: Allow for null values in batchInsert (skotos)
- Enh #2646: Added support for specifying hostinfo in the pattern of a URL rule (qiangxue)
- Enh #2661: Added boolean column type support for SQLite (qiangxue)
- Enh: Added support for using arrays as option values for console commands (qiangxue)
- Enh: Added `favicon.ico` and `robots.txt` to default application templates (samdark)
- Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue)

73
framework/base/Arrayable.php

@ -8,7 +8,14 @@
namespace yii\base;
/**
* Arrayable should be implemented by classes that need to be represented in array format.
* Arrayable is the interface that should be implemented by classes who want to support customizable representation of their instances.
*
* For example, if a class implements Arrayable, by calling [[toArray()]], an instance of this class
* can be turned into an array (including all its embedded objects) which can then be further transformed easily
* into other formats, such as JSON, XML.
*
* The methods [[fields()]] and [[extraFields()]] allow the implementing classes to customize how and which of their data
* should be formatted and put into the result of [[toArray()]].
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
@ -16,8 +23,68 @@ namespace yii\base;
interface Arrayable
{
/**
* Returns the list of fields that should be returned by default by [[toArray()]] when no specific fields are specified.
*
* A field is a named element in the returned array by [[toArray()]].
*
* This method should return an array of field names or field definitions.
* If the former, the field name will be treated as an object property name whose value will be used
* as the field value. If the latter, the array key should be the field name while the array value should be
* the corresponding field definition which can be either an object property name or a PHP callable
* returning the corresponding field value. The signature of the callable should be:
*
* ```php
* function ($field, $model) {
* // return field value
* }
* ```
*
* For example, the following code declares four fields:
*
* - `email`: the field name is the same as the property name `email`;
* - `firstName` and `lastName`: the field names are `firstName` and `lastName`, and their
* values are obtained from the `first_name` and `last_name` properties;
* - `fullName`: the field name is `fullName`. Its value is obtained by concatenating `first_name`
* and `last_name`.
*
* ```php
* return [
* 'email',
* 'firstName' => 'first_name',
* 'lastName' => 'last_name',
* 'fullName' => function () {
* return $this->first_name . ' ' . $this->last_name;
* },
* ];
* ```
*
* @return array the list of field names or field definitions.
* @see toArray()
*/
public function fields();
/**
* Returns the list of additional fields that can be returned by [[toArray()]] in addition to those listed in [[fields()]].
*
* This method is similar to [[fields()]] except that the list of fields declared
* by this method are not returned by default by [[toArray()]]. Only when a field in the list
* is explicitly requested, will it be included in the result of [[toArray()]].
*
* @return array the list of expandable field names or field definitions. Please refer
* to [[fields()]] on the format of the return value.
* @see toArray()
* @see fields()
*/
public function extraFields();
/**
* Converts the object into an array.
* @return array the array representation of this object
*
* @param array $fields the fields that the output array should contain. Fields not specified
* in [[fields()]] will be ignored. If this parameter is empty, all fields as specified in [[fields()]] will be returned.
* @param array $expand the additional fields that the output array should contain.
* Fields not specified in [[extraFields()]] will be ignored. If this parameter is empty, no extra fields
* will be returned.
* @param boolean $recursive whether to recursively return array representation of embedded objects.
* @return array the array representation of the object
*/
public function toArray();
public function toArray(array $fields = [], array $expand = [], $recursive = true);
}

4
framework/base/ArrayableTrait.php

@ -13,6 +13,10 @@ use yii\web\Link;
use yii\web\Linkable;
/**
* ArrayableTrait provides a common implementation of the [[Arrayable]] interface.
*
* ArrayableTrait implements [[toArray()]] by respecting the field definitions as declared
* in [[fields()]] and [[extraFields()]].
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0

30
framework/base/ErrorException.php

@ -15,7 +15,7 @@ use Yii;
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class ErrorException extends \ErrorException implements Arrayable
class ErrorException extends \ErrorException
{
/**
* Constructs the exception.
@ -93,32 +93,4 @@ class ErrorException extends \ErrorException implements Arrayable
];
return isset($names[$this->getCode()]) ? $names[$this->getCode()] : 'Error';
}
/**
* Returns the array representation of this object.
* @return array the array representation of this object.
*/
public function toArray()
{
return $this->toArrayRecursive($this);
}
/**
* Returns the array representation of the exception and all previous exceptions recursively.
* @param \Exception $exception object
* @return array the array representation of the exception.
*/
protected function toArrayRecursive($exception)
{
$array = [
'type' => get_class($exception),
'name' => $exception instanceof self ? $exception->getName() : 'Exception',
'message' => $exception->getMessage(),
'code' => $exception->getCode(),
];
if (($prev = $exception->getPrevious()) !== null) {
$array['previous'] = $this->toArrayRecursive($prev);
}
return $array;
}
}

31
framework/base/ErrorHandler.php

@ -119,15 +119,8 @@ class ErrorHandler extends Component
'exception' => $exception,
]);
}
} elseif ($exception instanceof Arrayable) {
$response->data = $exception->toArray();
} else {
$response->data = [
'type' => get_class($exception),
'name' => 'Exception',
'message' => $exception->getMessage(),
'code' => $exception->getCode(),
];
$response->data = $this->convertExceptionToArray($exception);
}
if ($exception instanceof HttpException) {
@ -140,6 +133,28 @@ class ErrorHandler extends Component
}
/**
* Converts an exception into an array.
* @param \Exception $exception the exception being converted
* @return array the array representation of the exception.
*/
protected function convertExceptionToArray($exception)
{
$array = [
'type' => get_class($exception),
'name' => $exception instanceof \yii\base\Exception || $exception instanceof \yii\base\ErrorException ? $exception->getName() : 'Exception',
'message' => $exception->getMessage(),
'code' => $exception->getCode(),
];
if ($exception instanceof HttpException) {
$array['status'] = $exception->statusCode;
}
if (($prev = $exception->getPrevious()) !== null) {
$array['previous'] = $this->convertExceptionToArray($prev);
}
return $array;
}
/**
* Converts special characters to HTML entities.
* @param string $text to encode.
* @return string encoded original text.

30
framework/base/Exception.php

@ -13,7 +13,7 @@ namespace yii\base;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Exception extends \Exception implements Arrayable
class Exception extends \Exception
{
/**
* @return string the user-friendly name of this exception
@ -22,32 +22,4 @@ class Exception extends \Exception implements Arrayable
{
return 'Exception';
}
/**
* Returns the array representation of this object.
* @return array the array representation of this object.
*/
public function toArray()
{
return $this->toArrayRecursive($this);
}
/**
* Returns the array representation of the exception and all previous exceptions recursively.
* @param \Exception $exception object
* @return array the array representation of the exception.
*/
protected function toArrayRecursive($exception)
{
$array = [
'type' => get_class($exception),
'name' => $exception instanceof self ? $exception->getName() : 'Exception',
'message' => $exception->getMessage(),
'code' => $exception->getCode(),
];
if (($prev = $exception->getPrevious()) !== null) {
$array['previous'] = $this->toArrayRecursive($prev);
}
return $array;
}
}

7
framework/base/Module.php

@ -222,7 +222,10 @@ class Module extends Component
/**
* Returns the directory that contains the controller classes according to [[controllerNamespace]].
* Note that in order for this method to return a value, you must define
* an alias for the root namespace of [[controllerNamespace]].
* @return string the directory that contains the controller classes.
* @throws InvalidParamException if there is no alias defined for the root namespace of [[controllerNamespace]].
*/
public function getControllerPath()
{
@ -670,13 +673,11 @@ class Module extends Component
}
$className = str_replace(' ', '', ucwords(str_replace('-', ' ', $className))) . 'Controller';
$classFile = $this->getControllerPath() . '/' . $prefix . $className . '.php';
$className = ltrim($this->controllerNamespace . '\\' . str_replace('/', '\\', $prefix) . $className, '\\');
if (strpos($className, '-') !== false || !is_file($classFile)) {
if (strpos($className, '-') !== false || !class_exists($className)) {
return null;
}
Yii::$classMap[$className] = $classFile;
if (is_subclass_of($className, 'yii\base\Controller')) {
return new $className($id, $this);
} elseif (YII_DEBUG) {

16
framework/data/Pagination.php

@ -8,7 +8,6 @@
namespace yii\data;
use Yii;
use yii\base\Arrayable;
use yii\base\Object;
use yii\web\Link;
use yii\web\Linkable;
@ -68,7 +67,7 @@ use yii\web\Request;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Pagination extends Object implements Linkable, Arrayable
class Pagination extends Object implements Linkable
{
const LINK_NEXT = 'next';
const LINK_PREV = 'prev';
@ -317,19 +316,6 @@ class Pagination extends Object implements Linkable, Arrayable
}
/**
* @inheritdoc
*/
public function toArray()
{
return [
'totalCount' => $this->totalCount,
'pageCount' => $this->getPageCount(),
'currentPage' => $this->getPage(),
'perPage' => $this->getPageSize(),
];
}
/**
* Returns the value of the specified query parameter.
* This method returns the named parameter value from [[params]]. Null is returned if the value does not exist.
* @param string $name the parameter name

2
framework/db/sqlite/Schema.php

@ -24,6 +24,8 @@ class Schema extends \yii\db\Schema
public $typeMap = [
'tinyint' => self::TYPE_SMALLINT,
'bit' => self::TYPE_SMALLINT,
'boolean' => self::TYPE_BOOLEAN,
'bool' => self::TYPE_BOOLEAN,
'smallint' => self::TYPE_SMALLINT,
'mediumint' => self::TYPE_INTEGER,
'int' => self::TYPE_INTEGER,

6
framework/helpers/BaseJson.php

@ -91,7 +91,11 @@ class BaseJson
} elseif ($data instanceof Arrayable) {
$data = $data->toArray();
} else {
$data = get_object_vars($data);
$result = [];
foreach ($data as $name => $value) {
$result[$name] = $value;
}
$data = $result;
}
if ($data === []) {

7
framework/i18n/I18N.php

@ -8,7 +8,6 @@
namespace yii\i18n;
use Yii;
use yii\base\Arrayable;
use yii\base\Component;
use yii\base\InvalidConfigException;
@ -104,11 +103,7 @@ class I18N extends Component
*/
public function format($message, $params, $language)
{
if ($params instanceof Arrayable) {
$params = $params->toArray();
} else {
$params = (array)$params;
}
$params = (array)$params;
if ($params === []) {
return $message;
}

25
framework/rest/Serializer.php

@ -169,14 +169,33 @@ class Serializer extends Component
$this->collectionEnvelope => $models,
];
if ($pagination !== false) {
$result['_links'] = Link::serialize($pagination->getLinks());
$result['_meta'] = $pagination->toArray();
return array_merge($result, $this->serializePagination($pagination));
} else {
return $result;
}
return $result;
}
}
/**
* Serializes a pagination into an array.
* @param Pagination $pagination
* @return array the array representation of the pagination
* @see addPaginationHeader()
*/
protected function serializePagination($pagination)
{
return [
'_links' => Link::serialize($pagination->getLinks(true)),
'_meta' => [
'totalCount' => $pagination->totalCount,
'pageCount' => $pagination->getPageCount(),
'currentPage' => $pagination->getPage(),
'perPage' => $pagination->getPageSize(),
],
];
}
/**
* Adds HTTP headers about the pagination to the response.
* @param Pagination $pagination
*/

6
framework/web/CookieCollection.php

@ -9,7 +9,6 @@ namespace yii\web;
use Yii;
use ArrayIterator;
use yii\base\Arrayable;
use yii\base\InvalidCallException;
use yii\base\Object;
@ -23,7 +22,7 @@ use yii\base\Object;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class CookieCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
class CookieCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable
{
/**
* @var boolean whether this collection is read only.
@ -169,8 +168,7 @@ class CookieCollection extends Object implements \IteratorAggregate, \ArrayAcces
/**
* Returns the collection as a PHP array.
* @return array the array representation of the collection.
* The array keys are cookie names, and the array values are the corresponding
* cookie objects.
* The array keys are cookie names, and the array values are the corresponding cookie objects.
*/
public function toArray()
{

3
framework/web/HeaderCollection.php

@ -8,7 +8,6 @@
namespace yii\web;
use Yii;
use yii\base\Arrayable;
use yii\base\Object;
use ArrayIterator;
@ -22,7 +21,7 @@ use ArrayIterator;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class HeaderCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
class HeaderCollection extends Object implements \IteratorAggregate, \ArrayAccess, \Countable
{
/**
* @var array the headers in this collection (indexed by the header names)

11
framework/web/HttpException.php

@ -58,15 +58,4 @@ class HttpException extends UserException
return 'Error';
}
}
/**
* Returns the array representation of this object.
* @return array the array representation of this object.
*/
public function toArray()
{
$array = parent::toArray();
$array['status'] = $this->statusCode;
return $array;
}
}

12
framework/web/Link.php

@ -7,7 +7,6 @@
namespace yii\web;
use yii\base\Arrayable;
use yii\base\Object;
/**
@ -16,7 +15,7 @@ use yii\base\Object;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Link extends Object implements Arrayable
class Link extends Object
{
/**
* The self link.
@ -53,13 +52,6 @@ class Link extends Object implements Arrayable
*/
public $hreflang;
/**
* @inheritdoc
*/
public function toArray()
{
return array_filter((array)$this);
}
/**
* Serializes a list of links into proper array format.
@ -71,7 +63,7 @@ class Link extends Object implements Arrayable
foreach ($links as $rel => $link) {
if (is_array($link)) {
foreach ($link as $i => $l) {
$link[$i] = $l instanceof self ? $l->toArray() : ['href' => $l];
$link[$i] = $l instanceof self ? array_filter((array)$l) : ['href' => $l];
}
$links[$rel] = $link;
} elseif (!$link instanceof self) {

12
framework/web/Session.php

@ -8,7 +8,6 @@
namespace yii\web;
use Yii;
use yii\base\Arrayable;
use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\base\InvalidParamException;
@ -72,7 +71,7 @@ use yii\base\InvalidParamException;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Countable, Arrayable
class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Countable
{
/**
* @var string the name of the session variable that stores the flash message data.
@ -600,15 +599,6 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
}
/**
* @return array the list of all session variables in array
*/
public function toArray()
{
$this->open();
return $_SESSION;
}
/**
* Updates the counters for flash messages and removes outdated flash messages.
* This method should only be called once in [[init()]].
*/

20
tests/unit/extensions/mongodb/CollectionTest.php

@ -419,4 +419,24 @@ class CollectionTest extends MongoDbTestCase
$this->assertNotEmpty($result);
$this->assertCount(2, $result);
}
public function testFindByNotObjectId()
{
$collection = $this->getConnection()->getCollection('customer');
$data = [
'name' => 'customer 1',
'address' => 'customer 1 address',
];
$id = $collection->insert($data);
$cursor = $collection->find(['_id' => (string)$id]);
$this->assertTrue($cursor instanceof \MongoCursor);
$row = $cursor->getNext();
$this->assertEquals($id, $row['_id']);
$cursor = $collection->find(['_id' => 'fake']);
$this->assertTrue($cursor instanceof \MongoCursor);
$this->assertEquals(0, $cursor->count());
}
}

1
tests/unit/extensions/mongodb/file/ActiveRecordTest.php

@ -248,6 +248,7 @@ class ActiveRecordTest extends MongoDbTestCase
$record2 = CustomerFile::find($record->_id);
$this->assertEquals($record->status, $record2->status);
$this->assertEquals(file_get_contents($updateFileName), $record2->getFileContent());
$this->assertEquals($record->tag, $record2->tag);
}
/**

23
tests/unit/framework/base/ExceptionTest.php

@ -1,23 +0,0 @@
<?php
namespace yiiunit\framework\base;
use yiiunit\TestCase;
use yii\base\UserException;
use yii\base\InvalidCallException;
class ExceptionTest extends TestCase
{
public function testToArrayWithPrevious()
{
$e = new InvalidCallException('bar', 0 ,new InvalidCallException('foo'));
$array = $e->toArray();
$this->assertEquals('bar', $array['message']);
$this->assertEquals('foo', $array['previous']['message']);
$e = new InvalidCallException('bar', 0, new UserException('foo'));
$array = $e->toArray();
$this->assertEquals('bar', $array['message']);
$this->assertEquals('foo', $array['previous']['message']);
}
}

9
tests/unit/framework/i18n/I18NTest.php

@ -85,10 +85,6 @@ class I18NTest extends TestCase
$this->assertEquals('His speed is about 42 km/h.', $this->i18n->translate('test', $msg, 42, 'en-US'));
$this->assertEquals('His speed is about {0} km/h.', $this->i18n->translate('test', $msg, null, 'en-US'));
$this->assertEquals('His speed is about {0} km/h.', $this->i18n->translate('test', $msg, [], 'en-US'));
$msg = 'His name is {name} and he is {age} years old.';
$model = new ParamModel();
$this->assertEquals('His name is peer and he is 5 years old.', $this->i18n->translate('test', $msg, $model, 'en-US'));
}
/**
@ -129,8 +125,3 @@ class I18NTest extends TestCase
}
}
class ParamModel extends Model
{
public $name = 'peer';
public $age = 5;
}

Loading…
Cancel
Save