it-swarm.com.de

Überprüfen Sie alle Instanzen eines Feldes programmgesteuert

Was ist der beste Weg (Hook), um alle Instanzen eines Feldes programmgesteuert zu validieren? Ich habe viele Inhaltstypen mit denselben Feldern wie field_phone. Ich möchte field_phone Programmgesteuert überall dort validieren, wo es verwendet wird.

7
hpn

Sie könnten hook_field_validate implementieren und prüfen, ob es die richtige Instanz ist. Funktioniert nicht, wenn das Feld nicht vom Modul definiert wird.

Eine Möglichkeit zum Erstellen würde hook_form_alter verwenden und element_validator hinzufügen, wenn das Feld im Formular vorhanden ist.

function mymodule_form_alter(&$form, &$form_state, $form_id) {
   if (isset($form['field_phone'])) {
      $form['field_phone']['#element_validate'][] = 'mymodule_somevalidator';
    }
 }

function mymodule_somevalidator($element, &$form_state) {
  if (!empty($element['#value']) && !is_numeric(parse_size($element['#value'])) {
    form_error($element, t('The "!name" must be x', array('!name' => t($element['title']))));
  }
} 
6
user20301

Probieren Sie das Modul Field Validation aus.

Sie müssen jedem Feld, das Sie validieren möchten, noch eine ordnungsgemäße Validierung hinzufügen.

4
Scott Joudry

Von field_attach_form_validate :

Es gibt zwei Validierungsstufen für Felder in Formularen: Widget-Validierung und Feldvalidierung.

für die Widget-Validierung können Sie dem Pfad hook_form_alter folgen. Dies ist schwer zu verallgemeinern, da Sie Details darüber wissen müssen, wie das Formular erstellt wird. Beispielsweise können Elemente oder Werte für einige Entitäten verschachtelt sein.

IMO, es ist am besten, eine Feldvalidierung durchzuführen. Dies erfolgt durch Implementierung von hook_field_attach_validate . Hier ist ein einfaches Beispiel:

function hook_field_attach_validate($entity_type, $entity, &$errors) {
  if (isset($entity->field_phone)) {
    $errors['field_phone'][LANGUAGE_NONE][0][] = array(
      'error' => 'error_key',
      'message' => t('Error message'),
    );
  }
}

error_key wird von hook_field_widget_error verwendet, um ein Formularelement zu kennzeichnen, wenn ein Widget aus mehreren Elementen besteht. Zum Beispiel in Implementierung dieses Hooks im Textfeld der Fehlerschlüssel text_summary_max_length wird verwendet, um ein Element innerhalb der Widget-Struktur zu kennzeichnen.

Im Allgemeinen wird der Fehlerschlüssel nicht für Widgets mit einem einzelnen Element verwendet. Im Fall von Telefonfeldtyp (von dem ich annehme, dass Sie es verwenden) stellen sie ein zusammengesetztes Widget bereit, aber implementieren Sie keine Fehlerverteilung auf Elemente , ignorieren Sie es also einfach .

2
jonhattan

Der beste Weg, um es zu implementieren, indem Sie hook_form_alter implementieren. Die Logik ist so, dass Sie die benutzerdefinierte Validierungsfunktion für alle Inhaltstypformulare hinzufügen müssen, die dasselbe Feld wie field_phone Haben (in Ihrem Fall) und dynamisch sein müssen. Einmal war ich auf eine solche Situation gestoßen, musste mich aber gegen das einzelne Formular validieren. Der folgende Code ist fast dieselbe Implementierung, aber ich habe ihn für Ihren Fall viel dynamischer gestaltet.

Erstellen Sie ein Modul und implementieren Sie hook_form_alter wie folgt:

/**
 * Implementation of hook_form_alter
 */
function MODULE_NAME_form_alter(&$form, $form_state, $form_id) {
  // $cck_type contains the array of all Drupal content type machine names
  $cck_type = array_keys(node_type_get_types());

  // Machine names of those content type whose instance you want to validate
  // Add your machine name for whom you want to validate. You can get the 
  // machine names of content types from Admin > Structure > Content types. Fill
  // as many required bu you.
  $my_types = array('CCK_TYPE_1', 'CCK_TYPE_2', 'CCK_TYPE_3');

  // Since, a user fill one form at particular time. The variable $current_type 
  // hold the Content Type machine name for current form. 
  if (arg(0) == 'node' && arg(1) == 'add') {
    $current_type = arg(2);
  } elseif ((arg(0) == 'node') && is_numeric(arg(1)) && (arg(2) == 'edit')) {
    $node = node_load(arg(1));
    $current_type = $node->type;
  }

  // gets current form's ID
  $id_of_form = $form['form_id']['#value'];

  // checks if the current form is part of Drupal Content Type
  if (in_array($current_type, $my_types) && in_array($current_type, $cck_type)) {
    $id_of_form = $form['form_id']['#value'];
    if ($form_id == $id_of_form) {
      // Adding custom validation function to the form so that we can validate
      // the field of that form
      $form['#validate'][] = 'custom_validates';
    }
  }
}

Implementieren Sie jetzt die benutzerdefinierte Validierungsfunktion zur Validierung.

/**
 * Implementation of custom validation for validating 'field_phone' in your case.
 * It can be any field, assuming that it is part of that form.
 */
function custom_validates(&$form, $form_state) {
  $values = $form_state['values'];

  // Language of the $form
  $lang = $form['language']['#value'];
  $field_phone = $values['field_phone'][$lang][0]['value'];

  // In my case, for testing purpose, I had set the strings in Phone field
  if (!is_integer($field_phone)) {
    form_set_error('field_phone', 'Invalid phone number');
  }
}

Bei dem einfachen Ansatz müssen Sie nur das $form_id Ihres Inhaltstypformulars überprüfen und die benutzerdefinierte Validierungsfunktion wie folgt hinzufügen:

/**
 * Implementation of hook_form_alter
 */
function MODULE_NAME_form_alter(&$form, $form_state, $form_id) {
  if (($form_id == 'content_type_form_id_1') ||
          ($form_id == 'content_type_form_id_2') ||
          ($form_id == 'content_type_form_id_3')) {
    // Adding custom validation function to the form so that we can validate
    // the field of that form
    $form['#validate'][] = 'custom_validates';
  }
}

Das Problem bei diesem einfachen Ansatz besteht jedoch darin, dass Sie die Formular-ID jedes einzelnen Formulars vom Inhaltstyp kennen und diese dann wie zuvor gezeigt mit dem Operator || Zur if-Anweisung hinzufügen müssen. Dies wird viel Zeit in Anspruch nehmen.

Ich habe entsprechende Kommentare abgegeben, damit Sie die Logik und Implementierung verstehen.

Ich hoffe, dass meine Lösung Ihr Problem beantwortet.

1
Asad

Die Antwort lautet hook_field_widget_WIDGET_TYPE_form_alter () meiner Meinung nach. Verwenden Sie den Hook, um Ihren Validierungsrückruf zum Array $ element [#element_validate] hinzuzufügen, und Sie können loslegen.

hook_form_alter () ist sehr allgemein und wird für jedes Formular aufgerufen, unabhängig davon, ob es field_phone hat oder nicht (zunehmender Overhead). Was ist außerdem, wenn sich das field_phone tief in verschiedenen Feldsätzen oder Containern befindet? Sie müssen rekursiv danach suchen (zusätzlicher Aufwand).

0
Jigarius