Компонент
=========
Yii-приложения состоят из компонентов–объектов, созданных согласно спецификациям.
Компонент (component) — это экземпляр класса [CComponent] или производного от него.
Использование компонента, как правило, включает доступ к его свойствам, а также вызов и обработку его событий.
Базовый класс [CComponent] устанавливает правила, согласно которым определяются свойства и события.

Объявление и использование свойства компонента
----------------------------------------------
Свойство компонента схоже с открытой переменной-членом класса (public member variable).
Мы можем читать или устанавливать его значение. Например:

~~~
[php]
$width=$component->textWidth; // получаем значение свойства textWidth
$component->enableCaching=true; // устанавливаем значение свойства enableCaching
~~~

Существует два разных способа определения свойства компонента. Первым способом является обычное объявление
открытой переменной-члена класса компонента так, как показано ниже:

~~~
[php]
class Document extends CComponent
{
    public $textWidth;
}
~~~

Другим способом является использование геттеров и сеттеров. Это более гибкий подход потому как
помимо обычных свойств вы можете объявлять и свойства, доступные только для чтения или только
для записи.

~~~
[php]
class Document extends CComponent
{
    private $_textWidth;
    protected $_completed=false;

    public function getTextWidth()
    {
        return $this->_textWidth;
    }

    public function setTextWidth($value)
    {
        $this->_textWidth=$value;
    }

    public function getTextHeight()
    {
        // вычисляет и возвращает высоту текста
    }

    public function setCompleted($value)
    {
        $this->_completed=$value;
    }
}
~~~

Компонент выше может быть использован следующим образом:

~~~
[php]
$document=new Document();

// мы можем как писать в, так и читать из textWidth
$document->textWidth=100;
echo $document->textWidth;

// значение textHeight мы можем только получать
echo $document->textHeight;

// значение completed мы можем только изменять
$document->completed=true;
~~~

При чтении свойства, которое не было объявлено публичным членом класса, Yii пытается
использовать методы-геттеры, т.е. для `textWidth` методом-геттером будет `getTextWidth`. Тоже самое
происходит и при изменении свойства, которое не было объявлено публичным членом класса.

Если существует метод-геттер, но метода-сеттера при этом объявлено не было, то свойство компонента
можно использовать только для чтения, в противном случае будет вызвано исключение. Обратное верно и для
свойств, доступных только для изменения.

Использование методов чтения и записи имеет дополнительное преимущество: при чтении или записи значения
свойства могут быть выполнены дополнительные действия (такие как проверка на корректность,
вызов события и др.).

>Note|Примечание: Есть небольшая разница в определении свойства через методы и через простое
объявление переменной. В первом случае имя свойства не чувствительно к регистру,
во втором — чувствительно.


События компонента
------------------
События компонента — это специальные свойства, в качестве значений которых выступают
методы (называемые обработчиками событий). Назначение метода событию приведет к тому, что метод будет вызван
автоматически при возникновении этого события. Поэтому поведение компонента может быть
изменено совершенно отлично от закладываемого при разработке.

Событие компонента объявляется путём создания метода с именем, начинающимся на `on`.
Так же как и имена свойств, заданных через методы чтения и записи, имена событий
не чувствительны к регистру. Следующий код объявляет событие `onClicked`:

~~~
[php]
public function onClicked($event)
{
	$this->raiseEvent('onClicked', $event);
}
~~~

где `$event` — это экземпляр класса [CEvent] или производного от него,
представляющего параметр события. К событию можно подключить обработчик как показано ниже:

~~~
[php]
$component->onClicked=$callback;
~~~

где `$callback` — это корректный callback-вызов PHP (см.
PHP-функцию call_user_func). Это может быть либо глобальная функция, либо метод класса.
В последнем случае вызову должен передаваться массив: `array($object,'methodName')`.

Обработчик события должен быть определён следующим образом:

~~~
[php]
function methodName($event)
{
    …
}
~~~

где `$event` — это параметр, описывающий событие (передаётся методом `raiseEvent()`).
Параметр `$event` — это экземпляр класса [CEvent] или его производного.
Как минимум, он содержит информацию о том, кто вызвал событие.

Обработчик события может быть анонимной функцией,
требующей наличия версии PHP 5.3+. Например,

~~~
[php]
$component->onClicked=function($event) {
	…
}
~~~

Если теперь использовать метод `onClicked()`, то в нём будет вызвано событие `onClicked`.
Назначенный ему обработчик будет запущен автоматически.

Событию могут быть назначены несколько обработчиков.
При возникновении события обработчики будут вызваны в порядке их назначения.
Если в обработчике необходимо предотвратить вызов последующих обработчиков,
необходимо установить [$event->handled|CEvent::handled] в `true`.


Поведения компонента
---------------------

Для компонентов реализован шаблон проектирования [mixin](http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%81%D1%8C_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)),
что позволяет присоединить к ним одно или несколько поведений. *Поведение* —
объект, чьи методы «наследуются» компонентом, к которому он присоединён. Под
«наследованием» здесь понимается наращивание функционала, а не наследование
в классическом смысле. К компоненту можно прикрепить несколько поведений и,
таким образом, получить аналог множественного наследования.

Поведения классов должны реализовывать интерфейс [IBehavior]. Большинство поведений могут быть созданы путём расширения
базового класса [CBehavior]. В случае если поведение необходимо прикрепить к [модели](/doc/guide/basics.model), его можно
создать на основе класса [CModelBehavior] или класса [CActiveRecordBehavior], которые реализуют дополнительные,
специфические для моделей, возможности.

Чтобы использовать поведение, его необходимо прикрепить к компоненту путём вызова метода поведения
[attach()|IBehavior::attach]. После этого мы можем вызывать методы поведения через компонент:

~~~
[php]
// $name уникально идентифицирует поведения в компоненте
$component->attachBehavior($name,$behavior);
// test() является методом $behavior
$component->test();
~~~

К прикреплённому поведению можно обращаться как к обычному свойству компонента.
Например, если поведение с именем `tree` прикреплено к компоненту, мы можем получить
ссылку на объект поведения следующим образом:

~~~
[php]
$behavior=$component->tree;
// эквивалентно выражению:
// $behavior=$component->asa('tree');
~~~

Поведение можно временно деактивировать, чтобы его методы и свойства были недоступны через компонент.
Например:

~~~
[php]
$component->disableBehavior($name);
// выражение ниже приведет к вызову исключения
$component->test();
$component->enableBehavior($name);
// здесь все будет работать нормально
$component->test();
~~~

В случае когда два поведения, прикреплённые к одному компоненту, имеют методы с одинаковыми именами,
преимущество будет иметь метод поведения, прикреплённого раньше.

Использование поведений совместно с [событиями](/doc/guide/basics.component#component-event) даёт дополнительные возможности.
Поведение, прикреплённое к компоненту, может назначать некоторые свои методы в качестве обработчиков событий компонента.
В этом случае поведение получает возможность следить за ходом работы компонента и даже изменять его.

Свойства поведения также доступны из компонента, к которому оно присоединено.
Свойства включают в себя как открытые поля класса поведения, так и его методы чтения/записи (getters/setters).
Например, если поведение имеет свойство с именем `xyz` и привязано к компоненту
`$a`, то мы можем использовать выражение `$a->xyz` для доступа к этому свойству.