mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 06:15:19 +08:00
Merge branch 'master' of git://github.com/yiisoft/yii2
This commit is contained in:
45
docs/internals-ru/getting-started.md
Normal file
45
docs/internals-ru/getting-started.md
Normal file
@ -0,0 +1,45 @@
|
||||
Подготовка к разработке Yii2
|
||||
============================
|
||||
|
||||
1. Создаём клон своего форка yii2 `git clone git@github.com:<ваше имя>/yii2.git`.
|
||||
2. Переходим в папку репозитория `cd yii2`.
|
||||
3. Запускаем `./build/build app/link basic` для установки composer зависимостей приложения basic.
|
||||
*Эта команда установит сторонние пакеты composer как обычно, но создаст ссылку с репозитория yii2
|
||||
на только что загуженный репозиторий. Таким образом у вас будет только один экземпляр кода.*
|
||||
4. При необходимости делаем тоже самое для приложения advanced: `./build/build app/link advanced`
|
||||
Внутри эта команда использует `composer update` для обновления кода.
|
||||
5. Теперь у нас есть рабочая площадка для экспериментов с Yii 2.
|
||||
|
||||
Можно так же добавить репозиторий yii2 upstream для получения последних изменений:
|
||||
|
||||
```
|
||||
git remote add upstream https://github.com/yiisoft/yii2.git
|
||||
```
|
||||
|
||||
Пожалуйста ознакомьтесь с разделом «[рабочий процесс Git для разработчиков Yii 2](git-workflow.md)»
|
||||
для получения подробной информации о создании pull request-ов.
|
||||
|
||||
Модульные тесты
|
||||
---------------
|
||||
|
||||
Для запуска модульных тестов нужно установить composer пакеты для dev-репозитория.
|
||||
В корневой директории делаем `composer update` для получения последней версии пакетов.
|
||||
|
||||
Теперь можно выполнить модульные тесты, запустив `phpunit`.
|
||||
|
||||
Можно ограничиться группой тестов, над которыми вы работаете. Например, следующая команда запустит тесты только для
|
||||
валидаторов и redis `phpunit --group=validators,redis`.
|
||||
|
||||
Расширения
|
||||
----------
|
||||
|
||||
Для работы над расширениями необходимо установить их в приложение. Добавляем их в `composer.json` как обычно. Например,
|
||||
добавим `"yiisoft/yii2-redis": "*"` в секцию `require` для приложения basic.
|
||||
Запускаем `./build/build app/link basic` для установки расширения, его зависимостей и создания символической
|
||||
ссылки на `extensions/redis`. Теперь вы работаете с репозиторием yii2, а не с директорией vendor.
|
||||
|
||||
Функциональные и приёмочные тесты для приложений
|
||||
------------------------------------------------
|
||||
|
||||
Cмотрите `apps/advanced/tests/README.md` и `apps/basic/tests/README.md`, чтобы узнать о том как запускать
|
||||
тесты Codeception.
|
@ -575,7 +575,7 @@ class ActiveRecord extends BaseActiveRecord
|
||||
{
|
||||
$pkName = static::primaryKey()[0];
|
||||
if (count($condition) == 1 && isset($condition[$pkName])) {
|
||||
$primaryKeys = is_array($condition[$pkName]) ? $condition[$pkName] : [$condition[$pkName]];
|
||||
$primaryKeys = (array)$condition[$pkName];
|
||||
} else {
|
||||
$primaryKeys = static::find()->where($condition)->column($pkName); // TODO check whether this works with default pk _id
|
||||
}
|
||||
@ -635,7 +635,7 @@ class ActiveRecord extends BaseActiveRecord
|
||||
{
|
||||
$pkName = static::primaryKey()[0];
|
||||
if (count($condition) == 1 && isset($condition[$pkName])) {
|
||||
$primaryKeys = is_array($condition[$pkName]) ? $condition[$pkName] : [$condition[$pkName]];
|
||||
$primaryKeys = (array)$condition[$pkName];
|
||||
} else {
|
||||
$primaryKeys = static::find()->where($condition)->column($pkName); // TODO check whether this works with default pk _id
|
||||
}
|
||||
@ -771,7 +771,7 @@ class ActiveRecord extends BaseActiveRecord
|
||||
{
|
||||
$pkName = static::primaryKey()[0];
|
||||
if (count($condition) == 1 && isset($condition[$pkName])) {
|
||||
$primaryKeys = is_array($condition[$pkName]) ? $condition[$pkName] : [$condition[$pkName]];
|
||||
$primaryKeys = (array)$condition[$pkName];
|
||||
} else {
|
||||
$primaryKeys = static::find()->where($condition)->column($pkName); // TODO check whether this works with default pk _id
|
||||
}
|
||||
|
@ -35,6 +35,17 @@ use yii\helpers\Html;
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* You can also use this widget in an [[yii\widgets\ActiveForm|ActiveForm]] using the [[yii\widgets\ActiveField::widget()|widget()]]
|
||||
* method, for example like this:
|
||||
*
|
||||
* ```php
|
||||
* <?= $form->field($model, 'from_date')->widget(\yii\jui\AutoComplete::classname(), [
|
||||
* 'clientOptions' => [
|
||||
* 'source' => ['USA', 'RUS'],
|
||||
* ],
|
||||
* ]) ?>
|
||||
* ```
|
||||
*
|
||||
* @see http://api.jqueryui.com/autocomplete/
|
||||
* @author Alexander Kochetov <creocoder@gmail.com>
|
||||
* @since 2.0
|
||||
|
@ -38,8 +38,19 @@ use yii\helpers\Json;
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* Note that empty values like empty strings and 0 will result in a date displayed as `1970-01-01`.
|
||||
* So to make sure empty values result in an empty text field in the datepicker you need to add a
|
||||
* You can also use this widget in an [[yii\widgets\ActiveForm|ActiveForm]] using the [[yii\widgets\ActiveField::widget()|widget()]]
|
||||
* method, for example like this:
|
||||
*
|
||||
* ```php
|
||||
* <?= $form->field($model, 'from_date')->widget(\yii\jui\DatePicker::classname(), [
|
||||
* //'language' => 'ru',
|
||||
* //'dateFormat' => 'yyyy-MM-dd',
|
||||
* ]) ?>
|
||||
* ```
|
||||
*
|
||||
* Note that and empty string (`''`) and `null` will result in an empty text field while `0` will be
|
||||
* interpreted as a UNIX timestamp and result in a date displayed as `1970-01-01`.
|
||||
* It is recommended to add a
|
||||
* validation filter in your model that sets the value to `null` in case when no date has been entered:
|
||||
*
|
||||
* ```php
|
||||
|
@ -14,6 +14,15 @@ use yii\helpers\Html;
|
||||
/**
|
||||
* InputWidget is the base class for all jQuery UI input widgets.
|
||||
*
|
||||
* Classes extending from this widget can be used in an [[yii\widgets\ActiveForm|ActiveForm]]
|
||||
* using the [[yii\widgets\ActiveField::widget()|widget()]] method, for example like this:
|
||||
*
|
||||
* ```php
|
||||
* <?= $form->field($model, 'from_date')->widget('WidgetClassName', [
|
||||
* // configure additional widget properties here
|
||||
* ]) ?>
|
||||
* ```
|
||||
*
|
||||
* @author Alexander Kochetov <creocoder@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
|
@ -37,6 +37,18 @@ use yii\helpers\Html;
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* You can also use this widget in an [[yii\widgets\ActiveForm|ActiveForm]] using the [[yii\widgets\ActiveField::widget()|widget()]]
|
||||
* method, for example like this:
|
||||
*
|
||||
* ```php
|
||||
* <?= $form->field($model, 'from_date')->widget(\yii\jui\SliderInput::classname(), [
|
||||
* 'clientOptions' => [
|
||||
* 'min' => 1,
|
||||
* 'max' => 10,
|
||||
* ],
|
||||
* ]) ?>
|
||||
* ```
|
||||
*
|
||||
* @see http://api.jqueryui.com/slider/
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @since 2.0
|
||||
|
@ -31,6 +31,15 @@ use yii\helpers\Html;
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* You can also use this widget in an [[yii\widgets\ActiveForm|ActiveForm]] using the [[yii\widgets\ActiveField::widget()|widget()]]
|
||||
* method, for example like this:
|
||||
*
|
||||
* ```php
|
||||
* <?= $form->field($model, 'from_date')->widget(\yii\jui\Spinner::classname(), [
|
||||
* 'clientOptions' => ['step' => 2],
|
||||
* ]) ?>
|
||||
* ```
|
||||
*
|
||||
* @see http://api.jqueryui.com/spinner/
|
||||
* @author Alexander Kochetov <creocoder@gmail.com>
|
||||
* @since 2.0
|
||||
|
@ -213,9 +213,7 @@ class Collection extends Object
|
||||
*/
|
||||
public function createIndex($columns, $options = [])
|
||||
{
|
||||
if (!is_array($columns)) {
|
||||
$columns = [$columns];
|
||||
}
|
||||
$columns = (array)$columns;
|
||||
$keys = $this->normalizeIndexKeys($columns);
|
||||
$token = $this->composeLogToken('createIndex', [$keys, $options]);
|
||||
$options = array_merge(['w' => 1], $options);
|
||||
@ -258,9 +256,7 @@ class Collection extends Object
|
||||
*/
|
||||
public function dropIndex($columns)
|
||||
{
|
||||
if (!is_array($columns)) {
|
||||
$columns = [$columns];
|
||||
}
|
||||
$columns = (array)$columns;
|
||||
$keys = $this->normalizeIndexKeys($columns);
|
||||
$token = $this->composeLogToken('dropIndex', [$keys]);
|
||||
Yii::info($token, __METHOD__);
|
||||
|
@ -17,6 +17,7 @@ Yii Framework 2 Change Log
|
||||
- Enh #6697: Added `yii\helpers\Url::current()` method that allows adding or removing parameters from current URL (samdark, callmez)
|
||||
- Enh #6852: Added `yii\helpers\BaseHtmlPurifier::helpers()` in order to be able to configure `HtmlPurifier` helper globally via subclassing (Alex-Code)
|
||||
- Enh #6882: Added `yii\web\ErrorHandler::getTypeUrl()` in order to allow providing custom types/classes/methods URLs for subclasses (brandonkelly)
|
||||
- Enh #6883: `yii\base\ErrorHandler::logException()` is now public (samdark)
|
||||
- Enh #6896: Added `yii\log\FileTarget::$enableRotation` to allow disabling log rotation when external tools are configured for this (cebe)
|
||||
- Enh #7008: Removed extra white space in GridView filter cell (uran1980)
|
||||
- Enh #7051: Added support for preventing swapping values between different cookies (pavimus, qiangxue)
|
||||
|
@ -197,7 +197,7 @@ abstract class ErrorHandler extends Component
|
||||
* Logs the given exception
|
||||
* @param \Exception $exception the exception to be logged
|
||||
*/
|
||||
protected function logException($exception)
|
||||
public function logException($exception)
|
||||
{
|
||||
$category = get_class($exception);
|
||||
if ($exception instanceof HttpException) {
|
||||
|
@ -17,8 +17,8 @@ use yii\widgets\InputWidget;
|
||||
/**
|
||||
* Captcha renders a CAPTCHA image and an input field that takes user-entered verification code.
|
||||
*
|
||||
* Captcha is used together with [[CaptchaAction]] provide [CAPTCHA](http://en.wikipedia.org/wiki/Captcha)
|
||||
* - a way of preventing Website spamming.
|
||||
* Captcha is used together with [[CaptchaAction]] provide [CAPTCHA](http://en.wikipedia.org/wiki/Captcha) - a way
|
||||
* of preventing Website spamming.
|
||||
*
|
||||
* The image element rendered by Captcha will display a CAPTCHA image generated by
|
||||
* an action whose route is specified by [[captchaAction]]. This action must be an instance of [[CaptchaAction]].
|
||||
@ -29,6 +29,32 @@ use yii\widgets\InputWidget;
|
||||
* You may use [[\yii\captcha\CaptchaValidator]] to validate the user input matches
|
||||
* the current CAPTCHA verification code.
|
||||
*
|
||||
* The following example shows how to use this widget with a model attribute:
|
||||
*
|
||||
* ```php
|
||||
* echo Captcha::widget([
|
||||
* 'model' => $model,
|
||||
* 'attribute' => 'captcha',
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* The following example will use the name property instead:
|
||||
*
|
||||
* ```php
|
||||
* echo Captcha::widget([
|
||||
* 'name' => 'captcha',
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* You can also use this widget in an [[yii\widgets\ActiveForm|ActiveForm]] using the [[yii\widgets\ActiveField::widget()|widget()]]
|
||||
* method, for example like this:
|
||||
*
|
||||
* ```php
|
||||
* <?= $form->field($model, 'captcha')->widget(\yii\widgets\Captcha::classname(), [
|
||||
* // configure additional widget properties here
|
||||
* ]) ?>
|
||||
* ```
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
|
@ -615,7 +615,7 @@ abstract class BaseMigrateController extends Controller
|
||||
continue;
|
||||
}
|
||||
$path = $this->migrationPath . DIRECTORY_SEPARATOR . $file;
|
||||
if (preg_match('/^(m(\d{6}_\d{6})_.*?)\.php$/', $file, $matches) && is_file($path) && !isset($applied[$matches[2]])) {
|
||||
if (preg_match('/^(m(\d{6}_\d{6})_.*?)\.php$/', $file, $matches) && !isset($applied[$matches[2]]) && is_file($path)) {
|
||||
$migrations[] = $matches[1];
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ class HelpController extends Controller
|
||||
$class = new \ReflectionClass($controller);
|
||||
foreach ($class->getMethods() as $method) {
|
||||
$name = $method->getName();
|
||||
if ($method->isPublic() && !$method->isStatic() && strpos($name, 'action') === 0 && $name !== 'actions') {
|
||||
if ($name !== 'actions' && $method->isPublic() && !$method->isStatic() && strpos($name, 'action') === 0) {
|
||||
$actions[] = Inflector::camel2id(substr($name, 6), '-', true);
|
||||
}
|
||||
}
|
||||
|
@ -248,10 +248,7 @@ class MessageController extends Controller
|
||||
$this->stdout("Extracting messages from $coloredFileName...\n");
|
||||
$subject = file_get_contents($fileName);
|
||||
$messages = [];
|
||||
if (!is_array($translator)) {
|
||||
$translator = [$translator];
|
||||
}
|
||||
foreach ($translator as $currentTranslator) {
|
||||
foreach ((array)$translator as $currentTranslator) {
|
||||
$translatorTokens = token_get_all('<?php ' . $currentTranslator);
|
||||
array_shift($translatorTokens);
|
||||
|
||||
@ -401,7 +398,7 @@ class MessageController extends Controller
|
||||
}
|
||||
ksort($existingMessages);
|
||||
foreach ($existingMessages as $message => $translation) {
|
||||
if (!isset($merged[$message]) && !isset($todo[$message]) && !$removeUnused) {
|
||||
if (!$removeUnused && !isset($merged[$message]) && !isset($todo[$message])) {
|
||||
if (!empty($translation) && strncmp($translation, '@@', 2) === 0 && substr_compare($translation, '@@', -2, 2) === 0) {
|
||||
$todo[$message] = $translation;
|
||||
} else {
|
||||
@ -515,7 +512,7 @@ EOD;
|
||||
|
||||
// add obsolete unused messages
|
||||
foreach ($existingMessages as $message => $translation) {
|
||||
if (!isset($merged[$category . chr(4) . $message]) && !isset($todos[$category . chr(4) . $message]) && !$removeUnused) {
|
||||
if (!$removeUnused && !isset($merged[$category . chr(4) . $message]) && !isset($todos[$category . chr(4) . $message])) {
|
||||
if (!empty($translation) && substr($translation, 0, 2) === '@@' && substr($translation, -2) === '@@') {
|
||||
$todos[$category . chr(4) . $message] = $translation;
|
||||
} else {
|
||||
|
@ -232,7 +232,7 @@ class Pagination extends Object implements Linkable
|
||||
$this->_pageSize = null;
|
||||
} else {
|
||||
$value = (int) $value;
|
||||
if ($validatePageSize && count($this->pageSizeLimit) === 2 && isset($this->pageSizeLimit[0], $this->pageSizeLimit[1])) {
|
||||
if ($validatePageSize && isset($this->pageSizeLimit[0], $this->pageSizeLimit[1]) && count($this->pageSizeLimit) === 2) {
|
||||
if ($value < $this->pageSizeLimit[0]) {
|
||||
$value = $this->pageSizeLimit[0];
|
||||
} elseif ($value > $this->pageSizeLimit[1]) {
|
||||
|
@ -215,7 +215,7 @@ trait ActiveRelationTrait
|
||||
$this->filterByModels($primaryModels);
|
||||
}
|
||||
|
||||
if (count($primaryModels) === 1 && !$this->multiple) {
|
||||
if (!$this->multiple && count($primaryModels) === 1) {
|
||||
$model = $this->one();
|
||||
foreach ($primaryModels as $i => $primaryModel) {
|
||||
if ($primaryModel instanceof ActiveRecordInterface) {
|
||||
|
@ -980,7 +980,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
|
||||
public function getPrimaryKey($asArray = false)
|
||||
{
|
||||
$keys = $this->primaryKey();
|
||||
if (count($keys) === 1 && !$asArray) {
|
||||
if (!$asArray && count($keys) === 1) {
|
||||
return isset($this->_attributes[$keys[0]]) ? $this->_attributes[$keys[0]] : null;
|
||||
} else {
|
||||
$values = [];
|
||||
@ -1014,7 +1014,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface
|
||||
if (empty($keys)) {
|
||||
throw new Exception(get_class($this) . ' does not have a primary key. You should either define a primary key for the corresponding table or override the primaryKey() method.');
|
||||
}
|
||||
if (count($keys) === 1 && !$asArray) {
|
||||
if (!$asArray && count($keys) === 1) {
|
||||
return isset($this->_oldAttributes[$keys[0]]) ? $this->_oldAttributes[$keys[0]] : null;
|
||||
} else {
|
||||
$values = [];
|
||||
|
@ -189,7 +189,7 @@ class QueryBuilder extends \yii\base\Object
|
||||
foreach ($rows as $row) {
|
||||
$vs = [];
|
||||
foreach ($row as $i => $value) {
|
||||
if (!is_array($value) && isset($columns[$i]) && isset($columnSchemas[$columns[$i]])) {
|
||||
if (isset($columns[$i], $columnSchemas[$columns[$i]]) && !is_array($value)) {
|
||||
$value = $columnSchemas[$columns[$i]]->dbTypecast($value);
|
||||
}
|
||||
if (is_string($value)) {
|
||||
|
@ -87,9 +87,7 @@ class TableSchema extends Object
|
||||
*/
|
||||
public function fixPrimaryKey($keys)
|
||||
{
|
||||
if (!is_array($keys)) {
|
||||
$keys = [$keys];
|
||||
}
|
||||
$keys = (array)$keys;
|
||||
$this->primaryKey = $keys;
|
||||
foreach ($this->columns as $column) {
|
||||
$column->isPrimaryKey = false;
|
||||
|
@ -305,7 +305,7 @@ class BaseFileHelper
|
||||
if (!is_dir($dir)) {
|
||||
return;
|
||||
}
|
||||
if (!is_link($dir) || isset($options['traverseSymlinks']) && $options['traverseSymlinks']) {
|
||||
if (isset($options['traverseSymlinks']) && $options['traverseSymlinks'] || !is_link($dir)) {
|
||||
if (!($handle = opendir($dir))) {
|
||||
return;
|
||||
}
|
||||
@ -424,7 +424,7 @@ class BaseFileHelper
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_dir($path) && !empty($options['only'])) {
|
||||
if (!empty($options['only']) && !is_dir($path)) {
|
||||
if (($except = self::lastExcludeMatchingFromList($options['basePath'], $path, $options['only'])) !== null) {
|
||||
// don't check PATTERN_NEGATIVE since those entries are not prefixed with !
|
||||
return true;
|
||||
|
@ -109,8 +109,7 @@ class GettextMoFile extends GettextFile
|
||||
$separatorPosition = strpos($id, chr(4));
|
||||
|
||||
|
||||
if (($context && $separatorPosition !== false && strncmp($id, $context, $separatorPosition) === 0) ||
|
||||
(!$context && $separatorPosition === false)) {
|
||||
if ((!$context && $separatorPosition === false) || ($context && $separatorPosition !== false && strncmp($id, $context, $separatorPosition) === 0)) {
|
||||
if ($separatorPosition !== false) {
|
||||
$id = substr($id, $separatorPosition+1);
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ class Logger extends Component
|
||||
$matched = empty($categories);
|
||||
foreach ($categories as $category) {
|
||||
$prefix = rtrim($category, '*');
|
||||
if (strpos($timing['category'], $prefix) === 0 && ($timing['category'] === $category || $prefix !== $category)) {
|
||||
if (($timing['category'] === $category || $prefix !== $category) && strpos($timing['category'], $prefix) === 0) {
|
||||
$matched = true;
|
||||
break;
|
||||
}
|
||||
@ -219,7 +219,7 @@ class Logger extends Component
|
||||
foreach ($excludeCategories as $category) {
|
||||
$prefix = rtrim($category, '*');
|
||||
foreach ($timings as $i => $timing) {
|
||||
if (strpos($timing['category'], $prefix) === 0 && ($timing['category'] === $category || $prefix !== $category)) {
|
||||
if (($timing['category'] === $category || $prefix !== $category) && strpos($timing['category'], $prefix) === 0) {
|
||||
$matched = false;
|
||||
break;
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ abstract class Target extends Component
|
||||
if ($matched) {
|
||||
foreach ($except as $category) {
|
||||
$prefix = rtrim($category, '*');
|
||||
if (strpos($message[2], $prefix) === 0 && ($message[2] === $category || $prefix !== $category)) {
|
||||
if (($message[2] === $category || $prefix !== $category) && strpos($message[2], $prefix) === 0) {
|
||||
$matched = false;
|
||||
break;
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ class DbManager extends BaseManager
|
||||
*/
|
||||
protected function updateItem($name, $item)
|
||||
{
|
||||
if (!$this->supportsCascadeUpdate() && $item->name !== $name) {
|
||||
if ($item->name !== $name && !$this->supportsCascadeUpdate()) {
|
||||
$this->db->createCommand()
|
||||
->update($this->itemChildTable, ['parent' => $item->name], ['parent' => $name])
|
||||
->execute();
|
||||
@ -259,7 +259,7 @@ class DbManager extends BaseManager
|
||||
*/
|
||||
protected function updateRule($name, $rule)
|
||||
{
|
||||
if (!$this->supportsCascadeUpdate() && $rule->name !== $name) {
|
||||
if ($rule->name !== $name && !$this->supportsCascadeUpdate()) {
|
||||
$this->db->createCommand()
|
||||
->update($this->itemTable, ['rule_name' => $rule->name], ['rule_name' => $name])
|
||||
->execute();
|
||||
|
@ -9,7 +9,7 @@
|
||||
/* @var $end integer */
|
||||
/* @var $handler \yii\web\ErrorHandler */
|
||||
?>
|
||||
<li class="<?php if (!$handler->isCoreFile($file) || $index === 1) echo 'application'; ?> call-stack-item"
|
||||
<li class="<?php if ($index === 1 || !$handler->isCoreFile($file)) echo 'application'; ?> call-stack-item"
|
||||
data-line="<?= (int) ($line - $begin) ?>">
|
||||
<div class="element-wrap">
|
||||
<div class="element">
|
||||
|
@ -470,7 +470,7 @@ class AssetManager extends Component
|
||||
if (!is_dir($dstDir)) {
|
||||
symlink($src, $dstDir);
|
||||
}
|
||||
} elseif (!is_dir($dstDir) || !empty($options['forceCopy']) || (!isset($options['forceCopy']) && $this->forceCopy)) {
|
||||
} elseif (!empty($options['forceCopy']) || ($this->forceCopy && !isset($options['forceCopy'])) || !is_dir($dstDir)) {
|
||||
$opts = [
|
||||
'dirMode' => $this->dirMode,
|
||||
'fileMode' => $this->fileMode,
|
||||
|
@ -73,7 +73,7 @@ class Controller extends \yii\base\Controller
|
||||
$name = $param->getName();
|
||||
if (array_key_exists($name, $params)) {
|
||||
if ($param->isArray()) {
|
||||
$args[] = $actionParams[$name] = is_array($params[$name]) ? $params[$name] : [$params[$name]];
|
||||
$args[] = $actionParams[$name] = (array)$params[$name];
|
||||
} elseif (!is_array($params[$name])) {
|
||||
$args[] = $actionParams[$name] = $params[$name];
|
||||
} else {
|
||||
|
@ -84,7 +84,7 @@ class ErrorHandler extends \yii\base\ErrorHandler
|
||||
$response->data = $result;
|
||||
}
|
||||
} elseif ($response->format === Response::FORMAT_HTML) {
|
||||
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest' || YII_ENV_TEST) {
|
||||
if (YII_ENV_TEST || isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') {
|
||||
// AJAX request
|
||||
$response->data = '<pre>' . $this->htmlEncode($this->convertExceptionToString($exception)) . '</pre>';
|
||||
} else {
|
||||
|
@ -205,7 +205,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
|
||||
if ($this->_hasSessionId === null) {
|
||||
$name = $this->getName();
|
||||
$request = Yii::$app->getRequest();
|
||||
if (ini_get('session.use_cookies') && !empty($_COOKIE[$name])) {
|
||||
if (!empty($_COOKIE[$name]) && ini_get('session.use_cookies')) {
|
||||
$this->_hasSessionId = true;
|
||||
} elseif (!ini_get('session.use_only_cookies') && ini_get('session.use_trans_sid')) {
|
||||
$this->_hasSessionId = $request->get($name) !== null;
|
||||
|
@ -121,7 +121,7 @@ abstract class BaseListView extends Widget
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if ($this->dataProvider->getCount() > 0 || $this->showOnEmpty) {
|
||||
if ($this->showOnEmpty || $this->dataProvider->getCount() > 0) {
|
||||
$content = preg_replace_callback("/{\\w+}/", function ($matches) {
|
||||
$content = $this->renderSection($matches[0]);
|
||||
|
||||
|
@ -20,6 +20,15 @@ use yii\helpers\Html;
|
||||
* or a name and a value. If the former, the name and the value will
|
||||
* be generated automatically.
|
||||
*
|
||||
* Classes extending from this widget can be used in an [[yii\widgets\ActiveForm|ActiveForm]]
|
||||
* using the [[yii\widgets\ActiveField::widget()|widget()]] method, for example like this:
|
||||
*
|
||||
* ```php
|
||||
* <?= $form->field($model, 'from_date')->widget('WidgetClassName', [
|
||||
* // configure additional widget properties here
|
||||
* ]) ?>
|
||||
* ```
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
@ -54,7 +63,7 @@ class InputWidget extends Widget
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (!$this->hasModel() && $this->name === null) {
|
||||
if ($this->name === null && !$this->hasModel()) {
|
||||
throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified.");
|
||||
}
|
||||
if (!isset($this->options['id'])) {
|
||||
|
@ -29,6 +29,15 @@ use yii\web\View;
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* You can also use this widget in an [[yii\widgets\ActiveForm|ActiveForm]] using the [[yii\widgets\ActiveField::widget()|widget()]]
|
||||
* method, for example like this:
|
||||
*
|
||||
* ```php
|
||||
* <?= $form->field($model, 'from_date')->widget(\yii\jui\MaskedInput::classname(), [
|
||||
* 'mask' => '999-999-9999',
|
||||
* ]) ?>
|
||||
* ```
|
||||
*
|
||||
* The masked text field is implemented based on the
|
||||
* [jQuery input masked plugin](https://github.com/RobinHerbots/jquery.inputmask).
|
||||
*
|
||||
@ -143,8 +152,8 @@ class MaskedInput extends InputWidget
|
||||
{
|
||||
$options = $this->clientOptions;
|
||||
foreach ($options as $key => $value) {
|
||||
if (in_array($key, ['oncomplete', 'onincomplete', 'oncleared', 'onKeyUp', 'onKeyDown', 'onBeforeMask',
|
||||
'onBeforePaste', 'onUnMask', 'isComplete', 'determineActiveMasksetIndex']) && !$value instanceof JsExpression
|
||||
if (!$value instanceof JsExpression && in_array($key, ['oncomplete', 'onincomplete', 'oncleared', 'onKeyUp',
|
||||
'onKeyDown', 'onBeforeMask', 'onBeforePaste', 'onUnMask', 'isComplete', 'determineActiveMasksetIndex'])
|
||||
) {
|
||||
$options[$key] = new JsExpression($value);
|
||||
}
|
||||
|
Reference in New Issue
Block a user