diff --git a/docs/guide/README.md b/docs/guide/README.md index 37caef1..f5ce8b9 100644 --- a/docs/guide/README.md +++ b/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 diff --git a/docs/guide/extend-creating-extensions.md b/docs/guide/extend-creating-extensions.md deleted file mode 100644 index e597616..0000000 --- a/docs/guide/extend-creating-extensions.md +++ /dev/null @@ -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. diff --git a/docs/guide/extend-customizing-core.md b/docs/guide/extend-customizing-core.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/guide/extend-using-composer.md b/docs/guide/extend-using-composer.md deleted file mode 100644 index c84f332..0000000 --- a/docs/guide/extend-using-composer.md +++ /dev/null @@ -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 , 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 , 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). diff --git a/docs/guide/extend-using-libs.md b/docs/guide/extend-using-libs.md deleted file mode 100644 index 27fd2d7..0000000 --- a/docs/guide/extend-using-libs.md +++ /dev/null @@ -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' -``` diff --git a/docs/guide/structure-extensions.md b/docs/guide/structure-extensions.md index ec75adf..d3bf113 100644 --- a/docs/guide/structure-extensions.md +++ b/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 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 -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 -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` 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 -### 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 -### 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 +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 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 + +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 + +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 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 -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 + +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 -## 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 + +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 + +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 + +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 + +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/). diff --git a/docs/guide/tutorial-yii-integration.md b/docs/guide/tutorial-yii-integration.md new file mode 100644 index 0000000..9e42b35 --- /dev/null +++ b/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 + +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 + +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 + +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 + +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 + +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' +``` diff --git a/docs/internals/translation-status.md b/docs/internals/translation-status.md index e3d87fa..55816a4 100644 --- a/docs/internals/translation-status.md +++ b/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 |