Класс 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 minutes read Sodium Carbonate

Comments (0)

No comments yet
Only registered users can post new comments

Content author

webitproff

Offline

Sodium Carbonate

Last logged: 2026-09-01 22:41

About me briefly
Support and development of web projects on the CMF Cotonti: private messengers via the website, open and closed small social networks, trading platforms and marketplaces, freelance and services exchange portal, catalogs of goods from wholesale suppliers, dropshipping platforms, online stores, and much more.
View developments and download
Public portfolio of my works and developments
Telegram for messages
@webitproff
Telegram channel
@s/aBuyFILE
  • Page published: 2025-02-28 19:53
  • Last update: 2025-03-08 13:44

Similar pages

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