Commit 6a193f38 by Johnny Theill

Merge branch 'master' of https://github.com/yiisoft/yii2 into travis-advanced-app

parents af8f1e25 bd3dd038
...@@ -63,5 +63,7 @@ script: ...@@ -63,5 +63,7 @@ script:
- cd ../frontend && ../vendor/bin/codecept run - cd ../frontend && ../vendor/bin/codecept run
after_script: after_script:
- cd ../..
- pwd
- wget https://scrutinizer-ci.com/ocular.phar - wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
...@@ -10,21 +10,23 @@ $loginPage = LoginPage::openBy($I); ...@@ -10,21 +10,23 @@ $loginPage = LoginPage::openBy($I);
$I->amGoingTo('submit login form with no data'); $I->amGoingTo('submit login form with no data');
$loginPage->login('', ''); $loginPage->login('', '');
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$I->see('Username cannot be blank.'); $I->see('Username cannot be blank.', '.help-block');
$I->see('Password cannot be blank.'); $I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('try to login with wrong credentials'); $I->amGoingTo('try to login with wrong credentials');
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$loginPage->login('admin', 'wrong'); $loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors'); $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'); $I->amGoingTo('try to login with correct credentials');
$loginPage->login('erau', 'password_0'); $loginPage->login('erau', 'password_0');
$I->expectTo('see that user is logged'); $I->expectTo('see that user is logged');
$I->see('Logout (erau)'); $I->seeLink('Logout (erau)');
$I->dontSee('Login'); $I->dontSeeLink('Login');
$I->dontSee('Signup'); $I->dontSeeLink('Signup');
$I->click('Logout (erau)'); /** Uncomment if using WebDriver
$I->dontSee('Logout (erau)'); * $I->click('Logout (erau)');
$I->see('Login'); * $I->dontSeeLink('Logout (erau)');
* $I->seeLink('Login');
*/
...@@ -10,21 +10,18 @@ $loginPage = LoginPage::openBy($I); ...@@ -10,21 +10,18 @@ $loginPage = LoginPage::openBy($I);
$I->amGoingTo('submit login form with no data'); $I->amGoingTo('submit login form with no data');
$loginPage->login('', ''); $loginPage->login('', '');
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$I->see('Username cannot be blank.'); $I->see('Username cannot be blank.', '.help-block');
$I->see('Password cannot be blank.'); $I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('try to login with wrong credentials'); $I->amGoingTo('try to login with wrong credentials');
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$loginPage->login('admin', 'wrong'); $loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors'); $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'); $I->amGoingTo('try to login with correct credentials');
$loginPage->login('erau', 'password_0'); $loginPage->login('erau', 'password_0');
$I->expectTo('see that user is logged'); $I->expectTo('see that user is logged');
$I->see('Logout (erau)'); $I->seeLink('Logout (erau)');
$I->dontSee('Login'); $I->dontSeeLink('Login');
$I->dontSee('Signup'); $I->dontSeeLink('Signup');
$I->click('Logout (erau)');
$I->dontSee('Logout (erau)');
$I->see('Login');
...@@ -13,11 +13,11 @@ $I->amGoingTo('submit contact form with no data'); ...@@ -13,11 +13,11 @@ $I->amGoingTo('submit contact form with no data');
$contactPage->submit([]); $contactPage->submit([]);
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$I->see('Contact', 'h1'); $I->see('Contact', 'h1');
$I->see('Name cannot be blank'); $I->see('Name cannot be blank', '.help-block');
$I->see('Email cannot be blank'); $I->see('Email cannot be blank', '.help-block');
$I->see('Subject cannot be blank'); $I->see('Subject cannot be blank', '.help-block');
$I->see('Body cannot be blank'); $I->see('Body cannot be blank', '.help-block');
$I->see('The verification code is incorrect'); $I->see('The verification code is incorrect', '.help-block');
$I->amGoingTo('submit contact form with not correct email'); $I->amGoingTo('submit contact form with not correct email');
$contactPage->submit([ $contactPage->submit([
...@@ -28,11 +28,11 @@ $contactPage->submit([ ...@@ -28,11 +28,11 @@ $contactPage->submit([
'verifyCode' => 'testme', 'verifyCode' => 'testme',
]); ]);
$I->expectTo('see that email adress is wrong'); $I->expectTo('see that email adress is wrong');
$I->dontSee('Name cannot be blank', '.help-inline'); $I->dontSee('Name cannot be blank', '.help-block');
$I->see('Email is not a valid email address.'); $I->see('Email is not a valid email address.', '.help-block');
$I->dontSee('Subject cannot be blank', '.help-inline'); $I->dontSee('Subject cannot be blank', '.help-block');
$I->dontSee('Body cannot be blank', '.help-inline'); $I->dontSee('Body cannot be blank', '.help-block');
$I->dontSee('The verification code is incorrect', '.help-inline'); $I->dontSee('The verification code is incorrect', '.help-block');
$I->amGoingTo('submit contact form with correct data'); $I->amGoingTo('submit contact form with correct data');
$contactPage->submit([ $contactPage->submit([
......
...@@ -10,21 +10,23 @@ $loginPage = LoginPage::openBy($I); ...@@ -10,21 +10,23 @@ $loginPage = LoginPage::openBy($I);
$I->amGoingTo('submit login form with no data'); $I->amGoingTo('submit login form with no data');
$loginPage->login('', ''); $loginPage->login('', '');
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$I->see('Username cannot be blank.'); $I->see('Username cannot be blank.', '.help-block');
$I->see('Password cannot be blank.'); $I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('try to login with wrong credentials'); $I->amGoingTo('try to login with wrong credentials');
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$loginPage->login('admin', 'wrong'); $loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors'); $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'); $I->amGoingTo('try to login with correct credentials');
$loginPage->login('erau', 'password_0'); $loginPage->login('erau', 'password_0');
$I->expectTo('see that user is logged'); $I->expectTo('see that user is logged');
$I->see('Logout (erau)'); $I->seeLink('Logout (erau)');
$I->dontSee('Login'); $I->dontSeeLink('Login');
$I->dontSee('Signup'); $I->dontSeeLink('Signup');
$I->click('Logout (erau)'); /** Uncomment if using WebDriver
$I->dontSee('Logout (erau)'); * $I->click('Logout (erau)');
$I->see('Login'); * $I->dontSeeLink('Logout (erau)');
* $I->seeLink('Login');
*/
...@@ -9,7 +9,7 @@ class SignupCest ...@@ -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 * @param \Codeception\Event\Test $event
*/ */
public function _before($event) public function _before($event)
...@@ -37,7 +37,6 @@ class SignupCest ...@@ -37,7 +37,6 @@ class SignupCest
} }
/** /**
*
* @param \WebGuy $I * @param \WebGuy $I
* @param \Codeception\Scenario $scenario * @param \Codeception\Scenario $scenario
*/ */
...@@ -46,6 +45,7 @@ class SignupCest ...@@ -46,6 +45,7 @@ class SignupCest
$I->wantTo('ensure that signup works'); $I->wantTo('ensure that signup works');
$signupPage = SignupPage::openBy($I); $signupPage = SignupPage::openBy($I);
$I->see('Signup', 'h1');
$I->see('Please fill out the following fields to signup:'); $I->see('Please fill out the following fields to signup:');
$I->amGoingTo('submit signup form with no data'); $I->amGoingTo('submit signup form with no data');
...@@ -53,9 +53,9 @@ class SignupCest ...@@ -53,9 +53,9 @@ class SignupCest
$signupPage->submit([]); $signupPage->submit([]);
$I->expectTo('see validation errors'); $I->expectTo('see validation errors');
$I->see('Username cannot be blank.'); $I->see('Username cannot be blank.', '.help-block');
$I->see('Email cannot be blank.'); $I->see('Email cannot be blank.', '.help-block');
$I->see('Password cannot be blank.'); $I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('submit signup form with not correct email'); $I->amGoingTo('submit signup form with not correct email');
$signupPage->submit([ $signupPage->submit([
...@@ -64,9 +64,9 @@ class SignupCest ...@@ -64,9 +64,9 @@ class SignupCest
'password' => 'tester_password', 'password' => 'tester_password',
]); ]);
$I->expectTo('see that email adress is wrong'); $I->expectTo('see that email address is wrong');
$I->dontSee('Username cannot be blank.', '.help-inline'); $I->dontSee('Username cannot be blank.', '.help-block');
$I->dontSee('Password cannot be blank.', '.help-inline'); $I->dontSee('Password cannot be blank.', '.help-block');
$I->see('Email is not a valid email address.', '.help-block'); $I->see('Email is not a valid email address.', '.help-block');
$I->amGoingTo('submit signup form with correct email'); $I->amGoingTo('submit signup form with correct email');
...@@ -77,6 +77,6 @@ class SignupCest ...@@ -77,6 +77,6 @@ class SignupCest
]); ]);
$I->expectTo('see that user logged in'); $I->expectTo('see that user logged in');
$I->see('Logout (tester)'); $I->seeLink('Logout (tester)');
} }
} }
...@@ -13,11 +13,11 @@ $I->amGoingTo('submit contact form with no data'); ...@@ -13,11 +13,11 @@ $I->amGoingTo('submit contact form with no data');
$contactPage->submit([]); $contactPage->submit([]);
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$I->see('Contact', 'h1'); $I->see('Contact', 'h1');
$I->see('Name cannot be blank'); $I->see('Name cannot be blank', '.help-block');
$I->see('Email cannot be blank'); $I->see('Email cannot be blank', '.help-block');
$I->see('Subject cannot be blank'); $I->see('Subject cannot be blank', '.help-block');
$I->see('Body cannot be blank'); $I->see('Body cannot be blank', '.help-block');
$I->see('The verification code is incorrect'); $I->see('The verification code is incorrect', '.help-block');
$I->amGoingTo('submit contact form with not correct email'); $I->amGoingTo('submit contact form with not correct email');
$contactPage->submit([ $contactPage->submit([
...@@ -28,11 +28,11 @@ $contactPage->submit([ ...@@ -28,11 +28,11 @@ $contactPage->submit([
'verifyCode' => 'testme', 'verifyCode' => 'testme',
]); ]);
$I->expectTo('see that email adress is wrong'); $I->expectTo('see that email adress is wrong');
$I->dontSee('Name cannot be blank', '.help-inline'); $I->dontSee('Name cannot be blank', '.help-block');
$I->see('Email is not a valid email address.'); $I->see('Email is not a valid email address.', '.help-block');
$I->dontSee('Subject cannot be blank', '.help-inline'); $I->dontSee('Subject cannot be blank', '.help-block');
$I->dontSee('Body cannot be blank', '.help-inline'); $I->dontSee('Body cannot be blank', '.help-block');
$I->dontSee('The verification code is incorrect', '.help-inline'); $I->dontSee('The verification code is incorrect', '.help-block');
$I->amGoingTo('submit contact form with correct data'); $I->amGoingTo('submit contact form with correct data');
$contactPage->submit([ $contactPage->submit([
......
...@@ -10,21 +10,18 @@ $loginPage = LoginPage::openBy($I); ...@@ -10,21 +10,18 @@ $loginPage = LoginPage::openBy($I);
$I->amGoingTo('submit login form with no data'); $I->amGoingTo('submit login form with no data');
$loginPage->login('', ''); $loginPage->login('', '');
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$I->see('Username cannot be blank.'); $I->see('Username cannot be blank.', '.help-block');
$I->see('Password cannot be blank.'); $I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('try to login with wrong credentials'); $I->amGoingTo('try to login with wrong credentials');
$I->expectTo('see validations errors'); $I->expectTo('see validations errors');
$loginPage->login('admin', 'wrong'); $loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors'); $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'); $I->amGoingTo('try to login with correct credentials');
$loginPage->login('erau', 'password_0'); $loginPage->login('erau', 'password_0');
$I->expectTo('see that user is logged'); $I->expectTo('see that user is logged');
$I->see('Logout (erau)'); $I->seeLink('Logout (erau)');
$I->dontSee('Login'); $I->dontSeeLink('Login');
$I->dontSee('Signup'); $I->dontSeeLink('Signup');
$I->click('Logout (erau)');
$I->dontSee('Logout (erau)');
$I->see('Login');
...@@ -9,7 +9,7 @@ class SignupCest ...@@ -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 * @param \Codeception\Event\Test $event
*/ */
public function _before($event) public function _before($event)
...@@ -34,10 +34,11 @@ class SignupCest ...@@ -34,10 +34,11 @@ class SignupCest
*/ */
public function _fail($event) public function _fail($event)
{ {
} }
/** /**
* *
* @param \TestGuy $I * @param \TestGuy $I
* @param \Codeception\Scenario $scenario * @param \Codeception\Scenario $scenario
*/ */
...@@ -46,6 +47,7 @@ class SignupCest ...@@ -46,6 +47,7 @@ class SignupCest
$I->wantTo('ensure that signup works'); $I->wantTo('ensure that signup works');
$signupPage = SignupPage::openBy($I); $signupPage = SignupPage::openBy($I);
$I->see('Signup', 'h1');
$I->see('Please fill out the following fields to signup:'); $I->see('Please fill out the following fields to signup:');
$I->amGoingTo('submit signup form with no data'); $I->amGoingTo('submit signup form with no data');
...@@ -53,9 +55,9 @@ class SignupCest ...@@ -53,9 +55,9 @@ class SignupCest
$signupPage->submit([]); $signupPage->submit([]);
$I->expectTo('see validation errors'); $I->expectTo('see validation errors');
$I->see('Username cannot be blank.'); $I->see('Username cannot be blank.', '.help-block');
$I->see('Email cannot be blank.'); $I->see('Email cannot be blank.', '.help-block');
$I->see('Password cannot be blank.'); $I->see('Password cannot be blank.', '.help-block');
$I->amGoingTo('submit signup form with not correct email'); $I->amGoingTo('submit signup form with not correct email');
$signupPage->submit([ $signupPage->submit([
...@@ -64,9 +66,9 @@ class SignupCest ...@@ -64,9 +66,9 @@ class SignupCest
'password' => 'tester_password', 'password' => 'tester_password',
]); ]);
$I->expectTo('see that email adress is wrong'); $I->expectTo('see that email address is wrong');
$I->dontSee('Username cannot be blank.', '.help-inline'); $I->dontSee('Username cannot be blank.', '.help-block');
$I->dontSee('Password cannot be blank.', '.help-inline'); $I->dontSee('Password cannot be blank.', '.help-block');
$I->see('Email is not a valid email address.', '.help-block'); $I->see('Email is not a valid email address.', '.help-block');
$I->amGoingTo('submit signup form with correct email'); $I->amGoingTo('submit signup form with correct email');
...@@ -76,7 +78,13 @@ class SignupCest ...@@ -76,7 +78,13 @@ class SignupCest
'password' => 'tester_password', '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->expectTo('see that user logged in');
$I->see('Logout (tester)'); $I->seeLink('Logout (tester)');
} }
} }
...@@ -4,6 +4,7 @@ namespace frontend\tests\unit\models; ...@@ -4,6 +4,7 @@ namespace frontend\tests\unit\models;
use Yii; use Yii;
use frontend\tests\unit\TestCase; use frontend\tests\unit\TestCase;
use frontend\models\ContactForm;
class ContactFormTest extends TestCase class ContactFormTest extends TestCase
{ {
...@@ -26,8 +27,7 @@ class ContactFormTest extends TestCase ...@@ -26,8 +27,7 @@ class ContactFormTest extends TestCase
public function testContact() public function testContact()
{ {
$model = $this->getMock('frontend\models\ContactForm', ['validate']); $model = new ContactForm();
$model->expects($this->once())->method('validate')->will($this->returnValue(true));
$model->attributes = [ $model->attributes = [
'name' => 'Tester', 'name' => 'Tester',
...@@ -36,7 +36,7 @@ class ContactFormTest extends TestCase ...@@ -36,7 +36,7 @@ class ContactFormTest extends TestCase
'body' => 'body of current message', 'body' => 'body of current message',
]; ];
$model->contact('admin@example.com'); $model->sendEmail('admin@example.com');
$this->specify('email should be send', function () { $this->specify('email should be send', function () {
expect('email file should exist', file_exists($this->getMessageFile()))->true(); expect('email file should exist', file_exists($this->getMessageFile()))->true();
......
...@@ -381,6 +381,7 @@ the `self` link, for example: ...@@ -381,6 +381,7 @@ the `self` link, for example:
```php ```php
use yii\db\ActiveRecord; use yii\db\ActiveRecord;
use yii\web\Link;
use yii\web\Linkable; use yii\web\Linkable;
use yii\helpers\Url; use yii\helpers\Url;
......
...@@ -522,7 +522,8 @@ TBD ...@@ -522,7 +522,8 @@ TBD
Extensions Extensions
---------- ----------
TBD Yii 1.1 extensions are not compatible with 2.0 so you have to port or rewrite these. In order to get more info about
extensions in 2.0 [referer to corresponding guide section](extensions.md).
Integration with Composer Integration with Composer
------------------------- -------------------------
......
...@@ -93,7 +93,7 @@ class ApiMarkdown extends GithubMarkdown ...@@ -93,7 +93,7 @@ class ApiMarkdown extends GithubMarkdown
} }
} }
protected function highlight($code, $language) public static function highlight($code, $language)
{ {
if ($language !== 'php') { if ($language !== 'php') {
return htmlspecialchars($code, ENT_NOQUOTES, 'UTF-8'); return htmlspecialchars($code, ENT_NOQUOTES, 'UTF-8');
......
...@@ -117,7 +117,7 @@ abstract class BaseRenderer extends Component ...@@ -117,7 +117,7 @@ abstract class BaseRenderer extends Component
$links[] = $this->generateLink($linkText, $this->generateApiUrl($type->name)) . $postfix; $links[] = $this->generateLink($linkText, $this->generateApiUrl($type->name)) . $postfix;
} }
} }
return implode('|', $links); return implode(' | ', $links);
} }
......
...@@ -57,4 +57,9 @@ blockquote { ...@@ -57,4 +57,9 @@ blockquote {
td p { td p {
margin: 0; margin: 0;
} }
\ No newline at end of file
table.detailTable .paramNameCol { width: 15%; min-width: 100px; }
table.detailTable .paramTypeCol { width: 15%; min-width: 150px; }
table.detailTable .paramDescCol { width: 70%; }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
namespace yii\apidoc\templates\html; namespace yii\apidoc\templates\html;
use yii\apidoc\helpers\ApiMarkdown;
use yii\apidoc\models\MethodDoc; use yii\apidoc\models\MethodDoc;
use yii\apidoc\models\PropertyDoc; use yii\apidoc\models\PropertyDoc;
use yii\apidoc\models\ClassDoc; use yii\apidoc\models\ClassDoc;
...@@ -225,7 +226,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface ...@@ -225,7 +226,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface
} }
return implode('<br />', $sig); return implode('<br />', $sig);
} }
return $this->createTypeLink($property->types) . ' ' . $property->name . ' = ' . ($property->defaultValue === null ? 'null' : $property->defaultValue); return $this->createTypeLink($property->types) . ' ' . $this->createSubjectLink($property, $property->name) . ' '
. ApiMarkdown::highlight('= ' . ($property->defaultValue === null ? 'null' : $property->defaultValue), 'php');
} }
/** /**
...@@ -244,9 +246,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface ...@@ -244,9 +246,8 @@ class ApiRenderer extends BaseApiRenderer implements ViewContextInterface
return ($method->isReturnByReference ? '<b>&</b>' : '') return ($method->isReturnByReference ? '<b>&</b>' : '')
. ($method->returnType === null ? 'void' : $this->createTypeLink($method->returnTypes)) . ($method->returnType === null ? 'void' : $this->createTypeLink($method->returnTypes))
. ' ' . $this->createSubjectLink($method, $method->name) . '( ' . ' ' . $this->createSubjectLink($method, $method->name)
. implode(', ', $params) . ApiMarkdown::highlight('( ' . implode(', ', $params) . ' )', 'php');
. ' )';
} }
public function generateApiUrl($typeName) public function generateApiUrl($typeName)
......
...@@ -34,28 +34,28 @@ ArrayHelper::multisort($methods, 'name'); ...@@ -34,28 +34,28 @@ ArrayHelper::multisort($methods, 'name');
</span> </span>
</div> </div>
<table class="summaryTable table table-striped table-bordered table-hover"> <table class="detailTable table table-striped table-bordered table-hover">
<tr><td colspan="3"> <tr><td colspan="3">
<div class="signature2"><?= $renderer->renderMethodSignature($method) ?></div> <div class="signature2"><?= $renderer->renderMethodSignature($method) ?></div>
</td></tr> </td></tr>
<?php if (!empty($method->params) || !empty($method->return) || !empty($method->exceptions)): ?> <?php if (!empty($method->params) || !empty($method->return) || !empty($method->exceptions)): ?>
<?php foreach ($method->params as $param): ?> <?php foreach ($method->params as $param): ?>
<tr> <tr>
<td class="paramNameCol"><?= $param->name ?></td> <td class="paramNameCol"><?= ApiMarkdown::highlight($param->name, 'php') ?></td>
<td class="paramTypeCol"><?= $renderer->createTypeLink($param->types) ?></td> <td class="paramTypeCol"><?= $renderer->createTypeLink($param->types) ?></td>
<td class="paramDescCol"><?= ApiMarkdown::process($param->description, $type) ?></td> <td class="paramDescCol"><?= ApiMarkdown::process($param->description, $type) ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
<?php if (!empty($method->return)): ?> <?php if (!empty($method->return)): ?>
<tr> <tr>
<td class="paramNameCol"><?= 'return'; ?></td> <th class="paramNameCol"><?= 'return'; ?></th>
<td class="paramTypeCol"><?= $renderer->createTypeLink($method->returnTypes); ?></td> <td class="paramTypeCol"><?= $renderer->createTypeLink($method->returnTypes); ?></td>
<td class="paramDescCol"><?= ApiMarkdown::process($method->return, $type); ?></td> <td class="paramDescCol"><?= ApiMarkdown::process($method->return, $type); ?></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
<?php foreach ($method->exceptions as $exception => $description): ?> <?php foreach ($method->exceptions as $exception => $description): ?>
<tr> <tr>
<td class="paramNameCol"><?= 'throws' ?></td> <th class="paramNameCol"><?= 'throws' ?></th>
<td class="paramTypeCol"><?= $renderer->createTypeLink($exception) ?></td> <td class="paramTypeCol"><?= $renderer->createTypeLink($exception) ?></td>
<td class="paramDescCol"><?= ApiMarkdown::process($description, $type) ?></td> <td class="paramDescCol"><?= ApiMarkdown::process($description, $type) ?></td>
</tr> </tr>
......
...@@ -107,12 +107,70 @@ class Collection extends Object ...@@ -107,12 +107,70 @@ class Collection extends Object
{ {
$parts = []; $parts = [];
foreach ($arguments as $argument) { foreach ($arguments as $argument) {
$parts[] = is_scalar($argument) ? $argument : Json::encode($argument); $parts[] = is_scalar($argument) ? $argument : $this->encodeLogData($argument);
} }
return $this->getFullName() . '.' . $command . '(' . implode(', ', $parts) . ')'; return $this->getFullName() . '.' . $command . '(' . implode(', ', $parts) . ')';
} }
/** /**
* Encodes complex log data into JSON format string.
* @param mixed $data raw data.
* @return string encoded data string.
*/
protected function encodeLogData($data)
{
return json_encode($this->processLogData($data));
}
/**
* Pre-processes the log data before sending it to `json_encode()`.
* @param mixed $data raw data.
* @return mixed the processed data.
*/
protected function processLogData($data)
{
if (is_object($data)) {
if ($data instanceof \MongoId ||
$data instanceof \MongoRegex ||
$data instanceof \MongoDate ||
$data instanceof \MongoInt32 ||
$data instanceof \MongoInt64 ||
$data instanceof \MongoTimestamp
) {
$data = get_class($data) . '(' . $data->__toString() . ')';
} elseif ($data instanceof \MongoCode) {
$data = 'MongoCode( ' . $data->__toString() . ' )';
} elseif ($data instanceof \MongoBinData) {
$data = 'MongoBinData(...)';
} elseif ($data instanceof \MongoDBRef) {
$data = 'MongoDBRef(...)';
} elseif ($data instanceof \MongoMinKey || $data instanceof \MongoMaxKey) {
$data = get_class($data);
} else {
$result = [];
foreach ($data as $name => $value) {
$result[$name] = $value;
}
$data = $result;
}
if ($data === []) {
return new \stdClass();
}
}
if (is_array($data)) {
foreach ($data as $key => $value) {
if (is_array($value) || is_object($value)) {
$data[$key] = $this->processLogData($value);
}
}
}
return $data;
}
/**
* Drops this collection. * Drops this collection.
* @throws Exception on failure. * @throws Exception on failure.
* @return boolean whether the operation successful. * @return boolean whether the operation successful.
...@@ -733,7 +791,13 @@ class Collection extends Object ...@@ -733,7 +791,13 @@ class Collection extends Object
$rawId = (string)$rawId; $rawId = (string)$rawId;
} }
} }
return new \MongoId($rawId); try {
$mongoId = new \MongoId($rawId);
} catch (\MongoException $e) {
// invalid id format
$mongoId = $rawId;
}
return $mongoId;
} }
/** /**
......
...@@ -184,6 +184,37 @@ $models = $provider->getModels(); ...@@ -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 Using GridFS
------------ ------------
......
...@@ -178,6 +178,16 @@ abstract class ActiveRecord extends \yii\mongodb\ActiveRecord ...@@ -178,6 +178,16 @@ abstract class ActiveRecord extends \yii\mongodb\ActiveRecord
unset($values['file']); unset($values['file']);
} }
if (isset($newFileContent) || isset($newFile)) { if (isset($newFileContent) || isset($newFile)) {
$fileAssociatedAttributeNames = [
'filename',
'uploadDate',
'length',
'chunkSize',
'md5',
'file',
'newFileContent'
];
$values = array_merge($this->getAttributes(null, $fileAssociatedAttributeNames), $values);
$rows = $this->deleteInternal(); $rows = $this->deleteInternal();
$insertValues = $values; $insertValues = $values;
$insertValues['_id'] = $this->getAttribute('_id'); $insertValues['_id'] = $this->getAttribute('_id');
......
...@@ -33,8 +33,8 @@ class TwigSimpleFileLoader implements \Twig_LoaderInterface ...@@ -33,8 +33,8 @@ class TwigSimpleFileLoader implements \Twig_LoaderInterface
/** /**
* Compare a file's freshness with previously stored timestamp * Compare a file's freshness with previously stored timestamp
* *
* @param $name string file name to check * @param string $name file name to check
* @param $time int timestamp to compare with * @param integer $time timestamp to compare with
* @return boolean true if file is still fresh and not changes, false otherwise * @return boolean true if file is still fresh and not changes, false otherwise
*/ */
public function isFresh($name, $time) public function isFresh($name, $time)
......
...@@ -31,7 +31,7 @@ class Widget extends Component implements ViewContextInterface ...@@ -31,7 +31,7 @@ class Widget extends Component implements ViewContextInterface
public static $counter = 0; public static $counter = 0;
/** /**
* @var string the prefix to the automatically generated widget IDs. * @var string the prefix to the automatically generated widget IDs.
* @see [[getId()]] * @see getId()
*/ */
public static $autoIdPrefix = 'w'; public static $autoIdPrefix = 'w';
......
...@@ -62,7 +62,7 @@ class AssetController extends Controller ...@@ -62,7 +62,7 @@ class AssetController extends Controller
*/ */
public $targets = []; public $targets = [];
/** /**
* @var string|callback JavaScript file compressor. * @var string|callable JavaScript file compressor.
* If a string, it is treated as shell command template, which should contain * If a string, it is treated as shell command template, which should contain
* placeholders {from} - source file name - and {to} - output file name. * placeholders {from} - source file name - and {to} - output file name.
* Otherwise, it is treated as PHP callback, which should perform the compression. * Otherwise, it is treated as PHP callback, which should perform the compression.
...@@ -72,7 +72,7 @@ class AssetController extends Controller ...@@ -72,7 +72,7 @@ class AssetController extends Controller
*/ */
public $jsCompressor = 'java -jar compiler.jar --js {from} --js_output_file {to}'; public $jsCompressor = 'java -jar compiler.jar --js {from} --js_output_file {to}';
/** /**
* @var string|callback CSS file compressor. * @var string|callable CSS file compressor.
* If a string, it is treated as shell command template, which should contain * If a string, it is treated as shell command template, which should contain
* placeholders {from} - source file name - and {to} - output file name. * placeholders {from} - source file name - and {to} - output file name.
* Otherwise, it is treated as PHP callback, which should perform the compression. * Otherwise, it is treated as PHP callback, which should perform the compression.
...@@ -88,6 +88,7 @@ class AssetController extends Controller ...@@ -88,6 +88,7 @@ class AssetController extends Controller
*/ */
private $_assetManager = []; private $_assetManager = [];
/** /**
* Returns the asset manager instance. * Returns the asset manager instance.
* @throws \yii\console\Exception on invalid configuration. * @throws \yii\console\Exception on invalid configuration.
......
...@@ -46,7 +46,7 @@ class HttpBearerAuth extends Component implements AuthInterface ...@@ -46,7 +46,7 @@ class HttpBearerAuth extends Component implements AuthInterface
*/ */
public function handleFailure($response) public function handleFailure($response)
{ {
$response->getHeaders()->set('WWW-Authenticate', "Basic realm=\"{$this->realm}\""); $response->getHeaders()->set('WWW-Authenticate', "Bearer realm=\"{$this->realm}\"");
throw new UnauthorizedHttpException('You are requesting with an invalid access token.'); throw new UnauthorizedHttpException('You are requesting with an invalid access token.');
} }
} }
...@@ -525,7 +525,7 @@ class User extends Component ...@@ -525,7 +525,7 @@ class User extends Component
protected function renewAuthStatus() protected function renewAuthStatus()
{ {
$session = Yii::$app->getSession(); $session = Yii::$app->getSession();
$id = $session->getHasSessionId() ? $session->get($this->idParam) : null; $id = $session->getHasSessionId() || $session->getIsActive() ? $session->get($this->idParam) : null;
if ($id === null) { if ($id === null) {
$identity = null; $identity = null;
......
...@@ -76,7 +76,7 @@ class DetailView extends Widget ...@@ -76,7 +76,7 @@ class DetailView extends Widget
*/ */
public $attributes; public $attributes;
/** /**
* @var string|callback the template used to render a single attribute. If a string, the token `{label}` * @var string|callable the template used to render a single attribute. If a string, the token `{label}`
* and `{value}` will be replaced with the label and the value of the corresponding attribute. * and `{value}` will be replaced with the label and the value of the corresponding attribute.
* If a callback (e.g. an anonymous function), the signature must be as follows: * If a callback (e.g. an anonymous function), the signature must be as follows:
* *
......
...@@ -25,7 +25,7 @@ class ListView extends BaseListView ...@@ -25,7 +25,7 @@ class ListView extends BaseListView
*/ */
public $itemOptions = []; public $itemOptions = [];
/** /**
* @var string|callback the name of the view for rendering each data item, or a callback (e.g. an anonymous function) * @var string|callable the name of the view for rendering each data item, or a callback (e.g. an anonymous function)
* for rendering each data item. If it specifies a view name, the following variables will * for rendering each data item. If it specifies a view name, the following variables will
* be available in the view: * be available in the view:
* *
......
...@@ -419,4 +419,48 @@ class CollectionTest extends MongoDbTestCase ...@@ -419,4 +419,48 @@ class CollectionTest extends MongoDbTestCase
$this->assertNotEmpty($result); $this->assertNotEmpty($result);
$this->assertCount(2, $result); $this->assertCount(2, $result);
} }
/**
* @depends testInsert
* @depends testFind
*/
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());
}
/**
* @depends testInsert
*
* @see https://github.com/yiisoft/yii2/issues/2548
*/
public function testInsertMongoBin()
{
$collection = $this->getConnection()->getCollection('customer');
$fileName = realpath(__DIR__ . '/../../../../extensions/gii/assets/logo.png');
$data = [
'name' => 'customer 1',
'address' => 'customer 1 address',
'binData' => new \MongoBinData(file_get_contents($fileName), 2),
];
$id = $collection->insert($data);
$this->assertTrue($id instanceof \MongoId);
$this->assertNotEmpty($id->__toString());
}
} }
\ No newline at end of file
...@@ -248,6 +248,7 @@ class ActiveRecordTest extends MongoDbTestCase ...@@ -248,6 +248,7 @@ class ActiveRecordTest extends MongoDbTestCase
$record2 = CustomerFile::find($record->_id); $record2 = CustomerFile::find($record->_id);
$this->assertEquals($record->status, $record2->status); $this->assertEquals($record->status, $record2->status);
$this->assertEquals(file_get_contents($updateFileName), $record2->getFileContent()); $this->assertEquals(file_get_contents($updateFileName), $record2->getFileContent());
$this->assertEquals($record->tag, $record2->tag);
} }
/** /**
......
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