Merge commit 'bdce87b242abbff800020deba0a5c2031fc2efe7' into feature-restapi

Conflicts:
	framework/db/BaseActiveRecord.php
This commit is contained in:
Qiang Xue
2014-03-06 00:00:33 -05:00
127 changed files with 581 additions and 1169 deletions

View File

@ -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'],

View File

@ -1,10 +1,9 @@
<?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() ?>

View File

@ -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
],
];
}
}

View File

@ -18,5 +18,4 @@ class LoginPage extends BasePage
$this->guy->fillField('input[name="LoginForm[password]"]', $password);
$this->guy->click('login-button');
}
}

View File

@ -65,5 +65,4 @@ class LoginFormTest extends TestCase
$loginForm->expects($this->any())->method('getUser')->will($this->returnValue($user));
return $loginForm;
}
}

View File

@ -1,7 +1,7 @@
{
"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",

View File

@ -20,5 +20,4 @@ class SignupPage extends BasePage
}
$this->guy->click('signup-button');
}
}

View File

@ -79,5 +79,4 @@ class SignupCest
$I->expectTo('see that user logged in');
$I->see('Logout (tester)');
}
}

View File

@ -79,5 +79,4 @@ class SignupCest
$I->expectTo('see that user logged in');
$I->see('Logout (tester)');
}
}

View File

@ -56,5 +56,4 @@ class ContactFormTest extends TestCase
{
return Yii::getAlias(Yii::$app->mail->fileTransportPath) . '/testing_message.eml';
}
}

View File

@ -75,5 +75,4 @@ class PasswordResetRequestFormTest extends DbTestCase
{
return Yii::getAlias(Yii::$app->mail->fileTransportPath) . '/testing_message.eml';
}
}

View File

@ -33,5 +33,4 @@ class ResetPasswordFormTest extends DbTestCase
],
];
}
}

View File

@ -43,5 +43,4 @@ class SignupFormTest extends DbTestCase
],
];
}
}

View File

@ -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'],

View File

@ -1,7 +1,7 @@
{
"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",

View File

@ -1,10 +1,9 @@
<?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() ?>

View File

@ -1,7 +1,7 @@
{
"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",

View File

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

View File

@ -1,7 +1,7 @@
{
"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.*"
},

View File

@ -81,18 +81,26 @@ following way:
```php
class LanguageAsset extends AssetBundle
{
public $language;
public $sourcePath = '@app/assets/language';
public $js = [
];
public function init()
public function registerAssetFiles($view)
{
$this->js[] = 'language-' . Yii::$app->language . '.js';
parent::init();
$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
------------------------

View File

@ -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.

View File

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

View File

@ -1,7 +1,12 @@
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
-------------------------
@ -19,3 +24,26 @@ be in your application config 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.

View File

@ -329,9 +329,9 @@ public function behaviors()
'class' => 'yii\web\AccessControl',
'rules' => [
['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
),
),
);
],
],
];
}
```

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -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)): ?>

View File

@ -36,7 +36,7 @@ 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>

View File

@ -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) ?>

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,6 +1,4 @@
<?php
use yii\helpers\Html;
/**
* @var yii\debug\panels\ConfigPanel $panel
*/

View File

@ -1,7 +1,4 @@
<?php
use yii\helpers\Html;
/**
* @var yii\debug\panels\ConfigPanel $panel
*/

View File

@ -1,6 +1,6 @@
<?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>

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -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
-----------------------------

View File

@ -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 () {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

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

View File

@ -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>

View File

@ -1,7 +1,7 @@
{
"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": {

0
extensions/jui/assets/jquery.ui.datepicker-i18n.js vendored Executable file → Normal file
View File

0
extensions/jui/assets/jquery.ui.effect-all.js vendored Executable file → Normal file
View File

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

View File

Before

Width:  |  Height:  |  Size: 208 B

After

Width:  |  Height:  |  Size: 208 B

View File

Before

Width:  |  Height:  |  Size: 335 B

After

Width:  |  Height:  |  Size: 335 B

View File

Before

Width:  |  Height:  |  Size: 207 B

After

Width:  |  Height:  |  Size: 207 B

View File

Before

Width:  |  Height:  |  Size: 262 B

After

Width:  |  Height:  |  Size: 262 B

View File

Before

Width:  |  Height:  |  Size: 262 B

After

Width:  |  Height:  |  Size: 262 B

View File

Before

Width:  |  Height:  |  Size: 332 B

After

Width:  |  Height:  |  Size: 332 B

View File

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 280 B

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

0
extensions/jui/assets/theme/jquery.ui.css Executable file → Normal file
View File

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -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.
@ -271,6 +271,32 @@ class Collection extends Object
return $this->mongoCollection->findOne($this->buildCondition($condition), $fields);
}
/**
* 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.

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -19,7 +19,7 @@ use yii\mail\BaseMailer;
* ~~~
* 'components' => [
* ...
* 'email' => [
* 'mail' => [
* 'class' => 'yii\swiftmailer\Mailer',
* 'transport' => [
* 'class' => 'Swift_SmtpTransport',

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -1,7 +1,7 @@
{
"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": {

View File

@ -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];

View File

@ -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)

View File

@ -1,20 +0,0 @@
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.

View File

@ -1,839 +0,0 @@
// 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);

View 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 () {
@ -119,7 +121,8 @@
},
data: function () {
return this.data('yiiGridView');
var id = $(this).prop('id');
return gridData[id];
}
};
})(window.jQuery);

View File

@ -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];
}
return isset($controller) ? [$controller, $route] : false;
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;
}
$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;
}
}
/**

View File

@ -6,6 +6,7 @@
*/
namespace yii\base;
use Yii;
/**

View File

@ -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.

View File

@ -6,6 +6,7 @@
*/
namespace yii\caching;
use yii\base\InvalidConfigException;
/**

View File

@ -6,6 +6,7 @@
*/
namespace yii\caching;
use yii\base\InvalidConfigException;
/**

View File

@ -1,7 +1,7 @@
{
"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.*"
},

View File

@ -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 = [])
@ -317,5 +318,4 @@ class FixtureController extends Controller
{
return Yii::getAlias('@' . str_replace('\\', '/', $this->namespace));
}
}

View File

@ -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 = [];
@ -196,6 +201,11 @@ class MessageController extends Controller
$db->createCommand()
->insert($sourceMessageTable, ['category' => $category, 'message' => $m])->execute();
$lastId = $db->getLastInsertID();
foreach ($languages as $language) {
$db->createCommand()
->insert($messageTable, ['id' => $lastId, 'language' => $language])->execute();
}
}
}
@ -210,12 +220,17 @@ class MessageController extends Controller
->delete($sourceMessageTable, ['in', 'id', $obsolete])->execute();
echo "deleted.\n";
} else {
$last_id = $db->getLastInsertID();
$db->createCommand()
->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";
}
}

View File

@ -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';

View File

@ -86,6 +86,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.
*

View File

@ -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]);

View File

@ -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) {

View File

@ -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]);

View File

@ -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';

View File

@ -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',
]);
};
}

View File

@ -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.
@ -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,7 +546,7 @@ class BaseFileHelper
*/
private static function firstWildcardInPattern($pattern)
{
$wildcards = array('*','?','[','\\');
$wildcards = ['*', '?', '[', '\\'];
$wildcardSearch = function ($r, $c) use ($pattern) {
$p = strpos($pattern, $c);
return $r===false ? $p : ($p===false ? $r : min($r, $p));

View File

@ -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 {

View File

@ -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'
];
/**

View File

@ -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;

View File

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

Some files were not shown because too many files have changed in this diff Show More