Класс Cotpl_logical в Cotonti. Блоки (IF, ELSE, ENDIF)

предназначен для работы с условными конструкциями (IF, ELSE, ENDIF) в шаблонизаторе CoTemplate. Он расширяет Cotpl_block и добавляет поддержку логических выражений для динамического отображения контента в шаблонах

Этот класс Cotpl_logical в Cotonti предназначен для работы с условными конструкциями (IF, ELSE, ENDIF) в шаблонизаторе CoTemplate. Он расширяет Cotpl_block и добавляет поддержку логических выражений для динамического отображения контента в шаблонах.

Разбор кода:

  1. Конструктор __construct($expr_str, $if_code, $else_code, &$index, $path)

    • $expr_str — строка с условием (IF выражение).
    • $if_code — содержимое блока внутри IF.
    • $else_code — содержимое ELSE (если есть).
    • $index и $path — параметры, используемые для структуры шаблона.
    • Выражение парсится с помощью Cotpl_expr, а код IF и ELSE компилируется в отдельные блоки.
  2. Метод __toString()

    • Генерирует строковое представление условного блока для отладки.
    • Выводит <!-- IF условие -->, затем содержимое IF и ELSE, если оно есть.
  3. Метод getTags()

    • Возвращает список тегов, присутствующих в блоке.
    • Рекурсивно обходит дочерние блоки (Cotpl_data или Cotpl_block).
  4. Метод parse($xtpl) и reset($dummy = null)

    • Бросают исключения. Логические блоки не должны парситься стандартными методами.
  5. Метод text($tpl)

    • Определяет, какой блок (IF или ELSE) должен быть отображен.
    • Использует evaluate($tpl) из Cotpl_expr для вычисления выражения.
    • Если условие истинно, выводит IF-блок, иначе ELSE-блок.

Как это используется в Cotonti?

Этот класс позволяет в шаблонах использовать конструкции вида:

<!-- IF {USER_LOGGED} -->
    <p>Добро пожаловать, {USER_NAME}!</p>
<!-- ELSE -->
    <p>Пожалуйста, <a href="login.php">войдите</a>.</p>
<!-- ENDIF -->

Где {USER_LOGGED} — переменная, которая оценивается в true или false.

Фактически, Cotpl_logical отвечает за обработку таких условных выражений внутри CoTemplate.

Класс Cotpl_logical в Cotonti отвечает за обработку условных блоков (IF, ELSE, ENDIF) внутри шаблонизатора CoTemplate. Разберём каждый метод подробно с пояснениями и примерами.


1. Конструктор

public function __construct($expr_str, $if_code, $else_code, &$index, $path)

Описание:

Конструктор инициализирует объект логического блока, парсит переданные условия и компилирует код для блоков IF и ELSE.

Аргументы:

  • $expr_str — строка с логическим выражением (IF условие).
  • $if_code — содержимое IF-блока.
  • $else_code — содержимое ELSE-блока (если есть).
  • &$index — ссылка на индекс шаблонов CoTemplate (используется для хранения структуры).
  • $path — массив, содержащий путь текущего блока в шаблоне.

Логика работы:

  1. Создаёт объект Cotpl_expr для вычисления логического выражения.
  2. Компилирует код IF в this->blocks[0], если он есть.
  3. Компилирует код ELSE в this->blocks[1], если он есть.

Пример:

$logicalBlock = new Cotpl_logical('{USER_LOGGED}', '<p>Добро пожаловать!</p>', '<p>Пожалуйста, войдите.</p>', $index, []);

2. Метод __toString()

public function __toString()

Описание:

Этот метод возвращает строковое представление блока для отладки.

Логика работы:

  1. Формирует строку <!-- IF {условие} -->.
  2. Добавляет текст IF-блока.
  3. Если есть ELSE-блок, добавляет <!-- ELSE --> и его содержимое.
  4. Завершает <!-- ENDIF -->.

Пример:

$logicalBlock = new Cotpl_logical('{USER_LOGGED}', '<p>Вы вошли</p>', '<p>Гость</p>', $index, []);
echo $logicalBlock->__toString();

Выведет:

<!-- IF {USER_LOGGED} -->
<p>Вы вошли</p>
<!-- ELSE -->
<p>Гость</p>
<!-- ENDIF -->

3. Метод getTags()

public function getTags()

Описание:

Этот метод возвращает массив тегов (переменных), используемых внутри блока.

Логика работы:

  1. Проходит по всем вложенным блокам (IF и ELSE).
  2. Если внутри есть Cotpl_data или Cotpl_block, рекурсивно получает их теги.
  3. Возвращает список всех найденных тегов.

Пример:

$logicalBlock = new Cotpl_logical('{USER_LOGGED}', '<p>{USER_NAME}</p>', '<p>{SITE_NAME}</p>', $index, []);
print_r($logicalBlock->getTags());

Выведет:

Array ( [0] => USER_NAME [1] => SITE_NAME )

4. Метод parse()

public function parse($xtpl)

Описание:

Метод запрещает вызов parse() для логических блоков, выбрасывая исключение.

Логика работы:

  • Вызывает throw new Exception('Calling parse() on logical block');
    Это предотвращает ошибочное использование метода.

Пример вызова (приведёт к исключению):

try {
    $logicalBlock->parse($xtpl);
} catch (Exception $e) {
    echo $e->getMessage();
}

Выведет:

Calling parse() on logical block

5. Метод reset()

public function reset($dummy = null)

Описание:

Также запрещает вызов reset() для логических блоков, выбрасывая исключение.

Логика работы:

  • Вызывает throw new Exception('Calling reset() on logical block');

Пример вызова (приведёт к исключению):

try {
    $logicalBlock->reset();
} catch (Exception $e) {
    echo $e->getMessage();
}

Выведет:

Calling reset() on logical block

6. Метод text()

public function text($tpl)

Описание:

Этот метод обрабатывает и возвращает содержимое условного блока (IF или ELSE).

Логика работы:

  1. Оценивает выражение IF с помощью $this->expr->evaluate($tpl).
  2. Если условие истинно:
    • Возвращает содержимое блока IF (this->blocks[0]).
  3. Если условие ложно:
    • Возвращает содержимое ELSE-блока (this->blocks[1]), если он есть.

Пример:

Допустим, у нас есть шаблон:

<!-- IF {USER_LOGGED} -->
    <p>Привет, {USER_NAME}!</p>
<!-- ELSE -->
    <p>Гость, пожалуйста, войдите.</p>
<!-- ENDIF -->

Реализация на PHP:

$tplData = new XTemplate();
$tplData->assign('USER_LOGGED', true);
$tplData->assign('USER_NAME', 'Иван');

$logicalBlock = new Cotpl_logical('{USER_LOGGED}', '<p>Привет, {USER_NAME}!</p>', '<p>Гость, пожалуйста, войдите.</p>', $index, []);

echo $logicalBlock->text($tplData);

Выведет:

<p>Привет, Иван!</p>

Если USER_LOGGED = false, то результат будет:

<p>Гость, пожалуйста, войдите.</p>

Вывод

Класс Cotpl_logical обрабатывает условные конструкции в шаблонах Cotonti. Он:

  • Разбирает IF и ELSE блоки.
  • Оценивает логическое выражение.
  • Возвращает соответствующий блок в зависимости от условия.
  • Не позволяет вручную вызывать parse() и reset().

Примеры показывают, как этот класс работает на практике, помогая динамически управлять выводом в шаблонах Cotonti. 🚀

 

Подробный разбор кода с комментариями

Класс Cotpl_logical предназначен для обработки условных блоков (IF, ELSE, ENDIF) в шаблонизаторе CoTemplate.


/**
 * CoTemplate run-time conditional block class
 */
class Cotpl_logical extends Cotpl_block
  • Класс Cotpl_logical — отвечает за обработку условных конструкций (IF, ELSE).
  • Наследуется от Cotpl_block — это базовый класс для всех типов блоков в шаблонах.

/**
 * @var Cotpl_expr Condition expression
 */
protected $expr = null;
  • $expr — объект Cotpl_expr, представляющий логическое выражение для IF блока.
  • Используется для вычисления условия при рендеринге шаблона.

Конструктор

/**
 * Constructs logical block structure from strings
 *
 * @param string $expr_str Condition string
 * @param string $if_code IF clause body
 * @param string $else_code ELSE clause body
 * @param array $index CoTemplate index
 * @param array $path Current block path
 */
public function __construct($expr_str, $if_code, $else_code, &$index, $path)
  • Создаёт логический блок (IF-ELSE) в шаблоне, компилируя его части.
  • Аргументы:
    • $expr_str — строка с логическим выражением ({USER_LOGGED} и т. д.).
    • $if_code — содержимое IF блока.
    • $else_code — содержимое ELSE блока (если есть).
    • &$index — ссылка на индекс шаблона.
    • $path — путь блока в структуре шаблона.

$this->expr = new Cotpl_expr($expr_str);
  • Создаётся объект Cotpl_expr для хранения и обработки выражения условия.

if (!empty($if_code)) {
    $bpath = $path;
    array_push($bpath, 0);
    $this->compile($if_code, $this->blocks[0], $index, $bpath);
}
  • Если передан код для IF блока, он компилируется:
    • Копируется $path в $bpath.
    • Добавляется 0 в $bpath (обозначает IF часть).
    • Вызывается compile(), которая разбирает IF блок.

if (!empty($else_code)) {
    $bpath = $path;
    array_push($bpath, 1);
    $this->compile($else_code, $this->blocks[1], $index, $bpath);
}
  • Если передан код для ELSE, он компилируется:
    • $bpath копирует $path.
    • Добавляется 1 в $bpath (обозначает ELSE часть).
    • Вызывается compile(), которая разбирает ELSE блок.

Метод __toString()

/**
 * TPL code representation for debugging
 *
 * @return string
 */
public function  __toString()
  • Возвращает отладочную строку с представлением IF-ELSE блока.

$str = "<!-- IF " . $this->expr->__toString() . " -->\n";
  • Создаётся строка <!-- IF {условие} --> (например, <!-- IF {USER_LOGGED} -->).

$str .= $this->blocks_toString($this->blocks[0]);
  • Добавляется содержимое IF блока.

if (count($this->blocks[1]) > 0) {
    $str .= "<!-- ELSE -->\n" . $this->blocks_toString($this->blocks[1]);
}
  • Если есть ELSE блок, он добавляется в строку.

$str .= "<!-- ENDIF -->\n";
return $str;
  • Закрывает конструкцию <!-- ENDIF -->.
  • Пример вывода:
    <!-- IF {USER_LOGGED} -->
    <p>Вы вошли</p>
    <!-- ELSE -->
    <p>Вы гость</p>
    <!-- ENDIF -->
    

Метод getTags()

/**
 * Returns the list of tag names present in the block
 * @return array
 */
public function getTags()
  • Возвращает список всех тегов ({VAR_NAME}), используемых в блоке.

$list = array();
for ($i = 0; $i < 2; $i++) {
    if (isset($this->blocks[$i]) && is_array($this->blocks[$i])) {
        foreach ($this->blocks[$i] as $block) {
            if ($block instanceof Cotpl_data || $block instanceof Cotpl_block) {
                $list = array_merge($list, $block->getTags());
            }
        }
    }
}
  • Проходит по IF ($blocks[0]) и ELSE ($blocks[1]) блокам.
  • Рекурсивно собирает все переменные (Cotpl_data или Cotpl_block).

Методы parse() и reset()

/**
 * Overloads parse()
 *
 * @param XTemplate $xtpl Reference to XTemplate object
 */
public function parse($xtpl)
{
    throw new Exception('Calling parse() on logical block');
}
  • Запрещает вызов parse().
  • Выбрасывает исключение, если кто-то попытается вызвать parse() на IF блоке.

/**
 * Overloads reset()
 * @param mixed $dummy A stub to match Cotpl_block::reset() declaration (Strict mode)
 */
public function reset($dummy = null)
{
    throw new Exception('Calling reset() on logical block');
}
  • Запрещает reset(), так как логические блоки не требуют сброса.

Метод text()

/**
 * Actually parses a conditional block and returns parsed contents
 *
 * @param XTemplate $tpl A reference to XTemplate object containing variables
 * @return string
 */
public function text($tpl)
  • Оценивает условие и возвращает содержимое IF или ELSE блока.

$data = '';
if ($this->expr->evaluate($tpl)) {
    if (!empty($this->blocks[0])) {
        foreach ($this->blocks[0] as $block) {
            $data .= $block->text($tpl);
        }
    }
  • Если выражение IF истинно, берётся IF блок ($blocks[0]).

} elseif (!empty($this->blocks[1])) {
    foreach ($this->blocks[1] as $block) {
        $data .= $block->text($tpl);
    }
}
  • Если IF ложен и есть ELSE блок, берётся ELSE ($blocks[1]).

return $data;
  • Возвращает готовый HTML-код.

Пример использования:

$tplData = new XTemplate();
$tplData->assign('USER_LOGGED', true);
$tplData->assign('USER_NAME', 'Иван');

$logicalBlock = new Cotpl_logical('{USER_LOGGED}', '<p>Привет, {USER_NAME}!</p>', '<p>Гость</p>', $index, []);
echo $logicalBlock->text($tplData);

Выведет:

<p>Привет, Иван!</p>

Если USER_LOGGED = false, то:

<p>Гость</p>

Вывод

  • Класс Cotpl_logical обрабатывает IF-ELSE блоки.
  • Парсит, компилирует и вычисляет условия.
  • Запрещает parse() и reset().
  • Возвращает HTML-код в зависимости от переменных.

 

Сам класс

/**
 * Класс условного блока времени выполнения CoTemplate
 */
class Cotpl_logical extends Cotpl_block // Класс Cotpl_logical наследуется от Cotpl_block и предназначен для обработки условных блоков в шаблонах.
{
	/**
	 * @var Cotpl_expr Выражение условия
	 */
	protected $expr = null; // Переменная для хранения выражения условия в виде объекта Cotpl_expr.

	/**
	 * Создаёт структуру логического блока из строк
	 *
	 * @param string $expr_str Строка условия
	 * @param string $if_code Тело блока IF
	 * @param string $else_code Тело блока ELSE
	 * @param array $index Индекс CoTemplate
	 * @param array $path Текущий путь блока
	 */
	public function __construct($expr_str, $if_code, $else_code, &$index, $path) // Конструктор класса принимает строку условия, коды блоков IF и ELSE, индекс шаблона и путь текущего блока.
	{
		$this->expr = new Cotpl_expr($expr_str); // Создаётся объект Cotpl_expr для хранения и обработки выражения.
		if (!empty($if_code)) { // Проверяет, есть ли содержимое для блока IF.
			$bpath = $path; // Копирует текущий путь блока.
			array_push($bpath, 0); // Добавляет 0 в путь, чтобы обозначить, что это блок IF.
			$this->compile($if_code, $this->blocks[0], $index, $bpath); // Компилирует содержимое блока IF и сохраняет его в $this->blocks[0].
		}
		if (!empty($else_code)) { // Проверяет, есть ли содержимое для блока ELSE.
			$bpath = $path; // Копирует текущий путь блока.
			array_push($bpath, 1); // Добавляет 1 в путь, чтобы обозначить, что это блок ELSE.
			$this->compile($else_code, $this->blocks[1], $index, $bpath); // Компилирует содержимое блока ELSE и сохраняет его в $this->blocks[1].
		}
	}

	/**
	 * Представление кода TPL для отладки
	 *
	 * @return string
	 */
	public function  __toString() // Метод возвращает строковое представление блока для отладки.
	{
		$str = "<!-- IF " . $this->expr->__toString() . " -->\n"; // Начинает строку с комментария IF и условия.
		$str .= $this->blocks_toString($this->blocks[0]); // Добавляет текстовое представление блока IF.
		if (count($this->blocks[1]) > 0) { // Если есть блок ELSE, добавляет его содержимое.
			$str .= "<!-- ELSE -->\n" . $this->blocks_toString($this->blocks[1]);
		}
		$str .= "<!-- ENDIF -->\n"; // Завершает блок комментарием ENDIF.
		return $str; // Возвращает полное представление блока.
	}

	/**
	 * Возвращает список имён тегов, присутствующих в блоке
	 * @return array
	 */
	public function getTags() // Метод возвращает массив с именами тегов, используемых в блоках IF и ELSE.
	{
		$list = array(); // Инициализация пустого массива.
		for ($i = 0; $i < 2; $i++) { // Перебирает оба блока (IF и ELSE).
			if (isset($this->blocks[$i]) && is_array($this->blocks[$i])) { // Если блок существует и является массивом.
				foreach ($this->blocks[$i] as $block) { // Перебирает все элементы блока.
					if ($block instanceof Cotpl_data || $block instanceof Cotpl_block) { // Если элемент — это Cotpl_data или Cotpl_block.
						$list = array_merge($list, $block->getTags()); // Объединяет теги с уже найденными.
					}
				}
			}
		}

		return $list; // Возвращает массив тегов.
	}

	/**
	 * Перегружает метод parse()
	 *
	 * @param XTemplate $xtpl Ссылка на объект XTemplate
	 */
	public function parse($xtpl) // Метод parse() перегружается, чтобы предотвратить его вызов для логических блоков.
	{
		throw new Exception('Вызов parse() на логическом блоке'); // Бросает исключение.
	}

	/**
	 * Перегружает метод reset()
	 * @param mixed $dummy Заглушка для соответствия объявлению Cotpl_block::reset() (Строгий режим)
	 */
	public function reset($dummy = null) // Метод reset() перегружается, чтобы предотвратить его вызов для логических блоков.
	{
		throw new Exception('Вызов reset() на логическом блоке'); // Бросает исключение.
	}

	/**
	 * Фактически парсит условный блок и возвращает обработанное содержимое
	 *
	 * @param XTemplate $tpl Ссылка на объект XTemplate, содержащий переменные
	 * @return string
	 */
	public function text($tpl) // Основной метод, который выполняет обработку условного блока и возвращает его содержимое.
	{
		$data = ''; // Инициализация строки с результатом.
		if ($this->expr->evaluate($tpl)) { // Оценивает выражение.
			if (!empty($this->blocks[0])) { // Если блок IF не пуст.
				foreach ($this->blocks[0] as $block) { // Перебирает все элементы блока IF.
					$data .= $block->text($tpl); // Добавляет их содержимое в результат.
				}
			}
		} elseif (!empty($this->blocks[1])) { // Если выражение ложно и есть блок ELSE.
			foreach ($this->blocks[1] as $block) { // Перебирает все элементы блока ELSE.
				$data .= $block->text($tpl); // Добавляет их содержимое в результат.
			}
		}
		return $data; // Возвращает результат.
	}
}

 

11 минут чтения Sodium Carbonate

Комментарии (0)

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Автор контента

webitproff

Онлайн

Sodium Carbonate

Последняя авторизация: 19.07.2026 01:13

  • Страница размещена: 28.02.2025 19:53
  • Последнее обновление: 08.03.2025 13:44

Похожие страницы

Класс Cot. Фасад (Facade) в Cotonti
1 Фасад (Facade) — это паттерн проектирования, который предоставляет упрощённый интерфейс для работы с более сложной
Как правильно обрезать строки и выровнять блоки по высоте
2 Обрезать строку по количеству символов можно несколькими способами. Наиболее оптимальный – средствами CSS.
Условия в PHP. if, else, elseif
3 Условия в PHP. if, else, elseifРассмотрим базовые конструкции для работы с условиями в PHP: if, else, elseif.1️⃣ if,