Member Medals Provider API Guide

Relação de extensões criadas.
Avatar do usuário
Chico Gois
Administrador
Administrador
Mensagens: 140
Registrado em: 16 Dez 2025, 22:05
Localização: São Paulo - SP
Contato:

Member Medals Provider API Guide

  • Favoritar esta postagem
  • Mensagem por Chico Gois »

    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:
    • pontos
    • doações
    • curtidas recebidas
    • tópicos resolvidos
    • amigos / inimigos
    • anexos enviados
    Como a arquitetura funciona

    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
    2. Registry
    • reúne providers nativos e externos
    3. Rules manager
    • 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_providers
    Extensões externas devem ouvir esse evento e anexar seus providers no array [c]providers[/c].

    Interface obrigatória

    Todo provider externo deve implementar:

    Código: Selecionar todos

    \mundophpbb\membermedals\contract\rule_provider_interface
    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:

    Código: Selecionar todos

    ['>=', '>', '=', '<=', '<']
    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:

    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
    
    Provider mínimo (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];
        }
    }
    
    services.yml:

    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 }
    
    Limitações e Dicas
    • 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.
    Responder