Conditions¶
O Condition Engine avalia regras de inclusao e exclusao baseadas em contextos Moodle. Ele responde a pergunta: "esta regra se aplica neste contexto?" — considerando categorias, cursos e tipos de atividade.
O sistema faz parte do Core Capability CC-09 (core.conditions) e esta sempre disponivel via core extension.
Exemplo rapido¶
Verificar se um contexto Moodle corresponde a uma regra de condicao:
use local_middag\facade\conditions;
use local_middag\framework\contract\condition_rule;
// Regra: incluir apenas cursos das categorias 5 e 12, excluindo atividades do tipo quiz
$rule = new condition_rule(
include_category_ids: [5, 12],
exclude_module_types: ['quiz'],
);
// Verificar se o contexto atual corresponde
$context = \core\context\course::instance($course_id);
if (conditions::matches($rule, $context)) {
// A regra se aplica neste contexto
}
Conceitos¶
| Conceito | Descricao |
|---|---|
| Condition rule | Value object que define criterios de inclusao/exclusao |
| Condition provider | Implementacao que avalia um tipo customizado de condicao |
| Contexto Moodle | Objeto core\context (sistema, categoria, curso, modulo, bloco) |
| Graceful degradation | Quando nenhuma regra esta configurada, todos os contextos correspondem |
A logica de avaliacao segue o padrao:
- Se nao ha regras (rule vazia), tudo corresponde.
- Se ha listas de inclusao, apenas os contextos listados correspondem.
- Se ha listas de exclusao, os contextos listados sao removidos do match.
- Inclusao e exclusao podem ser combinadas: inclusao filtra primeiro, exclusao remove depois.
Referencia da API¶
conditions_interface (contract @api)¶
| Metodo | Descricao |
|---|---|
matches(condition_rule $rule, context $context): bool |
Verifica se o contexto corresponde a regra |
get_applicable_context_ids(condition_rule $rule): array |
Retorna todos os context IDs que correspondem a regra |
Acesso via facade:
use local_middag\facade\conditions;
use local_middag\framework\contract\condition_rule;
$rule = new condition_rule(include_course_ids: [10, 20, 30]);
// Verificar um contexto especifico
$matches = conditions::matches($rule, $context);
// Obter todos os contextos que correspondem
$context_ids = conditions::get_applicable_context_ids($rule);
condition_rule (value object @api)¶
final readonly class condition_rule
{
public function __construct(
public array $include_category_ids = [], // Categorias a incluir (vazio = todas)
public array $exclude_category_ids = [], // Categorias a excluir
public array $include_course_ids = [], // Cursos a incluir (vazio = todos)
public array $exclude_course_ids = [], // Cursos a excluir
public array $include_module_types = [], // Tipos de atividade a incluir (ex: 'assign', 'quiz')
public array $exclude_module_types = [], // Tipos de atividade a excluir
) {}
public function is_empty(): bool; // True se nenhuma condicao esta configurada
}
O condition_rule e imutavel (readonly). Construa uma nova instancia para cada combinacao de regras.
Construindo regras¶
Sem restricoes (tudo corresponde)¶
$rule = new condition_rule();
// $rule->is_empty() === true
// matches() retorna true para qualquer contexto
Apenas categorias especificas¶
Excluir tipos de atividade¶
Combinacao: incluir cursos, excluir modulos¶
$rule = new condition_rule(
include_course_ids: [101, 102, 103],
exclude_module_types: ['quiz'],
);
// Apenas contextos nos cursos 101-103, excluindo atividades do tipo quiz
Implementar um condition provider¶
Extensions podem adicionar tipos customizados de condicao implementando condition_provider_interface e registrando o provider durante boot().
Exemplo: condicao por faixa horaria¶
namespace local_meuplugin\extensions\horarios;
use core\context;
use local_middag\framework\contract\condition_provider_interface;
use local_middag\framework\contract\condition_rule;
class time_range_condition_provider implements condition_provider_interface
{
/**
* Identificador unico deste tipo de condicao.
*/
public function get_type(): string
{
return 'time_range';
}
/**
* Avalia se o contexto corresponde dentro da faixa horaria.
*/
public function matches(condition_rule $rule, context $context): bool
{
// Exemplo: verificar se a hora atual esta dentro de uma faixa
$hour = (int) date('H');
// Logica customizada: ativo entre 8h e 18h
return $hour >= 8 && $hour < 18;
}
/**
* Retorna todos os context IDs que correspondem.
*/
public function get_applicable_context_ids(condition_rule $rule): array
{
// Para condicoes temporais, todos os contextos correspondem
// quando a faixa horaria e valida
if (!$this->matches($rule, \core\context\system::instance())) {
return [];
}
// Delegar ao engine padrao para os context IDs
return [];
}
}
Registro no boot()¶
namespace local_meuplugin\extensions\horarios;
class horarios_extension extends \local_middag\base\extension
{
public function boot(): void
{
// Registrar o provider no conditions registry
// O registro concreto depende da implementacao do registry;
// consulte a documentacao da versao para o metodo exato.
}
}
Referencia do condition_provider_interface¶
| Metodo | Descricao |
|---|---|
get_type(): string |
Identificador unico do tipo de condicao |
matches(condition_rule $rule, context $context): bool |
Avalia se o contexto corresponde |
get_applicable_context_ids(condition_rule $rule): list<int> |
Retorna todos os context IDs que correspondem |
Patterns¶
Visibilidade condicional de componentes¶
Use conditions para controlar onde um componente e exibido:
use local_middag\facade\conditions;
use local_middag\framework\contract\condition_rule;
class banner_widget
{
public function render(int $course_id): string
{
$rule = $this->load_visibility_rule();
$context = \core\context\course::instance($course_id);
if (!conditions::matches($rule, $context)) {
return ''; // Nao exibir neste contexto
}
return $this->build_html();
}
private function load_visibility_rule(): condition_rule
{
// Carregar regra do banco de dados ou configuracao
return new condition_rule(
include_category_ids: [5, 12],
);
}
}
Filtrar contextos para operacoes em massa¶
Use get_applicable_context_ids() quando precisar aplicar uma operacao a todos os contextos validos:
use local_middag\facade\conditions;
use local_middag\framework\contract\condition_rule;
$rule = new condition_rule(
include_category_ids: [5],
exclude_module_types: ['quiz'],
);
$context_ids = conditions::get_applicable_context_ids($rule);
// Aplicar operacao aos contextos filtrados
foreach ($context_ids as $context_id) {
$this->process_context($context_id);
}
Combinar conditions com segments¶
Conditions e segments resolvem dimensoes diferentes e podem ser compostos:
use local_middag\facade\conditions;
use local_middag\facade\segments;
use local_middag\framework\contract\condition_rule;
// 1. Verificar se o contexto e aplicavel (conditions)
$rule = new condition_rule(include_category_ids: [5]);
$context = \core\context\course::instance($course_id);
if (!conditions::matches($rule, $context)) {
return; // Contexto nao se aplica
}
// 2. Verificar se o usuario pertence ao segmento (segments)
$subquery = segments::get_subquery($segment_id);
global $DB, $USER;
$is_targeted = $DB->record_exists_sql(
"SELECT 1 FROM ({$subquery->sql}) sub WHERE sub.userid = ?",
array_merge($subquery->params, [$USER->id])
);
if ($is_targeted) {
// Contexto valido E usuario no segmento — entregar conteudo
}
Anti-patterns¶
Usar conditions para filtrar usuarios¶
Conditions filtram contextos, nao usuarios. Para filtrar usuarios, use Segments:
// ERRADO: conditions nao filtra usuarios
$rule = new condition_rule(include_course_ids: [10]);
// Nao ha como verificar "usuario X pertence a esta condicao"
// CORRETO: usar segments para usuarios
$subquery = segments::get_subquery($segment_id);
Criar regras com inclusao e exclusao redundantes¶
Nao inclua e exclua o mesmo valor:
// ERRADO: contraditorrio
$rule = new condition_rule(
include_course_ids: [10, 20],
exclude_course_ids: [20], // 20 esta nas duas listas
);
// CORRETO: incluir apenas o necessario
$rule = new condition_rule(
include_course_ids: [10],
);
Avaliar conditions em loop sem cache¶
Se voce precisa verificar o mesmo rule contra multiplos contextos, obtenha os context IDs de uma vez:
// ERRADO: N chamadas para o mesmo rule
foreach ($contexts as $ctx) {
if (conditions::matches($rule, $ctx)) { /* ... */ }
}
// CORRETO: obter todos os IDs de uma vez
$valid_ids = conditions::get_applicable_context_ids($rule);
$valid_set = array_flip($valid_ids);
foreach ($contexts as $ctx) {
if (isset($valid_set[$ctx->id])) { /* ... */ }
}
Diferenca entre Conditions e Segments¶
| Aspecto | Conditions (CC-09) | Segments (CC-07) |
|---|---|---|
| Pergunta | "Em quais contextos esta regra se aplica?" | "Quais usuarios pertencem a este grupo?" |
| Alvo | Contextos Moodle (categorias, cursos, atividades) | Usuarios (user IDs) |
| Retorno | bool (match) ou list<int> (context IDs) |
segment_subquery (SQL de user IDs) |
| Uso | Visibilidade, filtro por area do site | Audiencia, targeting, conteudo segmentado |
| Analogia | "Onde mostrar" (page builder display conditions) | "Para quem mostrar" (audience targeting) |
Conditions responde onde. Segments responde para quem. Combine os dois para targeting completo.