¿Cómo crear campos mediante programación?

56

¿Cómo puedo abordar la implementación de lo siguiente en Drupal 7?

Lo que necesito hacer es crear un módulo que defina una nueva entidad de campo, llamada 'Compañía'. Tengo una lista de, digamos, 20 campos que debe completar cada instancia de la Compañía. Estas preguntas están predefinidas y algunas pueden contener validación personalizada.

En este momento, estoy en el punto en que puedo agregar nuevos campos a la entidad de la Compañía. Esto funciona bien en este momento. Mi problema es que necesito que todos estos campos estén allí tan pronto como se instale el módulo, por lo que agregarlos a través de la interfaz no es una opción.

Me preguntaba cómo puedo abordar esto? Supongo que se reduce a poder hacer lo que se puede hacer usando la interfaz de usuario 'Administrar campos' mediante programación.

NRaf
fuente
No tengo claro el alcance total de sus necesidades, pero creo que este hilo será útil para usted: drupal.org/node/721552 Muestra un código de muestra para crear un tipo de contenido personalizado con campos cuando se instala un módulo por primera vez. Probablemente tendrá que buscar en la API para obtener la configuración de campo exacta que necesita, pero este sería un buen punto de partida. Básicamente, tendrá que investigar node_type_set_defaults()y node_type_save(), por supuesto, también hook_install().
aplastado el
Si está haciendo esto en código en lugar de en Características, eche un vistazo al Ejemplo de campos y al Ejemplo de nodo en el Proyecto de ejemplos .
rfay
Algunas palabras de orientación. Si desea mantener un nivel de control sobre la configuración de los campos, use Características para registrarlos y aplicarlos. Si desea definirlos como una operación única y dejar que su configuración se anule libremente en el futuro, elija una solución de código en un archivo .install.
Alfred Armstrong

Respuestas:

41

Use field_create_field () para crear el campo en sí mismo y field_create_instance () para tener una instancia para el paquete de entidad dado.

Al crear campos como parte de un módulo personalizado, es posible que desee o no eliminar el campo cuando se desinstala el módulo. Para hacerlo, puede usar field_delete_field () si desea eliminar el campo y todas las instancias de campo, o si desea eliminar instancias específicas, puede usar field_delete_instance () .

tamasd
fuente
¿Cómo eliminamos los campos que creamos al desinstalar el módulo?
Ashok KS
Ashok, agregué una aclaración para ti en una edición que acabo de hacer a la respuesta.
Lester Peabody
9

Ejemplo sobre cómo agregar campos mediante programación al perfil de usuario y cómo aprovecharlos, o no, en el formulario de registro de usuario.


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
fuente
3
Esto debería implementarse en hook_install ().
revagomes
Si todo lo que quiere hacer es agregar un nuevo campo a un tipo de contenido existente y de ahí en adelante continuar en el back-end, ese enfoque está totalmente bien. Active el módulo, desactívelo, listo. El nuevo campo está allí, editable, el módulo se puede eliminar.
leymannx
8

Si necesita crear / eliminar rápidamente campos de un tipo de contenido o entidad existente, sin usar la interfaz de usuario ni la programación, puede usar estos comandos Drush poco conocidos:

drush field-create <bundle(for nodes)> <field_name>,<field_type>,[widget_name] --entity_type: Tipo de entidad (por ejemplo, nodo, usuario, comentario). El valor predeterminado es nodo.

Por ejemplo: cree dos nuevos campos para el artículo:

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

Otros comandos:

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
fuente
4

Como señalaron otros, puede usar las funciones de API de campo desde la implementación hook_install () de su módulo para crear campos y sus instancias para su tipo de contenido. Consulte node_example_install (), por ejemplo, el uso de la función.

Otra solución es usar el módulo Características . Las características pueden exportar varios componentes del sitio para codificar en un módulo. Los tipos de contenido y los campos se encuentran entre estos exportables. Puede generar un módulo de Características y anular su código existente, las Características harán todo lo posible para evitar romper su código. O puede generar un módulo ficticio y copiarlo. Pegar el código relacionado con los campos en su módulo. Esto requiere una comprensión básica del funcionamiento de las características.

Pierre Buyle
fuente
3

En su archivo de instalación, deberá definir tanto 'hook_install' como 'hook_uninstall'. Ejemplo incluido, pero lea todo sobre las claves adicionales en las referencias de la API (el código no se ha probado, por lo que podría haber errores tipográficos allí).

En el hook_installpuede agregar los campos usando:

field_create_field , esta función crea una plantilla para un campo.

field_create_instance Se puede usar después de crear el campo para agregarlo a content_types (también conocido como paquetes).

NOTA Los nombres de varios tipos de campo se pueden encontrar en los módulos que los generan (es la clave del elemento de matriz en su hook_field_info). Puede encontrar todos los módulos de implementación de campo principal en la carpeta modules / field / modules.

La configuración también se puede derivar de los módulos de campo. La configuración que establezca en field_create_fieldel sitio es amplia. Los que estableces field_instance_createson los específicos de 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); 
      }
    }

En el hook_uninstall

field_delete_instance y field_delete_field se pueden usar para eliminarlos nuevamente, field_delete_fieldse llama automáticamente si elimina la última instancia (normalmente).

    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
fuente
2

Recientemente tuve una necesidad similar de un proyecto, así es como lo aborde, espero que ayude a alguien.

Básicamente, creará los campos que necesita utilizando la interfaz de usuario de campos, los exportará a código y luego los incluirá en su módulo personalizado. Necesitará el módulo Devel habilitado.

También creé un Gist con esta información.

Aquí vamos....

  1. Cree los campos que necesita, utilizando la interfaz de usuario habitual de Drupal.
  2. En el mismo sitio, vaya a example.com/devel/php
  3. Pegue el siguiente código en el cuadro de texto "Código PHP para ejecutar".
  4. Establezca las primeras 3 variables y luego haga clic en ejecutar

    $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. Obtendrá 2 matrices, algo así, con suerte con todas las propiedades completadas.

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

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

Ahora agregue el siguiente código a su archivo .install. Reemplace todas las instancias de mymodule con el nombre real del módulo. Pegue el código de la salida de desarrollo en _mymodule_field_data y _mymodule_instance_data, como se indica en las funciones respectivas a continuación. Puede hacer esto para todos los campos que desee, simplemente coloque todas las matrices $ fields en la función _mymodule_field_data y todas las instancias $ en la función _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
fuente
h / t steindom.com/articles/…
MikeNGarrett
0

También podría considerar usar el módulo Características para crear los campos en el momento de la instalación.

Como las características generan código para los campos, una opción es usar el módulo de características para generar el código en un módulo ficticio y luego copiar y pegar en el archivo .install de su módulo.

El beneficio es que el módulo no depende del módulo Características en su entorno de destino.


fuente
1
Aunque las características son una buena forma de exportar campos a código, no es cómo usar las características. Las características no utilizan la API de campo CRUD para crear campos a partir de la instalación generada.
Pierre Buyle
0

Puede usar el código de módulo de empresa personalizado que se proporciona a continuación para crear programáticamente un tipo de contenido con sus diversos campos.

Puede agregar este código en un archivo .install de su módulo personalizado. Agregará mediante programación un tipo de contenido llamado "empresa" y sus diversos tipos de campos (texto, numérico, fecha (nota: necesitará instalar el módulo de fecha ya que el campo de fecha no se proporciona de forma predeterminada), imagen, lista).

También he agregado el código de desinstalación que eliminará el tipo de contenido "empresa" junto con todos sus campos y datos cuando desinstale su módulo 'customcompanymodule'.

Puede modificar / eliminar estos campos según sus necesidades:

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
fuente