Um dos grandes poderes do nosso construtor de documentos provêm da capacidade de avaliar expressões condicionais. Isto permite manter ou remover códigos do modelo, fazendo com que este se adapte às condições específicas de cada documento.
Mas, infelizmente – por uma questão de segurança – não podemos deixar o PHP avaliar estas condições – o que poderia ser feito com eval(). Teremos que “interpretar” as condições com nosso próprio programa.
Mais adiante veremos como funcionam os escopos de variáveis do nosso documento. Por hora, basta compreender que estaremos trabalhando com dois escopos de variáveis: um escopo global – acessível em qualquer parte do documento – e um escopo local – acessível somente em um item de lista. Quer dizer que, quando percorremos uma lista com [loop]…[/loop], a variável $caption terá um conteúdo diferente à cada iteração.
Utilizaremos o cifrão (“$”) para identificar as variáveis locais, enquanto variáveis globais (constantes) não serão prefixadas.
Para avaliar uma condição, precisaremos, portanto, ter acesso ao escopo global e ao escopo local do documento:
$boolean = condition ($condition, $global_scope, $local_scope);
As expreções consistem basicamente de nomes de variáveis (globais ou locais) e operadores AND (“&&”) e OR (“||”).
Para processar a expressão, vamos separar os grupos OR (“||”) com explode(). Assim que um membro OR for avaliado como true, o processo retornará true.
Cada membro OR pode ser um grupo AND, separado por &&. Iremos desmembrá-lo com explode() para avaliar cada membro individualmente. Assim que um membro AND retornar false, false será o resultado do grupo AND.
Um ponto de exclamação (“!”) precedendo uma variável irá negar a sua avaliação, lembrando que um cifrão (“$”) precedendo um nome de variável indica que ela pertence ao escopo local.
Vejamos como isto funcionará:
<?php function condition ($condition, $global, $local) { // condition if (!$condition) return true; $not = false; // Vamos separar os membros OR $or_list = explode ('||', $condition); foreach ($or_list as $or_condition) { // each or condition $result = true; $or_condition = trim ($or_condition); // Para cada membro OR, vamos criar uma lista AND $and_list = explode ('&&', $or_condition); foreach ($and_list as $and_condition) { // each and condition $c = trim ($and_condition); if ($c[0] == '!') { // negative operator on $not = true; $c = trim (substr ($c, 1)); } // negative operator on if ($c[0] == '$') { // local scope $c = substr ($c, 1); if (!$not and (!isset ($local[$c]) or !$local[$c])) $result = false; elseif ($not and isset ($local[$c]) and $local[$c]) $result = false; } // local scope else { // global scope if (!$not and (!isset ($global[$c]) or !$global[$c])) $result = false; elseif ($not and isset ($global[$c]) and $global[$c]) $result = false; } // global scope $not = false; } // each and condition if ($result) return true; } // each or condition return false; } // condition ?>
Atualmente não sentimos a necessidade de avaliar expressões mais complexas, como as que utilizam operadores de comparação. As questões mais complexas serão realizadas pelas aplicações e módulos do nosso gerenciador de conteúdos. A avaliação de expressões durante o processamento de um modelo serve somente para manter ou retirar algum trecho de HTML, para que o resultado fique limpo.