Member Medals Provider API Guide (0.7.3)
Este guia descreve a API mínima de integração externa do mundophpbb/membermedals.
Objetivo
A API permite que outras extensões adicionem novos critérios de medalhas sem alterar o core do Member Medals.
Exemplos de critérios externos:
O core trabalha com três peças:
1. Provider
Evento público de registro
O core dispara o evento:
Extensões externas devem ouvir esse evento e anexar seus providers no array [c]providers[/c].
Interface obrigatória
Todo provider externo deve implementar:
Métodos
get_key(): string
Chave única do critério. Exemplo: friends_count, likes_received.
get_label_lang_key(): string
Lang key usada no ACP para o nome do critério.
get_description_lang_key(): string
Lang key usada para a descrição do critério.
get_supported_operators(): array
Operadores aceitos. Exemplo comum:
get_family(): string
Família lógica da progressão. Use a mesma família para medalhas que devem se substituir dentro da mesma trilha.
is_progressive(): bool
Define se a família usa progressão. Se retornar true, o core tenta manter apenas a medalha automática mais alta daquela família.
get_user_value(int $user_id, array $rule, array $context = [])
Retorna o valor atual do usuário para o critério (int, float, string, bool ou null).
normalize_rule_data(array $data): array
Normaliza dados salvos no ACP (conversão de tipos, min/max, etc).
get_rule_options_schema(): array
Reservado para opções extras do critério (compatibilidade futura).
get_value_input_attributes(): array
Define atributos do campo numérico no ACP (min, max, step).
Exemplo de Implementação
Estrutura de arquivos:
Provider mínimo (PHP):
services.yml:
Limitações e Dicas
Este guia descreve a API mínima de integração externa do mundophpbb/membermedals.
Objetivo
A API permite que outras extensões adicionem novos critérios de medalhas sem alterar o core do Member Medals.
Exemplos de critérios externos:
- pontos
- doações
- curtidas recebidas
- tópicos resolvidos
- amigos / inimigos
- anexos enviados
O core trabalha com três peças:
1. Provider
- sabe como calcular um valor para um usuário
- define nome, família, operadores e normalização da regra
- reúne providers nativos e externos
- usa o provider para avaliar a regra
- delega a concessão da medalha ao grant manager
Evento público de registro
O core dispara o evento:
Código: Selecionar todos
mundophpbb.membermedals.collect_rule_providersInterface obrigatória
Todo provider externo deve implementar:
Código: Selecionar todos
\mundophpbb\membermedals\contract\rule_provider_interfaceget_key(): string
Chave única do critério. Exemplo: friends_count, likes_received.
get_label_lang_key(): string
Lang key usada no ACP para o nome do critério.
get_description_lang_key(): string
Lang key usada para a descrição do critério.
get_supported_operators(): array
Operadores aceitos. Exemplo comum:
Código: Selecionar todos
['>=', '>', '=', '<=', '<']Família lógica da progressão. Use a mesma família para medalhas que devem se substituir dentro da mesma trilha.
is_progressive(): bool
Define se a família usa progressão. Se retornar true, o core tenta manter apenas a medalha automática mais alta daquela família.
get_user_value(int $user_id, array $rule, array $context = [])
Retorna o valor atual do usuário para o critério (int, float, string, bool ou null).
normalize_rule_data(array $data): array
Normaliza dados salvos no ACP (conversão de tipos, min/max, etc).
get_rule_options_schema(): array
Reservado para opções extras do critério (compatibilidade futura).
get_value_input_attributes(): array
Define atributos do campo numérico no ACP (min, max, step).
Exemplo de Implementação
Estrutura de arquivos:
Código: Selecionar todos
ext/
└── vendor/
└── myprovider/
├── composer.json
├── ext.php
├── config/
│ └── services.yml
├── event/
│ └── listener.php
├── provider/
│ └── my_provider.php
└── language/
├── en/common.php
└── pt_br/common.php
Código: Selecionar todos
<?php
namespace vendor\myprovider\provider;
use mundophpbb\membermedals\contract\rule_provider_interface;
use phpbb\db\driver\driver_interface;
class likes_received_provider implements rule_provider_interface
{
protected driver_interface $db;
public function __construct(driver_interface $db)
{
$this->db = $db;
}
public function get_key(): string { return 'likes_received'; }
public function get_label_lang_key(): string { return 'MEMBERMEDALS_RULE_TYPE_LIKES_RECEIVED'; }
public function get_description_lang_key(): string { return 'MEMBERMEDALS_RULE_TYPE_LIKES_RECEIVED_EXPLAIN'; }
public function get_supported_operators(): array { return ['>=', '>', '=', '<=', '<']; }
public function get_family(): string { return 'likes_received'; }
public function is_progressive(): bool { return true; }
public function get_user_value(int $user_id, array $rule, array $context = [])
{
$sql = 'SELECT COUNT(*) AS total
FROM ' . LIKES_TABLE . '
WHERE liked_user_id = ' . (int) $user_id;
$result = $this->db->sql_query($sql);
$row = (array) $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
return (int) ($row['total'] ?? 0);
}
public function normalize_rule_data(array $data): array
{
$data['rule_value'] = max(0, (int) ($data['rule_value'] ?? 0));
$data['rule_options'] = $data['rule_options'] ?? [];
return $data;
}
public function get_rule_options_schema(): array { return []; }
public function get_value_input_attributes(): array
{
return ['min' => 0, 'max' => 999999999, 'step' => 1];
}
}
Código: Selecionar todos
services:
vendor.myprovider.provider.likes_received:
class: vendor\myprovider\provider\likes_received_provider
arguments:
- '@dbal.conn'
vendor.myprovider.listener:
class: vendor\myprovider\event\listener
arguments:
- '@vendor.myprovider.provider.likes_received'
tags:
- { name: event.listener }
- Progressão: Para funcionar, is_progressive() deve ser true e os providers relacionados devem compartilhar a mesma family.
- ACP: O rule_options_schema ainda não é renderizado dinamicamente na versão atual.
- Checklist: Sempre verifique se o novo critério aparece no ACP e se a coluna award_family é preenchida corretamente no banco de dados.
O core avalia regras; o provider resolve a métrica.
