Консольні додатки
=================

Консольні додатки головним чином використовуються для виконання вторинних або фонових завдань, таких як генерація коду, компіляція пошукового індексу, відправлення повідомлень електронної пошти і т.д. Yii надає інструмент для розробки консольних додатків, дотримуючись обʼєктно-орієнтованого підходу. Він дозволяє консольному додатку отримати доступ до ресурсів, які використовує основний веб-додаток (наприклад, до бази даних).

Огляд
-----

Кожне консольне завдання представленк ​​в Yii як [команда|CConsoleCommand].
Консольна команда описується у класі, успадкованому від [CConsoleCommand].

Після використання `yiic webapp` для створення початкового прототипу додатка,
в `protected` будуть два файла:

* `yiic` — скрипт для Linux/Unix;
* `yiic.bat` — скрипт для Windows.

В консолі можна ввести наступні команди:

~~~
cd protected
yiic help
~~~

Після введення буде відображено перелік всіх доступних команд на даний момент.
За замовчуванням, це команди, що надаються Yii (так звані **системні команди**) і команди, 
розроблені для конкретних додатків (так звані **користувальницькі команди**).

Для отримання довідки по команді можна запустити

~~~
yiic help <імʼя-команди>
~~~

Для запуску команди використовується наступний формат:

~~~
yiic <імʼя-команди> [параметри…]
~~~


Створення команд
----------------

Консольні команди знаходяться у файлах з класами в папці, зазначеної в
[CConsoleApplication::commandPath]. За умовчанням це `protected/commands`.

Клас консольної команди повинен бути успадкований від [CConsoleCommand]. Імʼя класу
повинно бути вигляду `XyzCommand`, де `Xyz` відповідає імені команди, перша буква якого приведена до верхнього регістру. 
Наприклад, команда `sitemap` повинна використовувати клас `SitemapCommand`. 
Імена консольних команд реєстрозалежні.

> Tip|Підказка: Конфігуруючи [CConsoleApplication::commandMap], 
можна при бажанні змінити порядок іменування і розташування класів команд.

Для створення нової команди необхідно або реалізувати метод [CConsoleCommand::run()],
чи одне або декілька дій (будуть описані далі).

При введенні консольної команди додаток запускає метод [CConsoleCommand::run()].
Консольні параметри передаються методам відповідно із наступним заголовком:

~~~
[php]
public function run($args) { ... }
~~~

де `$args` — додаткові параметри, передані із командного рядка.

Усередині консольної команди для отримання доступу до примірника консольного додатку можна використовувати `Yii::app()`. 
Через отриманий примірник можна звертатися до різних компонентів, таких як зʼєднання з базою даних (`Yii::app()->db`).
Наскільки можна судити, це дуже схоже на звичайний веб-додаток.

> Info|Інформація: Починаючи з версії 1.1.1 можна створювати глобальні команди, які використовуються
***всіма*** додатками. Для цього визначається змінна оточення `YII_CONSOLE_COMMANDS` 
і в її значення записується шлях до директорії з класами глобальних консольних команд.

Дія консольної команди
----------------------

> Note|Примітка: Дана можливість доступна починаючи з версії 1.1.5.

Часто в консольній команді потрібно працювати із різними параметрами. 
Частина з них можуть бути обовʼязковими, а частина ні. 
Також може знадобитися реалізувати субкоманди для виконання різних підзадач. 
Все це спрощується при використанні дій.

Дія консольної команди — метод в її класі. Імʼя методу повинно бути
вигляду `actionXyz`, де `Xyz` відповідає імені дії і першою літерою, приведеною до верхнього регістру. 
Наприклад, метод `actionIndex` задає дію з імʼям `index`.

Для того, щоб запустити певну дію, використовується наступний формат команди:

~~~
yiic <імʼя-команди> <імʼя-дії]> --параметр1=значення1 --параметр2=значення2 ...
~~~

Додаткові пари імʼя-значення передаються методу дії як іменовані параметри.
Значення опції `xyz` відповідає параметру `$xyz` методу дії.
Наприклад, якщо ми визначимо наступний клас команди:

~~~
[php]
class SitemapCommand extends CConsoleCommand
{
    public function actionIndex($type, $limit=5) { ... }
    public function actionInit() { ... }
}
~~~

То все наступні консольні команди викличуть `actionIndex('News', 5)`:

~~~
yiic sitemap index --type=News --limit=5

// $limit приймає значення за замовчуванням
yiic sitemap index --type=News

// $limit приймає значення за замовчуванням
// Так як 'index' — дія за замовчуванням, ми можемо опустити імʼя дії.
yiic sitemap --type=News

// порядок опцій не важливий
yiic sitemap index --limit=5 --type=News
~~~

Якщо значення опції не вказано (тобто `--type` замість `--type=News`), 
відповідному параметру дії буде присвоєно значення `true`.

> Note|Примітка: Альтернативні формати вказівки опцій, такі як
> `--type News` або `-t News` не підтримуються.

Якщо оголосити параметр як масив, він зможе прийняти масив значень:

~~~
[php]
public function actionIndex(array $types) { ... }
~~~

Щоб передати масив значень необхідно вказати одну і ту ж опцію кілька разів:

~~~
yiic sitemap index --types=News --types=Article
~~~

Команда, наведена вище, запустить `actionIndex(array('News', 'Article'))`.

Починаючи з версії 1.1.6, Yii дозволяє використовувати анонімні параметри дій і глобальні опції.

Анонімні параметри — це параметри командного рядка, які не є опціями.
Наприклад, в команді `yiic sitemap index --limit=5 News` зустрічається анонімний параметр із значенням `News`. 
Іменований параметр (опція) `limit` приймає значення, рівне 5.

Для того, щоб використовувати анонімні параметри, дія повинна описати параметр з іменем `$args`:

~~~
[php]
public function actionIndex($limit=10, $args=array()) {...}
~~~

У масиві `$args` будуть міститися всі доступні значення анонімних параметрів.

Глобальні опції — це параметри командного рядка, загальні для всіх дій команди.
Приміром, нам може знадобитися для команди з декількома діями завести загальну опцію `verbose`. 
Звичайно, можна визначити параметр `$verbose` для кожної дії, але краще задати його **public свойством** класу команди, 
що автоматично зробить `verbose` глобальною опцією:

~~~
[php]
class SitemapCommand extends CConsoleCommand
{
	public $verbose=false;
	public function actionIndex($type) {...}
}
~~~

Наведений код дозволяє використовувати опцію `verbose`:

~~~
yiic sitemap index --verbose=1 --type=News
~~~


Код повернення
--------------

> Note|Примітка: можливість вказати код повернення у консольній команді зʼявилася у версії 1.1.11.

При автоматичному запуску консольних команд, наприклад, по cron або використовуючи сервер безперервної інтеграції, важливо знати, чи завершилося виконання команди з помилкою чи ні. Якраз для цього і призначені коди повернення.

Дані коди є цілочисельними значеннями від 0 до 254 (даний інтервал
заданий у [PHP](http://www.php.net/manual/ru/function.exit.php)),
де 0 повертається в разі успіху, а всі інші значення використовуються для різних помилок.

Як у методі `run()`, так і в діях команди ви можете повернути ціле число.
Воно буде використано у якості коду повернення.

Приклад:

~~~
[php]
if (/* помилка */) {
    return 1; // виходимо з кодом 1
}
// … різний код …
return 0; // все добре, виходимо з кодом 0
~~~

Коли немає значення повернення, додаток завершить роботу з кодом 0.

Налаштування консольного додатка
--------------------------------

За замовчуванням, якщо додаток створюється з використанням `yiic webapp`, 
конфігурація консольного додатка знаходиться у `protected/config/console.php`. 
Як і конфігурація веб-додатки, даний файл є PHP-скриптом, що повертає масив з початковими значеннями примірника консольного додатку. 
Тобто у даному файлі можна задати будь-яку public властивість [CConsoleApplication].

Так як консольні команди часто створюються для підтримки веб-додатку, потрібно використовувати ті ж ресурси (такі, як зʼєднання з БД), що використовуються у веб-додатку. Це можна зробити, налаштувавши відповідні компоненти в конфігурації консольного додатку:

~~~
[php]
return array(
	......
	'components'=>array(
		'db'=>array(
			......
		),
	),
);
~~~

Формат конфігурації дуже схожий на той, що використовується у веб-додатку, так як
і [CConsoleApplication] і [CWebApplication] успадковують один і той же базовий клас.