Upgrading Instructions for Yii Framework v2
!!!IMPORTANT!!!
The following upgrading instructions are cumulative. That is, if you want to upgrade from version A to version C and there is version B between A and C, you need to follow the instructions for both A and B.
Make sure you have global install of latest version of composer asset plugin as well as a stable version of composer:
php composer.phar self-update
php composer.phar global require "fxp/composer-asset-plugin:^1.2.0"
Upgrade from Yii 2.0.8
- Part of code from
yii\web\User::loginByCookie()
method was moved to newgetIdentityAndDurationFromCookie()
andremoveIdentityCookie()
methods. If you overrideloginByCookie()
method, update it in order use new methods. - Fixture console command syntax was changed from
yii fixture "*" -User
toyii fixture "*, -User"
. Upgrade your scripts if necessary.
Upgrade from Yii 2.0.7
The signature of
yii\helpers\BaseArrayHelper::index()
was changed. The method has got an extra optional parameter$groups
.yii\helpers\BaseArrayHelper
methodsisIn()
andisSubset()
throw\yii\base\InvalidParamException
instead of\InvalidArgumentException
. If you wrap calls of these methods in try/catch block, change expected exception class.yii\rbac\ManagerInterface::canAddChild()
method was added. If you have custom backend for RBAC you need to implement it.The signature of
yii\web\User::loginRequired()
was changed. The method has got an extra optional parameter$checkAcceptHeader
.The signature of
yii\db\ColumnSchemaBuilder::__construct()
was changed. The method has got an extra optional parameter$db
. In case you are instantiating this class yourself and using the$config
parameter, you will need to move it to the right by one.String types in the MSSQL column schema map were upgraded to Unicode storage types. This will have no effect on existing columns, but any new columns you generate via the migrations engine will now store data as Unicode.
Output buffering was introduced in the pair of
yii\widgets\ActiveForm::init()
and::run()
. If you override any of these methods, make sure that output buffer handling is not corrupted. If you call the parent implementation, when overriding, everything should work fine. You should be doing that anyway.
Upgrade from Yii 2.0.6
- Added new requirement: ICU Data version >= 49.1. Please, ensure that your environment has ICU data installed and up to date to prevent unexpected behavior or crashes. This may not be the case on older systems e.g. running Debian Wheezy.
Tip: Use Yii2 Requirements checker for easy and fast check. Look for
requirements.php
in root of Basic and Advanced templates (howto-comment is in head of the script).
The signature of
yii\helpers\BaseInflector::transliterate()
was changed. The method is now public and has an extra optional parameter$transliterator
.-
In
yii\web\UrlRule
thepattern
matching group names are being replaced with the placeholders on class initialization to support wider range of allowed characters. Because of this change:- You are required to flush your application cache to remove outdated
UrlRule
serialized objects. See the Cache Flushing Guide - If you implement
parseRequest()
orcreateUrl()
and rely on parameter names, callsubstitutePlaceholderNames()
in order to replace temporary IDs with parameter names after doing matching.
- You are required to flush your application cache to remove outdated
-
The context of
yii.confirm
JavaScript function was changed fromyii
object to the DOM element which triggered the event.- If you overrode the
yii.confirm
function and accessed theyii
object throughthis
, you must access it with global variableyii
instead.
- If you overrode the
Traversable objects are now formatted as arrays in XML response to support SPL objects and Generators. Previous behavior could be turned on by setting
XmlResponseFormatter::$useTraversableAsArray
tofalse
.If you've implemented
yii\rbac\ManagerInterface
you need to implement additional methodgetUserIdsByRole($roleName)
.If you're using ApcCache with APCu, set
useApcu
totrue
in the component config.-
The
yii\behaviors\SluggableBehavior
class has been refactored to make it more reusable. Added newprotected
methods:isSlugNeeded()
makeUnique()
The visibility of the following Methods has changed from private
to protected
:
validateSlug()
-
generateUniqueSlug()
- The
yii\console\controllers\MessageController
class has been refactored to be better configurable and now also allows setting a lot of configuration options via command line. If you extend from this class, make sure it works as expected after these changes.
- The
Upgrade from Yii 2.0.5
- The signature of the following methods in
yii\console\controllers\MessageController
has changed. They have an extra parameter$markUnused
.saveMessagesToDb($messages, $db, $sourceMessageTable, $messageTable, $removeUnused, $languages, $markUnused)
saveMessagesToPHP($messages, $dirName, $overwrite, $removeUnused, $sort, $markUnused)
saveMessagesCategoryToPHP($messages, $fileName, $overwrite, $removeUnused, $sort, $category, $markUnused)
saveMessagesToPO($messages, $dirName, $overwrite, $removeUnused, $sort, $catalog, $markUnused)
Upgrade from Yii 2.0.4
Upgrading from 2.0.4 to 2.0.5 does not require any changes.
Upgrade from Yii 2.0.3
- Updated dependency to
cebe/markdown
to version1.1.x
. If you need stick with 1.0.x, you can specify that in yourcomposer.json
by adding the following line in therequire
section:
"cebe/markdown": "~1.0.0",
Upgrade from Yii 2.0.2
Starting from version 2.0.3 Yii Security
component relies on OpenSSL crypto lib instead of Mcrypt. The reason is that
Mcrypt is abandoned and isn't maintained for years. Therefore your PHP should be compiled with OpenSSL support. Most
probably there's nothing to worry because it is quite typical.
If you've extended yii\base\Security
to override any of the config constants you have to update your code:
- `MCRYPT_CIPHER` — now encoded in `$cipher` (and hence `$allowedCiphers`).
- `MCRYPT_MODE` — now encoded in `$cipher` (and hence `$allowedCiphers`).
- `KEY_SIZE` — now encoded in `$cipher` (and hence `$allowedCiphers`).
- `KDF_HASH` — now `$kdfHash`.
- `MAC_HASH` — now `$macHash`.
- `AUTH_KEY_INFO` — now `$authKeyInfo`.
Upgrade from Yii 2.0.0
- Upgraded Twitter Bootstrap to version 3.3.x.
If you need to use an older version (i.e. stick with 3.2.x) you can specify that in your
composer.json
by adding the following line in therequire
section:
"bower-asset/bootstrap": "3.2.*",
Upgrade from Yii 2.0 RC
If you've implemented
yii\rbac\ManagerInterface
you need to add implementation for new methodremoveChildren()
.The input dates for datetime formatting are now assumed to be in UTC unless a timezone is explicitly given. Before, the timezone assumed for input dates was the default timezone set by PHP which is the same as
Yii::$app->timeZone
. This causes trouble because the formatter usesYii::$app->timeZone
as the default values for output so no timezone conversion was possible. If your timestamps are stored in the database without a timezone identifier you have to ensure they are in UTC or add a timezone identifier explicitly.yii\bootstrap\Collapse
is now encoding labels by default.encode
item option and globalencodeLabels
property were introduced to disable it. Keys are no longer used as labels. You need to remove keys and uselabel
item option instead.The
yii\base\View::beforeRender()
andyii\base\View::afterRender()
methods have two extra parameters$viewFile
and$params
. If you are overriding these methods, you should adjust the method signature accordingly.If you've used
asImage
formatter i.e.Yii::$app->formatter->asImage($value, $alt);
you should change it toYii::$app->formatter->asImage($value, ['alt' => $alt]);
.Yii now requires
cebe/markdown
1.0.0 or higher, which includes breaking changes in its internal API. If you extend the markdown class you need to update your implementation. See https://github.com/cebe/markdown/releases/tag/1.0.0-rc for details. If you just used the markdown helper class there is no need to change anything.If you are using CUBRID DBMS, make sure to use at least version 9.3.0 as the server and also as the PDO extension. Quoting of values is broken in prior versions and Yii has no reliable way to work around this issue. A workaround that may have worked before has been removed in this release because it was not reliable.
Upgrade from Yii 2.0 Beta
- If you are using Composer to upgrade Yii, you should run the following command first (once for all) to install the composer-asset-plugin, before you update your project:
php composer.phar global require "fxp/composer-asset-plugin:~1.0.0"
You also need to add the following code to your project's composer.json
file:
"extra": {
"asset-installer-paths": {
"npm-asset-library": "vendor/npm",
"bower-asset-library": "vendor/bower"
}
}
It is also a good idea to upgrade composer itself to the latest version if you see any problems:
php composer.phar self-update
If you used
clearAll()
orclearAllAssignments()
ofyii\rbac\DbManager
, you should replace them withremoveAll()
andremoveAllAssignments()
respectively.If you created RBAC rule classes, you should modify their
execute()
method by adding$user
as the first parameter:execute($user, $item, $params)
. The$user
parameter represents the ID of the user currently being access checked. Previously, this is passed via$params['user']
.If you override
yii\grid\DataColumn::getDataCellValue()
with visibilityprotected
you have to change visibility topublic
as visibility of the base method has changed.If you have classes implementing
yii\web\IdentityInterface
(very common), you should modify the signature offindIdentityByAccessToken()
aspublic static function findIdentityByAccessToken($token, $type = null)
. The new$type
parameter will contain the type information about the access token. For example, if you useyii\filters\auth\HttpBearerAuth
authentication method, the value of this parameter will beyii\filters\auth\HttpBearerAuth
. This allows you to differentiate access tokens taken by different authentication methods.If you are sharing the same cache across different applications, you should configure the
keyPrefix
property of the cache component to use some unique string. Previously, this property was automatically assigned with a unique string.If you are using
dropDownList()
,listBox()
,activeDropDownList()
, oractiveListBox()
ofyii\helpers\Html
, and your list options use multiple blank spaces to format and align option label texts, you need to specify the optionencodeSpaces
to be true.If you are using
yii\grid\GridView
and have configured a data column to use a PHP callable to return cell values (viayii\grid\DataColumn::value
), you may need to adjust the signature of the callable to befunction ($model, $key, $index, $widget)
. The$key
parameter was newly added in this release.yii\console\controllers\AssetController
is now using hashes instead of timestamps. Replace all{ts}
with{hash}
.The database table of the
yii\log\DbTarget
now needs aprefix
column to store context information. You can add it withALTER TABLE log ADD COLUMN prefix TEXT AFTER log_time;
.The
fileinfo
PHP extension is now required by Yii. If you useyii\helpers\FileHelper::getMimeType()
, make sure you have enabled this extension. This extension is builtin in php above5.3
.Please update your main layout file by adding this line in the
<head>
section:<?= Html::csrfMetaTags() ?>
. This change is needed becauseyii\web\View
no longer automatically generates CSRF meta tags due to issue #3358.If your model code is using the
file
validation rule, you should rename itstypes
option toextensions
.MailEvent
class has been moved to theyii\mail
namespace. You have to adjust all references that may exist in your code.The behavior and signature of
ActiveRecord::afterSave()
has changed.ActiveRecord::$isNewRecord
will now always be false in afterSave and also dirty attributes are not available. This change has been made to have a more consistent and expected behavior. The changed attributes are now available in the new parameter of afterSave()$changedAttributes
.$changedAttributes
contains the old values of attributes that had changed and were saved.ActiveRecord::updateAttributes()
has been changed to not trigger events and not respect optimistic locking anymore to differentiate it more from callingupdate(false)
and to ensure it can be used inafterSave()
without triggering infinite loops.If you are developing RESTful APIs and using an authentication method such as
yii\filters\auth\HttpBasicAuth
, you should explicitly configureyii\web\User::enableSession
in the application configuration to be false to avoid starting a session when authentication is performed. Previously this was done automatically by authentication method.mail
component was renamed tomailer
,yii\log\EmailTarget::$mail
was renamed toyii\log\EmailTarget::$mailer
. Please update all references in the code and config files.yii\caching\GroupDependency
was renamed toTagDependency
. You should create such a dependency using the codenew \yii\caching\TagDependency(['tags' => 'TagName'])
, whereTagName
is similar to the group name that you previously used.If you are using the constant
YII_PATH
in your code, you should rename it toYII2_PATH
now.You must explicitly configure
yii\web\Request::cookieValidationKey
with a secret key. Previously this is done automatically. To do so, modify your application configuration like the following:
return [
// ...
'components' => [
'request' => [
'cookieValidationKey' => 'your secret key here',
],
],
];
Note: If you are using the
Advanced Project Template
you should not add this configuration tocommon/config
orconsole/config
because the console application doesn't have to deal with CSRF and uses its own request that doesn't havecookieValidationKey
property.
-
yii\rbac\PhpManager
now stores data in three separate files instead of one. In order to convert old file to new ones save the following code asconvert.php
that should be placed in the same directory yourrbac.php
is in:
<?php
$oldFile = 'rbac.php';
$itemsFile = 'items.php';
$assignmentsFile = 'assignments.php';
$rulesFile = 'rules.php';
$oldData = include $oldFile;
function saveToFile($data, $fileName) {
$out = var_export($data, true);
$out = "<?php\nreturn " . $out . ";";
$out = str_replace(['array (', ')'], ['[', ']'], $out);
file_put_contents($fileName, $out);
}
$items = [];
$assignments = [];
if (isset($oldData['items'])) {
foreach ($oldData['items'] as $name => $data) {
if (isset($data['assignments'])) {
foreach ($data['assignments'] as $userId => $assignmentData) {
$assignments[$userId][] = $assignmentData['roleName'];
}
unset($data['assignments']);
}
$items[$name] = $data;
}
}
$rules = [];
if (isset($oldData['rules'])) {
$rules = $oldData['rules'];
}
saveToFile($items, $itemsFile);
saveToFile($assignments, $assignmentsFile);
saveToFile($rules, $rulesFile);
echo "Done!\n";
Run it once, delete rbac.php
. If you've configured authFile
property, remove the line from config and instead
configure itemFile
, assignmentFile
and ruleFile
.
- Static helper
yii\helpers\Security
has been converted into an application component. You should change all usage of its methods to a new syntax, for example: instead ofyii\helpers\Security::hashData()
useYii::$app->getSecurity()->hashData()
. ThegenerateRandomKey()
method now produces not an ASCII compatible output. UsegenerateRandomString()
instead. Default encryption and hash parameters has been upgraded. If you need to decrypt/validate data that was encrypted/hashed before, use the following configuration of the 'security' component:
return [
'components' => [
'security' => [
'derivationIterations' => 1000,
],
// ...
],
// ...
];
- If you are using query caching, you should modify your relevant code as follows, as
beginCache()
andendCache()
are replaced bycache()
:
$db->cache(function ($db) {
// ... SQL queries that need to use query caching
}, $duration, $dependency);
Due to significant changes to security you need to upgrade your code to use
\yii\base\Security
component instead of helper. If you have any data encrypted it should be re-encrypted. In order to do so you can use old security helper as explained by @docsolver at github.[[yii\helpers\Url::to()]] will no longer prefix base URL to relative URLs. For example,
Url::to('images/logo.png')
will returnimages/logo.png
directly. If you want a relative URL to be prefix with base URL, you should make use of the alias@web
. For example,Url::to('@web/images/logo.png')
will return/BaseUrl/images/logo.png
.-
The following properties are now taking
false
instead ofnull
for "don't use" case:-
yii\bootstrap\NavBar::$brandLabel
. -
yii\bootstrap\NavBar::$brandUrl
. -
yii\bootstrap\Modal::$closeButton
. -
yii\bootstrap\Modal::$toggleButton
. -
yii\bootstrap\Alert::$closeButton
. -
yii\widgets\LinkPager::$nextPageLabel
. -
yii\widgets\LinkPager::$prevPageLabel
. -
yii\widgets\LinkPager::$firstPageLabel
. -
yii\widgets\LinkPager::$lastPageLabel
.
-
The format of the Faker fixture template is changed. For an example, please refer to the file
apps/advanced/common/tests/templates/fixtures/user.php
.-
The signature of all file downloading methods in
yii\web\Response
is changed, as summarized below:sendFile($filePath, $attachmentName = null, $options = [])
sendContentAsFile($content, $attachmentName, $options = [])
sendStreamAsFile($handle, $attachmentName, $options = [])
xSendFile($filePath, $attachmentName = null, $options = [])
The signature of callbacks used in
yii\base\ArrayableTrait::fields()
is changed fromfunction ($field, $model) {
tofunction ($model, $field) {
.Html::radio()
,Html::checkbox()
,Html::radioList()
,Html::checkboxList()
no longer generate the container tag around each radio/checkbox when you specify labels for them. You should manually render such container tags, or set theitem
option forHtml::radioList()
,Html::checkboxList()
to generate the container tags.-
The formatter class has been refactored to have only one class regardless whether PHP intl extension is installed or not. Functionality of
yii\base\Formatter
has been merged intoyii\i18n\Formatter
andyii\base\Formatter
has been removed so you have to replace all usage ofyii\base\Formatter
withyii\i18n\Formatter
in your code. Also the API of the Formatter class has changed in many ways. The signature of the following Methods has changed:asDate
asTime
asDatetime
-
asSize
has been split up intoasSize
andasShortSize
asCurrency
asDecimal
asPercent
asScientific
The following methods have been removed, this also means that the corresponding format which may be used by a GridView or DetailView is not available anymore:
asNumber
asDouble
Also due to these changes some formatting defaults have changes so you have to check all your GridView and DetailView configuration and make sure the formatting is displayed correctly.
The configuration for asSize()
has changed. It now uses the configuration for the number formatting from intl
and only the base is configured using $sizeFormatBase
.
The specification of the date and time formats is now using the ICU pattern format even if PHP intl extension is not installed.
You can prefix a date format with php:
to use the old format of the PHP date()
-function.
- The DateValidator has been refactored to use the same format as the Formatter class now (see previous change). When you use the DateValidator and did not specify a format it will now be what is configured in the formatter class instead of 'Y-m-d'. To get the old behavior of the DateValidator you have to set the format explicitly in your validation rule:
['attributeName', 'date', 'format' => 'php:Y-m-d'],
-
beforeValidate()
,beforeValidateAll()
,afterValidate()
,afterValidateAll()
,ajaxBeforeSend()
andajaxComplete()
are removed fromActiveForm
. The same functionality is now achieved via JavaScript event mechanism like the following:
$('#myform').on('beforeValidate', function (event, messages, deferreds) {
// called when the validation is triggered by submitting the form
// return false if you want to cancel the validation for the whole form
}).on('beforeValidateAttribute', function (event, attribute, messages, deferreds) {
// before validating an attribute
// return false if you want to cancel the validation for the attribute
}).on('afterValidateAttribute', function (event, attribute, messages) {
// ...
}).on('afterValidate', function (event, messages) {
// ...
}).on('beforeSubmit', function () {
// after all validations have passed
// you can do ajax form submission here
// return false if you want to stop form submission
});
-
The signature of
View::registerJsFile()
andView::registerCssFile()
has changed. The$depends
and$position
paramaters have been merged into$options
. The new signatures are as follows:registerJsFile($url, $options = [], $key = null)
registerCssFile($url, $options = [], $key = null)