Commit e38c4225 by Qiang Xue

Merge commit 'bdce87b2' into feature-restapi

Conflicts: framework/db/BaseActiveRecord.php
parents 1b03dc8f bdce87b2
......@@ -37,7 +37,11 @@ AppAsset::register($this);
if (Yii::$app->user->isGuest) {
$menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
} else {
$menuItems[] = ['label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => ['/site/logout']];
$menuItems[] = [
'label' => 'Logout (' . Yii::$app->user->identity->username . ')',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post']
];
}
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
......
<?php
use yii\helpers\Html;
use yii\mail\BaseMessage;
/**
* @var \yii\web\View $this
* @var BaseMessage $content
* @var \yii\mail\BaseMessage $content
*/
?>
<?php $this->beginPage() ?>
......
......@@ -32,7 +32,7 @@ class FixtureHelper extends Module
* to use in acceptance and functional tests.
* @param array $settings
*/
public function _beforeSuite($settings = array())
public function _beforeSuite($settings = [])
{
$this->loadFixtures();
}
......@@ -54,5 +54,4 @@ class FixtureHelper extends Module
],
];
}
}
......@@ -18,5 +18,4 @@ class LoginPage extends BasePage
$this->guy->fillField('input[name="LoginForm[password]"]', $password);
$this->guy->click('login-button');
}
}
......@@ -25,7 +25,7 @@ class LoginFormTest extends TestCase
$model->username = 'some_username';
$model->password = 'some_password';
$this->specify('user should not be able to login, when there is no identity' , function () use ($model) {
$this->specify('user should not be able to login, when there is no identity', function () use ($model) {
expect('model should not login user', $model->login())->false();
expect('user should not be logged in', Yii::$app->user->isGuest)->true();
});
......@@ -52,7 +52,7 @@ class LoginFormTest extends TestCase
$model->username = 'demo';
$model->password = 'demo';
$this->specify('user should be able to login with correct credentials', function() use ($model) {
$this->specify('user should be able to login with correct credentials', function () use ($model) {
expect('model should login user', $model->login())->true();
expect('error message should not be set', $model->errors)->hasntKey('password');
expect('user should be logged in', Yii::$app->user->isGuest)->false();
......@@ -61,9 +61,8 @@ class LoginFormTest extends TestCase
private function mockUser($user)
{
$loginForm = $this->getMock('common\models\LoginForm',['getUser']);
$loginForm = $this->getMock('common\models\LoginForm', ['getUser']);
$loginForm->expects($this->any())->method('getUser')->will($this->returnValue($user));
return $loginForm;
}
}
{
"name": "yiisoft/yii2-app-advanced",
"description": "Yii 2 Advanced Application Template",
"keywords": ["yii", "framework", "advanced", "application template"],
"keywords": ["yii2", "framework", "advanced", "application template"],
"homepage": "http://www.yiiframework.com/",
"type": "project",
"license": "BSD-3-Clause",
......
......@@ -20,5 +20,4 @@ class SignupPage extends BasePage
}
$this->guy->click('signup-button');
}
}
......@@ -79,5 +79,4 @@ class SignupCest
$I->expectTo('see that user logged in');
$I->see('Logout (tester)');
}
}
......@@ -79,5 +79,4 @@ class SignupCest
$I->expectTo('see that user logged in');
$I->see('Logout (tester)');
}
}
......@@ -42,7 +42,7 @@ class ContactFormTest extends TestCase
expect('email file should exist', file_exists($this->getMessageFile()))->true();
});
$this->specify('message should contain correct data', function () use($model) {
$this->specify('message should contain correct data', function () use ($model) {
$emailMessage = file_get_contents($this->getMessageFile());
expect('email should contain user name', $emailMessage)->contains($model->name);
......@@ -56,5 +56,4 @@ class ContactFormTest extends TestCase
{
return Yii::getAlias(Yii::$app->mail->fileTransportPath) . '/testing_message.eml';
}
}
......@@ -28,14 +28,14 @@ class PasswordResetRequestFormTest extends DbTestCase
public function testSendEmailWrongUser()
{
$this->specify('no user with such email, message should not be send', function() {
$this->specify('no user with such email, message should not be send', function () {
$model = new PasswordResetRequestForm();
$model->email = 'not-existing-email@example.com';
expect('email not send', $model->sendEmail())->false();
});
$this->specify('user is not active, message should not be send', function() {
$this->specify('user is not active, message should not be send', function () {
$model = new PasswordResetRequestForm();
$model->email = $this->user[1]['email'];
......@@ -52,8 +52,8 @@ class PasswordResetRequestFormTest extends DbTestCase
expect('email sent', $model->sendEmail())->true();
expect('user has valid token', $user->password_reset_token)->notNull();
$this->specify('message has correct format', function() use ($model) {
expect('message file exists', file_exists($this->getMessageFile()))->true();
$this->specify('message has correct format', function () use ($model) {
expect('message file exists', file_exists($this->getMessageFile()))->true();
$message = file_get_contents($this->getMessageFile());
expect('message "from" is correct', $message)->contains(Yii::$app->params['supportEmail']);
......@@ -75,5 +75,4 @@ class PasswordResetRequestFormTest extends DbTestCase
{
return Yii::getAlias(Yii::$app->mail->fileTransportPath) . '/testing_message.eml';
}
}
......@@ -13,13 +13,13 @@ class ResetPasswordFormTest extends DbTestCase
public function testResetPassword()
{
$this->specify('wrong reset token', function() {
$this->setExpectedException('\Exception','Wrong password reset token.');
$this->specify('wrong reset token', function () {
$this->setExpectedException('\Exception', 'Wrong password reset token.');
new ResetPasswordForm('notexistingtoken_1391882543');
});
$this->specify('not correct token', function() {
$this->setExpectedException('yii\base\InvalidParamException','Password reset token cannot be blank.');
$this->specify('not correct token', function () {
$this->setExpectedException('yii\base\InvalidParamException', 'Password reset token cannot be blank.');
new ResetPasswordForm('');
});
}
......@@ -33,5 +33,4 @@ class ResetPasswordFormTest extends DbTestCase
],
];
}
}
......@@ -12,7 +12,7 @@ class SignupFormTest extends DbTestCase
public function testCorrectSignup()
{
$model = $this->getMock('frontend\models\SignupForm',['validate']);
$model = $this->getMock('frontend\models\SignupForm', ['validate']);
$model->expects($this->once())->method('validate')->will($this->returnValue(true));
$model->username = 'some_username';
......@@ -28,7 +28,7 @@ class SignupFormTest extends DbTestCase
public function testNotCorrectSignup()
{
$model = $this->getMock('frontend\models\SignupForm',['validate']);
$model = $this->getMock('frontend\models\SignupForm', ['validate']);
$model->expects($this->once())->method('validate')->will($this->returnValue(false));
expect('user should not be created', $model->signup())->null();
......@@ -43,5 +43,4 @@ class SignupFormTest extends DbTestCase
],
];
}
}
......@@ -41,7 +41,11 @@ AppAsset::register($this);
$menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']];
$menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];
} else {
$menuItems[] = ['label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => ['/site/logout']];
$menuItems[] = [
'label' => 'Logout (' . Yii::$app->user->identity->username . ')',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post']
];
}
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
......
{
"name": "yiisoft/yii2-app-basic",
"description": "Yii 2 Basic Application Template",
"keywords": ["yii", "framework", "basic", "application template"],
"keywords": ["yii2", "framework", "basic", "application template"],
"homepage": "http://www.yiiframework.com/",
"type": "project",
"license": "BSD-3-Clause",
......
<?php
use yii\helpers\Html;
use yii\mail\BaseMessage;
/**
* @var \yii\web\View $this
* @var BaseMessage $content
* @var \yii\mail\BaseMessage $content
*/
?>
<?php $this->beginPage() ?>
......
{
"name": "yiisoft/yii2-app-benchmark",
"description": "Yii 2 Benchmark Application",
"keywords": ["yii", "framework", "benchmark", "application"],
"keywords": ["yii2", "framework", "benchmark", "application"],
"homepage": "http://www.yiiframework.com/",
"type": "project",
"license": "BSD-3-Clause",
......
......@@ -52,7 +52,7 @@ class ClassmapController extends Controller
$files = FileHelper::findFiles($root, $options);
$map = [];
foreach ($files as $file) {
if (($pos = strpos($file, $root)) !== 0) {
if (strpos($file, $root) !== 0) {
die("Something wrong: $file\n");
}
$path = str_replace('\\', '/', substr($file, strlen($root)));
......
{
"name": "yiisoft/yii2-dev",
"description": "Yii PHP Framework Version 2 - Development Package",
"keywords": ["yii", "framework"],
"keywords": ["yii2", "framework"],
"homepage": "http://www.yiiframework.com/",
"type": "yii2-extension",
"license": "BSD-3-Clause",
......@@ -74,6 +74,7 @@
"lib-pcre": "*",
"yiisoft/yii2-composer": "*",
"yiisoft/jquery": "~2.0 | ~1.10",
"yiisoft/jquery-pjax": "*",
"ezyang/htmlpurifier": "4.6.*",
"cebe/markdown": "0.9.*"
},
......
......@@ -81,18 +81,26 @@ following way:
```php
class LanguageAsset extends AssetBundle
{
public $sourcePath = '@app/assets/language';
public $js = [
];
public function init()
{
$this->js[] = 'language-' . Yii::$app->language . '.js';
parent::init();
}
public $language;
public $sourcePath = '@app/assets/language';
public $js = [
];
public function registerAssetFiles($view)
{
$language = $this->language ? $this->language : Yii::$app->language;
$this->js[] = 'language-' . $language . '.js';
parent::registerAssetFiles($view);
}
}
```
In order to set language use the following code when registering an asset bundle in a view:
```php
LanguageAsset::register($this)->language = $language;
```
Registering asset bundle
------------------------
......@@ -114,6 +122,10 @@ To register an asset inside of a widget, the view instance is available as `$thi
AppAsset::register($this->view);
```
> Note: If there is a need to modify third party asset bundles it is recommended to create your own bundles depending
on third party ones and use CSS and JavaScript features to modify behavior instead of editing files directly or
copying them over.
Overriding asset bundles
------------------------
......
......@@ -81,13 +81,16 @@ Routes
------
Each controller action has a corresponding internal route. In our example above `actionIndex` has `site/index` route
and `actionTest` has `site/test` route. In this route `site` is referred to as controller ID while `test` is referred to
as action ID.
and `actionTest` has `site/test` route. In this route `site` is referred to as controller ID while `test` is action ID.
By default you can access specific controller and action using the `http://example.com/?r=controller/action` URL. This
behavior is fully customizable. For details refer to [URL Management](url.md).
behavior is fully customizable. For more details please refer to [URL Management](url.md).
If controller is located inside a module its action internal route will be `module/controller/action`.
If a controller is located inside a module, the route of its actions will be in the format of `module/controller/action`.
A controller can be located under a subdirectory of the controller directory of an application or module. The route
will be prefixed with the corresponding directory names. For example, you may have a `UserController` under `controllers/admin`.
The route of its `actionIndex` would be `admin/user/index`, and `admin/user` would be the controller ID.
In case module, controller or action specified isn't found Yii will return "not found" page and HTTP status code 404.
......
......@@ -110,7 +110,7 @@ class ViewsPanel extends Panel
{
parent::init();
Event::on(View::className(), View::EVENT_BEFORE_RENDER, function (ViewEvent $event) {
$this->_viewFiles[] = $event->viewFile;
$this->_viewFiles[] = $event->sender->getViewFile();
});
}
......
Theming
=======
TBD
A theme is a directory of view and layout files. Each file of the theme overrides corresponding file of an application
when rendered. A single application may use multiple themes and each may provide totally different experience. At any
time only one theme can be active.
> Note: Themes usually do not meant to be redistributed since views are too application specific. If you want to
redistribute customized look and feel consider CSS and JavaScript files in form of [asset bundles](assets.md) instead.
Configuring current theme
-------------------------
......@@ -18,4 +23,27 @@ be in your application config file:
],
],
],
```
\ No newline at end of file
```
In the above `pathMap` defines where to look for view files while `baseUrl` defines base URL for resources referenced
from these files. For example, if `pathMap` is `['/web/views' => '/web/themes/basic']`, then the themed version
for a view file `/web/views/site/index.php` will be `/web/themes/basic/site/index.php`.
Using multiple paths
--------------------
It is possible to map a single path to multiple paths. For example,
```php
'pathMap' => [
'/web/views' => [
'/web/themes/christmas',
'/web/themes/basic',
],
]
```
In this case, the view will be searched in `/web/themes/christmas/site/index.php` then if it's not found it will check
`/web/themes/basic/site/index.php`. If there's no view there as well application view will be used.
This ability is especially useful if you want to temporary or conditionally override some views.
......@@ -329,9 +329,9 @@ public function behaviors()
'class' => 'yii\web\AccessControl',
'rules' => [
['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
),
),
);
],
],
];
}
```
......
{
"name": "yiisoft/yii2-apidoc",
"description": "API Documentation generator for the Yii framework 2.0",
"keywords": ["yii", "phpdoc", "apidoc", "api", "documentation"],
"keywords": ["yii2", "phpdoc", "apidoc", "api", "documentation"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
......@@ -18,7 +18,7 @@ ArrayHelper::multisort($events, 'name');
<h2>Event Details</h2>
<?php foreach($events as $event): ?>
<div class="detailHeader h3" id="<?= $event->name.'-detail' ?>">
<?php echo $event->name; ?>
<?= $event->name ?>
<span class="detailHeaderTag small">
event
<?php if(!empty($event->since)): ?>
......
......@@ -36,11 +36,11 @@ ArrayHelper::multisort($events, 'name');
<td>
<?= ApiMarkdown::process($event->shortDescription, $event->definedBy, true) ?>
<?php if(!empty($event->since)): ?>
(available since version <?php echo $event->since; ?>)
(available since version <?= $event->since ?>)
<?php endif; ?>
</td>
<td><?= $this->context->typeLink($event->definedBy) ?></td>
</tr>
<?php endforeach; ?>
</table>
</div>
\ No newline at end of file
</div>
......@@ -21,7 +21,7 @@ ArrayHelper::multisort($properties, 'name');
<?php foreach($properties as $property): ?>
<div class="detailHeader h3" id="<?= $property->name.'-detail' ?>">
<?php echo $property->name; ?>
<?= $property->name ?>
<span class="detailHeaderTag small">
<?= $property->visibility ?>
<?php if($property->getIsReadOnly()) echo ' <em>read-only</em> '; ?>
......@@ -33,7 +33,7 @@ ArrayHelper::multisort($properties, 'name');
</span>
</div>
<div class="signature"><?php echo $this->context->renderPropertySignature($property); ?></div>
<div class="signature"><?= $this->context->renderPropertySignature($property) ?></div>
<?= ApiMarkdown::process($property->description, $type) ?>
......
{
"name": "yiisoft/yii2-authclient",
"description": "External authentication via OAuth and OpenID for the Yii framework",
"keywords": ["yii", "OAuth", "OpenID", "auth"],
"keywords": ["yii2", "OAuth", "OpenID", "auth"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-bootstrap",
"description": "The Twitter Bootstrap extension for the Yii framework",
"keywords": ["yii", "bootstrap"],
"keywords": ["yii2", "bootstrap"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-codeception",
"description": "The Codeception integration for the Yii framework",
"keywords": ["yii", "codeception"],
"keywords": ["yii2", "codeception"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-composer",
"description": "The composer plugin for Yii extension installer",
"keywords": ["yii", "composer", "extension installer"],
"keywords": ["yii2", "composer", "extension installer"],
"type": "composer-plugin",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-debug",
"description": "The debugger extension for the Yii framework",
"keywords": ["yii", "debug", "debugger"],
"keywords": ["yii2", "debug", "debugger"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
<?php
use yii\helpers\Html;
/**
* @var yii\debug\panels\ConfigPanel $panel
*/
......
<?php
use yii\helpers\Html;
/**
* @var yii\debug\panels\ConfigPanel $panel
*/
......
<?php if ($queryCount): ?>
<div class="yii-debug-toolbar-block">
<a href="<?= $panel->getUrl() ?>" title="Executed <?php echo $queryCount; ?> database queries which took <?= $queryTime ?>.">
<a href="<?= $panel->getUrl() ?>" title="Executed <?= $queryCount ?> database queries which took <?= $queryTime ?>.">
DB <span class="label label-info"><?= $queryCount ?></span> <span class="label"><?= $queryTime ?></span>
</a>
</div>
......
{
"name": "yiisoft/yii2-elasticsearch",
"description": "Elasticsearch integration and ActiveRecord for the Yii framework",
"keywords": ["yii", "elasticsearch", "active-record", "search", "fulltext"],
"keywords": ["yii2", "elasticsearch", "active-record", "search", "fulltext"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-faker",
"description": "Fixture generator. The Faker integration for the Yii framework.",
"keywords": ["yii", "faker", "fixture"],
"keywords": ["yii2", "faker", "fixture"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
......@@ -13,6 +13,8 @@ Yii Framework 2 gii extension Change Log
- Enh #1897: diff markup is now copy paste friendly (samdark)
- Enh #2327: better visual representation of changed files, added header and refresh button to diff modal (thiagotalma)
- Enh #2491: Added support for using the same base class name of search model and data model in Gii (qiangxue)
- Enh #2595: Browse through all generated files using right and left arrows (thiagotalma)
- Enh #2633: Keyboard shortcuts to browse through files (thiagotalma)
2.0.0 alpha, December 1, 2013
-----------------------------
......
......@@ -35,10 +35,13 @@ yii.gii = (function ($) {
};
var initPreviewDiffLinks = function () {
$('.preview-code, .diff-code, .modal-refresh').on('click', function () {
$('.preview-code, .diff-code, .modal-refresh, .modal-previous, .modal-next').on('click', function () {
var $modal = $('#preview-modal');
var $link = $(this);
$modal.find('.modal-refresh').attr('href', $link.prop('href'));
$modal.find('.modal-refresh').attr('href', $link.attr('href'));
if ($link.hasClass('preview-code') || $link.hasClass('diff-code')) {
$modal.data('action', ($link.hasClass('preview-code') ? 'preview-code' : 'diff-code'))
}
$modal.find('.modal-title').text($link.data('title'));
$modal.find('.modal-body').html('Loading ...');
$modal.modal('show');
......@@ -48,6 +51,15 @@ yii.gii = (function ($) {
url: $link.prop('href'),
data: $('.default-view form').serializeArray(),
success: function (data) {
if (!$link.hasClass('modal-refresh')) {
var filesSelector = 'a.' + $modal.data('action');
var $files = $(filesSelector);
var index = $files.filter('[href="' + $link.attr('href') + '"]').index(filesSelector);
var $prev = $files.eq(index-1);
var $next = $files.eq((index+1 == $files.length ? 0 : index+1));
$modal.find('.modal-previous').attr('href', $prev.attr('href')).data('title', $prev.data('title'));
$modal.find('.modal-next').attr('href', $next.attr('href')).data('title', $next.data('title'));
}
$modal.find('.modal-body').html(data);
$modal.find('.content').css('max-height', ($(window).height() - 200) + 'px');
},
......@@ -57,6 +69,16 @@ yii.gii = (function ($) {
});
return false;
});
$('#preview-modal').on('keydown', function(e) {
if (e.keyCode === 37) {
$('.modal-previous').trigger('click');
} else if(e.keyCode === 39) {
$('.modal-next').trigger('click');
} else if(e.keyCode === 82) {
$('.modal-refresh').trigger('click');
}
});
};
var initConfirmationCheckboxes = function () {
......
{
"name": "yiisoft/yii2-gii",
"description": "The Gii extension for the Yii framework",
"keywords": ["yii", "gii", "code generator"],
"keywords": ["yii2", "gii", "code generator"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
......@@ -18,5 +18,5 @@ echo "<?php\n";
<p>
You may change the content of this page by modifying
the file <code><?= '<?php' ?> echo __FILE__; ?></code>.
the file <code><?= '<?=' ?> __FILE__; ?></code>.
</p>
......@@ -26,8 +26,8 @@ $this->params['breadcrumbs'][] = $this->title;
<h1><?= "<?= " ?>Html::encode($this->title) ?></h1>
<?= "<?php " ?>echo $this->render('_form', [
<?= "<?= " ?>$this->render('_form', [
'model' => $model,
]); ?>
]) ?>
</div>
......@@ -37,7 +37,7 @@ $this->params['breadcrumbs'][] = $this->title;
</p>
<?php if ($generator->indexWidgetType === 'grid'): ?>
<?= "<?php " ?>echo GridView::widget([
<?= "<?= " ?>GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
......@@ -69,13 +69,13 @@ if (($tableSchema = $generator->getTableSchema()) === false) {
],
]); ?>
<?php else: ?>
<?= "<?php " ?>echo ListView::widget([
<?= "<?= " ?>ListView::widget([
'dataProvider' => $dataProvider,
'itemOptions' => ['class' => 'item'],
'itemView' => function ($model, $key, $index, $widget) {
return Html::a(Html::encode($model-><?= $nameAttribute ?>), ['view', <?= $urlParams ?>]);
},
]); ?>
]) ?>
<?php endif; ?>
</div>
......@@ -29,8 +29,8 @@ $this->params['breadcrumbs'][] = 'Update';
<h1><?= "<?= " ?>Html::encode($this->title) ?></h1>
<?= "<?php " ?>echo $this->render('_form', [
<?= "<?= " ?>$this->render('_form', [
'model' => $model,
]); ?>
]) ?>
</div>
......@@ -31,16 +31,16 @@ $this->params['breadcrumbs'][] = $this->title;
<p>
<?= "<?= " ?>Html::a('Update', ['update', <?= $urlParams ?>], ['class' => 'btn btn-primary']) ?>
<?= "<?php " ?>echo Html::a('Delete', ['delete', <?= $urlParams ?>], [
<?= "<?= " ?>Html::a('Delete', ['delete', <?= $urlParams ?>], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => Yii::t('app', 'Are you sure to delete this item?'),
'method' => 'post',
],
]); ?>
]) ?>
</p>
<?= "<?php " ?>echo DetailView::widget([
<?= "<?= " ?>DetailView::widget([
'model' => $model,
'attributes' => [
<?php
......@@ -56,6 +56,6 @@ if (($tableSchema = $generator->getTableSchema()) === false) {
}
?>
],
]); ?>
]) ?>
</div>
......@@ -471,7 +471,7 @@ class Generator extends \yii\gii\Generator
*/
public function validateTableName()
{
if (($pos = strpos($this->tableName, '*')) !== false && substr($this->tableName, -1) !== '*') {
if (strpos($this->tableName, '*') !== false && substr($this->tableName, -1) !== '*') {
$this->addError('tableName', 'Asterisk is only allowed as the last character.');
return;
}
......
......@@ -81,7 +81,14 @@ use yii\gii\CodeFile;
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4><a class="modal-refresh glyphicon glyphicon-refresh" href="#"></a> <span class="modal-title">Modal title</span></h4>
<div class="btn-group pull-left">
<a class="modal-previous btn btn-xs btn-default" href="#" title="Previous File (Left Arrow)"><span class="glyphicon glyphicon-arrow-left"></span></a>
<a class="modal-next btn btn-xs btn-default" href="#" title="Next File (Right Arrow)"><span class="glyphicon glyphicon-arrow-right"></span></a>
<a class="modal-refresh btn btn-xs btn-default" href="#" title="Refresh File (R)"><span class="glyphicon glyphicon-refresh"></span></a>
&nbsp;
</div>
<strong class="modal-title pull-left">Modal title</strong>
<div class="clearfix"></div>
</div>
<div class="modal-body">
<p>Please wait ...</p>
......
{
"name": "yiisoft/yii2-imagine",
"description": "The Imagine integration for the Yii framework",
"keywords": ["yii", "imagine", "image", "helper"],
"keywords": ["yii2", "imagine", "image", "helper"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
{
"name": "yiisoft/yii2-jui",
"description": "The Jquery UI extension for the Yii framework",
"keywords": ["yii", "Jquery UI", "renderer"],
"keywords": ["yii2", "Jquery UI", "renderer"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
......@@ -260,7 +260,7 @@ class Collection extends Object
}
/**
* Returns a a single document.
* Returns a single document.
* @param array $condition query condition
* @param array $fields fields to be selected
* @return array|null the single document. Null is returned if the query results in nothing.
......@@ -272,6 +272,32 @@ class Collection extends Object
}
/**
* Updates a document and returns it.
* @param array $condition query condition
* @param array $update update criteria
* @param array $fields fields to be returned
* @param array $options list of options in format: optionName => optionValue.
* @return array|null the original document, or the modified document when $options['new'] is set.
* @throws Exception on failure.
* @see http://www.php.net/manual/en/mongocollection.findandmodify.php
*/
public function findAndModify($condition, $update, $fields = [], $options = [])
{
$condition = $this->buildCondition($condition);
$token = $this->composeLogToken('findAndModify', [$condition, $update, $fields, $options]);
Yii::info($token, __METHOD__);
try {
Yii::beginProfile($token, __METHOD__);
$result = $this->mongoCollection->findAndModify($condition, $update, $fields, $options);
Yii::endProfile($token, __METHOD__);
return $result;
} catch (\Exception $e) {
Yii::endProfile($token, __METHOD__);
throw new Exception($e->getMessage(), (int)$e->getCode(), $e);
}
}
/**
* Inserts new data into collection.
* @param array|object $data data to be inserted.
* @param array $options list of options in format: optionName => optionValue.
......
{
"name": "yiisoft/yii2-mongodb",
"description": "MongoDb extension for the Yii framework",
"keywords": ["yii", "mongo", "mongodb", "active-record"],
"keywords": ["yii2", "mongo", "mongodb", "active-record"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-redis",
"description": "Redis Cache, Session and ActiveRecord for the Yii framework",
"keywords": ["yii", "redis", "active-record", "cache", "session"],
"keywords": ["yii2", "redis", "active-record", "cache", "session"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-smarty",
"description": "The Smarty integration for the Yii framework",
"keywords": ["yii", "smarty", "renderer"],
"keywords": ["yii2", "smarty", "renderer"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-sphinx",
"description": "Sphinx full text search engine extension for the Yii framework",
"keywords": ["yii", "sphinx", "active-record", "search", "fulltext"],
"keywords": ["yii2", "sphinx", "active-record", "search", "fulltext"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
......@@ -19,7 +19,7 @@ use yii\mail\BaseMailer;
* ~~~
* 'components' => [
* ...
* 'email' => [
* 'mail' => [
* 'class' => 'yii\swiftmailer\Mailer',
* 'transport' => [
* 'class' => 'Swift_SmtpTransport',
......
{
"name": "yiisoft/yii2-swiftmailer",
"description": "The SwiftMailer integration for the Yii framework",
"keywords": ["yii", "swift", "swiftmailer", "mail", "email", "mailer"],
"keywords": ["yii2", "swift", "swiftmailer", "mail", "email", "mailer"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
{
"name": "yiisoft/yii2-twig",
"description": "The Twig integration for the Yii framework",
"keywords": ["yii", "twig", "renderer"],
"keywords": ["yii2", "twig", "renderer"],
"type": "yii2-extension",
"license": "BSD-3-Clause",
"support": {
......
......@@ -356,7 +356,7 @@ class BaseYii
$config = array_merge(static::$objectConfig[$class], $config);
}
if (($n = func_num_args()) > 1) {
if (func_num_args() > 1) {
/** @var \ReflectionClass $reflection */
if (isset($reflections[$class])) {
$reflection = $reflections[$class];
......
......@@ -49,6 +49,9 @@ Yii Framework 2 Change Log
- Bug #2502: Unclear error message when `$_SERVER['DOCUMENT_ROOT']` is empty (samdark)
- Bug #2519: MessageSource removed translation messages when event handler was bound to `missingTranslation`-event (cebe)
- Bug #2527: Source language for `app` message category was always `en` no matter which application `sourceLanguage` was used (samdark)
- Bug #2559: Going back on browser history breaks GridView filtering with `Pjax` (tonydspaniard)
- Bug #2607: `yii message` tool wasn't updating `message` table (mitalcoi)
- Bug #2624: Html::textArea() should respect "name" option. (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 incorrect event name for `yii\jui\Spinner` (samdark)
- Bug: Json::encode() did not handle objects that implement JsonSerializable interface correctly (cebe)
......@@ -68,6 +71,7 @@ Yii Framework 2 Change Log
- Enh #1293: Replaced Console::showProgress() with a better approach. See Console::startProgress() for details (cebe)
- Enh #1406: DB Schema support for Oracle Database (p0larbeer, qiangxue)
- Enh #1437: Added ListView::viewParams (qiangxue)
- Enh #1467: Added support for organizing controllers in subdirectories (qiangxue)
- Enh #1469: ActiveRecord::find() now works with default conditions (default scope) applied by createQuery (cebe)
- Enh #1476: Add yii\web\Session::handler property (nineinchnick)
- Enh #1499: Added `ActionColumn::controller` property to support customizing the controller for handling GridView actions (qiangxue)
......
Copyright (c) Chris Wanstrath
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Software), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
// jquery.pjax.js
// copyright chris wanstrath
// https://github.com/defunkt/jquery-pjax
(function($){
// When called on a container with a selector, fetches the href with
// ajax into the container or with the data-pjax attribute on the link
// itself.
//
// Tries to make sure the back button and ctrl+click work the way
// you'd expect.
//
// Exported as $.fn.pjax
//
// Accepts a jQuery ajax options object that may include these
// pjax specific options:
//
//
// container - Where to stick the response body. Usually a String selector.
// $(container).html(xhr.responseBody)
// (default: current jquery context)
// push - Whether to pushState the URL. Defaults to true (of course).
// replace - Want to use replaceState instead? That's cool.
//
// For convenience the second parameter can be either the container or
// the options object.
//
// Returns the jQuery object
function fnPjax(selector, container, options) {
var context = this
return this.on('click.pjax', selector, function(event) {
var opts = $.extend({}, optionsFor(container, options))
if (!opts.container)
opts.container = $(this).attr('data-pjax') || context
handleClick(event, opts)
})
}
// Public: pjax on click handler
//
// Exported as $.pjax.click.
//
// event - "click" jQuery.Event
// options - pjax options
//
// Examples
//
// $(document).on('click', 'a', $.pjax.click)
// // is the same as
// $(document).pjax('a')
//
// $(document).on('click', 'a', function(event) {
// var container = $(this).closest('[data-pjax-container]')
// $.pjax.click(event, container)
// })
//
// Returns nothing.
function handleClick(event, container, options) {
options = optionsFor(container, options)
var link = event.currentTarget
if (link.tagName.toUpperCase() !== 'A')
throw "$.fn.pjax or $.pjax.click requires an anchor element"
// Middle click, cmd click, and ctrl click should open
// links in a new tab as normal.
if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
return
// Ignore cross origin links
if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
return
// Ignore anchors on the same page
if (link.hash && link.href.replace(link.hash, '') ===
location.href.replace(location.hash, ''))
return
// Ignore empty anchor "foo.html#"
if (link.href === location.href + '#')
return
var defaults = {
url: link.href,
container: $(link).attr('data-pjax'),
target: link
}
var opts = $.extend({}, defaults, options)
var clickEvent = $.Event('pjax:click')
$(link).trigger(clickEvent, [opts])
if (!clickEvent.isDefaultPrevented()) {
pjax(opts)
event.preventDefault()
$(link).trigger('pjax:clicked', [opts])
}
}
// Public: pjax on form submit handler
//
// Exported as $.pjax.submit
//
// event - "click" jQuery.Event
// options - pjax options
//
// Examples
//
// $(document).on('submit', 'form', function(event) {
// var container = $(this).closest('[data-pjax-container]')
// $.pjax.submit(event, container)
// })
//
// Returns nothing.
function handleSubmit(event, container, options) {
options = optionsFor(container, options)
var form = event.currentTarget
if (form.tagName.toUpperCase() !== 'FORM')
throw "$.pjax.submit requires a form element"
var defaults = {
type: form.method.toUpperCase(),
url: form.action,
data: $(form).serializeArray(),
container: $(form).attr('data-pjax'),
target: form
}
pjax($.extend({}, defaults, options))
event.preventDefault()
}
// Loads a URL with ajax, puts the response body inside a container,
// then pushState()'s the loaded URL.
//
// Works just like $.ajax in that it accepts a jQuery ajax
// settings object (with keys like url, type, data, etc).
//
// Accepts these extra keys:
//
// container - Where to stick the response body.
// $(container).html(xhr.responseBody)
// push - Whether to pushState the URL. Defaults to true (of course).
// replace - Want to use replaceState instead? That's cool.
//
// Use it just like $.ajax:
//
// var xhr = $.pjax({ url: this.href, container: '#main' })
// console.log( xhr.readyState )
//
// Returns whatever $.ajax returns.
function pjax(options) {
options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
if ($.isFunction(options.url)) {
options.url = options.url()
}
var target = options.target
var hash = parseURL(options.url).hash
var context = options.context = findContainerFor(options.container)
// We want the browser to maintain two separate internal caches: one
// for pjax'd partial page loads and one for normal page loads.
// Without adding this secret parameter, some browsers will often
// confuse the two.
if (!options.data) options.data = {}
options.data._pjax = context.selector
function fire(type, args) {
var event = $.Event(type, { relatedTarget: target })
context.trigger(event, args)
return !event.isDefaultPrevented()
}
var timeoutTimer
options.beforeSend = function(xhr, settings) {
// No timeout for non-GET requests
// Its not safe to request the resource again with a fallback method.
if (settings.type !== 'GET') {
settings.timeout = 0
}
xhr.setRequestHeader('X-PJAX', 'true')
xhr.setRequestHeader('X-PJAX-Container', context.selector)
if (!fire('pjax:beforeSend', [xhr, settings]))
return false
if (settings.timeout > 0) {
timeoutTimer = setTimeout(function() {
if (fire('pjax:timeout', [xhr, options]))
xhr.abort('timeout')
}, settings.timeout)
// Clear timeout setting so jquerys internal timeout isn't invoked
settings.timeout = 0
}
options.requestUrl = parseURL(settings.url).href
}
options.complete = function(xhr, textStatus) {
if (timeoutTimer)
clearTimeout(timeoutTimer)
fire('pjax:complete', [xhr, textStatus, options])
fire('pjax:end', [xhr, options])
}
options.error = function(xhr, textStatus, errorThrown) {
var container = extractContainer("", xhr, options)
var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
locationReplace(container.url)
}
}
options.success = function(data, status, xhr) {
// If $.pjax.defaults.version is a function, invoke it first.
// Otherwise it can be a static string.
var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
$.pjax.defaults.version() :
$.pjax.defaults.version
var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
var container = extractContainer(data, xhr, options)
// If there is a layout version mismatch, hard load the new url
if (currentVersion && latestVersion && currentVersion !== latestVersion) {
locationReplace(container.url)
return
}
// If the new response is missing a body, hard load the page
if (!container.contents) {
locationReplace(container.url)
return
}
pjax.state = {
id: options.id || uniqueId(),
url: container.url,
title: container.title,
container: context.selector,
fragment: options.fragment,
timeout: options.timeout
}
if (options.push || options.replace) {
window.history.replaceState(pjax.state, container.title, container.url)
}
// Clear out any focused controls before inserting new page contents.
document.activeElement.blur()
if (container.title) document.title = container.title
context.html(container.contents)
// FF bug: Won't autofocus fields that are inserted via JS.
// This behavior is incorrect. So if theres no current focus, autofocus
// the last field.
//
// http://www.w3.org/html/wg/drafts/html/master/forms.html
var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
if (autofocusEl && document.activeElement !== autofocusEl) {
autofocusEl.focus();
}
executeScriptTags(container.scripts)
// Scroll to top by default
if (typeof options.scrollTo === 'number')
$(window).scrollTop(options.scrollTo)
// If the URL has a hash in it, make sure the browser
// knows to navigate to the hash.
if ( hash !== '' ) {
// Avoid using simple hash set here. Will add another history
// entry. Replace the url with replaceState and scroll to target
// by hand.
//
// window.location.hash = hash
var url = parseURL(container.url)
url.hash = hash
pjax.state.url = url.href
window.history.replaceState(pjax.state, container.title, url.href)
var target = $(url.hash)
if (target.length) $(window).scrollTop(target.offset().top)
}
fire('pjax:success', [data, status, xhr, options])
}
// Initialize pjax.state for the initial page load. Assume we're
// using the container and options of the link we're loading for the
// back button to the initial page. This ensures good back button
// behavior.
if (!pjax.state) {
pjax.state = {
id: uniqueId(),
url: window.location.href,
title: document.title,
container: context.selector,
fragment: options.fragment,
timeout: options.timeout
}
window.history.replaceState(pjax.state, document.title)
}
// Cancel the current request if we're already pjaxing
var xhr = pjax.xhr
if ( xhr && xhr.readyState < 4) {
xhr.onreadystatechange = $.noop
xhr.abort()
}
pjax.options = options
var xhr = pjax.xhr = $.ajax(options)
if (xhr.readyState > 0) {
if (options.push && !options.replace) {
// Cache current container element before replacing it
cachePush(pjax.state.id, context.clone().contents())
window.history.pushState(null, "", stripPjaxParam(options.requestUrl))
}
fire('pjax:start', [xhr, options])
fire('pjax:send', [xhr, options])
}
return pjax.xhr
}
// Public: Reload current page with pjax.
//
// Returns whatever $.pjax returns.
function pjaxReload(container, options) {
var defaults = {
url: window.location.href,
push: false,
replace: true,
scrollTo: false
}
return pjax($.extend(defaults, optionsFor(container, options)))
}
// Internal: Hard replace current state with url.
//
// Work for around WebKit
// https://bugs.webkit.org/show_bug.cgi?id=93506
//
// Returns nothing.
function locationReplace(url) {
window.history.replaceState(null, "", "#")
window.location.replace(url)
}
var initialPop = true
var initialURL = window.location.href
var initialState = window.history.state
// Initialize $.pjax.state if possible
// Happens when reloading a page and coming forward from a different
// session history.
if (initialState && initialState.container) {
pjax.state = initialState
}
// Non-webkit browsers don't fire an initial popstate event
if ('state' in window.history) {
initialPop = false
}
// popstate handler takes care of the back and forward buttons
//
// You probably shouldn't use pjax on pages with other pushState
// stuff yet.
function onPjaxPopstate(event) {
var state = event.state
if (state && state.container) {
// When coming forward from a separate history session, will get an
// initial pop with a state we are already at. Skip reloading the current
// page.
if (initialPop && initialURL == state.url) return
// If popping back to the same state, just skip.
// Could be clicking back from hashchange rather than a pushState.
if (pjax.state.id === state.id) return
var container = $(state.container)
if (container.length) {
var direction, contents = cacheMapping[state.id]
if (pjax.state) {
// Since state ids always increase, we can deduce the history
// direction from the previous state.
direction = pjax.state.id < state.id ? 'forward' : 'back'
// Cache current container before replacement and inform the
// cache which direction the history shifted.
cachePop(direction, pjax.state.id, container.clone().contents())
}
var popstateEvent = $.Event('pjax:popstate', {
state: state,
direction: direction
})
container.trigger(popstateEvent)
var options = {
id: state.id,
url: state.url,
container: container,
push: false,
fragment: state.fragment,
timeout: state.timeout,
scrollTo: false
}
if (contents) {
container.trigger('pjax:start', [null, options])
if (state.title) document.title = state.title
container.html(contents)
pjax.state = state
container.trigger('pjax:end', [null, options])
} else {
pjax(options)
}
// Force reflow/relayout before the browser tries to restore the
// scroll position.
container[0].offsetHeight
} else {
locationReplace(location.href)
}
}
initialPop = false
}
// Fallback version of main pjax function for browsers that don't
// support pushState.
//
// Returns nothing since it retriggers a hard form submission.
function fallbackPjax(options) {
var url = $.isFunction(options.url) ? options.url() : options.url,
method = options.type ? options.type.toUpperCase() : 'GET'
var form = $('<form>', {
method: method === 'GET' ? 'GET' : 'POST',
action: url,
style: 'display:none'
})
if (method !== 'GET' && method !== 'POST') {
form.append($('<input>', {
type: 'hidden',
name: '_method',
value: method.toLowerCase()
}))
}
var data = options.data
if (typeof data === 'string') {
$.each(data.split('&'), function(index, value) {
var pair = value.split('=')
form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
})
} else if (typeof data === 'object') {
for (key in data)
form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
}
$(document.body).append(form)
form.submit()
}
// Internal: Generate unique id for state object.
//
// Use a timestamp instead of a counter since ids should still be
// unique across page loads.
//
// Returns Number.
function uniqueId() {
return (new Date).getTime()
}
// Internal: Strips _pjax param from url
//
// url - String
//
// Returns String.
function stripPjaxParam(url) {
return url
.replace(/\?_pjax=[^&]+&?/, '?')
.replace(/_pjax=[^&]+&?/, '')
.replace(/[\?&]$/, '')
}
// Internal: Parse URL components and returns a Locationish object.
//
// url - String URL
//
// Returns HTMLAnchorElement that acts like Location.
function parseURL(url) {
var a = document.createElement('a')
a.href = url
return a
}
// Internal: Build options Object for arguments.
//
// For convenience the first parameter can be either the container or
// the options object.
//
// Examples
//
// optionsFor('#container')
// // => {container: '#container'}
//
// optionsFor('#container', {push: true})
// // => {container: '#container', push: true}
//
// optionsFor({container: '#container', push: true})
// // => {container: '#container', push: true}
//
// Returns options Object.
function optionsFor(container, options) {
// Both container and options
if ( container && options )
options.container = container
// First argument is options Object
else if ( $.isPlainObject(container) )
options = container
// Only container
else
options = {container: container}
// Find and validate container
if (options.container)
options.container = findContainerFor(options.container)
return options
}
// Internal: Find container element for a variety of inputs.
//
// Because we can't persist elements using the history API, we must be
// able to find a String selector that will consistently find the Element.
//
// container - A selector String, jQuery object, or DOM Element.
//
// Returns a jQuery object whose context is `document` and has a selector.
function findContainerFor(container) {
container = $(container)
if ( !container.length ) {
throw "no pjax container for " + container.selector
} else if ( container.selector !== '' && container.context === document ) {
return container
} else if ( container.attr('id') ) {
return $('#' + container.attr('id'))
} else {
throw "cant get selector for pjax container!"
}
}
// Internal: Filter and find all elements matching the selector.
//
// Where $.fn.find only matches descendants, findAll will test all the
// top level elements in the jQuery object as well.
//
// elems - jQuery object of Elements
// selector - String selector to match
//
// Returns a jQuery object.
function findAll(elems, selector) {
return elems.filter(selector).add(elems.find(selector));
}
function parseHTML(html) {
return $.parseHTML(html, document, true)
}
// Internal: Extracts container and metadata from response.
//
// 1. Extracts X-PJAX-URL header if set
// 2. Extracts inline <title> tags
// 3. Builds response Element and extracts fragment if set
//
// data - String response data
// xhr - XHR response
// options - pjax options Object
//
// Returns an Object with url, title, and contents keys.
function extractContainer(data, xhr, options) {
var obj = {}
// Prefer X-PJAX-URL header if it was set, otherwise fallback to
// using the original requested url.
obj.url = stripPjaxParam(xhr.getResponseHeader('X-PJAX-URL') || options.requestUrl)
// Attempt to parse response html into elements
if (/<html/i.test(data)) {
var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]))
var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
} else {
var $head = $body = $(parseHTML(data))
}
// If response data is empty, return fast
if ($body.length === 0)
return obj
// If there's a <title> tag in the header, use it as
// the page's title.
obj.title = findAll($head, 'title').last().text()
if (options.fragment) {
// If they specified a fragment, look for it in the response
// and pull it out.
if (options.fragment === 'body') {
var $fragment = $body
} else {
var $fragment = findAll($body, options.fragment).first()
}
if ($fragment.length) {
obj.contents = $fragment.contents()
// If there's no title, look for data-title and title attributes
// on the fragment
if (!obj.title)
obj.title = $fragment.attr('title') || $fragment.data('title')
}
} else if (!/<html/i.test(data)) {
obj.contents = $body
}
// Clean up any <title> tags
if (obj.contents) {
// Remove any parent title elements
obj.contents = obj.contents.not(function() { return $(this).is('title') })
// Then scrub any titles from their descendants
obj.contents.find('title').remove()
// Gather all script[src] elements
obj.scripts = findAll(obj.contents, 'script[src]').remove()
obj.contents = obj.contents.not(obj.scripts)
}
// Trim any whitespace off the title
if (obj.title) obj.title = $.trim(obj.title)
return obj
}
// Load an execute scripts using standard script request.
//
// Avoids jQuery's traditional $.getScript which does a XHR request and
// globalEval.
//
// scripts - jQuery object of script Elements
//
// Returns nothing.
function executeScriptTags(scripts) {
if (!scripts) return
var existingScripts = $('script[src]')
scripts.each(function() {
var src = this.src
var matchedScripts = existingScripts.filter(function() {
return this.src === src
})
if (matchedScripts.length) return
var script = document.createElement('script')
script.type = $(this).attr('type')
script.src = $(this).attr('src')
document.head.appendChild(script)
})
}
// Internal: History DOM caching class.
var cacheMapping = {}
var cacheForwardStack = []
var cacheBackStack = []
// Push previous state id and container contents into the history
// cache. Should be called in conjunction with `pushState` to save the
// previous container contents.
//
// id - State ID Number
// value - DOM Element to cache
//
// Returns nothing.
function cachePush(id, value) {
cacheMapping[id] = value
cacheBackStack.push(id)
// Remove all entires in forward history stack after pushing
// a new page.
while (cacheForwardStack.length)
delete cacheMapping[cacheForwardStack.shift()]
// Trim back history stack to max cache length.
while (cacheBackStack.length > pjax.defaults.maxCacheLength)
delete cacheMapping[cacheBackStack.shift()]
}
// Shifts cache from directional history cache. Should be
// called on `popstate` with the previous state id and container
// contents.
//
// direction - "forward" or "back" String
// id - State ID Number
// value - DOM Element to cache
//
// Returns nothing.
function cachePop(direction, id, value) {
var pushStack, popStack
cacheMapping[id] = value
if (direction === 'forward') {
pushStack = cacheBackStack
popStack = cacheForwardStack
} else {
pushStack = cacheForwardStack
popStack = cacheBackStack
}
pushStack.push(id)
if (id = popStack.pop())
delete cacheMapping[id]
}
// Public: Find version identifier for the initial page load.
//
// Returns String version or undefined.
function findVersion() {
return $('meta').filter(function() {
var name = $(this).attr('http-equiv')
return name && name.toUpperCase() === 'X-PJAX-VERSION'
}).attr('content')
}
// Install pjax functions on $.pjax to enable pushState behavior.
//
// Does nothing if already enabled.
//
// Examples
//
// $.pjax.enable()
//
// Returns nothing.
function enable() {
$.fn.pjax = fnPjax
$.pjax = pjax
$.pjax.enable = $.noop
$.pjax.disable = disable
$.pjax.click = handleClick
$.pjax.submit = handleSubmit
$.pjax.reload = pjaxReload
$.pjax.defaults = {
timeout: 650,
push: true,
replace: false,
type: 'GET',
dataType: 'html',
scrollTo: 0,
maxCacheLength: 20,
version: findVersion
}
$(window).on('popstate.pjax', onPjaxPopstate)
}
// Disable pushState behavior.
//
// This is the case when a browser doesn't support pushState. It is
// sometimes useful to disable pushState for debugging on a modern
// browser.
//
// Examples
//
// $.pjax.disable()
//
// Returns nothing.
function disable() {
$.fn.pjax = function() { return this }
$.pjax = fallbackPjax
$.pjax.enable = enable
$.pjax.disable = $.noop
$.pjax.click = $.noop
$.pjax.submit = $.noop
$.pjax.reload = function() { window.location.reload() }
$(window).off('popstate.pjax', onPjaxPopstate)
}
// Add the state property to jQuery's event object so we can use it in
// $(window).bind('popstate')
if ( $.inArray('state', $.event.props) < 0 )
$.event.props.push('state')
// Is pjax supported by this browser?
$.support.pjax =
window.history && window.history.pushState && window.history.replaceState &&
// pushState isn't reliable on iOS until 5.
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)
$.support.pjax ? enable() : disable()
})(jQuery);
......@@ -26,17 +26,18 @@
filterSelector: undefined
};
var gridData = {};
var methods = {
init: function (options) {
return this.each(function () {
var $e = $(this);
var settings = $.extend({}, defaults, options || {});
$e.data('yiiGridView', {
settings: settings
});
gridData[$e.prop('id')] = {settings: settings};
var enterPressed = false;
$(settings.filterSelector).on('change.yiiGridView keydown.yiiGridView', function (event) {
$(document).off('change.yiiGridView keydown.yiiGridView', settings.filterSelector)
.on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) {
if (event.type === 'keydown') {
if (event.keyCode !== 13) {
return; // only react to enter key
......@@ -60,7 +61,7 @@
applyFilter: function () {
var $grid = $(this);
var settings = $grid.data('yiiGridView').settings;
var settings = gridData[$grid.prop('id')].settings;
var data = {};
$.each($(settings.filterSelector).serializeArray(), function () {
data[this.name] = this.value;
......@@ -85,15 +86,16 @@
setSelectionColumn: function (options) {
var $grid = $(this);
var data = $grid.data('yiiGridView');
data.selectionColumn = options.name;
var id = $(this).prop('id');
gridData[id].selectionColumn = options.name;
if (!options.multiple) {
return;
}
$grid.on('click.yiiGridView', "input[name='" + options.checkAll + "']", function () {
var inputs = "#" + id + " input[name='" + options.checkAll + "']";
$(document).off('click.yiiGridView', inputs).on('click.yiiGridView', inputs, function () {
$grid.find("input[name='" + options.name + "']:enabled").prop('checked', this.checked);
});
$grid.on('click.yiiGridView', "input[name='" + options.name + "']:enabled", function () {
$(document).off('click.yiiGridView', inputs + ":enabled").on('click.yiiGridView', inputs + ":enabled", function () {
var all = $grid.find("input[name='" + options.name + "']").length == $grid.find("input[name='" + options.name + "']:checked").length;
$grid.find("input[name='" + options.checkAll + "']").prop('checked', all);
});
......@@ -101,7 +103,7 @@
getSelectedRows: function () {
var $grid = $(this);
var data = $grid.data('yiiGridView');
var data = gridData[$grid.prop('id')];
var keys = [];
if (data.selectionColumn) {
$grid.find("input[name='" + data.selectionColumn + "']:checked").each(function () {
......@@ -118,8 +120,9 @@
});
},
data: function() {
return this.data('yiiGridView');
data: function () {
var id = $(this).prop('id');
return gridData[id];
}
};
})(window.jQuery);
......
......@@ -442,17 +442,17 @@ class Formatter extends Component
switch($position) {
case 0:
return $verbose ? Yii::t('yii','{n, plural, =1{# byte} other{# bytes}}', $params) : Yii::t('yii', '{n} B', $params);
return $verbose ? Yii::t('yii', '{n, plural, =1{# byte} other{# bytes}}', $params) : Yii::t('yii', '{n} B', $params);
case 1:
return $verbose ? Yii::t('yii','{n, plural, =1{# kilobyte} other{# kilobytes}}', $params) : Yii::t('yii','{n} KB', $params);
return $verbose ? Yii::t('yii', '{n, plural, =1{# kilobyte} other{# kilobytes}}', $params) : Yii::t('yii', '{n} KB', $params);
case 2:
return $verbose ? Yii::t('yii','{n, plural, =1{# megabyte} other{# megabytes}}', $params) : Yii::t('yii','{n} MB', $params);
return $verbose ? Yii::t('yii', '{n, plural, =1{# megabyte} other{# megabytes}}', $params) : Yii::t('yii', '{n} MB', $params);
case 3:
return $verbose ? Yii::t('yii','{n, plural, =1{# gigabyte} other{# gigabytes}}', $params) : Yii::t('yii','{n} GB', $params);
return $verbose ? Yii::t('yii', '{n, plural, =1{# gigabyte} other{# gigabytes}}', $params) : Yii::t('yii', '{n} GB', $params);
case 4:
return $verbose ? Yii::t('yii','{n, plural, =1{# terabyte} other{# terabytes}}', $params) : Yii::t('yii','{n} TB', $params);
return $verbose ? Yii::t('yii', '{n, plural, =1{# terabyte} other{# terabytes}}', $params) : Yii::t('yii', '{n} TB', $params);
default:
return $verbose ? Yii::t('yii','{n, plural, =1{# petabyte} other{# petabytes}}', $params) : Yii::t('yii','{n} PB', $params);
return $verbose ? Yii::t('yii', '{n, plural, =1{# petabyte} other{# petabytes}}', $params) : Yii::t('yii', '{n} PB', $params);
}
}
}
......@@ -596,12 +596,21 @@ class Module extends Component
}
/**
* Creates a controller instance based on the controller ID.
* Creates a controller instance based on the given route.
*
* The controller is created within this module. The method first attempts to
* create the controller based on the [[controllerMap]] of the module. If not available,
* it will look for the controller class under the [[controllerPath]] and create an
* instance of it.
* The route should be relative to this module. The method implements the following algorithm
* to resolve the given route:
*
* 1. If the route is empty, use [[defaultRoute]];
* 2. If the first segment of the route is a valid module ID as declared in [[modules]],
* call the module's `createController()` with the rest part of the route;
* 3. If the first segment of the route is found in [[controllerMap]], create a controller
* based on the corresponding configuration found in [[controllerMap]];
* 4. The given route is in the format of `abc/def/xyz`. Try either `abc\DefController`
* or `abc\def\XyzController` class within the [[controllerNamespace|controller namespace]].
*
* If any of the above steps resolves into a controller, it is returned together with the rest
* part of the route which will be treated as the action ID. Otherwise, false will be returned.
*
* @param string $route the route consisting of module, controller and action IDs.
* @return array|boolean If the controller is created successfully, it will be returned together
......@@ -613,6 +622,13 @@ class Module extends Component
if ($route === '') {
$route = $this->defaultRoute;
}
// double slashes or leading/ending slashes may cause substr problem
$route = trim($route, '/');
if (strpos($route, '//') !== false) {
return false;
}
if (strpos($route, '/') !== false) {
list ($id, $route) = explode('/', $route, 2);
} else {
......@@ -620,29 +636,73 @@ class Module extends Component
$route = '';
}
// module and controller map take precedence
$module = $this->getModule($id);
if ($module !== null) {
return $module->createController($route);
}
if (isset($this->controllerMap[$id])) {
$controller = Yii::createObject($this->controllerMap[$id], $id, $this);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
$className = str_replace(' ', '', ucwords(str_replace('-', ' ', $id))) . 'Controller';
$classFile = $this->controllerPath . DIRECTORY_SEPARATOR . $className . '.php';
if (!is_file($classFile)) {
return false;
}
$className = ltrim($this->controllerNamespace . '\\' . $className, '\\');
Yii::$classMap[$className] = $classFile;
if (is_subclass_of($className, 'yii\base\Controller')) {
$controller = new $className($id, $this);
} elseif (YII_DEBUG) {
throw new InvalidConfigException("Controller class must extend from \\yii\\base\\Controller.");
}
return [$controller, $route];
}
if (($pos = strrpos($route, '/')) !== false) {
$id .= '/' . substr($route, 0, $pos);
$route = substr($route, $pos + 1);
}
$controller = $this->createControllerByID($id);
if ($controller === null && $route !== '') {
$controller = $this->createControllerByID($id . '/' . $route);
$route = '';
}
return $controller === null ? false : [$controller, $route];
}
/**
* Creates a controller based on the given controller ID.
*
* The controller ID is relative to this module. The controller class
* should be located under [[controllerPath]] and namespaced under [[controllerNamespace]].
*
* Note that this method does not check [[modules]] or [[controllerMap]].
*
* @param string $id the controller ID
* @return Controller the newly created controller instance, or null if the controller ID is invalid.
* @throws InvalidConfigException if the controller class and its file name do not match.
* This exception is only thrown when in debug mode.
*/
public function createControllerByID($id)
{
if (!preg_match('%^[a-z0-9\\-_/]+$%', $id)) {
return null;
}
return isset($controller) ? [$controller, $route] : false;
$pos = strrpos($id, '/');
if ($pos === false) {
$prefix = '';
$className = $id;
} else {
$prefix = substr($id, 0, $pos + 1);
$className = substr($id, $pos + 1);
}
$className = str_replace(' ', '', ucwords(str_replace('-', ' ', $className))) . 'Controller';
$classFile = $this->controllerPath . '/' . $prefix . $className . '.php';
$className = ltrim($this->controllerNamespace . '\\' . str_replace('/', '\\', $prefix) . $className, '\\');
if (strpos($className, '-') !== false || !is_file($classFile)) {
return null;
}
Yii::$classMap[$className] = $classFile;
if (is_subclass_of($className, 'yii\base\Controller')) {
return new $className($id, $this);
} elseif (YII_DEBUG) {
throw new InvalidConfigException("Controller class must extend from \\yii\\base\\Controller.");
} else {
return null;
}
}
/**
......
......@@ -6,6 +6,7 @@
*/
namespace yii\base;
use Yii;
/**
......
......@@ -13,7 +13,7 @@ use yii\helpers\FileHelper;
/**
* Theme represents an application theme.
*
* When [[View]] renders a view file, it will check the [[Application::theme|active theme]]
* When [[View]] renders a view file, it will check the [[View::theme|active theme]]
* to see if there is a themed version of the view file exists. If so, the themed version will be rendered instead.
*
* A theme is a directory consisting of view files which are meant to replace their non-themed counterparts.
......
......@@ -6,6 +6,7 @@
*/
namespace yii\caching;
use yii\base\InvalidConfigException;
/**
......
......@@ -6,6 +6,7 @@
*/
namespace yii\caching;
use yii\base\InvalidConfigException;
/**
......
{
"name": "yiisoft/yii2",
"description": "Yii PHP Framework Version 2",
"keywords": ["yii", "framework"],
"keywords": ["yii2", "framework"],
"homepage": "http://www.yiiframework.com/",
"type": "library",
"license": "BSD-3-Clause",
......@@ -54,6 +54,7 @@
"lib-pcre": "*",
"yiisoft/yii2-composer": "*",
"yiisoft/jquery": "~2.0 | ~1.10",
"yiisoft/jquery-pjax": "*",
"ezyang/htmlpurifier": "4.6.*",
"cebe/markdown": "0.9.*"
},
......
......@@ -64,7 +64,7 @@ class FixtureController extends Controller
public function globalOptions()
{
return array_merge(parent::globalOptions(), [
'namespace','globalFixtures'
'namespace', 'globalFixtures'
]);
}
......@@ -74,6 +74,7 @@ class FixtureController extends Controller
* whitespace between names. Note that if you are loading fixtures to storage, for example: database or nosql,
* storage will not be cleared, data will be appended to already existed.
* @param array $fixtures
* @param array $except
* @throws \yii\console\Exception
*/
public function actionLoad(array $fixtures, array $except = [])
......@@ -99,7 +100,7 @@ class FixtureController extends Controller
}
$filtered = array_diff($foundFixtures, $except);
$fixtures = $this->getFixturesConfig(array_merge($this->globalFixtures ,$filtered));
$fixtures = $this->getFixturesConfig(array_merge($this->globalFixtures, $filtered));
if (!$fixtures) {
throw new Exception('No fixtures were found in namespace: "' . $this->namespace . '"' . '');
......@@ -317,5 +318,4 @@ class FixtureController extends Controller
{
return Yii::getAlias('@' . str_replace('\\', '/', $this->namespace));
}
}
......@@ -134,11 +134,14 @@ class MessageController extends Controller
throw new Exception('The "db" option must refer to a valid database application component.');
}
$sourceMessageTable = isset($config['sourceMessageTable']) ? $config['sourceMessageTable'] : '{{%source_message}}';
$messageTable = isset($config['messageTable']) ? $config['messageTable'] : '{{%message}}';
$this->saveMessagesToDb(
$messages,
$db,
$sourceMessageTable,
$config['removeUnused']
$messageTable,
$config['removeUnused'],
$config['languages']
);
}
}
......@@ -149,9 +152,11 @@ class MessageController extends Controller
* @param array $messages
* @param \yii\db\Connection $db
* @param string $sourceMessageTable
* @param string $messageTable
* @param boolean $removeUnused
* @param array $languages
*/
protected function saveMessagesToDb($messages, $db, $sourceMessageTable, $removeUnused)
protected function saveMessagesToDb($messages, $db, $sourceMessageTable, $messageTable, $removeUnused, $languages)
{
$q = new \yii\db\Query;
$current = [];
......@@ -190,12 +195,17 @@ class MessageController extends Controller
echo "Inserting new messages...";
$savedFlag = false;
foreach ($new as $category => $msgs) {
foreach ($new as $category => $msgs) {
foreach ($msgs as $m) {
$savedFlag = true;
$db->createCommand()
->insert($sourceMessageTable, ['category' => $category, 'message' => $m])->execute();
->insert($sourceMessageTable, ['category' => $category, 'message' => $m])->execute();
$lastId = $db->getLastInsertID();
foreach ($languages as $language) {
$db->createCommand()
->insert($messageTable, ['id' => $lastId, 'language' => $language])->execute();
}
}
}
......@@ -207,15 +217,20 @@ class MessageController extends Controller
} else {
if ($removeUnused) {
$db->createCommand()
->delete($sourceMessageTable, ['in', 'id', $obsolete])->execute();
echo "deleted.\n";
->delete($sourceMessageTable, ['in', 'id', $obsolete])->execute();
echo "deleted.\n";
} else {
$last_id = $db->getLastInsertID();
$db->createCommand()
->update(
->update(
$sourceMessageTable,
['message' => new \yii\db\Expression("CONCAT('@@',message,'@@')")],
['in', 'id', $obsolete]
)->execute();
foreach ($languages as $language) {
$db->createCommand()
->insert($messageTable, ['id' => $last_id, 'language' => $language])->execute();
}
echo "updated.\n";
}
}
......@@ -268,7 +283,7 @@ class MessageController extends Controller
{
echo "Saving messages to $fileName...";
if (is_file($fileName)) {
if($format === 'po'){
if ($format === 'po') {
$translated = file_get_contents($fileName);
preg_match_all('/(?<=msgid ").*(?="\n(#*)msgstr)/', $translated, $keys);
preg_match_all('/(?<=msgstr ").*(?="\n\n)/', $translated, $values);
......@@ -285,7 +300,7 @@ class MessageController extends Controller
$merged = [];
$untranslated = [];
foreach ($messages as $message) {
if($format === 'po'){
if ($format === 'po') {
$message = preg_replace('/\"/', '\"', $message);
}
if (array_key_exists($message, $translated) && strlen($translated[$message]) > 0) {
......@@ -317,9 +332,9 @@ class MessageController extends Controller
if (false === $overwrite) {
$fileName .= '.merged';
}
if ($format === 'po'){
if ($format === 'po') {
$output = '';
foreach ($merged as $k => $v){
foreach ($merged as $k => $v) {
$k = preg_replace('/(\")|(\\\")/', "\\\"", $k);
$v = preg_replace('/(\")|(\\\")/', "\\\"", $v);
if (substr($v, 0, 2) === '@@' && substr($v, -2) === '@@') {
......@@ -338,7 +353,7 @@ class MessageController extends Controller
if ($format === 'po') {
$merged = '';
sort($messages);
foreach($messages as $message) {
foreach ($messages as $message) {
$message = preg_replace('/(\")|(\\\")/', '\\\"', $message);
$merged .= "msgid \"$message\"\n";
$merged .= "msgstr \"\"\n";
......
......@@ -120,7 +120,7 @@ class ActiveQuery extends Query implements ActiveQueryInterface
$this->findWith($this->with, $models);
}
if (!$this->asArray) {
foreach($models as $model) {
foreach ($models as $model) {
$model->afterFind();
}
}
......
......@@ -35,9 +35,6 @@ use yii\helpers\StringHelper;
*
* class Customer extends \yii\db\ActiveRecord
* {
* /**
* * @return string the name of the table associated with this ActiveRecord class.
* * /
* public static function tableName()
* {
* return 'tbl_customer';
......
......@@ -87,6 +87,13 @@ interface ActiveRecordInterface
public function getOldPrimaryKey($asArray = false);
/**
* Returns a value indicating whether the given set of attributes represents the primary key for this model
* @param array $keys the set of attributes to check
* @return boolean whether the given set of attributes represents the primary key for this model
*/
public static function isPrimaryKey($keys);
/**
* Creates an [[ActiveQueryInterface|ActiveQuery]] instance for query purpose.
*
* This method is usually ment to be used like this:
......
......@@ -288,7 +288,7 @@ trait ActiveRelationTrait
foreach ($primaryModels as $i => $primaryModel) {
if ($primaryModels[$i][$primaryName] instanceof ActiveRecordInterface) {
$primaryModels[$i][$primaryName]->populateRelation($name, $primaryModel);
} elseif (!empty($primaryModels[$i][$primaryName])) {
} elseif (!empty($primaryModels[$i][$primaryName])) {
$primaryModels[$i][$primaryName][$name] = $primaryModel;
}
}
......
......@@ -19,6 +19,8 @@ use yii\base\InvalidCallException;
/**
* ActiveRecord is the base class for classes representing relational data in terms of objects.
*
* See [[yii\db\ActiveRecord]] for a concrete implementation.
*
* @property array $dirtyAttributes The changed attribute values (name-value pairs). This property is
* read-only.
* @property boolean $isNewRecord Whether the record is new and should be inserted when calling [[save()]].
......@@ -342,7 +344,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
*/
public function hasOne($class, $link)
{
/** @var ActiveRecord $class */
/** @var ActiveRecordInterface $class */
return $class::createQuery([
'modelClass' => $class,
'primaryModel' => $this,
......@@ -383,7 +385,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
*/
public function hasMany($class, $link)
{
/** @var ActiveRecord $class */
/** @var ActiveRecordInterface $class */
return $class::createQuery([
'modelClass' => $class,
'primaryModel' => $this,
......@@ -396,7 +398,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* Populates the named relation with the related records.
* Note that this method does not check if the relation exists or not.
* @param string $name the relation name (case-sensitive)
* @param ActiveRecord|array|null $records the related records to be populated into the relation.
* @param ActiveRecordInterface|array|null $records the related records to be populated into the relation.
*/
public function populateRelation($name, $records)
{
......@@ -936,7 +938,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* Returns a value indicating whether the given active record is the same as the current one.
* The comparison is made by comparing the table names and the primary key values of the two active records.
* If one of the records [[isNewRecord|is new]] they are also considered not equal.
* @param ActiveRecord $record record to compare to
* @param ActiveRecordInterface $record record to compare to
* @return boolean whether the two active records refer to the same row in the same database table.
*/
public function equals($record)
......@@ -1104,7 +1106,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* Note that this method requires that the primary key value is not null.
*
* @param string $name the case sensitive name of the relationship
* @param ActiveRecord $model the model to be linked with the current one.
* @param ActiveRecordInterface $model the model to be linked with the current one.
* @param array $extraColumns additional column values to be saved into the pivot table.
* This parameter is only meaningful for a relationship involving a pivot table
* (i.e., a relation set with [[ActiveRelationTrait::via()]] or `[[ActiveQuery::viaTable()]]`.)
......@@ -1139,8 +1141,8 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
$columns[$k] = $v;
}
if (is_array($relation->via)) {
/** @var $viaClass ActiveRecord */
/** @var $record ActiveRecord */
/** @var $viaClass ActiveRecordInterface */
/** @var $record ActiveRecordInterface */
$record = new $viaClass();
foreach ($columns as $column => $value) {
$record->$column = $value;
......@@ -1191,7 +1193,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
* Otherwise, the foreign key will be set null and the model will be saved without validation.
*
* @param string $name the case sensitive name of the relationship.
* @param ActiveRecord $model the model to be unlinked from the current one.
* @param ActiveRecordInterface $model the model to be unlinked from the current one.
* @param boolean $delete whether to delete the model that contains the foreign key.
* If false, the model's foreign key will be set null and saved.
* If true, the model containing the foreign key will be deleted.
......@@ -1219,7 +1221,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
$columns[$b] = $model->$a;
}
if (is_array($relation->via)) {
/** @var $viaClass ActiveRecord */
/** @var $viaClass ActiveRecordInterface */
if ($delete) {
$viaClass::deleteAll($columns);
} else {
......@@ -1231,6 +1233,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
}
} else {
/** @var $viaTable string */
/** @var Command $command */
$command = static::getDb()->createCommand();
if ($delete) {
$command->delete($viaTable, $columns)->execute();
......@@ -1263,7 +1266,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
if (!$relation->multiple) {
unset($this->_related[$name]);
} elseif (isset($this->_related[$name])) {
/** @var ActiveRecord $b */
/** @var ActiveRecordInterface $b */
foreach ($this->_related[$name] as $a => $b) {
if ($model->getPrimaryKey() == $b->getPrimaryKey()) {
unset($this->_related[$name][$a]);
......
......@@ -108,6 +108,7 @@ class BatchQueryResult extends Object implements \Iterator
{
if ($this->_batch === null || !$this->each || $this->each && next($this->_batch) === false) {
$this->_batch = $this->fetchData();
reset($this->_batch);
}
if ($this->each) {
......
......@@ -599,7 +599,7 @@ class QueryBuilder extends \yii\base\Object
if (strpos($column, '(') === false) {
$column = $this->db->quoteColumnName($column);
}
$columns[$i] = "$column AS " . $this->db->quoteColumnName($i);;
$columns[$i] = "$column AS " . $this->db->quoteColumnName($i);
} elseif (strpos($column, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)([\w\-_\.]+)$/', $column, $matches)) {
$columns[$i] = $this->db->quoteColumnName($matches[1]) . ' AS ' . $this->db->quoteColumnName($matches[2]);
......
......@@ -242,7 +242,7 @@ EOD;
} elseif (strpos($dbType, 'NUMBER') !== false || strpos($dbType, 'INTEGER') !== false) {
if (strpos($dbType, '(') && preg_match('/\((.*)\)/', $dbType, $matches)) {
$values = explode(',', $matches[1]);
if (isset($values[1]) and (((int)$values[1]) > 0)) {
if (isset($values[1]) && (((int)$values[1]) > 0)) {
$column->type = 'double';
} else {
$column->type = 'integer';
......
......@@ -88,6 +88,7 @@ class ActionColumn extends Column
$this->buttons['view'] = function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', $url, [
'title' => Yii::t('yii', 'View'),
'data-pjax' => '0',
]);
};
}
......@@ -95,6 +96,7 @@ class ActionColumn extends Column
$this->buttons['update'] = function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('yii', 'Update'),
'data-pjax' => '0',
]);
};
}
......@@ -104,6 +106,7 @@ class ActionColumn extends Column
'title' => Yii::t('yii', 'Delete'),
'data-confirm' => Yii::t('yii', 'Are you sure to delete this item?'),
'data-method' => 'post',
'data-pjax' => '0',
]);
};
}
......
......@@ -152,7 +152,7 @@ class DataColumn extends Column
return parent::getDataCellContent($model, $key, $index);
}
return $value;
}
}
/**
* @inheritdoc
......
......@@ -147,6 +147,7 @@ class BaseFileHelper
* @param string $src the source directory
* @param string $dst the destination directory
* @param array $options options for directory copy. Valid options are:
* @throws \yii\base\InvalidParamException if unable to open directory
*
* - dirMode: integer, the permission to be set for newly copied directories. Defaults to 0775.
* - fileMode: integer, the permission to be set for newly copied files. Defaults to the current environment setting.
......@@ -280,14 +281,14 @@ class BaseFileHelper
$options['basePath'] = realpath($dir);
// this should also be done only once
if (isset($options['except'])) {
foreach($options['except'] as $key=>$value) {
foreach ($options['except'] as $key => $value) {
if (is_string($value)) {
$options['except'][$key] = static::parseExcludePattern($value);
}
}
}
if (isset($options['only'])) {
foreach($options['only'] as $key=>$value) {
foreach ($options['only'] as $key => $value) {
if (is_string($value)) {
$options['only'][$key] = static::parseExcludePattern($value);
}
......@@ -397,7 +398,7 @@ class BaseFileHelper
if ($pattern === $baseName) {
return true;
}
} else if ($flags & self::PATTERN_ENDSWITH) {
} elseif ($flags & self::PATTERN_ENDSWITH) {
/* "*literal" matching against "fooliteral" */
$n = StringHelper::byteLength($pattern);
if (StringHelper::byteSubstr($pattern, 1, $n) === StringHelper::byteSubstr($baseName, -$n, $n)) {
......@@ -472,7 +473,7 @@ class BaseFileHelper
*/
private static function lastExcludeMatchingFromList($basePath, $path, $excludes)
{
foreach(array_reverse($excludes) as $exclude) {
foreach (array_reverse($excludes) as $exclude) {
if (is_string($exclude)) {
$exclude = self::parseExcludePattern($exclude);
}
......@@ -508,13 +509,14 @@ class BaseFileHelper
if (!is_string($pattern)) {
throw new InvalidParamException('Exclude/include pattern must be a string.');
}
$result = array(
$result = [
'pattern' => $pattern,
'flags' => 0,
'firstWildcard' => false,
);
if (!isset($pattern[0]))
];
if (!isset($pattern[0])) {
return $result;
}
if ($pattern[0] == '!') {
$result['flags'] |= self::PATTERN_NEGATIVE;
......@@ -526,11 +528,13 @@ class BaseFileHelper
$len--;
$result['flags'] |= self::PATTERN_MUSTBEDIR;
}
if (strpos($pattern, '/') === false)
if (strpos($pattern, '/') === false) {
$result['flags'] |= self::PATTERN_NODIR;
}
$result['firstWildcard'] = self::firstWildcardInPattern($pattern);
if ($pattern[0] == '*' && self::firstWildcardInPattern(StringHelper::byteSubstr($pattern, 1, StringHelper::byteLength($pattern))) === false)
if ($pattern[0] == '*' && self::firstWildcardInPattern(StringHelper::byteSubstr($pattern, 1, StringHelper::byteLength($pattern))) === false) {
$result['flags'] |= self::PATTERN_ENDSWITH;
}
$result['pattern'] = $pattern;
return $result;
}
......@@ -542,8 +546,8 @@ class BaseFileHelper
*/
private static function firstWildcardInPattern($pattern)
{
$wildcards = array('*','?','[','\\');
$wildcardSearch = function($r, $c) use ($pattern) {
$wildcards = ['*', '?', '[', '\\'];
$wildcardSearch = function ($r, $c) use ($pattern) {
$p = strpos($pattern, $c);
return $r===false ? $p : ($p===false ? $r : min($r, $p));
};
......
......@@ -120,7 +120,7 @@ class BaseHtml
* For example when using `['class' => 'my-class', 'target' => '_blank', 'value' => null]` it will result in the
* html attributes rendered like this: `class="my-class" target="_blank"`.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated HTML tag
* @see beginTag()
......@@ -138,7 +138,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated start tag
* @see endTag()
* @see tag()
......@@ -167,7 +167,7 @@ class BaseHtml
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* If the options does not contain "type", a "type" attribute with value "text/css" will be used.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated style tag
*/
public static function style($content, $options = [])
......@@ -182,7 +182,7 @@ class BaseHtml
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* If the options does not contain "type", a "type" attribute with value "text/javascript" will be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated script tag
*/
public static function script($content, $options = [])
......@@ -196,7 +196,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated link tag
* @see url()
*/
......@@ -215,7 +215,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated script tag
* @see url()
*/
......@@ -235,7 +235,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated form start tag.
* @see endForm()
*/
......@@ -304,7 +304,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated hyperlink
* @see url()
*/
......@@ -326,7 +326,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated mailto link
*/
public static function mailto($text, $email = null, $options = [])
......@@ -341,7 +341,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated image tag
*/
public static function img($src, $options = [])
......@@ -363,7 +363,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated label tag
*/
public static function label($content, $for = null, $options = [])
......@@ -380,7 +380,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated button tag
*/
public static function button($content = 'Button', $options = [])
......@@ -396,7 +396,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated submit button tag
*/
public static function submitButton($content = 'Submit', $options = [])
......@@ -413,7 +413,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated reset button tag
*/
public static function resetButton($content = 'Reset', $options = [])
......@@ -430,7 +430,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated input tag
*/
public static function input($type, $name = null, $value = null, $options = [])
......@@ -447,7 +447,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated button tag
*/
public static function buttonInput($label = 'Button', $options = [])
......@@ -463,7 +463,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated button tag
*/
public static function submitInput($label = 'Submit', $options = [])
......@@ -478,7 +478,7 @@ class BaseHtml
* @param string $label the value attribute. If it is null, the value attribute will not be generated.
* @param array $options the attributes of the button tag. The values will be HTML-encoded using [[encode()]].
* Attributes whose value is null will be ignored and not put in the tag returned.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated button tag
*/
public static function resetInput($label = 'Reset', $options = [])
......@@ -495,7 +495,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated button tag
*/
public static function textInput($name, $value = null, $options = [])
......@@ -510,7 +510,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated button tag
*/
public static function hiddenInput($name, $value = null, $options = [])
......@@ -525,7 +525,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated button tag
*/
public static function passwordInput($name, $value = null, $options = [])
......@@ -543,7 +543,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated button tag
*/
public static function fileInput($name, $value = null, $options = [])
......@@ -558,7 +558,7 @@ class BaseHtml
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated text area tag
*/
public static function textarea($name, $value = '', $options = [])
......@@ -586,7 +586,7 @@ class BaseHtml
*
* The rest of the options will be rendered as the attributes of the resulting radio button tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated radio button tag
*/
......@@ -636,7 +636,7 @@ class BaseHtml
*
* The rest of the options will be rendered as the attributes of the resulting checkbox tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated checkbox tag
*/
......@@ -697,7 +697,7 @@ class BaseHtml
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated drop-down list tag
*/
......@@ -744,7 +744,7 @@ class BaseHtml
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated list box tag
*/
......@@ -800,7 +800,7 @@ class BaseHtml
* is the label for the checkbox; and $name, $value and $checked represent the name,
* value and the checked status of the checkbox input, respectively.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated checkbox list
*/
......@@ -871,7 +871,7 @@ class BaseHtml
* is the label for the radio button; and $name, $value and $checked represent the name,
* value and the checked status of the radio button input, respectively.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated radio button list
*/
......@@ -930,7 +930,7 @@ class BaseHtml
* where $index is the array key corresponding to `$item` in `$items`. The callback should return
* the whole list item tag.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated unordered list. An empty string is returned if `$items` is empty.
*/
......@@ -974,7 +974,7 @@ class BaseHtml
* where $index is the array key corresponding to `$item` in `$items`. The callback should return
* the whole list item tag.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated ordered list. An empty string is returned if `$items` is empty.
*/
......@@ -999,7 +999,7 @@ class BaseHtml
* If this is not set, [[Model::getAttributeLabel()]] will be called to get the label for display
* (after encoding).
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated label tag
*/
......@@ -1025,7 +1025,7 @@ class BaseHtml
*
* - tag: this specifies the tag name. If not set, "div" will be used.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated label tag
*/
......@@ -1048,7 +1048,7 @@ class BaseHtml
* about attribute expression.
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated input tag
*/
public static function activeInput($type, $model, $attribute, $options = [])
......@@ -1070,7 +1070,7 @@ class BaseHtml
* about attribute expression.
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated input tag
*/
public static function activeTextInput($model, $attribute, $options = [])
......@@ -1087,7 +1087,7 @@ class BaseHtml
* about attribute expression.
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated input tag
*/
public static function activeHiddenInput($model, $attribute, $options = [])
......@@ -1104,7 +1104,7 @@ class BaseHtml
* about attribute expression.
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated input tag
*/
public static function activePasswordInput($model, $attribute, $options = [])
......@@ -1121,7 +1121,7 @@ class BaseHtml
* about attribute expression.
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated input tag
*/
public static function activeFileInput($model, $attribute, $options = [])
......@@ -1140,12 +1140,12 @@ class BaseHtml
* about attribute expression.
* @param array $options the tag options in terms of name-value pairs. These will be rendered as
* the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
* @return string the generated textarea tag
*/
public static function activeTextarea($model, $attribute, $options = [])
{
$name = static::getInputName($model, $attribute);
$name = isset($options['name']) ? $options['name'] : static::getInputName($model, $attribute);
$value = static::getAttributeValue($model, $attribute);
if (!array_key_exists('id', $options)) {
$options['id'] = static::getInputId($model, $attribute);
......@@ -1173,7 +1173,7 @@ class BaseHtml
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated radio button tag
*/
......@@ -1216,7 +1216,7 @@ class BaseHtml
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated checkbox tag
*/
......@@ -1272,7 +1272,7 @@ class BaseHtml
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated drop-down list tag
*/
......@@ -1324,7 +1324,7 @@ class BaseHtml
*
* The rest of the options will be rendered as the attributes of the resulting tag. The values will
* be HTML-encoded using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated list box tag
*/
......@@ -1369,7 +1369,7 @@ class BaseHtml
* is the label for the checkbox; and $name, $value and $checked represent the name,
* value and the checked status of the checkbox input.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated checkbox list
*/
......@@ -1413,7 +1413,7 @@ class BaseHtml
* is the label for the radio button; and $name, $value and $checked represent the name,
* value and the checked status of the radio button input.
*
* See [[renderTagAttributes()]] for details on how these are beeing rendered.
* See [[renderTagAttributes()]] for details on how these are being rendered.
*
* @return string the generated radio button list
*/
......@@ -1579,7 +1579,7 @@ class BaseHtml
{
if (isset($options['class'])) {
$classes = ' ' . $options['class'] . ' ';
if (($pos = strpos($classes, ' ' . $class . ' ')) === false) {
if (strpos($classes, ' ' . $class . ' ') === false) {
$options['class'] .= ' ' . $class;
}
} else {
......
......@@ -275,7 +275,18 @@ class BaseInflector
'Ā' => 'A', 'Č' => 'C', 'Ē' => 'E', 'Ģ' => 'G', 'Ī' => 'i', 'Ķ' => 'k', 'Ļ' => 'L', 'Ņ' => 'N',
'Š' => 'S', 'Ū' => 'u', 'Ž' => 'Z',
'ā' => 'a', 'č' => 'c', 'ē' => 'e', 'ģ' => 'g', 'ī' => 'i', 'ķ' => 'k', 'ļ' => 'l', 'ņ' => 'n',
'š' => 's', 'ū' => 'u', 'ž' => 'z'
'š' => 's', 'ū' => 'u', 'ž' => 'z',
//Vietnamese
'Ấ' => 'A', 'Ầ' => 'A', 'Ẩ' => 'A', 'Ẫ' => 'A', 'Ậ' => 'A',
'Ắ' => 'A', 'Ằ' => 'A', 'Ẳ' => 'A', 'Ẵ' => 'A', 'Ặ' => 'A',
'Ố' => 'O', 'Ồ' => 'O', 'Ổ' => 'O', 'Ỗ' => 'O', 'Ộ' => 'O',
'Ớ' => 'O', 'Ờ' => 'O', 'Ở' => 'O', 'Ỡ' => 'O', 'Ợ' => 'O',
'Ế' => 'E', 'Ề' => 'E', 'Ể' => 'E', 'Ễ' => 'E', 'Ệ' => 'E',
'ấ' => 'a', 'ầ' => 'a', 'ẩ' => 'a', 'ẫ' => 'a', 'ậ' => 'a',
'ắ' => 'a', 'ằ' => 'a', 'ẳ' => 'a', 'ẵ' => 'a', 'ặ' => 'a',
'ố' => 'o', 'ồ' => 'o', 'ổ' => 'o', 'ỗ' => 'o', 'ộ' => 'o',
'ớ' => 'o', 'ờ' => 'o', 'ở' => 'o', 'ỡ' => 'o', 'ợ' => 'o',
'ế' => 'e', 'ề' => 'e', 'ể' => 'e', 'ễ' => 'e', 'ệ' => 'e'
];
/**
......
......@@ -86,7 +86,7 @@ class BaseMarkdown
/** @var \cebe\markdown\Markdown $parser */
if (!isset(static::$flavors[$flavor])) {
throw new InvalidParamException("Markdown flavor '$flavor' is not defined.'");
} elseif(!is_object($config = static::$flavors[$flavor])) {
} elseif (!is_object($config = static::$flavors[$flavor])) {
$parser = Yii::createObject($config);
if (is_array($config)) {
foreach ($config as $name => $value) {
......
......@@ -107,10 +107,10 @@ class BaseSecurity
*/
protected static function stripPadding($data)
{
$end = StringHelper::byteSubstr($data, -1, NULL);
$end = StringHelper::byteSubstr($data, -1, null);
$last = ord($end);
$n = StringHelper::byteLength($data) - $last;
if (StringHelper::byteSubstr($data, $n, NULL) == str_repeat($end, $last)) {
if (StringHelper::byteSubstr($data, $n, null) == str_repeat($end, $last)) {
return StringHelper::byteSubstr($data, 0, $n);
}
return false;
......
......@@ -70,9 +70,9 @@ class GettextMessageSource extends MessageSource
if ($messages === null && $fallbackMessages === null && $fallbackLanguage != $this->sourceLanguage) {
Yii::error("The message file for category '$category' does not exist: $messageFile Fallback file does not exist as well: $fallbackMessageFile", __METHOD__);
} else if (empty($messages)) {
} elseif (empty($messages)) {
return $fallbackMessages;
} else if (!empty($fallbackMessages)) {
} elseif (!empty($fallbackMessages)) {
foreach ($fallbackMessages as $key => $value) {
if (!empty($value) && empty($messages[$key])) {
$messages[$key] = $fallbackMessages[$key];
......
......@@ -126,7 +126,7 @@ class I18N extends Component
}
$p = [];
foreach($params as $name => $value) {
foreach ($params as $name => $value) {
$p['{' . $name . '}'] = $value;
}
return strtr($message, $p);
......
......@@ -143,7 +143,7 @@ class MessageFormatter extends Component
return false;
}
$map = [];
foreach($tokens as $i => $token) {
foreach ($tokens as $i => $token) {
if (is_array($token)) {
$param = trim($token[0]);
if (!isset($map[$param])) {
......@@ -169,7 +169,7 @@ class MessageFormatter extends Component
return false;
} else {
$values = [];
foreach($result as $key => $value) {
foreach ($result as $key => $value) {
$values[$map[$key]] = $value;
}
return $values;
......@@ -190,7 +190,7 @@ class MessageFormatter extends Component
if (($tokens = self::tokenizePattern($pattern)) === false) {
return false;
}
foreach($tokens as $i => $token) {
foreach ($tokens as $i => $token) {
if (!is_array($token)) {
continue;
}
......@@ -210,7 +210,7 @@ class MessageFormatter extends Component
}
$type = isset($token[1]) ? trim($token[1]) : 'none';
// replace plural and select format recursively
if ($type == 'plural' || $type == 'select') {
if ($type == 'plural' || $type == 'select') {
if (!isset($token[2])) {
return false;
}
......@@ -244,7 +244,7 @@ class MessageFormatter extends Component
$this->_errorMessage = "Message pattern is invalid.";
return false;
}
foreach($tokens as $i => $token) {
foreach ($tokens as $i => $token) {
if (is_array($token)) {
if (($tokens[$i] = $this->parseToken($token, $args, $locale)) === false) {
$this->_errorCode = -1;
......
......@@ -73,9 +73,9 @@ class PhpMessageSource extends MessageSource
if ($messages === null && $fallbackMessages === null && $fallbackLanguage != $this->sourceLanguage) {
Yii::error("The message file for category '$category' does not exist: $messageFile Fallback file does not exist as well: $fallbackMessageFile", __METHOD__);
} else if (empty($messages)) {
} elseif (empty($messages)) {
return $fallbackMessages;
} else if (!empty($fallbackMessages)) {
} elseif (!empty($fallbackMessages)) {
foreach ($fallbackMessages as $key => $value) {
if (!empty($value) && empty($messages[$key])) {
$messages[$key] = $fallbackMessages[$key];
......
......@@ -348,5 +348,4 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
$event = new MailEvent(['message' => $message, 'isSuccessful' => $isSuccessful]);
$this->trigger(self::EVENT_AFTER_SEND, $event);
}
}
<?php
<?php
/**
* Message translations.
*
......
......@@ -27,7 +27,7 @@
</p>
<p>
There are two kinds of requirements being checked. Mandatory requirements are those that have to be met
to allow Yii to work as expected. There are also some optional requirements beeing checked which will
to allow Yii to work as expected. There are also some optional requirements being checked which will
show you a warning when they do not meet. You can use Yii framework without them but some specific
functionality may be not available in this case.
</p>
......
......@@ -82,4 +82,3 @@ class Fixture extends Component
{
}
}
......@@ -124,7 +124,7 @@ class ImageValidator extends FileValidator
}
if ($this->underHeight === null) {
$this->underHeight = Yii::t('yii', 'The image "{file}" is too small. The height cannot be smaller than {limit, number} {limit, plural, one{pixel} other{pixels}}.');
}
}
if ($this->overWidth === null) {
$this->overWidth = Yii::t('yii', 'The image "{file}" is too large. The width cannot be larger than {limit, number} {limit, plural, one{pixel} other{pixels}}.');
}
......
......@@ -6,6 +6,7 @@
*/
namespace yii\validators;
use yii\web\AssetBundle;
/**
......
......@@ -6,6 +6,7 @@
*/
namespace yii\validators;
use yii\web\AssetBundle;
/**
......
......@@ -82,7 +82,7 @@ class AssetConverter extends Component implements AssetConverterInterface
$proc = proc_open($command, $descriptor, $pipes, $basePath);
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
foreach($pipes as $pipe) {
foreach ($pipes as $pipe) {
fclose($pipe);
}
$status = proc_close($proc);
......
......@@ -828,7 +828,7 @@ class Request extends \yii\base\Request
}
/**
* @return string the password sent via HTTP authentication, null if the username is not given
* @return string the password sent via HTTP authentication, null if the password is not given
*/
public function getAuthPassword()
{
......
......@@ -175,6 +175,7 @@ class User extends Component
public function setIdentity($identity)
{
$this->_identity = $identity;
$this->_access = [];
}
/**
......
......@@ -6,6 +6,7 @@
*/
namespace yii\widgets;
use yii\web\AssetBundle;
/**
......
......@@ -128,7 +128,7 @@ class LinkPager extends Widget
protected function registerLinkTags()
{
$view = $this->getView();
foreach($this->pagination->getLinks() as $rel => $href) {
foreach ($this->pagination->getLinks() as $rel => $href) {
$view->registerLinkTag(['rel' => $rel, 'href' => $href], $rel);
}
}
......
......@@ -14,7 +14,7 @@ use yii\helpers\Json;
use yii\web\Response;
/**
* Pjax is a widget integrating the [pjax](https://github.com/defunkt/jquery-pjax) jQuery plugin.
* Pjax is a widget integrating the [pjax](https://github.com/yiisoft/jquery-pjax) jQuery plugin.
*
* Pjax only deals with the content enclosed between its [[begin()]] and [[end()]] calls, called the *body content* of the widget.
* By default, any link click or form submission (for those forms with `data-pjax` attribute) within the body content
......@@ -25,7 +25,9 @@ use yii\web\Response;
* You may configure [[linkSelector]] to specify which links should trigger pjax, and configure [[formSelector]]
* to specify which form submission may trigger pjax.
*
* The following example shows how to use Pjax with the [[\yii\gridview\GridView]] widget so that the grid pagination,
* You may disable pjax for a specific link inside the container by adding `data-pjax="0"` attribute to this link.
*
* The following example shows how to use Pjax with the [[\yii\grid\GridView]] widget so that the grid pagination,
* sorting and filtering can be done via pjax:
*
* ```php
......@@ -78,7 +80,7 @@ class Pjax extends Widget
public $scrollTo = false;
/**
* @var array additional options to be passed to the pjax JS plugin. Please refer to
* [pjax project page](https://github.com/defunkt/jquery-pjax) for available options.
* [pjax project page](https://github.com/yiisoft/jquery-pjax) for available options.
*/
public $clientOptions;
......
......@@ -17,9 +17,9 @@ use yii\web\AssetBundle;
*/
class PjaxAsset extends AssetBundle
{
public $sourcePath = '@yii/assets';
public $sourcePath = '@vendor/yiisoft/jquery-pjax';
public $js = [
'pjax/jquery.pjax.js',
'jquery.pjax.js',
];
public $depends = [
'yii\web\YiiAsset',
......
......@@ -2,6 +2,11 @@
#
# install CUBRID DBMS
if (php --version | grep -i HHVM > /dev/null); then
echo "Skipping CUBRID on HHVM"
exit 0
fi
# cubrid dbms
echo 'yes' | sudo add-apt-repository ppa:cubrid/cubrid
sudo apt-get update
......
#!/bin/sh
echo "extension=memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
echo "extension=memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
if (php --version | grep -i HHVM > /dev/null); then
echo "skipping memcache on HHVM"
else
echo "extension=memcache.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
echo "extension=memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
fi
......@@ -187,6 +187,60 @@ class CollectionTest extends MongoDbTestCase
$this->assertNotEmpty($result[0]['items']);
}
public function testFindAndModify()
{
$collection = $this->getConnection()->getCollection('customer');
$rows = [
[
'name' => 'customer 1',
'status' => 1,
'amount' => 100,
],
[
'name' => 'customer 2',
'status' => 1,
'amount' => 200,
],
];
$collection->batchInsert($rows);
// increment field
$result = $collection->findAndModify(['name' => 'customer 1'], ['$inc' => ['status' => 1]]);
$this->assertEquals('customer 1', $result['name']);
$this->assertEquals(1, $result['status']);
$newResult = $collection->findOne(['name' => 'customer 1']);
$this->assertEquals(2, $newResult['status']);
// $set and return modified document
$result = $collection->findAndModify(
['name' => 'customer 2'],
['$set' => ['status' => 2]],
[],
['new' => true]
);
$this->assertEquals('customer 2', $result['name']);
$this->assertEquals(2, $result['status']);
// Full update document
$data = [
'name' => 'customer 3',
'city' => 'Minsk'
];
$result = $collection->findAndModify(
['name' => 'customer 2'],
$data,
[],
['new' => true]
);
$this->assertEquals('customer 3', $result['name']);
$this->assertEquals('Minsk', $result['city']);
$this->assertTrue(!isset($result['status']));
// Test exceptions
$this->setExpectedException('\yii\mongodb\Exception');
$collection->findAndModify(['name' => 'customer 1'], ['$wrongOperator' => ['status' => 1]]);
}
/**
* @depends testBatchInsert
*/
......@@ -240,54 +294,54 @@ class CollectionTest extends MongoDbTestCase
$this->assertEquals($expectedRows, $rows);
}
/**
* @depends testMapReduce
*/
public function testMapReduceInline()
{
$collection = $this->getConnection()->getCollection('customer');
$rows = [
[
'name' => 'customer 1',
'status' => 1,
'amount' => 100,
],
[
'name' => 'customer 2',
'status' => 1,
'amount' => 200,
],
[
'name' => 'customer 2',
'status' => 2,
'amount' => 400,
],
[
'name' => 'customer 2',
'status' => 3,
'amount' => 500,
],
];
$collection->batchInsert($rows);
$result = $collection->mapReduce(
'function () {emit(this.status, this.amount)}',
'function (key, values) {return Array.sum(values)}',
['inline' => true],
['status' => ['$lt' => 3]]
);
$expectedRows = [
[
'_id' => 1,
'value' => 300,
],
[
'_id' => 2,
'value' => 400,
],
];
$this->assertEquals($expectedRows, $result);
}
/**
* @depends testMapReduce
*/
public function testMapReduceInline()
{
$collection = $this->getConnection()->getCollection('customer');
$rows = [
[
'name' => 'customer 1',
'status' => 1,
'amount' => 100,
],
[
'name' => 'customer 2',
'status' => 1,
'amount' => 200,
],
[
'name' => 'customer 2',
'status' => 2,
'amount' => 400,
],
[
'name' => 'customer 2',
'status' => 3,
'amount' => 500,
],
];
$collection->batchInsert($rows);
$result = $collection->mapReduce(
'function () {emit(this.status, this.amount)}',
'function (key, values) {return Array.sum(values)}',
['inline' => true],
['status' => ['$lt' => 3]]
);
$expectedRows = [
[
'_id' => 1,
'value' => 300,
],
[
'_id' => 2,
'value' => 400,
],
];
$this->assertEquals($expectedRows, $result);
}
public function testCreateIndex()
{
......
......@@ -15,7 +15,7 @@ class ExceptionTest extends TestCase
$this->assertEquals('bar', $array['message']);
$this->assertEquals('foo', $array['previous']['message']);
$e = new InvalidCallException('bar', 0 ,new UserException('foo'));
$e = new InvalidCallException('bar', 0, new UserException('foo'));
$array = $e->toArray();
$this->assertEquals('bar', $array['message']);
$this->assertEquals('foo', $array['previous']['message']);
......
......@@ -173,7 +173,7 @@ abstract class ManagerTestCase extends TestCase
$this->assertTrue($this->auth->executeBizRule(null, [], null));
$this->assertTrue($this->auth->executeBizRule('return 1 == true;', [], null));
$this->assertTrue($this->auth->executeBizRule('return $params[0] == $params[1];', [1, '1'], null));
if (defined('HHVM_VERSION')) { // invalid code crashes on HHVM
if (!defined('HHVM_VERSION')) { // invalid code crashes on HHVM
$this->assertFalse($this->auth->executeBizRule('invalid;', [], null));
}
}
......
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