Модуль
======

Модуль — це самодостатня програмна одиниця, яка складається із 
[моделей](/doc/guide/basics.model), [представлень](/doc/guide/basics.view), [контролерів](/doc/guide/basics.controller) та інших компонентів. 
Багато в чому модуль схожий із [додатком](/doc/guide/basics.application).
Основна відмінність полягає в тому, що модуль не може використовуватися сам по собі 
— тільки у складі додатка. Користувачі можуть звертатися до контролерів всередині модуля абсолютно так само, 
як і у випадку роботи із звичайними контролерами додатка.

Модулі можуть бути корисними в декількох ситуаціях. Якщо додаток дуже обʼємний, 
ми можемо розділити його на кілька модулів, які розроблюються та підтримуються окремо. 
Крім того, деякий часто використовуваний функціонал, наприклад, управління користувачами, 
коментарями та ін., може розроблюватись як модулі, щоб згодом можна було із легкістю скористатися ним знову.


Створення модуля
----------------
Модуль організований як директорія, імʼя якої виступає у якості унікального 
[ідентифікатора модуля|CWebModule::id]. Структура директорії модуля схожа на структуру 
[базової директорії додатку](/doc/guide/basics.application#application-base-directory). 
Нижче наведена типова структура директорії модуля з іменем `forum`:

~~~
forum/
   ForumModule.php            файл класу модуля
   components/                містить компоненти користувача
      views/                  містить файли представлень для віджетів
   controllers/               містить файли класів контролерів
      DefaultController.php   файл класу контролера за замовчуванням
   extensions/                містить стороні розширення
   models/                    містить файли класів моделей
   views/                     містить файли представлень контролера та макетів
      layouts/                містить файли макетів
      default/                містить файли представлень для контролера за замовчуванням
         index.php            файл представлення 'index'
~~~

Модуль повинен мати клас модуля, успадкованого від класу [CWebModule]. Іʼмя класу визначається
за допомогою виразу `ucfirst($id).'Module'`, де `$id` відповідає ідентифікатору модуля 
(або назві директорії модуля). Клас модуля виконує роль центрального місця для зберігання 
спільно використовуваної інформації. Наприклад, ми можемо використовувати [CWebModule::params] 
для зберігання параметрів модуля, а також [CWebModule::components] для спільного використання
[компонентів додатку](/doc/guide/basics.application#application-component) на рівні модуля.

> Tip|Підказка: Для створення простого каркасу модуля можна скористатися
> генератором модулів, який входить до складу Gii.


Використання модуля
-------------------
Для використання модуля необхідно помістити папку модуля у директорію `modules`
[базової директорії додатку](/doc/guide/basics.application#application-base-directory). 
Далі необхідно оголосити ідентифікатор модуля у властивості додатка [modules|CWebApplication::modules]. 
Наприклад, щоб скористатися модулем `forum`, наведеним вище, можна використовувати
наступну [конфігурацію додатку](/doc/guide/basics.application#application-configuration):

~~~
[php]
return array(
	…
	'modules'=>array('forum',…),
	…
);
~~~

Крім того, модулю можна задати початкові значення властивостей. Порядок використання аналогічний порядку
з [компонентами додатку](/doc/guide/basics.application#application-component). Наприклад, 
модуль `forum` може мати у своєму  класі властивість з іменем `postPerPage`, 
яке може бути встановлено у [конфігурації додатку](/doc/guide/basics.application#application-configuration)
наступим чином:

~~~
[php]
return array(
	…
	'modules'=>array(
	    'forum'=>array(
	        'postPerPage'=>20,
	    ),
	),
	…
);
~~~

До екземпляра модуля можна звертатися за допомогою властивості [module|CController::module] 
активного у даний час контролера. Через екземпляр модуля можна отримати доступ до спільно використовуваній
інформації на рівні модуля. Наприклад, для того, щоб звернутися до згаданої вище властивості
`postPerPage`, ми можемо скористатися наступим виразом:

~~~
[php]
$postPerPage=Yii::app()->controller->module->postPerPage;
// або таким, якщо $this посилається на екземпляр контролеру
// $postPerPage=$this->module->postPerPage;
~~~

Звернутися до дії контролера в модулі можна, використовуючи 
[маршрут](/doc/guide/basics.controller#route) `moduleID/controllerID/actionID`.
Наприклад, допустимо, що все той же модуль `forum` має контролер з іменем `PostController`, 
тоді ми можемо використовувати [маршрут](/doc/guide/basics.controller#route) `forum/post/create` для того, 
щоб звернутися до дії `create` цього контролера.
Адреса URL, яка відповідає цьому маршруту, буде такою: 
`http://www.example.com/index.php?r=forum/post/create`.

> Tip|Підказка: Якщо контролер знаходиться у підпапці папки `controllers`, ми також можемо 
використовувати формат [маршруту](/doc/guide/basics.controller#route), наведений вище. 
Наприклад, допустимо, що контролер `PostController` знаходиться у папці `forum/controllers/admin`, 
тоді ми можемо звернутися до дії `create` через `forum/admin/post/create`.


Вкладені модулі
---------------
Модулі можуть бути вкладеними один в одного скільки завгодно разів,
тобто один модуль може містити у собі інший, який містить у собі ще один. 
Перший ми будем називати модуль-предок, другий — модуль-нащадок.
Модулі-нащадки повинні бути описані у властивості [modules|CWebModule::modules]
модуля-предка точно так само, як ми описуємо модулі у файлі конфігурації додатку.

Для звертання до дії контролера у дочірньому модулі використовується маршрут
`parentModuleID/childModuleID/controllerID/actionID`.