Wie programmgesteuert Felder erstellen?

56

Wie kann ich vorgehen, um Folgendes in Drupal 7 zu implementieren?

Ich muss ein Modul erstellen, das eine neue feldfähige Entität namens "Firma" definiert. Ich habe eine Liste von beispielsweise 20 Feldern, die von jeder Unternehmensinstanz ausgefüllt werden müssen. Diese Fragen sind vordefiniert und einige können eine benutzerdefinierte Validierung enthalten.

Im Moment bin ich an dem Punkt, an dem ich der Firma neue Felder hinzufügen kann. Dies funktioniert im Moment gut. Mein Problem ist, dass ich alle diese Felder dort haben muss, sobald das Modul installiert ist, so dass das Hinzufügen über die Schnittstelle keine Option ist.

Ich habe mich gefragt, wie ich das angehen kann. Ich nehme an, es kommt darauf an, in der Lage zu sein, das zu tun, was mit der 'Felder verwalten'-Benutzeroberfläche programmgesteuert getan werden kann.

NRaf
quelle
Ich bin mir nicht sicher, welchen Umfang Ihre Anforderungen haben, aber ich denke, dieser Thread wird für Sie nützlich sein: drupal.org/node/721552 Es zeigt Beispielcode zum Erstellen eines benutzerdefinierten Inhaltstyps mit Feldern, wenn ein Modul zum ersten Mal installiert wird. Sie müssen wahrscheinlich die API durchsuchen, um die genauen Feldeinstellungen zu erhalten, die Sie benötigen. Dies ist jedoch ein guter Ausgangspunkt. Grundsätzlich müssen Sie sich node_type_set_defaults()und node_type_save()natürlich auch darum kümmern hook_install().
Handsofaten
Wenn Sie dies im Code im Gegensatz zu Features tun, sehen Sie sich die Beispiele für Felder und Knoten im Beispielprojekt an .
rfay
Ein paar Ratschläge. Wenn Sie die Kontrolle über die Konfiguration der Felder behalten möchten, verwenden Sie Features, um diese aufzuzeichnen und anzuwenden. Wenn Sie sie als einmalige Operation definieren und ihre Konfiguration in Zukunft frei überschreiben möchten, wählen Sie eine Codelösung in einer .install-Datei.
Alfred Armstrong

Antworten:

41

Verwenden Sie field_create_field () , um das Feld selbst zu erstellen, und field_create_instance () , um eine Instanz für das angegebene Entitätspaket zu erhalten.

Wenn Sie Felder als Teil eines benutzerdefinierten Moduls erstellen, möchten Sie das Feld möglicherweise nicht löschen, wenn das Modul deinstalliert wird. Dazu können Sie field_delete_field () verwenden, wenn Sie das Feld und alle Feldinstanzen löschen möchten, oder wenn Sie bestimmte Instanzen löschen möchten, können Sie field_delete_instance () verwenden .

tamasd
quelle
Wie löschen wir die Felder, die wir beim Deinstallieren des Moduls erstellt haben?
Ashok KS
Ashok, ich habe in einer Bearbeitung, die ich gerade an der Antwort vorgenommen habe, eine Klarstellung für dich eingefügt.
Lester Peabody
9

Beispiel für das programmgesteuerte Hinzufügen von Feldern zum Benutzerprofil und deren Verwendung im Benutzerregistrierungsformular.


function MYMODULE_enable() {
  // Check if our field is not already created.
  if (!field_info_field('field_myField')) {

    // Create the field base.
    $field = array(
      'field_name' => 'field_myField', 
      'type' => 'text', 
    );
    field_create_field($field);

    // Create the field instance on the bundle.
    $instance = array(
      'field_name' => 'field_myField', 
      'entity_type' => 'user', 
      'label' => 'My Field Name', 
      'bundle' => 'user', 
      // If you don't set the "required" property then the field wont be required by default.
      'required' => TRUE,
      'settings' => array(
        // Here you inform either or not you want this field showing up on the registration form.
        'user_register_form' => 1,
      ),
      'widget' => array(
        'type' => 'textfield',
      ), 
    );
    field_create_instance($instance);
  }
}
Francisco Luz
quelle
3
Dies sollte in der hook_install () implementiert werden.
revagomes
Wenn Sie lediglich ein neues Feld zu einem vorhandenen Inhaltstyp hinzufügen und fortan im Backend fortfahren möchten, ist dieser Ansatz völlig in Ordnung. Aktivieren Sie das Modul, deaktivieren Sie es, fertig. Das neue Feld ist dort editierbar, das Modul kann gelöscht werden.
Leymannx
8

Wenn Sie Felder aus einem vorhandenen Inhaltstyp oder einer vorhandenen Entität schnell erstellen / löschen müssen, ohne die Benutzeroberfläche oder die Programmierung zu verwenden, können Sie die folgenden, wenig bekannten Drush-Befehle verwenden:

drush field-create <bundle(for nodes)> <field_name>,<field_type>,[widget_name] --entity_type: Entitätstyp (z. B. Knoten, Benutzer, Kommentar). Standardmäßig wird der Knoten verwendet.

Beispiel: Erstellen Sie zwei neue Felder für den Artikel:

drush field-create article city,text,text_textfield subtitle,text,text_textfield

Andere Befehle:

drush field-delete <field_name> [--bundle] [--entity_type]
drush field-info [field | types]
drush field-update <field_name> Return URL for field editing web page.
drush field-clone <source_field_name> <dst_field_name>
Interdruper
quelle
4

Wie bereits erwähnt, können Sie die Field-API-Funktionen aus der Implementierung von hook_install () Ihres Moduls verwenden, um Felder und deren Instanzen für Ihren Inhaltstyp zu erstellen. In node_example_install () finden Sie ein Beispiel für die Verwendung der Funktion.

Eine andere Lösung ist die Verwendung des Features- Moduls. Features können verschiedene Site-Komponenten exportieren, um sie in einem Modul zu codieren. Inhaltstypen und Felder können exportiert werden. Sie können entweder ein Featuremodul generieren und Ihren vorhandenen Code überschreiben. Features wird dann sein Bestes tun, um zu verhindern, dass Ihr Code beschädigt wird. Sie können auch ein Dummy-Modul generieren und den feldbezogenen Code in Ihr Modul kopieren. Dies setzt ein grundlegendes Verständnis der Funktionsweise von Features voraus.

Pierre Buyle
quelle
3

In Ihrer Installationsdatei müssen Sie sowohl 'hook_install' als auch 'hook_uninstall' definieren. Beispiel enthalten, aber lesen Sie alles über die zusätzlichen Schlüssel in den API-Referenzen (Code ist ungetestet, könnte Tippfehler enthalten).

Im hook_installkönnen Sie die Felder hinzufügen mit:

field_create_field , Diese Funktion erstellt eine Vorlage für ein Feld.

field_create_instance Kann nach dem Erstellen des Felds zum Hinzufügen zu content_types (auch als Bundles bezeichnet) verwendet werden.

HINWEIS Die Namen der verschiedenen Feldtypen finden Sie in den Modulen, die sie generieren (dies ist der Schlüssel des Array-Elements in ihrer hook_field_info). Sie finden alle Kernmodule für die Feldimplementierung im Ordner modules / field / modules.

Einstellungen können auch aus den Feldmodulen abgeleitet werden. Die Einstellungen, die Sie in festlegen, field_create_fieldgelten für die gesamte Site. Die von Ihnen festgelegten field_instance_createWerte sind knotentypspezifisch

    MY_MODULE_install(){
      // Generate the base for the field
      $field = array( 
        'field_name' => 'FIELD_MACHINE_NAME', 
        'type' => 'FIELD_TYPE' // See note above for what to put here
      );
      // Instance 
      $instance = array(
        'field_name' => 'FIELD_MACHINE_NAME', 
        'entity_type' => 'node', 
      ); 

      // Create instances of the field and add them to the content_types
      $node_types = node_type_get_types(); 
      foreach($node_types as $node_type){
         $instance['bundle'] = $node_type->type; 
         field_create_instance($instance); 
      }
    }

In dem hook_uninstall

field_delete_instance und field_delete_field können verwendet werden, um sie wieder zu entfernen field_delete_field. Wird automatisch aufgerufen, wenn Sie die letzte Instanz löschen (normalerweise).

    MY_MODULE_uninstall(){
      $node_types = node_type_get_types(); 
      foreach($node_types as $node_type){
        if($instance = field_info_instance('node', 'FIELD_MACHINE_NAME', $node_type->type)) {
          field_delete_instance($instance);
        }
      }
    }
Suranga Panagamuwa Gamage
quelle
2

Ich hatte kürzlich ein ähnliches Bedürfnis nach einem Projekt. Ich bin so vorgegangen und hoffe, es hilft jemandem.

Grundsätzlich erstellen Sie die benötigten Felder über die Benutzeroberfläche der Felder, exportieren sie in Code und fügen sie dann in Ihr benutzerdefiniertes Modul ein. Sie müssen das Entwicklungsmodul aktiviert haben.

Mit diesen Informationen habe ich auch ein Gist erstellt .

Auf geht's....

  1. Erstellen Sie die benötigten Felder mit der üblichen Drupal-Benutzeroberfläche.
  2. Gehen Sie auf derselben Site zu example.com/devel/php
  3. Fügen Sie den folgenden Code in das Textfeld "Auszuführender PHP-Code" ein.
  4. Setzen Sie die ersten 3 Variablen und klicken Sie dann auf Ausführen

    $entity_type = 'node';    
    $field_name = 'body';    
    $bundle_name = 'article'; 
    
    $info_config = field_info_field($field_name);
    $info_instance = field_info_instance($entity_type, $field_name, $bundle_name);
    unset($info_config['id']);
    unset($info_instance['id'], $info_instance['field_id']);
    include_once DRUPAL_ROOT . '/includes/utility.inc';
    $output = "\$fields['" . $field_name . "'] = " . drupal_var_export($info_config) . ";\n";
    $output .= "\$instances['" . $field_name . "'] = " . drupal_var_export($info_instance) . ";";
    drupal_set_message("<textarea rows=30 style=\"width: 100%;\">" . $output . '</textarea>');
    
  5. Sie erhalten 2 Arrays, in etwa so, hoffentlich mit allen Eigenschaften ausgefüllt.

$fields['field_some_field'] = array(
  'properties of the field'
);

$instances['field_some_field'] = array(
  'properties of the instance'
);

Fügen Sie Ihrer .install-Datei nun den folgenden Code hinzu. Ersetzen Sie alle Instanzen von mymodule durch den tatsächlichen Modulnamen. Fügen Sie den Code aus der Entwicklungsausgabe in die _mymodule_field_data und _mymodule_instance_data ein, wie in den entsprechenden Funktionen unten angegeben. Sie können dies für so viele Felder tun, wie Sie möchten. Fügen Sie einfach alle $ fields-Arrays in die Funktion _mymodule_field_data und alle $ instance in die Funktion _mymodule_instance_data ein.

function mymodule_install() {

  // Create all the fields we are adding to our entity type.
  // http://api.drupal.org/api/function/field_create_field/7
  foreach (_mymodule_field_data() as $field) {
    field_create_field($field);
  }

  // Create all the instances for our fields.
  // http://api.drupal.org/api/function/field_create_instance/7
  foreach (_mymodule_instance_data() as $instance) {
    field_create_instance($instance);
  }
}

// Create the array of information about the fields we want to create.
function _mymodule_field_data() {
  $fields = array();
  // Paste $fields data from devel ouput here.
  return $fields;
  }

// Create the array of information about the instances we want to create.
function _mymodule_instance_data() {
  $instances = array();
  // Paste $instances data from devel output here.
  return $instances;
}
John Laine
quelle
h / t steindom.com/articles/…
MikeNGarrett
0

Sie können auch das Modul Features verwenden, um die Felder bei der Installation zu erstellen.

Da Features Code für Felder generiert, können Sie den Code mit dem Feature-Modul in ein Dummy-Modul generieren und dann in die .install-Datei Ihres Moduls kopieren und einfügen.

Der Vorteil ist, dass das Modul nicht vom Funktionsmodul in Ihrer Zielumgebung abhängt.


quelle
1
Obwohl Features eine gute Möglichkeit zum Exportieren von Feldern in Code sind, können Features nicht verwendet werden. Features verwendet die Field API CRUD nicht zum Erstellen von Feldern aus der generierten .install-Datei.
Pierre Buyle
0

Sie können den unten angegebenen benutzerdefinierten Firmenmodul-Code verwenden, um programmgesteuert einen Inhaltstyp mit seinen verschiedenen Feldern zu erstellen.

Sie können diesen Code in eine .install-Datei Ihres benutzerdefinierten Moduls einfügen. Es wird programmgesteuert einen Inhaltstyp namens "Firma" und seine verschiedenen Feldtypen (Text, Numerisch, Datum (Hinweis: Sie müssen das Datumsmodul installieren, da das Datumsfeld nicht standardmäßig bereitgestellt wird), Bild und Liste hinzufügen.

Ich habe auch den Deinstallationscode hinzugefügt, der den Inhaltstyp "Firma" zusammen mit all seinen Feldern und Daten entfernt, wenn Sie Ihr Modul "customcompanymodule" deinstallieren.

Sie können diese Felder gemäß Ihren Anforderungen ändern / entfernen:

function customcompanymodule_install() {
     $t = get_t();
     node_types_rebuild();
     $company = array(
    'type' => 'company',
    'name' => $t('Company'),
    'base' => 'node_content',
    'module' => 'node',
    'description' => $t('Content type to handle companys.'),
    'body_label' => $t('Company Description'),
    'title_label' => $t('Company Title'),
    'promote' => 0,
    'status' => 1,
    'comment' => 0,
);
$content_type = node_type_set_defaults($company);

node_type_save($content_type);

foreach (_company_installed_fields() as $field) {
    field_create_field($field);
}

foreach (_company_installed_instances() as $instance) {
    $instance['entity_type'] = 'node';
    $instance['bundle'] = 'company';
    field_create_instance($instance);
}

$weight = db_query("SELECT weight FROM {system} WHERE name = :name",    array(':name' => 'categories'))->fetchField();
db_update('system')->fields(array(
            'weight' => $weight + 1,
        ))
        ->condition('name', 'company')
        ->execute();
}

function _company_installed_fields() {
$t = get_t();
$fields = array(
    'company_startdate' => array(
        'field_name' => 'company_startdate',
        'label' => $t('Company Start Date'),
        'cardinality' => 1,
        'type' => 'datetime',
        'module' => 'date',
        'settings' => array(
            'granularity' => array(
                'month' => 'month',
                'day' => 'day',
                'hour' => 'hour',
                'minute' => 'minute',
                'year' => 'year',
                'second' => 0,
            ),
            'tz_handling' => 'site',
            'timezone_db' => 'UTC',
            'cache_enabled' => 0,
            'cache_count' => '4',
            'todate' => 'required',
        ),
    ),
    'company_totalwinners' => array(
        'field_name' => 'company_totalwinners',
        'label' => $t('Maximum Company Winners'),
        'cardinality' => 1,
        'type' => 'number_integer',
        'module' => 'number',
        'settings' => array(
            'max_length' => 10000,
        ),
    ),
    'company_minwinner' => array(
        'field_name' => 'company_minwinner',
        'label' => $t('Minimum Entries for Company to Activate'),
        'cardinality' => 1,
        'type' => 'number_integer',
        'module' => 'number',
        'settings' => array(
            'max_length' => 10000,
        ),
    ),
    'company_totalentries' => array(
        'field_name' => 'company_totalentries',
        'label' => $t('Company Total Entries'),
        'cardinality' => 1,
        'type' => 'number_integer',
        'module' => 'number',
        'settings' => array(
            'max_length' => 10000,
        ),
    ),
    'company_points' => array(
        'field_name' => 'company_points',
        'label' => $t('Company Points'),
        'cardinality' => 1,
        'type' => 'number_integer',
        'module' => 'number',
        'settings' => array(
            'max_length' => 10000,
        ),
    ),
    'company_image' => array(
        'field_name' => 'company_image',
        'label' => $t('Image'),
        'cardinality' => 1,
        'type' => 'image',
        'settings' => array(
            'default_image' => 0,
            'uri_scheme' => 'public',
        ),
    ),
    'company_description' => array(
        'field_name' => 'company_description',
        'label' => $t('Company Description'),
        'cardinality' => 1,
        'type' => 'text',
        'module' => 'text',
        'length' => '255'
    ),
    'company_winner' => array(
        'field_name' => 'company_winner',
        'label' => $t('Company Description'),
        'cardinality' => 1,
        'type' => 'text',
        'module' => 'text',
        'length' => '255'
    ),
    'field_autowinnerselection' => array(
        'field_name' => 'field_autowinnerselection',
        'label' => $t('Auto Company Winner Selection'),
        'type' => 'list_boolean',
        'module' => 'list',
        'active' => '1',
        'locked' => '0',
        'cardinality' => '1',
        'deleted' => '0'
    ),
);
return $fields;
}

function _company_installed_instances() {
$t = get_t();
$instances = array(
    'company_startdate' => array(
        'field_name' => 'company_startdate',
        'label' => $t('Company Lifespan'),
        'cardinality' => 1,
        'widget' => array(
            'type' => 'date_popup',
            'module' => 'date',
            'settings' => array(
                'input_format' => 'm/d/Y - H:i:s',
                'input_format_custom' => '',
                'year_range' => '-3:+3',
                'increment' => '15',
                'label_position' => 'above',
                'text_parts' => array(),
            ),
        ),
    ),
    'company_totalwinners' => array(
        'field_name' => 'company_totalwinners',
        'label' => $t('Maximum Company Winners'),
        'cardinality' => 1,
        'widget' => array(
            'type' => 'number',
            'module' => 'number',
            'settings' => array('size' => 60),
        ),
    ),
    'company_minwinner' => array(
        'field_name' => 'company_minwinner',
        'label' => $t('Minimum Number of Entries for Company to Activate'),
        'cardinality' => 1,
        'required' => 1,
        'widget' => array(
            'type' => 'number',
            'module' => 'number',
            'settings' => array('size' => 60),
        ),
    ),
    'company_totalentries' => array(
        'field_name' => 'company_totalentries',
        'label' => $t('Company Total Entries'),
        'cardinality' => 1,
        'required' => 1,
        'widget' => array(
            'type' => 'number',
            'module' => 'number',
            'settings' => array('size' => 60),
        ),
    ),
    'company_points' => array(
        'field_name' => 'company_points',
        'label' => $t('Company Points'),
        'cardinality' => 1,
        'required' => 1,
        'widget' => array(
            'type' => 'number',
            'module' => 'number',
            'settings' => array('size' => 60),
        ),
    ),
    'company_image' => array(
        'field_name' => 'company_image',
        'label' => $t('Image'),
        'cardinality' => 1,
        'required' => 1,
        'type' => 'company_image',
        'settings' => array(
            'max_filesize' => '',
            'max_resolution' => '213x140',
            'min_resolution' => '213x140',
            'alt_field' => 1,
            'default_image' => 0
        ),
        'widget' => array(
            'settings' => array(
                'preview_image_style' => 'thumbnail',
                'progress_indicator' => 'throbber',
            ),
        ),
        'display' => array(
            'default' => array(
                'label' => 'hidden',
                'type' => 'image',
                'settings' => array('image_style' => 'medium', 'image_link' => ''),
                'weight' => -1,
            ),
            'teaser' => array(
                'label' => 'hidden',
                'type' => 'image',
                'settings' => array('image_style' => 'thumbnail', 'image_link' => 'content'),
                'weight' => -1,
            ),
        ),
    ),
    'company_description' => array(
        'field_name' => 'company_description',
        'label' => $t('Company Description'),
        'cardinality' => 1,
        'widget' => array(
            'weight' => '-3',
            'type' => 'text_textfield',
            'module' => 'text',
            'active' => 1,
            'settings' => array(
                'size' => '1000',
            ),
        ),
    ),
    'company_winner' => array(
        'field_name' => 'company_winner',
        'label' => $t('Company Winner'),
        'cardinality' => 1,
        'widget' => array(
            'weight' => '-3',
            'type' => 'text_textfield',
            'module' => 'text',
            'active' => 1,
            'settings' => array(
                'size' => '60',
            ),
        ),
    ),
    'field_autowinnerselection' => array(
        'field_name' => 'field_autowinnerselection',
        'required' => 1,
        'label' => $t('Auto Company Winner Selection'),
        'widget' => array(
            'weight' => '-3',
            'type' => 'options_buttons',
            'module' => 'options',
            'active' => 1,
            'settings' => array(),
        ),
    ),
);
return $instances;
}

function customcompanymodule_uninstall() {
$content_types = array(
    'name1' => 'company',
);
$sql = 'SELECT nid FROM {node} n WHERE n.type = :type1';
$result = db_query($sql, array(':type1' => $content_types['name1']));
$nids = array();
foreach ($result as $row) {
    $nids[] = $row->nid;
}
node_delete_multiple($nids);
node_type_delete($content_types['name1']);
field_purge_batch(1000);
}
Nadeem Khan
quelle