Browse Source

Finished extension and third-party lib usage guide [skip ci]

tags/2.0.0-rc
Qiang Xue 10 years ago
parent
commit
b66300788b
  1. 12
      docs/guide/README.md
  2. 149
      docs/guide/extend-creating-extensions.md
  3. 0
      docs/guide/extend-customizing-core.md
  4. 155
      docs/guide/extend-using-composer.md
  5. 177
      docs/guide/extend-using-libs.md
  6. 271
      docs/guide/structure-extensions.md
  7. 167
      docs/guide/tutorial-yii-integration.md
  8. 11
      docs/internals/translation-status.md

12
docs/guide/README.md

@ -157,17 +157,6 @@ Testing
* [Fixtures](test-fixtures.md)
Extending Yii
-------------
* [Creating Extensions](extend-creating-extensions.md)
* [Customizing Core Code](extend-customizing-core.md)
* [Using 3rd-Party Libraries](extend-using-libs.md)
* **TBD** [Using Yii in 3rd-Party Systems](extend-embedding-in-others.md)
* **TBD** [Using Yii 1.1 and 2.0 Together](extend-using-v1-v2.md)
* [Using Composer](extend-using-composer.md)
Special Topics
--------------
@ -180,6 +169,7 @@ Special Topics
* [Performance Tuning](tutorial-performance-tuning.md)
* **TBD** [Shared Hosting Environment](tutorial-shared-hosting.md)
* [Template Engines](tutorial-template-engines.md)
* [Working with Third-Party Code](tutorial-yii-integration.md)
Widgets

149
docs/guide/extend-creating-extensions.md

@ -1,149 +0,0 @@
Extending Yii
=============
> Note: This section is under development.
The Yii framework was designed to be easily extensible. Additional features can be added to your project and then reused, either by yourself on other projects or by sharing your work as a formal Yii extension.
Code style
----------
To be consistent with core Yii conventions, your extensions ought to adhere to certain coding styles:
- Use the [core framework code style](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style).
- Document classes, methods and properties using [phpdoc](http://www.phpdoc.org/). - Extension classes should *not* be prefixed. Do not use the format `TbNavBar`, `EMyWidget`, etc.
> Note that you can use Markdown within your code for documentation purposes. With Markdown, you can link to properties and methods using the following syntax: `[[name()]]`, `[[namespace\MyClass::name()]]`.
### Namespace
Yii 2 relies upon namespaces to organize code. (Namespace support was added to PHP in version 5.3.) If you want to use namespaces within your extension,
- Do not use `yiisoft` anywhere in your namespaces.
- Do not use `\yii`, `\yii2` or `\yiisoft` as root namespaces.
- Namespaces should use the syntax `vendorName\uniqueName`.
Choosing a unique namespace is important to prevent name collisions, and also results in faster autoloading of classes. Examples of unique, consistent namepacing are:
- `samdark\wiki`
- `samdark\debugger`
- `samdark\googlemap`
Distribution
------------
Beyond the code itself, the entire extension distribution ought to have certain things.
There should be a `readme.md` file, written in English. This file should clearly describe what the extension does, its requirements, how to install it,
and to use it. The README should be written using Markdown. If you want to provide translated README files, name them as `readme_ru.md`
where `ru` is your language code (in this case, Russian).
It is a good idea to include some screenshots as part of the documentation, especially if your extension provides a widget.
It is recommended to host your extensions at [Github](https://github.com).
Extensions should also be registered at [Packagist](https://packagist.org) in order to be installable via Composer.
### Composer package name
Choose your extension's package name wisely, as you shouldn't change the package name later on. (Changing the name leads to losing the Composer stats, and makes it impossible for people to install the package by the old name.)
If your extension was made specifically for Yii2 (i.e. cannot be used as a standalone PHP library) it is recommended to
name it like the following:
```
yii2-my-extension-name-type
```
Where:
- `yii2-` is a prefix.
- The extension name is in all lowercase letters, with words separated by `-`.
- The `-type` postfix may be `widget`, `behavior`, `module` etc.
### Dependencies
Some extensions you develop may have their own dependencies, such as relying upon other extensions or third-party libraries. When dependencies exist, you should require them in your extension's `composer.json` file. Be certain to also use appropriate version constraints, eg. `1.*`, `@stable` for requirements.
Finally, when your extension is released in a stable version, double-check that its requirements do not include `dev` packages that do not have a `stable` release. In other words, the stable release of your extension should only rely upon stable dependencies.
### Versioning
As you maintain and upgrading your extension,
- Use 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`.
### composer.json
Yii2 uses Composer for installation, and extensions for Yii2 should as well. Towards that end,
- Use the type `yii2-extension` in `composer.json` file if your extension is Yii-specific.
- Do not use `yii` or `yii2` as the Composer vendor name.
- Do not use `yiisoft` in the Composer package name or the Composer vendor name.
If your extension classes reside directly in the repository root directory, you can use the PSR-4 autoloader in the following way in your `composer.json` file:
```json
{
"name": "myname/mywidget",
"description": "My widget is a cool widget that does everything",
"keywords": ["yii", "extension", "widget", "cool"],
"homepage": "https://github.com/myname/yii2-mywidget-widget",
"type": "yii2-extension",
"license": "BSD-3-Clause",
"authors": [
{
"name": "John Doe",
"email": "doe@example.com"
}
],
"require": {
"yiisoft/yii2": "*"
},
"autoload": {
"psr-4": {
"myname\\mywidget\\": ""
}
}
}
```
In the above, `myname/mywidget` is the package name that will be registered
at [Packagist](https://packagist.org). It is common for the package name to match your Github repository name.
Also, the `psr-4` autoloader is specified in the above, which maps the `myname\mywidget` namespace to the root directory where the classes reside.
More details on this syntax can be found in the [Composer documentation](http://getcomposer.org/doc/04-schema.md#autoload).
Working with database
---------------------
Extensions sometimes have to use their own database tables. In such a situation,
- If the extension creates or modifies the database schema, always use Yii migrations instead of SQL files or custom scripts.
- Migrations should be applicable to different database systems.
- Do not use Active Record models in your migrations.
Assets
------
- Register assets [through bundles](assets.md).
Events
------
TBD
i18n
----
- If extension outputs messages intended for end user these should be wrapped into `Yii::t()` in order to be translatable.
- Exceptions and other developer-oriented message should not be translated.
- Consider proving `config.php` for `yii message` command to simplify translation.
Testing your extension
----------------------
- Consider adding unit tests for PHPUnit.

0
docs/guide/extend-customizing-core.md

155
docs/guide/extend-using-composer.md

@ -1,155 +0,0 @@
Composer
========
> Note: This section is under development.
Yii2 uses Composer as its dependency management tool. Composer is a PHP utility that can automatically handle the installation of needed libraries and
extensions, thereby keeping those third-party resources up to date while absolving you of the need to manually manage the project's dependencies.
Installing Composer
-------------------
In order to install Composer, check the official guide for your operating system:
* [Linux](http://getcomposer.org/doc/00-intro.md#installation-nix)
* [Windows](http://getcomposer.org/doc/00-intro.md#installation-windows)
All of the details can be found in the guide, but you'll either download Composer directly from <http://getcomposer.org/>, or run the following command:
```
curl -s http://getcomposer.org/installer | php
```
We strongly recommend a global composer installation.
Installing Composer Class Autoloader
------------------------------------
Make sure the [entry script](concept-entry-scripts.md) of your application contains the following lines of code:
```php
// install Composer's class autoloader
require(__DIR__ . '/../vendor/autoload.php');
// include Yii class file
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
```
Working with composer
---------------------
The act of [installing a Yii application](installation.md) with
```
composer.phar create-project --stability dev yiisoft/yii2-app-basic
```
creates a new root directory for your project along with the `composer.json` and `compoer.lock` file.
While the former lists the packages, which your application requires directly together with a version constraint, while the latter keeps track of all installed packages and their dependencies in a specific revision. Therefore the `composer.lock` file should also be [committed to your version control system](https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file).
These two files are strongly linked to the two composer commands `update` and `install`.
Usually, when working with your project, such as creating another copy for development or deployment, you will use
```
composer.phar install
```
to make sure you get exactly the same packages and versions as specified in `composer.lock`.
Only if want to intentionally update the packages in your project you should run
```
composer.phar update
```
As an example, packages on `dev-master` will constantly get new updates when you run `update`, while running `install` won't, unless you've pulled an update of the `composer.lock` file.
There are several parameters available to the above commands. Very commonly used ones are `--no-dev`, which would skip packages in the `require-dev` section and `--prefer-dist`, which downloads archives if available, instead of checking out repositories to your `vendor` folder.
> Composer commands must be executed within your Yii project's directory, where the `composer.json` file can be found.
Depending upon your operating system and setup, you may need to provide paths to the PHP executable and
to the `composer.phar` script.
Adding more packages to your project
------------------------------------
To add two new packages to your project run the follwing command:
```
composer.phar require "cebe/indent:>=1.0.2" "cebe/yii2-gravatar:>1.1"
```
This will resolve the dependencies and then update your `composer.json` file.
The above example says that a version greater than or equal to 1.0.3 of indent converter package
and version 1.1 or greater of gravatar extension are required.
For details of this syntax, see the [official Composer documentation](https://getcomposer.org/doc/01-basic-usage.md#package-versions).
The full list of available Composer-supported PHP packages can be found at [packagist](http://packagist.org/). You may also search packages interactively just by entering `composer.phar require`.
### Manually editing your version constraints
You may also edit the `composer.json` file manually. Within the `require` section, you specify the name and version of each required package, same as with the command above.
```json
{
"require": {
"michelf/php-markdown": ">=1.4",
"ezyang/htmlpurifier": ">=4.6.0"
}
}
```
Once you have edited the `composer.json`, you can invoke Composer to download the updated dependencies. Run
```
composer.phar update michelf/php-markdown ezyang/htmlpurifier
```
afterwards.
> Depending on the package additional configuration may be required (eg. you have to register a module in the config), but autoloading of the classes should be handled by composer.
Using a specific version of a package
------------------------------------
Yii always comes with the latest version of a required library that it is compatible with, but allows you to use an older version if you need to.
A good example for this is jQuery which has [dropped old IE browser support](http://jquery.com/browser-support/) in version 2.x.
When installing Yii via composer the installed jQuery version will be the latest 2.x release. When you want to use jQuery 1.10
because of IE browser support you can adjust your composer.json by requiring a specific version of jQuery like this:
```json
{
"require": {
...
"yiisoft/jquery": "1.10.*"
}
}
```
FAQ
---
### Getting "You must enable the openssl extension to download files via https"
If you're using WAMP check [this answer at StackOverflow](http://stackoverflow.com/a/14265815/1106908).
### Getting "Failed to clone <URL here>, git was not found, check that it is installed and in your Path env."
Either install git or try adding `--prefer-dist` to the end of `install` or `update` command.
### Should I Commit The Dependencies In My Vendor Directory?
Short answer: No. Long answer, see [here](https://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md).
See also
--------
- [Official Composer documentation](http://getcomposer.org).

177
docs/guide/extend-using-libs.md

@ -1,177 +0,0 @@
Using 3rd-Party Libraries
=========================
> Note: This section is under development.
Yii is carefully designed so that third-party libraries can be
easily integrated to further extend Yii's functionalities.
Using Packages Installed via Composer
-------------------------------------
Packages installed via Composer can be directly used in Yii without any special handling.
Using Downloaded Libraries
--------------------------
If a library has its own class autoloader, please follow its instruction on how to install the autoloader.
If a library does not have a class autoloader, you may face one of the following scenarios:
* The library requires specific PHP include path configuration.
* The library requires explicitly including one or several of its files.
* Neither of the above.
In the last scenario, the library is not written very well, but you can still do the following
work to make it work with Yii:
* Identify which classes the library contains.
* List the classes and the corresponding file paths in `Yii::$classMap`.
For example, if none of the classes in a library is namespaced, you may register the classes with Yii
like the following in the entry script after including `yii.php`:
```php
Yii::$classMap['Class1'] = 'path/to/Class1.php';
Yii::$classMap['Class2'] = 'path/to/Class2.php';
// ...
```
Using Yii in 3rd-Party Systems
------------------------------
Yii can also be used as a self-contained library to support developing and enhancing
existing 3rd-party systems, such as WordPress, Joomla, etc. To do so, include
the following code in the bootstrap code of the 3rd-party system:
```php
$yiiConfig = require(__DIR__ . '/../config/yii/web.php');
new yii\web\Application($yiiConfig); // No 'run()' invocation!
```
The above code is very similar to the bootstrap code used by a typical Yii application
except one thing: it does not call the `run()` method after creating the Web application
instance.
Now we can use most features offered by Yii when developing 3rd-party enhancements. For example,
we can use `Yii::$app` to access the application instance; we can use the database features
such as ActiveRecord; we can use the model and validation feature; and so on.
Using Yii2 with Yii1
--------------------
Yii2 can be used along with Yii1 at the same project.
Since Yii2 uses namespaced class names they will not conflict with any class from Yii1.
However there is single class, which name is used both in Yii1 and Yii2, it named 'Yii'.
In order to use both Yii1 and Yii2 you need to resolve this collision.
To do so you need to define your own 'Yii' class, which will combine content of 'Yii' from 1.x
and 'Yii' from 2.x.
When using composer you add the following to your composer.json in order to add both versions of yii to your project:
```json
"require": {
"yiisoft/yii": "*",
"yiisoft/yii2": "*",
},
```
Start from defining your own descendant of [[yii\BaseYii]]:
```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php');
class Yii extends \yii\BaseYii
{
}
Yii::$classMap = include($yii2path . '/classes.php');
```
Now we have a class, which suites Yii2, but causes fatal errors for Yii1.
So, first of all, we need to include `YiiBase` of Yii1 source code to our 'Yii' class
definition file:
```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php'); // Yii 2.x
$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php'); // Yii 1.x
class Yii extends \yii\BaseYii
{
}
Yii::$classMap = include($yii2path . '/classes.php');
```
Using this, defines all necessary constants and autoloader of Yii1.
Now we need to add all fields and methods from `YiiBase` of Yii1 to our 'Yii' class.
Unfortunately, there is no way to do so but copy-paste:
```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php');
$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php');
class Yii extends \yii\BaseYii
{
public static $classMap = [];
public static $enableIncludePath = true;
private static $_aliases = ['system'=>YII_PATH,'zii'=>YII_ZII_PATH];
private static $_imports = [];
private static $_includePaths;
private static $_app;
private static $_logger;
public static function getVersion()
{
return '1.1.15-dev';
}
public static function createWebApplication($config=null)
{
return self::createApplication('CWebApplication',$config);
}
public static function app()
{
return self::$_app;
}
// Rest of \YiiBase internal code placed here
...
}
Yii::$classMap = include($yii2path . '/classes.php');
Yii::registerAutoloader(['Yii', 'autoload']); // Register Yii2 autoloader via Yii1
```
Note: while copying methods you should NOT copy method "autoload()"!
Also you may avoid copying "log()", "trace()", "beginProfile()", "endProfile()"
in case you want to use Yii2 logging instead of Yii1 one.
Now we have 'Yii' class, which suites both Yii 1.x and Yii 2.x.
So bootstrap code used by your application will looks like following:
```php
require(__DIR__ . '/../components/my/Yii.php'); // include created 'Yii' class
$yii2Config = require(__DIR__ . '/../config/yii2/web.php');
new yii\web\Application($yii2Config); // create Yii 2.x application
$yii1Config = require(__DIR__ . '/../config/yii1/main.php');
Yii::createWebApplication($yii1Config)->run(); // create Yii 1.x application
```
Then in any part of your program ```Yii::$app``` refers to Yii 2.x application,
while ```Yii::app()``` refers to Yii 1.x application:
```php
echo get_class(Yii::app()); // outputs 'CWebApplication'
echo get_class(Yii::$app); // outputs 'yii\web\Application'
```

271
docs/guide/structure-extensions.md

@ -11,7 +11,7 @@ other people your great work.
that can be used without Yii, we will refer to them using the term "package" or "library".
## Using Extensions
## Using Extensions <a name="using-extensions"></a>
To use an extension, you need to install it first. Most extensions are distributed as [Composer](https://getcomposer.org/)
packages which can be installed by taking the following two simple steps:
@ -19,8 +19,7 @@ packages which can be installed by taking the following two simple steps:
1. modify the `composer.json` file of your application and specify which extensions (Composer packages) you want to install.
2. run `php composer.phar install` to install the specified extensions.
You may need to install [Composer](https://getcomposer.org/) if you do not have it. Composer is a dependency
manager. This means when installing a package, it will install all its dependent packages automatically.
Note that you may need to install [Composer](https://getcomposer.org/) if you do not have it.
By default, Composer installs packages registered on [Packagist](https://packagist.org/) - the biggest repository
for open source Composer packages. You can look for extensions on Packagist. You may also
@ -28,7 +27,8 @@ for open source Composer packages. You can look for extensions on Packagist. You
to use it. This is useful if you are developing closed open extensions and want to share within your projects.
Extensions installed by Composer are stored in the `BasePath/vendor` directory, where `BasePath` refers to the
application's [base path](structure-applications.md#basePath).
application's [base path](structure-applications.md#basePath). Because Composer is a dependency manager, when
it installs a package, it will also install all its dependent packages.
For example, to install the `yiisoft/yii2-imagine` extension, modify your `composer.json` like the following:
@ -66,36 +66,53 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120)
> Info: Extension classes are autoloaded by the [Yii class autoloader](concept-autoloading.md).
## Creating Extensions
### Installing Extensions Manually <a name="installing-extensions-manually"></a>
An extension can contain any code you like, such as a helper class, a widget, a module, etc.
In some rare occasions, you may want to install some or all extensions manually, rather than relying on Composer.
To do so, you should
You may consider creating an extension when you feel the need to redistribute some of your great code so that
they can be easily reused by other people or in your other projects.
1. download the extension archive files and unpack them in the `vendor` directory.
2. install the class autoloaders provided by the extensions, if any.
3. download and install all dependent extensions as instructed.
It is recommended that you create an extension in terms of a [Composer package](https://getcomposer.org/) so that
it can be more easily installed and used by other users, liked described in the last subsection.
If an extension does not have a class autoloader but follows the [PSR-4 standard](http://www.php-fig.org/psr/psr-4/),
you may use the class autoloader provided by Yii to autoload the extension classes. All you need to do is just to
declare a [root alias](concept-aliases.md#defining-aliases) for the extension root directory. For example,
assuming you have installed an extension in the directory `vendor/mycompany/myext`, and the extension classes
are under the `myext` namespace, then you can include the following code in your application configuration:
```php
[
'aliases' => [
'@myext' => '@vendor/mycompany/myext',
],
]
```
### Basic Steps
## Creating Extensions <a name="creating-extensions"></a>
Below are the basic steps you may follow to create an extension.
You may consider creating an extension when you feel the need to share with other people your great code.
An extension can contain any code you like, such as a helper class, a widget, a module, etc.
It is recommended that you create an extension in terms of a [Composer package](https://getcomposer.org/) so that
it can be more easily installed and used by other users, liked described in the last subsection.
Below are the basic steps you may follow to create an extension as a Composer package.
1. Create a project for your extension and host it on a VCS repository, such as [github.com](https://github.com).
Development and maintenance work about the extension should be done on this repository.
The development and maintenance work about the extension should be done on this repository.
2. Under the root directory of the project, create a file named `composer.json` as required by Composer. Please
refer to the next subsection for more details.
3. Register your extension with a Composer repository so that other users can find and install your extension.
If you are creating an open source extension, you can register it with [Packagist](https://packagist.org/);
If you are creating a private extension for internal use, you may register it with
[your own repository](https://getcomposer.org/doc/05-repositories.md#hosting-your-own).
3. Register your extension with a Composer repository, such as [Packagist](https://packagist.org/), so that
other users can find and install your extension using Composer.
### `composer.json`
### `composer.json` <a name="composer-json"></a>
Each Composer package must have a `composer.json` file in its root directory. The file contains the metadata about
the package. You may find complete specification about this file in the [Composer Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup).
You may also refer to the following example which is the `composer.json` file for the `yiisoft/yii2-imagine` extension:
The following example shows the `composer.json` file for the `yiisoft/yii2-imagine` extension:
```json
{
@ -137,36 +154,38 @@ You may also refer to the following example which is the `composer.json` file fo
}
```
> Info: It is important that you specify the package type as `yii2-extension` so that the package can
be recognized as a Yii extension when being installed.
#### Package Name <a name="package-name"></a>
### Package Names
Each Composer package should have a package name which uniquely identifies the package among all others.
The format of package names is `vendorName/projectName`. For example, in the package name `yiisoft/yii2-imagine`,
the vendor name and the project name are `yiisoft` and `yii2-imagine`, respectively.
Each extension, when released as a Composer package, should have a package name which uniquely identifies itself
among all other packages. The format of package names is `vendorName/projectName`. For example, in the package name
`yiisoft/yii2-imagine`, the vendor name and the project name are `yiisoft` and `yii2-imagine`, respectively.
Do NOT use `yiisoft` as vendor name as it is reserved for use by the Yii core code.
Do NOT use `yiisoft` as vendor name as this is reserved for use by the Yii core code.
We recommend you prefix `yii2-` to the project name for packages representing Yii 2 extensions, for example,
`myname/yii2-mywidget`. This will allow users to more easily tell whether a package is a Yii 2 extension.
Also, to easily tell from package name whether a package is a Yii extension, we recommend you prefix `yii2-`
to the project name.
#### Package Type <a name="package-type"></a>
### Namespaces
It is important that you specify the package type of your extension as `yii2-extension` so that the package can
be recognized as a Yii extension when being installed.
To avoid name collisions and make the classes in your extension autoloadable, you should use namespaces and
name the classes in your extension by following the [PSR-4 standard](http://www.php-fig.org/psr/psr-4/) or
[PSR-0 standard](http://www.php-fig.org/psr/psr-0/).
When a user runs `php composer.phar install` to install an extension, the file `vendor/yiisoft/extensions.php`
will be automatically updated to include the information about the new extension. From this file, Yii applications
can know which extensions are installed (the information can be accessed via [[yii\base\Application::extensions]].
You class namespaces should start with `vendorName\extensionName`, where `extensionName` is similar to the project name
in the package name except that it should not contain the `yii2-` prefix. For example, for the `yiisoft/yii2-imagine`
extension, we use `yii\imagine` as the namespace its classes.
Do not use `yii`, `yii2` or `yiisoft` as vendor name. These names are reserved for use by the Yii core code.
#### Dependencies <a name="dependencies"></a>
Your extension depends on Yii (of course). So you should list it in the `require` entry in `composer.json`.
If your extension also depends on other extensions or third-party libraries, you should list them as well.
Make sure you also list appropriate version constraints (e.g. `1.*`, `@stable`) for each dependency. Use stable
dependencies when your extension is released in a stable version.
### Class Autoloading
#### Class Autoloading <a name="class-autoloading"></a>
In order for your classes to be autoloaded by the Yii class autoloader or the Composer class autoloader,
you should specify the `autoload` entry in the `composer.json` file, like shown below:
@ -185,12 +204,31 @@ you should specify the `autoload` entry in the `composer.json` file, like shown
You may list one or multiple root namespaces and their corresponding file paths.
When the extension is installed in an application, Yii will create an [alias](concept-aliases.md#extension-aliases)
for each listed root namespace. The alias will refer to the directory corresponding to the root namespace.
When the extension is installed in an application, Yii will create for each listed root namespace
an [alias](concept-aliases.md#extension-aliases) that refers to the directory corresponding to the namespace.
For example, the above `autoload` declaration will correspond to an alias named `@yii/imagine`.
### Bootstrapping Classes
### Recommended Practices <a name="recommended-practices"></a>
Because extensions are meant to be used by other people, you often need to take extra development effort. Below
we introduce some common and recommended practices in creating high quality extensions.
#### Namespaces <a name="namespaces"></a>
To avoid name collisions and make the classes in your extension autoloadable, you should use namespaces and
name the classes in your extension by following the [PSR-4 standard](http://www.php-fig.org/psr/psr-4/) or
[PSR-0 standard](http://www.php-fig.org/psr/psr-0/).
You class namespaces should start with `vendorName\extensionName`, where `extensionName` is similar to the project name
in the package name except that it should not contain the `yii2-` prefix. For example, for the `yiisoft/yii2-imagine`
extension, we use `yii\imagine` as the namespace its classes.
Do not use `yii`, `yii2` or `yiisoft` as vendor name. These names are reserved for use by the Yii core code.
#### Bootstrapping Classes <a name="bootstrapping-classes"></a>
Sometimes, you may want your extension to execute some code during the [bootstrapping process](runtime-bootstrapping.md)
stage of an application. For example, your extension may want to respond to the application's `beginRequest` event
@ -230,37 +268,146 @@ You then list this class in the `composer.json` file of your extension like foll
```
When the extension is installed in an application, Yii will automatically instantiate the bootstrapping class
and call its [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]] during the bootstrapping process for
and call its [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]] method during the bootstrapping process for
every request.
## Installing Extensions Manually
#### Working with Databases <a name="working-with-databases"></a>
In some rare occasions, you may want to install some or all extensions manually, rather than relying on Composer.
To do so, you should
Your extension may need to access databases. Do not assume that the applications that use your extension will always
use `Yii::$db` as the DB connection. Instead, you should declare a `db` property for the classes that require DB access.
The property will allow users of your extension to customize which DB connection they would like your extension to use.
As an example, you may refer to the [[yii\caching\DbCache]] class and see how it declares and uses the `db` property.
1. download the extension archive files and unpack them in the `vendor` directory.
2. install the class autoloaders provided by the extensions, if any.
3. download and install all dependent extensions as instructed.
If your extension needs to create specific DB tables or make changes to DB schema, you should
If an extension does not have a class autoloader but follows the
[PSR-4 standard](https://github.com/php-fig/fig-standards/blob/master/proposed/psr-4-autoloader/psr-4-autoloader.md),
you may use the class autoloader provided by Yii to autoload the extension classes. All you need to do is just to
declare a [root alias](concept-aliases.md#defining-aliases) for the extension root directory. For example,
assuming you have installed an extension in the directory `vendor/mycompany/myext`, and the extension classes
are under the `myext` namespace, then you can include the following code in your application configuration:
- provide [migrations](db-migrations.md) to manipulate DB schema, rather than using plain SQL files;
- try to make the migrations applicable to different DBMS;
- avoid using [Active Record](db-active-record.md) in the migrations.
```php
[
'aliases' => [
'@myext' => '@vendor/mycompany/myext',
],
]
```
#### Using Assets <a name="using-assets"></a>
If your extension is a widget or a module, chances are that it may require some [assets](structure-assets.md) to work.
For example, a module may display some pages which contain images, JavaScript, and CSS. Because the files of an
extension are all under the same directory which is not Web accessible when installed in an application, you have
two choices to make the asset files directly accessible via Web:
- ask users of the extension to manually copy the asset files to a specific Web-accessible folder;
- declare an [asset bundle](structure-assets.md) and rely on the asset publishing mechanism to automatically
copy the files listed in the asset bundle to a Web-accessible folder.
We recommend you use the second approach so that your extension can be more easily used by other people.
## Core Extensions
### Internationalization and Localization <a name="i18n-l10n"></a>
## Best Practices
Your extension may be used by applications supporting different languages! Therefore, if your extension displays
content to end users, you should try to [internationalize and localize](tutorial-i18n.md) it. In particular,
- If the extension displays messages intended for end users, the messages should be wrapped into `Yii::t()`
so that they can be translated. Messages meant for developers (such as internal exception messages) do not need
to be translated.
- If the extension displays numbers, dates, etc., they should be formatted using [[yii\base\Formatter]] with
appropriate formatting rules.
For more details, please refer to the [Internationalization](tutorial-i18n.md) section.
#### Testing <a name="testing"></a>
You want your extension to run flawlessly without bringing problems to other people. To reach this goal, you should
test your extension before releasing it to public.
It is recommended that you create various test cases to cover your extension code rather than relying on manual tests.
Each time before you release a new version of your extension, you may simply run these test cases to make sure
everything is in good shape. Yii provides testing support, which can help you to more easily write unit tests,
acceptance tests and functionality tests. For more details, please refer to the [Testing](test-overview.md) section.
#### Versioning <a name="versioning"></a>
You should give each release of your extension a version number (e.g. `1.0.1`). We recommend you follow the
[semantic versioning](http://semver.org) practice when determining what version numbers should be used.
#### Releasing <a name="releasing"></a>
To let other people know your extension, you need to release it to public.
If it is the first time you release an extension, you should register it on a Composer repository, such as
[Packagist](https://packagist.org/). After that, all you need to do is simply creating a release tag (e.g. `v1.0.1`)
on the VCS repository of your extension and notify the Composer repository about the new release. People will
then be able to find the new release, and install or update the extension through the Composer repository.
In the releases of your extension, besides code files you should also consider including the followings to
help other people learn about and use your extension:
* A readme file in the package root directory: it describes what your extension does and how to install and use it.
We recommend you write it in [Markdown](http://daringfireball.net/projects/markdown/) format and name the file
as `readme.md`.
* A changelog file in the package root directory: it lists what changes are made in each release. The file
may be written in Markdown format and named as `changelog.md`.
also write it in Markdown format and name the file as `changelog.md`.
* An upgrade file in the package root directory: it gives the instructions on how to upgrade from older releases
of the extension. The file may be written in Markdown format and named as `upgrade.md`.
* Tutorials, demos, screenshots, etc.: these are needed if your extension provides many features that cannot be
fully covered in the readme file.
* API documentation: your code should be well documented to allow other people more easily read and understand it.
You may refer to the [Object class file](https://github.com/yiisoft/yii2/blob/master/framework/base/Object.php)
to learn how to document your code.
> Info: Your code comments can be written in Markdown format. The `yiisoft/yii2-apidoc` extension provides a tool
for you to generate pretty API documentation based on your code comments.
> Info: While not a requirement, we suggest your extension adhere to certain coding styles. You may refer to
the [core framework code style](https://github.com/yiisoft/yii2/wiki/Core-framework-code-style).
## Core Extensions <a name="core-extensions"></a>
Yii provides the following core extensions that are developed and maintained by the Yii developer team. They are all
registered on [Packagist](https://packagist.org/) and can be easily installed as described in the
[Using Extensions](#using-extensions) subsection.
- [yiisoft/yii2-apidoc](https://github.com/yiisoft/yii2-apidoc):
provides an extensible and high-performance API documentation generator. It is also used to generate the core
framework API documentation.
- [yiisoft/yii2-authclient](https://github.com/yiisoft/yii2-authclient):
provides a set of commonly used auth clients, such as Facebook OAuth2 client, GitHub OAuth2 client.
- [yiisoft/yii2-bootstrap](https://github.com/yiisoft/yii2-bootstrap):
provides a set of widgets that encapsulate the [Bootstrap](http://getbootstrap.com/) components and plugins.
- [yiisoft/yii2-codeception](https://github.com/yiisoft/yii2-codeception):
provides testing support based on [Codeception](http://codeception.com/).
- [yiisoft/yii2-debug](https://github.com/yiisoft/yii2-debug):
provides debugging support for Yii applications. When this extension is used, a debugger toolbar will appear
at the bottom of every page. The extension also provides a set of standalone pages to display more detailed
debug information.
- [yiisoft/yii2-elasticsearch](https://github.com/yiisoft/yii2-elasticsearch):
provides the support for using [Elasticsearch](http://www.elasticsearch.org/). It includes basic querying/search
support and also implements the [Active Record](db-active-record.md) pattern that allows you to store active records
in Elasticsearch.
- [yiisoft/yii2-faker](https://github.com/yiisoft/yii2-faker):
provides the support for using [Faker](https://github.com/fzaninotto/Faker) to generate fake data for you.
- [yiisoft/yii2-gii](https://github.com/yiisoft/yii2-gii):
provides a Web-based code generator that is highly extensible and can be used to quickly generate models,
forms, modules, CRUD, etc.
- [yiisoft/yii2-imagine](https://github.com/yiisoft/yii2-imagine):
provides commonly used image manipulation functions based on [Imagine](http://imagine.readthedocs.org/).
- [yiisoft/yii2-jui](https://github.com/yiisoft/yii2-jui):
provides a set of widgets that encapsulate the [JQuery UI](http://jqueryui.com/) interactions and widgets.
- [yiisoft/yii2-mongodb](https://github.com/yiisoft/yii2-mongodb):
provides the support for using [MongoDB](http://www.mongodb.org/). It includes features such as basic query,
Active Record, migrations, caching, code generation, etc.
- [yiisoft/yii2-redis](https://github.com/yiisoft/yii2-redis):
provides the support for using [redis](http://redis.io/). It includes features such as basic query,
Active Record, caching, etc.
- [yiisoft/yii2-smarty](https://github.com/yiisoft/yii2-smarty):
provides a template engine based on [Smarty](http://www.smarty.net/).
- [yiisoft/yii2-sphinx](https://github.com/yiisoft/yii2-sphinx):
provides the support for using [Sphinx](http://sphinxsearch.com). It includes features such as basic query,
Active Record, code generation, etc.
- [yiisoft/yii2-swiftmailer](https://github.com/yiisoft/yii2-swiftmailer):
provides email sending features based on [swiftmailer](http://swiftmailer.org/).
- [yiisoft/yii2-twig](https://github.com/yiisoft/yii2-twig):
provides a template engine based on [Twig](http://twig.sensiolabs.org/).

167
docs/guide/tutorial-yii-integration.md

@ -0,0 +1,167 @@
Working with Third-Party Code
=============================
From time to time, you may need to use some third-party code in your Yii applications. Or you may want to
use Yii as a library in some third-party systems. In this section, we will show how to achieve these goals.
## Using Third-Party Libraries in Yii <a name="using-libs-in-yii"></a>
To use a third-party library in a Yii application, you mainly need to make sure the classes in the library
are properly included or can be autoloaded.
### Using Composer Packages <a name="using-composer-packages"></a>
Many third-party libraries are released in terms of [Composer](https://getcomposer.org/) packages.
You can install such libraries by taking the following two simple steps:
1. modify the `composer.json` file of your application and specify which Composer packages you want to install.
2. run `php composer.phar install` to install the specified packages.
The classes in the installed Composer packages can be autoloaded using the Composer autoloader. Make sure
the [entry script](structure-entry-scripts.md) of your application contains the following lines to install
the Composer autoloader:
```php
// install Composer autoloader
require(__DIR__ . '/../vendor/autoload.php');
// include Yii class file
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
```
### Using Downloaded Libraries <a name="using-downloaded-libs"></a>
If a library is not released as a Composer package, you should follow its installation instructions to install it.
In most cases, you will need to download a release file manually and unpack it in the `BasePath/vendor` directory,
where `BasePath` represents the [base path](structure-applications.md#basePath) of your application.
If a library carries its own class autoloader, you may install it in the [entry script](structure-entry-scripts.md)
of your application. It is recommended the installation is done before you include the `Yii.php` file so that
the Yii class autoloader can take precedence in autoloading classes.
If a library does not provide a class autoloader, but its class naming follows [PSR-4](http://www.php-fig.org/psr/psr-4/),
you may use the Yii class autoloader to autoload the classes. All you need to do is just to declare a
[root alias](concept-aliases.md#defining-aliases) for each root namespace used in its classes. For example,
assume you have installed a library in the directory `vendor/foo/bar`, and the library classes are under
the `xyz` root namespace. You can include the following code in your application configuration:
```php
[
'aliases' => [
'@xyz' => '@vendor/foo/bar',
],
]
```
If neither of the above is the case, it is likely that the library relies on PHP include path configuration to
correctly locate and include class files. Simply follow its instruction on how to configure the PHP include path.
In the worst case when the library requires explicitly including every class file, you can use the following method
to include the classes on demand:
* Identify which classes the library contains.
* List the classes and the corresponding file paths in `Yii::$classMap` in the [entry script](structure-entry-scripts.md)
of the application. For example,
```php
Yii::$classMap['Class1'] = 'path/to/Class1.php';
Yii::$classMap['Class2'] = 'path/to/Class2.php';
```
## Using Yii in Third-Party Systems <a name="using-yii-in-others"></a>
Because Yii provides many excellent features, sometimes you may want to use some of its features to support
developing or enhancing 3rd-party systems, such as WordPress, Joomla, or applications developed using other PHP
frameworks. For example, you may want to use the [[yii\helpers\ArrayHelper]] class or use the
[Active Record](db-active-record.md) feature in a third-party system. To achieve this goal, you mainly need to
take two steps: install Yii, and bootstrap Yii.
If the third-party system uses Composer to manage its dependencies, you can simply run the following commands
to install Yii:
```
php composer.phar require yiisoft/yii2-framework:*
php composer.phar install
```
Otherwise, you can [download](http://www.yiiframework.com/download/) the Yii release file and unpack it in
the `BasePath/vendor` directory.
Next, you should modify the entry script of the 3rd-party system by including the following code at the beginning:
```php
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
$yiiConfig = require(__DIR__ . '/../config/yii/web.php');
new yii\web\Application($yiiConfig); // Do NOT call run() here
```
As you can see, the code above is very similar to that in the [entry script](structure-entry-scripts.md) of
a typical Yii application. The only difference is that after the application instance is created, the `run()` method
is not called. This is because by calling `run()`, Yii will take over the control of the request handling workflow.
Like in a Yii application, you should configure the application instance based on the environment running
the third-party system. For example, to use the [Active Record](db-active-record.md) feature, you need to configure
the `db` application component with the DB connection setting used by the third-party system.
Now you can use most features provided by Yii. For example, you can create Active Record classes and use them
to work with databases.
## Using Yii 2 with Yii 1 <a name="using-both-yii2-yii1"></a>
If you were using Yii 1 previously, it is likely you have a running Yii 1 application. Instead of rewriting
the whole application in Yii 2, you may just want to enhance it using some of the features only available in Yii 2.
This can be achieved as described below.
> Note: Yii 2 requires PHP 5.4 or above. You should make sure that both your server and the existing application
support this.
First, install Yii 2 in your existing application by following the instructions given in the last subsection.
Second, modify the entry script of the application as follows,
```php
// include the customized Yii class described below
require(__DIR__ . '/../components/Yii.php');
// configuration for Yii 2 application
$yii2Config = require(__DIR__ . '/../config/yii2/web.php');
new yii\web\Application($yii2Config); // Do NOT call run()
// configuration for Yii 1 application
$yii1Config = require(__DIR__ . '/../config/yii1/main.php');
Yii::createWebApplication($yii1Config)->run();
```
Because both Yii 1 and Yii 2 have the `Yii` class, you should create a customized version to combine them.
The above code includes the customized `Yii` class file, which can be created as follows.
```php
$yii2path = '/path/to/yii2';
require($yii2path . '/BaseYii.php'); // Yii 2.x
$yii1path = '/path/to/yii1';
require($yii1path . '/YiiBase.php'); // Yii 1.x
class Yii extends \yii\BaseYii
{
// copy-paste the code in YiiBase (1.x) here
}
Yii::$classMap = include($yii2path . '/classes.php');
// register Yii2 autoloader via Yii1
Yii::registerAutoloader(['Yii', 'autoload']);
```
That's all! Now in any part of your code, you can use `Yii::$app` to access the Yii 2 application instance, while
`Yii::app()` will give you the Yii 1 application instance:
```php
echo get_class(Yii::app()); // outputs 'CWebApplication'
echo get_class(Yii::$app); // outputs 'yii\web\Application'
```

11
docs/internals/translation-status.md

@ -12,7 +12,7 @@ start-hello.md | Yes
start-forms.md | Yes
start-databases.md | Yes
start-gii.md | Yes
start-looking-ahead.md | Yes
start-looking-ahead.md | Yes
structure-overview.md | Yes
structure-entry-scripts.md | Yes
structure-applications.md | Yes
@ -24,7 +24,7 @@ structure-modules.md | Yes
structure-filters.md | Yes
structure-widgets.md | Yes
structure-assets.md |
structure-extensions.md |
structure-extensions.md | Yes
runtime-bootstrapping.md |
runtime-routing.md |
runtime-requests.md |
@ -87,12 +87,6 @@ test-unit.md |
test-functional.md |
test-acceptance.md |
test-fixtures.md |
extend-creating-extensions.md |
extend-customizing-core.md |
extend-using-libs.md |
extend-embedding-in-others.md |
extend-using-v1-v2.md |
extend-using-composer.md |
tutorial-advanced-app.md |
tutorial-start-from-scratch.md |
tutorial-console.md |
@ -102,6 +96,7 @@ tutorial-performance-tuning.md |
tutorial-shared-hosting.md |
tutorial-template-engines.md |
tutorial-core-validators.md | Yes
tutorial-yii-integration.md | Yes
widget-bootstrap.md |
widget-jui.md |
helper-overview.md |

Loading…
Cancel
Save