# Класс Link

Давайте сделаем класс, который будет создавать HTML ссылку. Назовем его `Link`. Вот так мы будем пользоваться нашим классом:

`<?php // Выведет <a href="/test.html">link</a>: echo (new Link())->setAttr('href', '/test.html')->setText('link')->show(); ?>`

Реализация:

`<?php class Link extends Tag { public function __construct() { parent::__construct('a'); } } ?>`

Сделаем так, чтобы даже если атрибут `href` не задан, то по умолчанию он становился пустыми кавычками:

`<?php class Link extends Tag { public function __construct() { parent::__construct('a'); $this->setAttr('href', ''); } } ?>`

Проверим:

`<?php // Выведет <a href="">index</a>: echo (new Link())->setText('index')->show(); ?>`

Самостоятельно реализуйте описанный класс `Link`.

С помощью этого класса создайте меню из `5` ссылок. Пусть первая ссылка ведет на страницу `/1.php`, вторая - на страницу `/2.php` и так далее.

Разместите созданную менюшку в отдельном файле, например, в `menu.php`.

Создайте страницы, на которые ведут ссылки вашей менюшки. Добавьте в ним какой-нибудь текст.

Подключите инклудом к тексту каждой страницы вашу менюшку из файла. Убедитесь, что ссылки из этой менюшки будут работать корректно.

## Активация ссылок

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

Такая ссылка обычно называется активной и ее выделение происходит путем добавления ей CSS класса `active` (общепринятое название).

Добавленный к ссылке класс `active` каким-то образом выделяет ее - подчеркивает, красит в красный цвет и тому подобное: все это регулируется CSS стилями для этого класса.

Итак, давайте сделаем так, чтобы ссылки автоматически активировались (добавляли себе CSS класс `active`), если их `href` совпадает с урлом сайта.

`URL` сайта можно достать вот так:

`<?php echo $_SERVER['REQUEST_URI']; ?>`

Чтобы прочитать `href` нашей ссылки, используем геттер `getAttr`, унаследованный от родительского класса `Tag`. Вот так:

`<?php $href = $this->getAttr('href'); ?>`

Чтобы добавить нашей ссылке CSS класс `active`, используем метод `addClass`, также унаследованный от родителя. Вот так:

`<?php $this->addClass('active') ?>`

Соберем все вместе и напишем вспомогательный метод `activateSelf`, который будет проверять, совпадает ли `href` ссылки и `URI`, и активировать ее, если это так:

`<?php private function activateSelf() { if ($this->getAttr('href') === $_SERVER['REQUEST_URI']) { $this->addClass('active'); } } ?>`

Осталось придумать в каком месте вызывать созданный нами метод. В конструкторе класса `Link` этого делать нельзя, так как в момент вызова конструктора `href` ссылки еще не задан (конструктор же вызывается в самом начале, а потом методы цепочки, в том числе `setAttr`, который и задает `href` ссылки).

После таких рассуждений становится очевидным, что метод `activateSelf` следует вызвать в момент вывода ссылки на экран, то есть в методе `show`, с помощью которого скорее всего и будет формироваться ссылка.

Однако, представляется возможным то, что при использовании нашего класса кто-то будет применять метод `open` и метод `close` отдельно.

Хотя описанное выше и маловероятно, тем не менее вызовем метод `activateSelf` в методе `open`, переопределив тем самым метод родителя:

`<?php class Link extends Tag { public function __construct() { $this->setAttr('href', ''); parent::__construct('a'); } // Переопределяем метод родителя: public function open() { $this->activateSelf(); // вызываем активацию return parent::open(); // вызываем метод родителя } private function activateSelf() { if ($this->getAttr('href') === $_SERVER['REQUEST_URI']) { $this->addClass('active'); } } } ?>`

Так как метод `show` использует внутри себя метод `open`, то изменения для метода `show` произойдут автоматически. Можем теперь проверить работу нашего класса:

`<?php echo (new Link)->setAttr('href', '/index.php')->setText('index')->show(); /* Если URL страницы не /index.php, то результат выполнения кода выведет <a href="/index.php">index</a> Если URL страницы /index.php, то результат выполнения кода выведет <a href="/index.php" class="active">index</a> */ ?>`

Итак, теперь ссылки активируют сами себя. Это реально круто! При этом нам понадобилось совсем мало кода, чтобы реализовать такое поведение. Все потому, что у нас есть базовый класс `Tag`, который прячет внутри себя много универсального кода для манипуляций с тегами.

Реализуя новые классы на основе класса `Tag` мы не держим в голове детали реализации этого класса `Tag`. И вообще не видим код этого класса - он где-то в другом файле (если, конечно же, вы его туда вынесли) и не мешает нам работать. Мы просто знаем, какие методы предоставляет этот класс своим потомкам - и пользуемся ими.

Поэтому классы-потомки и получаются такими маленькими и изящными.

На самом деле наш код класса `Link` еще более крут, чем кажется. Дело в том, что наши ссылки могут иметь и другие - постоянные - классы. При этом наша активация никак не будет мешать этим классам - они будут оставаться, просто к ним будет добавляться еще и класс `active`.

Все потому, что так работает метод `addClass` - он добавляет новый класс к уже существующим классам.

Вот пример:

`<?php echo (new Link) ->setAttr('href', '/index.php') ->setAttr('class', 'link1 link2') // добавляем ссылке классы ->setText('index') ->show(); /* Результат выполнения кода выведет <a href="/index.html" class="link1 link2 active">index</a> */ ?>`

Добавьте в ваш класс `Link` активацию ссылок.

Проверьте работу активации ссылок на менюшке, которую вы создали в предыдущих задачах. Характерно, что правки в саму менюшку вносить не надо - создание ссылок никак не поменялось, просто ссылки теперь активируют сами себя. Попереходите по ссылкам меню и убедитесь в том, что соответствующие ссылки активируются.

Не очень хорошо то, что название класса `active` жестко зашито в коде (вдруг мы захотим поменять его на другое). Вынесите его в константу класса (константу используем для того, чтобы в процессе работы скрипта случайно не изменить наш CSS класс).

←→
↑