offline version v3
Запись на курсы по HTML, CSS, JavaScript, PHP, фреймворкам и CMS,
а также: помощь в поиске работы и заказов, стажировка на реальных проектах→
⊗ppOpClTgCCA 101 of 179 menu

Добавление CSS класса в классе Tag

Как вы знаете, наш класс Tag хранит атрибуты тега в свойстве $this->attrs. Данное свойство представляет собой массив. В этом массиве может быть элемент с ключом class, содержащий CSS классы элемента. Элемента с таким ключом может, однако, и не быть.

Все зависит от того, был ли при создании тега вызван метод setAttr для установки атрибута class или нет.

Вот пример того, когда он был вызван:

<?php // Выведет <input class="eee bbb">: echo (new Tag('input'))->setAttr('class', 'eee bbb')->open(); ?>

А вот пример того, когда он не был вызван:

<?php // Выведет <input id="test">: echo (new Tag('input'))->setAttr('id', 'test')->open(); ?>

В реализации нашего метода addClass нужно будет учесть оба варианта.

Получается, что если у элемента не заданы CSS классы, то вызов метода addClass должен просто создавать в массиве $this->attrs новый элемент с ключом class и записывать в него переданный класс:

<?php public function addClass($className) { // Если ключа class нет в массиве $this->attrs: if (!isset($this->attrs['class'])) { $this->attrs['class'] = $className; // запишем наш CSS класс } return $this; // возвращаем $this для работы цепочки } ?>

Обратите внимание на то, что параметр метода называется $className, а не $class, так как слово class является зарезервированным в PHP и его нельзя использовать в качестве имени переменной.

Давайте теперь рассмотрим второй вариант, когда в $this->attrs['class'] уже есть один или несколько классов. Как уже упоминалось выше, эти классы были добавлены ранее с помощью метода setAttr. Эти классы также могли быть добавлены с помощью вызова метода (или цепочки методов) addClass.

Способ добавления, в общем-то, не имеет никакого значения, главное, что, если классы есть, то они хранятся в виде строки, разделенные пробелами. Либо, если там один класс, то в $this->attrs['class'] просто хранится его имя, без пробелов.

Пусть в $this->attrs['class'] хранится несколько классов. В этом случае будет удобнее работать не со строкой с пробелами, а с массивом CSS классов. Для этого можно просто разбить нашу строку в массив с помощью функции explode:

<?php public function addClass($className) { if (isset($this->attrs['class'])) { // Получаем массив классов: $classNames = explode(' ', $this->attrs['class']); } return $this; } ?>

Затем необходимо проверить отсутствие переданного класса в этом массиве классов. Это легко сделать с помощью функции in_array:

<?php public function addClass($className) { if (isset($this->attrs['class'])) { $classNames = explode(' ', $this->attrs['class']); // Если такого класса нет в массиве классов: if (!in_array($className, $classNames)) { // добавим новый класс } } return $this; } ?>

Если переданного класса нет в массиве классов, то добавим его к уже существующим классам. А если есть - то просто ничего не будем делать.

Давайте реализуем добавление класса:

<?php public function addClass($className) { if (isset($this->attrs['class'])) { $classNames = explode(' ', $this->attrs['class']); if (!in_array($className, $classNames)) { // Добавим новый класс в массив с классами: $classNames[] = $className; // Сольем массив в строку и запишем ее в $this->attrs['class']: $this->attrs['class'] = implode(' ', $classNames); } } return $this; } ?>

Рассмотрим теперь вариант, когда в $this->attrs['class'] хранится только один класс. На самом деле, реализованный выше код будет прекрасно работать и в этом случае: применение explode к строке без пробела просто вернет массив из одного элемента, представляющего собой эту строку. Ну и далее все наши манипуляции будут работать также.

Давайте соберем весь наш код вместе:

<?php public function addClass($className) { if (isset($this->attrs['class'])) { $classNames = explode(' ', $this->attrs['class']); if (!in_array($className, $classNames)) { $classNames[] = $className; $this->attrs['class'] = implode(' ', $classNames); } } else { $this->attrs['class'] = $className; } return $this; } ?>

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

<?php // Выведет <input class="eee">: echo (new Tag('input'))->addClass('eee')->open(); ?>
<?php // Выведет <input class="eee bbb">: echo (new Tag('input'))->addClass('eee')->addClass('bbb')->open(); ?>
<?php // Выведет <input class="eee bbb kkk">: echo (new Tag('input')) ->setAttr('class', 'eee bbb') ->addClass('kkk')->open(); ?>
<?php // Выведет <input class="eee bbb">: echo (new Tag('input')) ->setAttr('class', 'eee bbb') ->addClass('eee') // такой класс уже есть и не добавится ->open(); ?>
<?php // Выведет <input class="eee bbb">: echo (new Tag('input')) ->addClass('eee') ->addClass('bbb') ->addClass('eee') // такой класс уже есть и не добавится ->open(); ?>