Estendendere il form di registrazione

Una delle caratteristiche più interessanti messa a disposizione dalle nuovi API di Joomla 1.6 è quella di poter personalizzare i form estendendo le classi JForm, JFormField. In questo articolo vedremo come è possibile aggiungere al form di registrazione standard di Joomla un campo, senza la necessità di intervenire sul codice core di Joomla con un hack, ma in maniera del tutto trasparente e standard utilizzando un plugin di tipo user.  Vediamo come è possibile personalizzare il form di registrazione, l'obiettivo che ci prefiggiamo è quello di aggiungere un campo "presentatore" al form di registrazione,cioè quale utente ci ha "consigliato" la registrazione al sito.
Mi sono ispirato per realizzare questo plugin all' esempio incluso nella distribuzione ufficiale, il cosiddetto "profile plugin". Per prima cosa dobbiamo definire attraverso l'apposito XML la tipologia del campo che vogliamo gestire,la classe JForm che trovate in libraries\joomla\form prevede già una serie di tipi di campo predefiniti, li trovate nella cartella libraries\joomla\form\fields tra cui il tipo sql che fa prorio al nostro caso,in quanto ci serve un elenco degli utenti del sito che dovremo prelevare dalla tabella utenti la #_users

La definizione dell'xml che definisce il nostro form è il seguente:
<!--?xml version="1.0" encoding="UTF-8"?-->
<form>    
        <fieldset>
            <!-- icampi vanno qui -->
        </fieldset>
 
</form>
 
definiamo il nostro campo presentatore di tipo sql
 
  <field
      name="myq"
      type="sql"
      default="nessuno"
      id="myq"
      label="Selezione il tuo presentatore"
            description="PLG_USER_PRESENTATORE_FIELD_MYQ_DESC"
      query="SELECT username FROM #__users WHERE block=0"
      key_field="username" value_field="username"
  />      
 

Vediamo ora il codice del nostro plugin che dovrà estendere la classe JPlugin è gestirà 4 eventi: onContentPrepareData, onContentPrepareForm, onUserAfterSave e onUserAfterDelete con i primi due eventi onContentPrepareData, onContentPrepareForm  gestiremo la manipolazione del form

function onContentPrepareData($context, $data)
  {
    // Verifichiamo  che siamo sui form desiderati
    if (!in_array($context, array('com_users.profile','com_users.user', 'com_users.registration', 'com_admin.profile'))) {
      return true;
    }
 
    if (is_object($data))
    {
      $userId = isset($data->id) ? $data->id : 0;
 
      // carico i dati dal database.
      $db = JFactory::getDbo();
      $db->setQuery(
        'SELECT profile_key, profile_value FROM #__user_profiles' .
        ' WHERE user_id = '.(int) $userId." AND profile_key LIKE 'profile.%'" .
        ' ORDER BY ordering'
      );
      $results = $db->loadRowList();
 
      // Se c'è un database error.
      if ($db->getErrorNum())
      {
        $this->_subject->setError($db->getErrorMsg());
        return false;
      }
 
      // Unisco il mio campo ai dati del form.
      $data->profile = array();
 
      foreach ($results as $v)
      {
        $k = str_replace('profile.', '', $v[0]);
        $data->profile[$k] = $v[1];
      }
 
    }
 
    return true;
  }
 
 
 
  function onContentPrepareForm($form, $data)
  {
    // Carico la  lingua
    $lang = JFactory::getLanguage();
    $lang->load('plg_user_presentatore', JPATH_ADMINISTRATOR);
 
    if (!($form instanceof JForm))
    {
      $this->_subject->setError('JERROR_NOT_A_FORM');
      return false;
    }
 
    // Verifichiamo  che siamo sui form desiderati.
    if (!in_array($form->getName(), array('com_admin.profile','com_users.user', 'com_users.registration','com_users.profile'))) {
      return true;
    }
 
    // Aggiungiamo il nostro campo al form di registrazione.
    JForm::addFormPath(dirname(__FILE__).'/profiles');
    $form->loadFile('profile', false);
 
    // Verifichiamo chel il campo sia richiesto.
    if ($this->params->get('register-require_pres', 1) > 0) {
      $form->setFieldAttribute('myq', 'required', $this->params->get('register-require_pres') == 2, 'profile');
    }
    else {
      $form->removeField('myq', 'profile');
    }
 
 
    return true;
  }
 
infine con gli eventi onUserAfterSave, onUserAfterDelete gestiamo la memorizzazione del nostro campo presentatore sulla tabella #_profiles in modo da poterla recuperare anche lato admini
 
function onUserAfterSave($data, $isNew, $result, $error)
{
  $userId  = JArrayHelper::getValue($data, 'id', 0, 'int');
  if ($userId && $result && isset($data['profile']) && (count($data['profile'])))
    {
      try
   {        
    $db = JFactory::getDbo();
    $db->setQuery(
                  'DELETE FROM #__user_profiles WHERE user_id = '.$userId .
                        " AND profile_key LIKE 'profile.%'"
      );
    if (!$db->query()) {
      throw new Exception($db->getErrorMsg());
    }
    $tuples = array();
    $order  = 1;
    foreach ($data['profile'] as $k => $v)
    {
     $tuples[] = '('.$userId.', '.$db->quote('profile.'.$k).', '.$db->quote($v).', '.$order++.')';
    }
          $db->setQuery('INSERT INTO #__user_profiles VALUES '.implode(', ', $tuples));
         if (!$db->query()) {
      throw new Exception($db->getErrorMsg());
   }
    }
  catch (JException $e)
        {
   $this->_subject->setError($e->getMessage());
   return false;
  }
  }
 
  return true;
}
function onUserAfterDelete($user, $success, $msg)
{
   if (!$success) {
     return false;
   }
   $userId  = JArrayHelper::getValue($user, 'id', 0, 'int');
   if ($userId)
  {
         try
      {
       $db = JFactory::getDbo();
       $db->setQuery(
    'DELETE FROM #__user_profiles WHERE user_id = '.$userId .
    " AND profile_key LIKE 'profile.%'"
              );
      if (!$db->query()) {
          throw new Exception($db->getErrorMsg());
      }
  }
      catch (JException $e)
  {
      $this->_subject->setError($e->getMessage());
      return false;
  }
  }
 
  return true;
}
 
Questo è il risultato finale
plugin presentatore

Comments (0)

500 characters remaining

Cancel or