Come escludere i diritti a un badge personalizzato se è già stato concesso un livello superiore? L’obiettivo è concedere solo il livello più alto per cui un particolare utente è idoneo…
Supponiamo che io abbia 3 badge:
Livello 1: 5 Mi piace dati, 5 ricevuti
Livello 2: 100 Mi piace dati, 100 ricevuti
Livello 3: 250 Mi piace dati, 250 ricevuti
Il codice seguente è per il Livello 2. Gli altri livelli non hanno nulla di diverso a parte il numero ‘100’
SELECT us.user_id, current_timestamp AS granted_at
FROM user_stats AS us
WHERE us.likes_received >= 100
AND us.likes_given >= 100
AND (:backfill OR us.user_id IN (:user_ids))
Nelle impostazioni di /admin/badges/BADGE-ID, è sufficiente selezionare l’opzione Esegui query di revoca giornalmente. Il badge verrà rimosso se non soddisfa più i criteri SQL.
Potresti anche voler impostare Aggiorna giornalmente in modo che l’assegnazione/revoca avvenga all’incirca nello stesso momento (credo a mezzanotte ora locale della tua istanza).
Servirebbe anche una riga in più nel SQL del badge per bilanciarlo? Qualcosa come:
SELECT us.user_id, current_timestamp AS granted_at
FROM user_stats AS us
WHERE us.likes_received >= 100
AND us.likes_given >= 100
AND us.likes_given < 250
AND (:backfill OR us.user_id IN (:user_ids))
(possibilmente usare un BETWEEN o simile, anche se non l’ho ancora testato )
E poi, quando la query viene eseguita, assegnerà il badge per 100 Mi piace la prima volta, lo ignorerà per 101-249 e poi lo revocherà a 250 (da dove riprenderà il badge successivo).
Aggiornamento: Ho fatto un po’ di pratica con BETWEEN e qualcosa come questo sembra catturare tutte le persone giuste nel test di esempio:
SELECT us.user_id
FROM user_stats AS us
WHERE us.likes_received BETWEEN 100 AND 249
ORDER BY us.likes_received DESC
Quindi qualcosa del genere dovrebbe funzionare se convertito in un badge attivato:
SELECT us.user_id, current_timestamp AS granted_at
FROM user_stats AS us
WHERE us.likes_received BETWEEN 100 AND 249
AND us.likes_given BETWEEN 100 AND 249
AND (:backfill OR us.user_id IN (:user_ids))
Questo è quasi perfetto. Può verificarsi un evento raro: l’utente consegna troppo in ‘dato’ mentre riceve poco (o viceversa), quindi il badge potrebbe essere perso prima che ne venga concesso un altro (routine di revoca).
Ho cercato e scoperto una proprietà interessante: something.badge_id = 123 dove ‘something’ è la variabile definita dall’utente e ‘123’ l’ID di un altro badge. Ci proverò e integrerò gli SQL originali di Tier 1 e Tier 2 con controlli di squalifica rispetto ai badge di livello superiore.