📜 ⬆️ ⬇️

Yii 2.0.14

The Yii team is pleased to present a new version of the PHP framework: Yii 2.0.14. It includes more than a hundred improvements and fixes , including security fixes.


The release includes several changes that may affect already running applications. These changes are described in UPGRADE.md.


Thanks to the Yii community for helping out with this update!


You can follow the development process by putting an asterisk on GitHub . We have many Yii communities where you can ask for help or share your experience - we and thousands of other Yii users will be happy to participate.


This release is significant because it is becoming the latest release in Yii 2.0, containing improvements . This means that we will concentrate our efforts on developing version 2.1.x, which will include many new improvements that cannot be included in the 2.0.x branch due to limitations in maintaining backward compatibility. Despite this, the 2.0.x branch will receive fixes and security improvements. Deadlines for support for 2.0.x will be announced along with the release of version 2.1.


Make sure that the version of the framework in composer.json spelled correctly ( ~2.0.14 ) and you will not upgrade to 2.1 by accident when it is released.


Below we look at the most interesting improvements and fixes release. The full list can, as usual, be found in CHANGELOG .


Scalability and concurrency


The problems of scalability and concurrency often fade into the background at the beginning of development, but they “pop up” as the business grows. In this release, we found and fixed an error that related to writing values ​​to the database and updating the session ID. When using master-slave replication, yii\web\DbSession , yii\validators\UniqueValidator and yii\validators\ExistValidator could access the slave server, while it would be more correct to contact the master server.


Validator improvements


In addition to the above, there are a few more validator improvements.


First, ExistValidator can now check for the existence of links if the targetRelation property is targetRelation . This means that you can now describe the following configuration of validation rules:


 public function rules() { return [ [['customer_id'], 'exists', 'targetRelation' => 'customer'], ]; } public function getCustomer() { return $this->hasOne(Customer::class, ['id' => 'customer_id']); } 

Secondly, FileValidator received a new minFiles property indicating the minimum number of files that the user must upload.


Behavior


yii\behaviors\BlameableBehavior received a new defaultValue property, which is used when a user ID cannot be defined. This usually happens if the ActiveRecord model is used in a console application.


In yii\behaviors\AttributeTypecastBehavior a new property typecastAfterSave . If it is set to true , the attribute values ​​will be cast to the specified types immediately after saving the model. The types will be the same as when loading the model from the database.


The behavior of yii\behaviors\CacheableWidgetBehavior been added. It automatically caches the widget content according to the dependencies settings and the cache validity time. For example:


 use yii\behaviors\CacheableWidgetBehavior; public function behaviors() { return [ [ 'class' => CacheableWidgetBehavior::className(), 'cacheDuration' => 0, 'cacheDependency' => [ 'class' => 'yii\caching\DbDependency', 'sql' => 'SELECT MAX(updated_at) FROM posts', ], ], ]; } 

Databases and ActiveRecord


This release adds many new things related to databases and ActiveRecord. These improvements were implemented by Dmitry Naumenko , Sergey Makinen , Robert Korulchyk , Nikolay Oleynikov and other community members.


Object format for describing the condition and user data types


Support for custom data types has been implemented. Added JSON support for MySQL and PostgreSQL , as well as arrays for PostgreSQL . To achieve this, the internal implementation of Query Builder has been significantly reworked, which also made it possible to implement support for describing conditions in an object format . Support for the usual format of describing the conditions remained unchanged. In addition, the formats can be combined:


 $query->andWhere(new OrCondition([ new InCondition('type', 'in', $types), ['like', 'name', '%good%'], 'disabled=false', ])); 

This improvement has several advantages. First, it’s now easier for the Yii development team to maintain conditional code. This has already added a new condition BetweenColumnsCondition , which collects SQL like 15 BETWEEN min_age AND max_age . Release 2.1 is likely to add support for new condition types. Secondly, now you can conveniently create your own classes of conditions and use them in your projects.


Query Builder Flexibility


The changes described above allowed us to accept yii\db\Query in conditions wherever it was possible to transfer yii\db\Expression before. For example:


 $subquery = (new Query) ->select([new Expression(1)]) ->from('tree') ->where(['parent_id' => 1, 'id' => new Expression('tree.parent_id'])); (new Query()) ->from('tree') ->where(['or', 'parent_id = 1', $subquery]) 

Upsert


Another significant improvement in the database layer is support for UPSERT , an atomic operation that creates new records if they do not already exist (a unique key is being checked) or changes existing records. For example, take a look at the following code:


 Yii::$app->db->createCommand()->upsert('pages', [ 'name' => 'Front page', 'url' => 'http://example.com/', // URL  'visits' => 0, ], [ 'visits' => new \yii\db\Expression('visits + 1'), ], $params)->execute(); 

It either creates a new page, or increases its visitor count automatically.


Schema builder and migration


Schema builder now supports tiny integer and JSON types, so you can use them in writing migrations:


 $this->createTable('post', [ 'id' => $this->primaryKey(), 'text' => $this->text(), 'title' => $this->string()->notNull(), 'attributes' => $this->json(), 'status' => $this->tinyInteger(), ]); 

Another improvement allows you to create and delete views (views):


 $this->createView( 'top_10_posts', (new \yii\db\Query()) ->from('post') ->orderBy(['rating' => SORT_DESC]) ->limit(10) ); $this->dropView('top_10_posts'); 

New Request Caching API


Previously, it was possible to cache the result of a query by wrapping it in Connection::cache() . Now you can use a more convenient API:


 //   query (new Query())->cache(7200)->all(); //   AR User::find()->cache(7200)->all(); 

Links in Active Record


Active Record now resets the associated models when the attribute on which this relationship is built changes:


 $item = Item::findOne(1); echo $item->category_id; // 1 echo $item->category->name; // weapons $item->category_id = 2; echo $item->category->name; // toys 

Error processing


Logging targets now throw an exception when they cannot export the log correctly. Previously, they silently ignored the error, which could lead to the absence of logs, for example, due to incorrect rights to the directory.


Also now if HTTP headers have already been sent, when trying to send additional ones, the exception yii\web\HeadersAlreadySentException will be thrown. Previously, this situation was silently ignored.


Now it is possible to configure the Yii error handler by changing the $traceLine property. This can be used, for example, to generate links that can be opened immediately in the development environment. The setting is similar to setting up links for the debug panel :


 'components' => [ // ... 'errorHandler' => [ 'errorAction' => 'site/error', 'traceLine' => '<a href="ide://open?url={file}&line={line}">{html}</a>', ], ], 

Using the yii\web\ErrorAction::$layout property, you can conveniently change the error page template:


 class SiteController extends Controller { // ... /** * @inheritdoc */ public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', 'layout' => 'error', // <-- HERE ], ]; } 

Security


Two vulnerabilities were discovered and fixed:



PHP 7.2


Yii 2.0.14 fully supports PHP 7.2. We have yii\filters\HttpCache , FileHelper::getExtensionsByMimeType() and yii\web\Session for normal operation on all supported versions of PHP.


Widgets, forms, client javascript


The <script> no longer contains the type property. It looks shorter and makes HTML5 validators happy :)


In the fields generated by the Active Form and Html helper for model attributes, you can use an automatically generated placeholder:


 <?= Html::activeTextInput($post, 'title', ['placeholder' => true]) ?> 

On the way to Bootstrap 4 support, added the ability to specify which element will receive a class mark indicating that there is a validation error:


 <?php $form = ActiveForm::begin([ 'validationStateOn' => ActiveForm::VALIDATION_STATE_ON_INPUT, //  VALIDATION_STATE_ON_CONTAINER ]) ?> 

Now you can safely register JavaScript variables from PHP code:


 class SiteController extends Controller { public function actionIndex() { $this->view->registerJsVar('username', 'SilverFire'); return $this->render('index'); } } 

Despite the fact that this method is widely used to transfer data from PHP to JS, we still recommend that you first try to use the HTML5 feature - data attributes .


Developments


Pavel Klimov added support for event handling masks, so now you can subscribe to a group of event objects that fall under the mask.
This can be very useful for logging and auditing. A new section of the documentation contains a detailed description and many examples of using this feature.


API, serialization and filters


When configuring JsonResponseFormatter you can now specify the type of content:


 'components' => [ 'response' => [ // ... 'formatters' => [ \yii\web\Response::FORMAT_JSON => [ 'class' => \yii\web\JsonResponseFormatter::className(), 'contentType' => \yii\web\JsonResponseFormatter::CONTENT_TYPE_HAL_JSON, ], ], ], ] 

Data filter now supports lt , gt , lte and gte for yii\validators\DateValidator .


yii\base\ArrayableTrait::toArray() now supports recursion in the $fields and $expand properties. Requests to REST APIs expand can be described as extra1.extra2 and this will mean that you need to deploy extra1 in the initial data set, and then extra2 in extra1 . That is, requests like http://localhost/comments?expand=post.author are now possible.


It is now easier to implement support for your authentication headers using yii\filters\auth\HttpHeaderAuth .


In the case when you need to serialize validation errors in JSON, you can use the new method \yii\helpers\Json::errorSummary() .


Console


Console applications also have a convenient way to serialize model validation errors:


 if (!$model->validate()) { echo "Model is not valid:\n"; echo \yii\helpers\Console::errorSummary($model); return ExitCode::DATAERR; } 

Improved auto completion script for bash and zsh . Now it supports autocompletion for ./yii help .


By calling console commands, the parameters can be specified in both camelCase and kebab-case: --selfUpdate and --self-update will be considered the same parameter.
Moreover, in addition to --<option>=<value> there is support for syntax --<option> <value> .


Routing


Short syntax support has been added to describe the method in group rules:


 'components' => [ 'urlManager' => [ // ... 'rules' => [ new GroupUrlRule([ 'prefix' => 'file', 'rules' => [ 'POST document' => 'document/create', ], ]), ], ], 

i18n


The yii\i18n\Locale component has been added with the getCurrencySymbol() method, which returns the currency symbol in the selected locale.


Helpery


This release contains some interesting helper improvements.


Two new methods yii\helpers\FileHelper :



The yii\helpers\StringHelper matchWildcard() method has been added to yii\helpers\StringHelper , which does the same as the native fnmatch() method, but taking into account the features of the operating system. It is confirmed that the native implementation gives different results on different operating systems.


Added yii\helpers\IpHelper . It provides methods for determining the IP address version, checking the IP address or subnet for entering another subnet, and expanding the IPv6 address to the full format. For example:


 if (!IpHelper::inRange($ip, '192.168.1.0/24')) { // deny access } 

DI Container


In the container, it became possible to reuse the descriptions in the properties:


 'container' => [ 'definitions' => [ \console\models\TestService::class => [ 'class' => \console\models\TestService::class, 'model' => Instance::of(\console\models\TestModel::class) ], \console\models\TestModel::class => [ 'class' => \console\models\TestModel::class, 'property' => 20, ], ], ] 

In this example, the value of the model property in the TestService class will be an object of the TestModel class, configured as described.


Application Templates


In addition to some minor improvements, the basic template received support from Docker and Vagrant.


Preparing for Release 2.1


To simplify the transition from 2.0 to 2.1, Brandon Kelly suggested @deprecated methods and classes that have already been deleted in branch 2.1 with the @deprecated annotation in branch 2.0.x. This mark received:



The code that uses these methods will continue to work, but the IDE will highlight it as outdated.


')

Source: https://habr.com/ru/post/349408/


All Articles