04
oct
2012
Robin Millette

Administrer les Flags des utilisateurs dans Drupal 7 (aka RSVP)

Section: 

Dans Drupal 6, on peut assez facilement ajouter une option à certains nodes pour permettre aux utilisateurs de s’inscrire à un événement par exemple. Il existe au moins quatre modules pour cela.

Dans Drupal 7, ce n’est pas encore aussi mature.

J’ai finalement utilisé http://drupal.org/project/flag qui permet par défaut aux utilisateurs d’un site de «bookmarker» des pages de ce site. Via Views, on peut aussi consulter la liste des pages flagguées par un utilisateur ou encore la liste des utilisateurs ayant flaggué une page.

Le bout de code qui suit permet aux administrateurs de changer la liste des utilisateurs ayant flaggué une page, soit en ajoutant des utilisateurs soit en en retirant.

En gros, les nodes de type event ont deux sous-pages:

  • une pour les membres qui affiche la liste des membres ayant flaggué cet event;
  • une pour les administrateurs qui affiche la même liste avec une colonne supplémentaire pour retirer des membres et un champ de texte qui s’auto-complète pour ajouter des membres.

J’utilise profile2 et les utilisateurs du site ont un prénom et un nom de famille dans leur profil principal. Le username peut être n’importe quoi. Le champ pour ajouter des membres à un event fait son auto-complétion sur ces champs, et retourne le UID.

Le code n’est pas encore publié autrement qu’ici. C’est plutôt spécifique à mon cas pour le moment mais je compte en publier une version plus générique éventuellement.

Je pensais, pour l’auto-complétion, pouvoir baser ça sur un view. On verra ça…

J’ai commenté un issue sur drupal.org à ce sujet.

flagmanage.module:

<?php
function flagmanage_unflag($nid, $account) {
 
$rsvp = flag_get_flag('rsvp');
 
$x = $rsvp->flag('unflag', $nid, $account);
 
// TODO
  // use destination or even better, override the module flag
  // to let admins unflag other users flags
 
drupal_goto("node/$nid/rsvipadmin");
}

function
flagmanage_menu() {
 
$items['flagmanage/unflag/%/%user'] = array(
   
'title' => 'Unflag',
   
'page callback' => 'flagmanage_unflag',
   
'page arguments' => array(2, 3),
   
'access callback' => 'user_access',
   
'access arguments' => array('administer users'),
   
'type' => MENU_CALLBACK,
  );

 
$items['flagmanage/user/autocomplete'] = array(
   
'title' => 'User autocomplete',
   
'page callback' => 'flagmanage_user_autocomplete',
   
'access callback' => 'user_access',
   
'access arguments' => array('administer users'),
   
'type' => MENU_CALLBACK,
  );

  return
$items;
}

function
flagmanage_user_autocomplete($string = '') {
 
// TODO
  // use a view or something more generic
  // Here, we're searching on specific profile fields
 
$result = db_query_range("SELECT uid, field_first_name_value, field_last_name_value FROM {profile} as p, {field_data_field_first_name} as f join {field_data_field_last_name as} l on f.entity_id=l.entity_id WHERE pid=f.entity_id and concat(field_first_name_value, ' ', field_last_name_value) like :string", 0, 10, array(':string' => "%$string%"));

 
$matches = array();
  foreach (
$result as $r) {
   
$n = "{$r->field_first_name_value} {$r->field_last_name_value}";
   
$matches["$n [{$r->uid}]"] = check_plain($n);
  }

 
drupal_json_output($matches);
}

function
_flagmanage_extract_uid($string) {
  if (
is_numeric($string)) return (int)$string;
  if (
preg_match('/\s\[(\d+)\]$/', $string, $matches)) return (int)$matches[1];
  return
false;
}

function
flagmanage_flaggersform_validate($form, &$form_state) {
 
$search = _flagmanage_extract_uid($form_state['values']['search']);
  if (!
$search || !db_query('SELECT uid FROM {users} WHERE uid = :uid', array(':uid' => $search))->fetchField()) {
   
form_set_error('search', t('That user doesn\'t exist.'));
  }
}

function
flagmanage_flaggersform_submit($form, &$form_state) {
  if ((
'node' !== arg(0)) || ('rsvipadmin' !== arg(2))) return;

 
$search = _flagmanage_extract_uid($form_state['values']['search']);
 
// TODO
  // don't silently return on error
 
if (!$search) return;

 
$rsvp = flag_get_flag('rsvp');
 
// TODO
  // don't silently return on error
 
if (empty($rsvp)) return;
 
$x = $rsvp->flag('flag', arg(1), user_load($search));
 
// TODO
  // if true drupal_set_message "User successfully added"
  // don't silently return on error
}

function
flagmanage_flaggersform($form, &$form_state) {
 
$form['flagger']['search'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Member\'s name'),
   
'#description' => t('Enter the member\'s UID directly if you know it, otherwise type in a few letters and select the name from the list.'),
   
'#id' => 'flagger',
   
'#required' => TRUE,
   
'#autocomplete_path' => 'flagmanage/user/autocomplete',
  );

 
$form['flagger']['add'] = array(
   
'#type' => 'submit',
   
'#value' => t('Add'),
  );

  return
$form;
}

function
flagmanage_block_info() {
 
// TODO
  // using something other than a block to display the form?
 
$blocks['flagmanage'] = array(
   
'info' => t('Flag manage'),
  );
  return
$blocks;
}

function
flagmanage_block_view($delta = '') {
 
// TODO
  // using something other than a block to display the form?
 
if ('flagmanage' !== $delta) return array();
  if ((
'node' !== arg(0)) || ('rsvipadmin' !== arg(2))) return array();

  return array(
   
'subject' => t('Flag manage'),
   
'content' => drupal_get_form('flagmanage_flaggersform'),
  );
}
?>

flagmanage.info:

name = Flag manage
description = Let admin manage user flags.
core = 7.x

Publier un nouveau commentaire

Plain text

  • Aucune balise HTML autorisée.
  • Les adresses de pages web et de courriels sont transformées en liens automatiquement.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
By submitting this form, you accept the Mollom privacy policy.