- Extension code style should be similar to [core framework code style](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style).
- Extension code style SHOULD be similar to [core framework code style](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style).
- In case of using getter and setter for defining a property it's preferred to use method in extension code rather than property.
- All classes, methods and properties SHOULD be documented using phpdoc. Note that you can use markdown and link to properties and methods
- All classes, methods and properties should be documented using phpdoc. Note that you can use markdown and link to properties and methods
using the following syntax: e.g. `[[name()]]`, `[[name\space\MyClass::name()]]`.
using the following syntax: e.g. `[[name()]]`, `[[name\space\MyClass::name()]]`.
- If you're displaying errors to developers do not translate these (i.e. do not use `\Yii::t()`). Errors should be
- If you're displaying errors to developers do not translate these (i.e. do not use `\Yii::t()`). Errors should be
translated only if they're displayed to end users.
translated only if they're displayed to end users.
- Extension SHOULD NOT use class prefixes (i.e. `TbNavBar`, `EMyWidget`, etc.)
- Extension MUST provide a valid autoloading configuration in `composer.json`. Details can be found in the [composer documentation](http://getcomposer.org/doc/04-schema.md#autoload) or see all [official Yii2 extensions](https://github.com/yiisoft/yii2/tree/master/extensions/yii) for example.
### Namespace and package names
### Namespace and package names
@ -19,24 +22,38 @@ using the following syntax: e.g. `[[name()]]`, `[[name\space\MyClass::name()]]`.
- Extension MAY use a `yii2-` prefix in the composer vendor name (URL).
- Extension MAY use a `yii2-` prefix in the composer vendor name (URL).
- Extension MAY use a `yii2-` prefix in the repository name (URL).
- Extension MAY use a `yii2-` prefix in the repository name (URL).
### Dependencies
- Additional code, eg. libraries, SHOULD be required in your `composer.json` file.
- When extension is released in a stable version, its requirements SHOULD NOT include `dev` packages that do not have a `stable` release.
- Use appropriate version constraints, eg. `1.*`, `@stable` for requirements.
### Versioning
- Extension SHOULD follow the rules of [semantic versioning](http://semver.org).
- Use a consistent format for your repository tags, as they are treated as version strings by composer, eg. `0.2.4`,`0.2.5`,`0.3.0`,`1.0.0`.
Distribution
Distribution
------------
------------
- There should be a `readme.md` file clearly describing what extension does in English, its requirements, how to install
- There should be a `readme.md` file clearly describing what extension does in English, its requirements, how to install
and use it. It should be written using markdown. If you want to provide translated readme, name it as `readme_ru.md`
and use it. It should be written using markdown. If you want to provide translated readme, name it as `readme_ru.md`
where `ru` is your language code. If extension provides a widget it is a good idea to include some screenshots.
where `ru` is your language code. If extension provides a widget it is a good idea to include some screenshots.
- It is recommended to host your extensions at [Github](github.com).
- Extension MUST be registered at [Packagist](https://packagist.org).
- TBD: composer.json
- TBD: composer.json
- It is recommended to host your extensions at github.com.
Working with database
Working with database
---------------------
---------------------
- If extension creates or modifies database schema always use Yii migrations instead of SQL files or custom scripts.
- If extension creates or modifies database schema always use Yii migrations instead of SQL files or custom scripts.
- Migrations SHOULD be DBMS agnostic.
- You MUST NOT make use of active-record model classes in your migrations.
Assets
Assets
------
------
TBD
- Asset files MUST be registered through Bundles.
Events
Events
------
------
@ -46,9 +63,16 @@ TBD
i18n
i18n
----
----
TBD
- Extension SHOULD provide at least one message catalogue with either source or target language in English.
- Extension MAY provide a configuration for creating message catalogues.
Authorization
-------------
- Auth-items for controllers SHOULD be named after the following format `vendor\ext\controller\action`.
- Auth-items names may be shortened using an asterisk, eg. `vendor\ext\*`
Yii provides a basic database access layer as was described in [Database basics](database-basics.md) section. Still it's
Yii provides a basic database access layer as described in the [Database basics](database-basics.md) section. The database access layer provides a low-level way to interact with the database. While useful in some situations, it can be tedious to rely too much upon direct SQL. An alternative approach that Yii provides is the Query Builder. The Query Builder provides an object-oriented vehicle for generating queries to be executed.
a bit too much to use SQL directly all the time. To solve the issue Yii provides a query builder that allows you to
work with the database in object-oriented style.
Basic query builder usage is the following:
Here's a basic example:
```php
```php
$query = new Query;
$query = new Query;
// Define query
// Define the query:
$query->select('id, name')
$query->select('id, name')
->from('tbl_user')
->from('tbl_user')
->limit(10);
->limit(10);
// Create a command. You can get the actual SQL using $command->sql
// Create a command.
$command = $query->createCommand();
$command = $query->createCommand();
// Execute command
// You can get the actual SQL using $command->sql
// Execute the command:
$rows = $command->queryAll();
$rows = $command->queryAll();
```
```
Basic selects and joins
Basic selects
-----------------------
-------------
In order to form a `SELECT` query you need to specify what to select and where to select it from.
In order to form a basic `SELECT` query, you need to specify what columns to select and from what table:
```php
```php
$query->select('id, name')
$query->select('id, name')
->from('tbl_user');
->from('tbl_user');
```
```
If you want to get IDs of all users with posts you can use `DISTINCT`. With query builder it will look like the following:
Select options can be specified as a comma-separated string, as in the above, or as an array. The array syntax is especially useful when forming the selection dynamically:
The first argument is the join type to perform. The second is the table to join to, and the third is the condition.
Specifying SELECT conditions
---------------------
---------------------
Usually you need data that matches some conditions. There are some useful methods to specify these and the most powerful
Usually data is selected based upon certain criteria. Query Builder has some useful methods to specify these, the most powerful of which being `where`. It can be used in multiple ways.
is `where`. There are multiple ways to use it.
The simplest is to specify condition in a string:
The simplest way to apply a condition is to use a string:
When using this format make sure you're binding parameters and not creating a query by string concatenation.
When using strings, make sure you're binding the query parameters, not creating a query by string concatenation. The above approach is safe to use, the following is not:
Instead of binding status value immediately you can do it using `params` or `addParams`:
```php
$query->where("status=$status"); // Dangerous!
```
Instead of binding the status value immediately, you can do so using `params` or `addParams`:
```php
```php
$query->where('status=:status');
$query->where('status=:status');
$query->addParams([':status' => $status]);
$query->addParams([':status' => $status]);
```
```
There is another convenient way to use the method called hash format:
Multiple conditions can simultaneously be set in `where` using the *hash format*:
```php
```php
$query->where([
$query->where([
@ -90,19 +102,19 @@ $query->where([
]);
]);
```
```
It will generate the following SQL:
That code will generate the following SQL:
```sql
```sql
WHERE (`status` = 10) AND (`type` = 2) AND (`id` IN (4, 8, 15, 16, 23, 42))
WHERE (`status` = 10) AND (`type` = 2) AND (`id` IN (4, 8, 15, 16, 23, 42))
```
```
If you'll specify value as `null` such as the following:
NULL is a special value in databases, and is handled smartly by the Query Builder. This code:
```php
```php
$query->where(['status' => null]);
$query->where(['status' => null]);
```
```
SQL generated will be:
results in this WHERE clause:
```sql
```sql
WHERE (`status` IS NULL)
WHERE (`status` IS NULL)
@ -174,6 +186,15 @@ $query->orderBy([
Here we are ordering by `id` ascending and then by `name` descending.
Here we are ordering by `id` ascending and then by `name` descending.
Distinct
--------
If you want to get IDs of all users with posts you can use `DISTINCT`. With query builder it will look like the following:
3. Change `composer.json`. Instead of all stable requirements add just one `"yiisoft/yii2-dev": "*"`.
3. Change `composer.json`. Instead of all stable requirements add just one `"yiisoft/yii2-dev": "*"`.
4. Execute `composer install`.
4. Execute `composer create-project`.
5. Now you have working playground that uses latest code.
5. Now you have working playground that uses latest code.
Note that requirements of extensions that come with `yii2-dev` are not loaded automatically.
If you want to use an extension, check if there are dependencies suggested for it and add them
to your `composer.json`. You can see suggested packages by running `composer show yiisoft/yii2-dev`.
If you're core developer there's no extra step needed. You can change framework code under
If you're core developer there's no extra step needed. You can change framework code under
`vendor/yiisoft/yii2-dev` and push it to main repository.
`vendor/yiisoft/yii2-dev` and push it to main repository.
@ -23,3 +27,5 @@ If you're not core developer or want to use your own fork for pull requests:
[remote "origin"]
[remote "origin"]
url = git://github.com/username/yii2.git
url = git://github.com/username/yii2.git
```
```
> Hint: The workflow of forking a package and pushing changes back into your fork and then sending a pull-request to the maintainer is the same for all extensions you require via composer.
B = Major version. Non-BC changes with upgrade instructions.
B = Major version. Non-BC changes with upgrade instructions.
C = BC changes and additions.
C = BC changes and additions.
A.B.CrcD
Release candidates
------------------
A.B.C-rc
A.B.C-rc2
This is when we want to do a release candidate. RC number increments till we're getting a stable release with no
critical bugs and backwards incompatibility reports.
Alphas and betas
----------------
A.B.C-alpha
A.B.C-alpha2
Alphas are unstable versions where significant bugs may and probably do exist. API isn't fixed yet and may be changed
significantly. `alpha2` etc. may or may not be released based on overall stability of code and API.
A.B.C-beta
A.B.C-beta2
This is when we want to release release candidate. D is the RC number. Starts with 1 and increments till we're getting a stable release with no critical bugs and BC incompatibility reports.
Beta is more or less stable with less bugs and API instability than alphas. There still could be changes in API but
This extension provides a `Codeception` mail solution for Yii 2. It includes some classes that are useful
This extension provides [Codeception](http://codeception.com/) integration for the Yii Framework 2.0.
for unit-testing (```TestCase```) or for codeception page-objects (```BasePage```).
When using codeception page-objects they have some similar code, this code was extracted and put into the ```BasePage```
It provides classes that help with testing with codeception:
class to reduce code duplication. Simply extend your page object from this class, like it is done in ```yii2-basic``` and
```yii2-advanced``` boilerplates.
For unit testing there is a ```TestCase``` class which holds some common features like application creation before each test
- a base class for unit-tests: `yii\codeception\TestCase
and application destroy after each test. You can configure your application by this class. ```TestCase``` is extended from ```PHPUnit_Framework_TestCase``` so all
- a base class for codeception page-objects: `yii\codeception\BasePage`.
methods and assertions are available.
- a solution for testing emails
Installation
------------
The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
Then run command ```php codecept.phar run --debug unit/SomeDebugTest``` (Codeception also available through composer) and you will see in output:
Then run command `php codecept.phar run --debug unit/SomeDebugTest` and you will see in output:
```html
```html
some my string
some string
Array
Array
(
(
@ -104,25 +149,4 @@ Then run command ```php codecept.phar run --debug unit/SomeDebugTest``` (Codecep
```
```
For further instructions refer to the testing section in the [Yii Definitive Guide](https://github.com/yiisoft/yii2/blob/master/docs/guide/testing.md).
For further instructions refer to the related section in the Yii Definitive Guide (https://github.com/yiisoft/yii2/blob/master/docs/guide/testing.md).
Installation
------------
The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
throw new InvalidParamException('Relation names are case sensitive. ' . get_class($this) . " has a relation named \"$realName\" instead of \"$name\".");
throw new InvalidParamException('Relation names are case sensitive. ' . get_class($this) . " has a relation named \"$realName\" instead of \"$name\".");
}
}
return $relation;
}
}
/**
/**
@ -1217,11 +1234,10 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface