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
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
......@@ -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));
};
......
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