it-swarm.it

Come faccio a creare un campo che accetta solo valori univoci?

Sto usando il modulo Field Collection perché ho una relazione complicata tra i campi e ho provato a integrarlo con il modulo Campo unico , senza successo , perché il modulo Campo unico non è supportato dal modulo Raccolta campi .

Esiste un metodo più semplice per verificare se il valore è univoco e per visualizzare l'errore di convalida, se il valore non è univoco?

Sfortunatamente, Drupal 7 non ha questa funzione di default, quindi ci deve essere un metodo per farlo.

4
Ek Kosmos

Ecco finalmente come ho adattato e affrontato i suggerimenti di @tostinni, @stefgosselin, @ uwe999 risposte e altri:

/**
 * implementation of hook_form_alter().
 */
function CUSTOM_MODULE_form_alter(&$form, &$form_state, $form_id) {
    switch ($form_id) {
        case 'MY_FORM_ID':
            // add custom validation callback
            $form['#validate'][] = 'CUSTOM_MODULE_MY_FORM_ID_validate';
            break;
            ...
        default:
            break;
    }
}

quindi tutte le funzionalità che ho implementato in:

/**
 * implementation of hook_form_FORM_ID_alter
 */
function CUSTOM_MODULE_MY_FORM_ID_validate(&$form, &$form_state) {

    //retrieve the value for your field
    $value = $form_state['values']['field_MY_FIELD']['und'][0]['value'];

    //Execute a count query to see if there's other similar values.
    $query = new EntityFieldQuery;
    $query->entityCondition('entity_type', 'field_collection_item')
            ->fieldCondition('field_MY_FIELD', 'value', $value)
            ->count();
    $count = $query->execute();
    if ($count > 0) {
        form_set_error('field_MY_FIELD', 'Unique field value is already used.');
    }
}

Ho provato a lavorare con entity_metadata_wrapper ma sfortunatamente non ci sono riuscito.

Grazie per le tue risposte.

1
Ek Kosmos

È necessario implementarlo in un modulo personalizzato, ecco un codice di esempio per raggiungere questo obiettivo:

function custom_node_validate($node, $form) {
  if ($node->type == 'page') {
    //retrieve the value for your field using Entity API
    $wrapper = entity_metadata_wrapper('node', $node);
    $value = $wrapper->field_collection->field_unique->value();

    //Execute a count query to see if there's other similar values.
    $query = new EntityFieldQuery;
    $query->entityCondition('entity_type', 'field_collection_item')
      ->fieldCondition('field_unique', 'value', $value)
      ->count();
    $count = $query->execute();
    if ($count > 1) {
      form_set_error('field_unique', 'Unique field value is already used.');
    }
  }
}

Alcune dichiarazioni di non responsabilità:

  • Sono davvero rifornito dalla complessità di Campo API per la raccolta sul campo ed è stato piuttosto complicato trovare buone informazioni su come recuperare valori ed eseguire query.
  • Mi piace molto fare query SQL (vedi Come modificare le impostazioni del campo legnth ) ma ho provato a usare solo l'API invece di fare una semplice query sulla tabella field_data_field_unique. Tuttavia, potrebbe non essere ancora perfetto, quindi sentiti libero di entrare.
  • form_set_error () non evidenzia il campo, non sono riuscito a trovare il nome corretto.

Ecco la documentazione che ho usato:

Modifica: Seguendo i consigli di chx, per passare direttamente field_name A fieldCondition().

8
tostinni

Non ho ancora programmato un modulo ma sembra che potrebbe essere più semplice scrivere un hook su form_alter e quindi eseguire una query sul campo "numero seriale" esistente per assicurarsi che sia univoco.

4
uwe

Fondamentalmente Ek Kosmos ha l'idea di base. Il più semplice sarebbe creare un piccolo modulo personalizzato , questo ha il vantaggio di isolare la funzione che vuoi costruire e ricordare la regola n. 1, tu davvero non voglio mai hackerare nulla nel core, a meno che tu non riesca davvero ad evitarlo.

Una volta che hai impostato il tuo file .info in una cartella e il file .module pronto per andare come indicato nel molti tutorial sull'argomento , puoi sfruttare la potenza di hook_form_alter scrivendo una funzione chiamata your-module-name _form_alter nel file del tuo modulo e sai che verrà chiamata la funzione.

Probabilmente avresti bisogno di un'istruzione switch dipendente dal modulo) per eseguire azioni specifiche a seconda dell'id modulo ,

Probabilmente dovresti provare ad aggiungere un attributo (#validate) che aggiunge una chiamata di funzione sull'array di moduli, essendo un nome di funzione della tua funzione di validazione personalizzata.

Qualcosa di simile a:

   // #validate adds callback to custom validator.
   $validators = $form['#validate'][]; // Save existing validation calls. 
   //  Not clear in docs, but this is important!

  // In your case, you may want to add a method callback with this attribute.                                   
  $form['#validate'][] = $validators . ' _custom_validate';

Naturalmente, nella funzione di convalida è possibile registrare errori, reindirizzare, assegnare messaggi di errore o notifiche.

Leggi modulo api e scarica gli esempi di modulo .

Se hai bisogno di aiuto ed esempi a bizzeffe, scarica i moduli contrib e vedi come gli altri hanno affrontato la bestia, o pubblica qui delle domande mentre procedi.

Felice conding, buona fortuna.

1
stefgosselin

Prova con validazione campo modulo, usa validatore univoco. Aggiungi una regola di convalida, scegli ambito unico, globale, entità, pacchetto.

1
ghr