Member Medals Provider API Guide

The English Hub is dedicated to our English-speaking community. Join us to exchange thoughts, ask for advice, or engage in discussions. Everyone is welcome!
Avatar do usuário
Chico Gois
Administrador
Administrador
Mensagens: 141
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)

    This guide describes the minimum external integration API for mundophpbb/membermedals.

    Objective

    The API allows other extensions to add new medal criteria without modifying the Member Medals core.

    Examples of external criteria:
    • points
    • donations
    • likes received
    • topics solved
    • friends / foes
    • attachments uploaded
    How the architecture works

    The core works with three main parts:

    1. Provider
    • knows how to calculate a value for a user
    • defines the name, family, operators, and rule normalization
    2. Registry
    • gathers both native and external providers
    3. Rules manager
    • uses the provider to evaluate the rule
    • delegates the medal awarding to the grant manager
    Public Registration Event

    The core triggers the event:

    Código: Selecionar todos

    mundophpbb.membermedals.collect_rule_providers
    External extensions must listen to this event and attach their providers to the [c]providers[/c] array.

    Mandatory Interface

    Every external provider must implement:

    Código: Selecionar todos

    \mundophpbb\membermedals\contract\rule_provider_interface
    Methods

    get_key(): string
    Unique key for the criterion. Example: friends_count, likes_received.

    get_label_lang_key(): string
    Language key used in the ACP for the criterion name.

    get_description_lang_key(): string
    Language key used for the criterion description.

    get_supported_operators(): array
    Accepted operators. Common example:

    Código: Selecionar todos

    ['>=', '>', '=', '<=', '<']
    get_family(): string
    Logical family for progression. Use the same family for medals that should replace each other within the same track.

    is_progressive(): bool
    Defines if the family uses progression. If it returns true, the core attempts to keep only the highest automatic medal of that family.

    get_user_value(int $user_id, array $rule, array $context = [])
    Returns the current user value for the criterion (int, float, string, bool, or null).

    normalize_rule_data(array $data): array
    Normalizes data saved in the ACP (type conversion, min/max, etc.).

    get_rule_options_schema(): array
    Reserved for extra criterion options (future compatibility).

    get_value_input_attributes(): array
    Defines attributes for the numeric field in the ACP (min, max, step).

    Implementation Example

    File structure:

    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
    
    Minimum Provider (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 }
    
    Limitations and Tips
    • Progression: For this to work, is_progressive() must be true and related providers must share the same family.
    • ACP: The rule_options_schema is not yet dynamically rendered in the current version.
    • Checklist: Always verify if the new criterion appears in the Member Medals ACP and if the award_family column is correctly populated in the database.
    The core evaluates rules; the provider resolves the metric.
    Responder