web-dev-qa-db-fra.com

Comment créer par programmation des champs?

Comment puis-je aborder l'implémentation de ce qui suit dans Drupal 7?

Ce que je dois faire, c'est créer un module qui définit une nouvelle entité utilisable sur le terrain, appelée "Société". J'ai une liste de, disons, 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.

Pour le moment, j'en suis au point où je peux ajouter de nouveaux champs à l'entité Société. Cela fonctionne bien pour le moment. Mon problème est que j'ai besoin que tous ces champs soient là dès que le module est installé, donc les ajouter via l'interface n'est pas une option.

Je me demandais comment puis-je aborder cela? Je suppose que cela revient à faire ce qui peut être fait à l'aide de l'interface utilisateur "Gérer les champs" par programme.

56
NRaf

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 vouloir supprimer le champ lorsque le module est désinstallé. 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 () .

41
tamasd

Exemple sur la façon d'ajouter par programme des champs au profil utilisateur et comment les utiliser ou non dans le formulaire d'inscription 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);
  }
}
9
Francisco Luz

Si vous devez créer/supprimer rapidement des champs d'un type de contenu ou d'une entité existant, sans utiliser ni 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 nœud, utilisateur, commentaire). Par défaut, le nœud.

Par exemple: créez deux nouveaux champs pour l'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>
8
Interdruper

Comme indiqué par d'autres, vous pouvez utiliser l'implémentation Fonctions API de champ de 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 du site pour coder dans un module. Les types de contenu et les champs sont parmi ceux-ci exportables. Vous pouvez soit 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 lié aux champs dans votre module. Cela nécessite une compréhension de base du fonctionnement des fonctionnalités.

4
Pierre Buyle

Dans votre fichier d'installation, vous devrez définir à la fois 'hook_install' et 'hook_uninstall'. Exemple inclus mais lisez tout sur les clés supplémentaires dans les références API (le code n'est pas testé, il pourrait donc y avoir des fautes de frappe là-dedans).

Dans le hook_install vous pouvez ajouter les champs en utilisant:

field_create_field , Cette fonction construit un modèle pour un champ.

field_create_instance Peut être utilisé après avoir créé le champ pour l'ajouter aux content_types (également appelés bundles).

REMARQUE 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 principaux de mise en œuvre sur le terrain dans le dossier modules/field/modules.

Les paramètres peuvent également être dérivés des modules de terrain. Les paramètres que vous définissez dans le field_create_field sont ceux du site. Ceux que vous définissez dans field_instance_create sont 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 à nouveau, field_delete_field est appelé 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);
        }
      }
    }

J'ai récemment eu un besoin similaire pour un projet, voici comment je l'ai abordé, j'espère qu'il aide 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 également créé un Gist avec cette info.

Et c'est parti....

  1. Créez les champs dont vous avez besoin, en utilisant l'habituel Drupal UI.
  2. Sur le même site, accédez à example.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, j'espère avec toutes les propriétés remplies.

$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 de module réel. Collez le code de la sortie devel 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 suffit de placer tous les tableaux $ fields 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;
}
2
John Laine

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 et coller dans le fichier .install de votre module.

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

0
thesurfinganalyst

Vous pouvez utiliser le code de société personnalisé 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é "entreprise" 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 "entreprise" ainsi que tous ses champs et données lorsque vous désinstallerez 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);
}
0
Nadeem Khan