Comment créer par programme des champs?

56

Comment puis-je aborder la mise en œuvre des éléments suivants dans Drupal 7?

Ce que je dois faire, c'est créer un module qui définit une nouvelle entité pouvant être saisie, appelée "Société". J'ai une liste de, par exemple, 20 champs qui doivent être remplis par chaque instance de la société. Ces questions sont prédéfinies et certaines peuvent contenir une validation personnalisée.

En ce moment, je suis sur le point de pouvoir ajouter de nouveaux champs à la société. Cela fonctionne bien pour le moment. Mon problème est que j'ai besoin de tous ces champs dès que le module est installé, donc leur ajout via l'interface n'est pas une option.

Je me demandais comment puis-je aborder cela? Je suppose que cela revient à pouvoir faire ce qui peut être fait en utilisant l'interface utilisateur «Gérer les champs» par programmation.

NRaf
la source
Je ne suis pas certain de la portée de vos besoins, mais je pense que ce fil vous sera utile: drupal.org/node/721552 Il montre un exemple de code permettant de créer un type de contenu personnalisé avec des champs lors de la première installation d'un module. Vous devrez probablement explorer l'API pour obtenir les paramètres de champ exacts dont vous avez besoin, mais ce serait un bon point de départ. Fondamentalement, vous aurez besoin de regarder dans node_type_set_defaults()et node_type_save(), ainsi que, bien sûr, hook_install().
Handsofaten
Si vous faites cela dans le code plutôt que dans les fonctionnalités, jetez un œil à l'exemple Champs et à l'exemple de nœud du projet Exemples .
Rfay
Quelques mots de conseils. Si vous souhaitez conserver un niveau de contrôle sur la configuration des champs, utilisez Fonctionnalités pour les enregistrer et les appliquer. Si vous souhaitez les définir comme une opération ponctuelle et laisser leur configuration être remplacée librement à l'avenir, choisissez une solution de code dans un fichier .install.
Alfred Armstrong

Réponses:

41

Utilisez field_create_field () pour créer le champ lui-même et field_create_instance () pour avoir une instance pour le groupe d'entités donné.

Lorsque vous créez des champs dans le cadre d'un module personnalisé, vous pouvez ou non souhaiter supprimer le champ lors de la désinstallation du module. Pour ce faire, vous pouvez utiliser field_delete_field () si vous souhaitez supprimer le champ et toutes les instances de champ, ou si vous souhaitez supprimer des instances spécifiques, vous pouvez utiliser field_delete_instance () .

Tamasd
la source
Comment nous supprimons les champs que nous avons créés lors de la désinstallation du module?
Ashok KS
Ashok, j'ai ajouté une clarification pour vous dans une modification que je viens de faire à la réponse.
Lester Peabody
9

Exemple sur la manière d’ajouter par programmation des champs au profil d’utilisateur et de les utiliser ou non dans le formulaire d’enregistrement d’utilisateur.


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
la source
3
Cela devrait être implémenté dans le hook_install ().
Revagomes
Si vous souhaitez simplement ajouter un nouveau champ à un type de contenu existant et continuer à partir du back-end, cette approche est tout à fait appropriée. Activer le module, le désactiver, c'est fait. Le nouveau champ est là, éditable, le module peut être supprimé.
leymannx
8

Si vous devez créer / supprimer rapidement des champs d'un type de contenu, d'une entité ou d'une entité existants, sans utiliser l'interface utilisateur ni la programmation, vous pouvez utiliser ces commandes Drush peu connues:

drush field-create <bundle(for nodes)> <field_name>,<field_type>,[widget_name] --entity_type: Type d'entité (par exemple, noeud, utilisateur, commentaire). Par défaut au noeud.

Ex: Créez deux nouveaux champs pour Article:

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

Autres commandes:

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
la source
4

Comme d'autres l'ont indiqué, vous pouvez utiliser les fonctions Field API de l' implémentation hook_install () de votre module pour créer des champs et leurs instances pour votre type de contenu. Voir node_example_install () pour un exemple d'utilisation de la fonction.

Une autre solution consiste à utiliser le module Fonctionnalités . Les fonctionnalités peuvent exporter divers composants de site pour coder dans un module. Les types de contenu et les champs sont parmi ceux exportables. Vous pouvez générer un module de fonctionnalités et remplacer votre code existant. Les fonctionnalités feront alors de leur mieux pour éviter de casser votre code. Ou vous pouvez générer un module factice et copier / coller le code associé aux champs dans votre module. Cela nécessite des connaissances de base sur le fonctionnement des fonctionnalités.

Pierre Buyle
la source
3

Dans votre fichier d'installation, vous devrez définir à la fois le "hook_install" et le "hook_uninstall". Exemple inclus mais lisez tout sur les clés supplémentaires dans les références d'API (le code n'est pas testé, il est donc possible qu'il y ait une faute de frappe ici).

Dans le, hook_installvous pouvez ajouter les champs en utilisant:

field_create_field , Cette fonction crée un modèle pour un champ.

field_create_instance Peut être utilisé après la création du champ pour l'ajouter à content_types (également appelé bundles).

NOTE Les noms des différents types de champs peuvent être trouvés dans les modules qui les génèrent (c'est la clé de l'élément de tableau dans leur hook_field_info). Vous pouvez trouver tous les modules d'implémentation de champs clés dans le dossier modules / champs / modules.

Les paramètres peuvent également être dérivés des modules de terrain. Les paramètres que vous définissez dans field_create_fieldsont ceux du site. Ceux que vous définissez field_instance_createsont ceux spécifiques à node_type

    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); 
      }
    }

dans le hook_uninstall

field_delete_instance et field_delete_field peuvent être utilisés pour les supprimer, field_delete_fieldest appelée automatiquement si vous supprimez la dernière instance (normalement).

    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
la source
2

J'avais récemment le même besoin de projet. Voici comment je l'ai abordé. J'espère que cela aidera quelqu'un.

Fondamentalement, vous allez créer les champs dont vous avez besoin à l'aide de l'interface utilisateur des champs, les exporter en code, puis les inclure dans votre module personnalisé. Vous aurez besoin du module Devel activé.

J'ai aussi créé un Gist avec cette information.

Et c'est parti....

  1. Créez les champs dont vous avez besoin, en utilisant l'interface utilisateur Drupal habituelle.
  2. Sur le même site, allez à exemple.com/devel/php
  3. Collez le code suivant dans la zone de texte "Code PHP à exécuter".
  4. Définissez les 3 premières variables, puis cliquez sur Exécuter

    $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. Vous obtiendrez 2 tableaux, quelque chose comme ça, avec toutes les propriétés renseignées.

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

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

Ajoutez maintenant le code suivant à votre fichier .install. Remplacez toutes les instances de mymodule par le nom du module actuel. Collez le code de la sortie de développement dans les _mymodule_field_data et _mymodule_instance_data, comme indiqué dans les fonctions respectives ci-dessous. Vous pouvez le faire pour autant de champs que vous le souhaitez. Il vous suffit de placer tous les tableaux de champs $ dans la fonction _mymodule_field_data et toutes les instances $ dans la fonction _mymodule_instance_data.

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
la source
h / t steindom.com/articles/…
MikeNGarrett Le
0

Vous pouvez également envisager d'utiliser le module Fonctionnalités pour créer les champs au moment de l'installation.

Comme Features génère du code pour les champs, une option consiste simplement à utiliser le module Feature pour générer le code dans un module factice, puis copier / coller dans le fichier .install de votre module.

L'avantage est que le module ne dépend pas du module Fonctionnalités de votre environnement cible.


la source
1
Altough Features est un bon moyen d’exporter des champs en code, ce n’est pas comment utiliser les fonctionnalités. Les fonctionnalités n'utilisent pas le CRUD de l'API de champ pour créer des champs à partir du fichier .install généré.
Pierre Buyle
0

Vous pouvez utiliser le code customcompanymodule donné ci-dessous pour créer par programme un type de contenu avec ses différents champs.

Vous pouvez ajouter ce code dans un fichier .install de votre module personnalisé. Il ajoutera par programme un type de contenu appelé "société" et ses différents types de champs (texte, numérique, date (remarque: vous devrez installer le module Date car le champ Date n'est pas fourni par défaut), image, liste).

J'ai également ajouté le code de désinstallation qui supprimera le type de contenu "société", ainsi que tous ses champs et données, lors de la désinstallation de votre module "customcompanymodule".

Vous pouvez modifier / supprimer ces champs selon vos besoins:

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
la source