Come creare campi a livello di codice?


56

Come posso affrontare l'implementazione di quanto segue in Drupal 7?

Quello che devo fare è creare un modulo che definisce una nuova entità fieldable, chiamata "Azienda". Ho un elenco di, diciamo, 20 campi che devono essere compilati da ogni istanza dell'azienda. Queste domande sono predefinite e alcune potrebbero contenere una convalida personalizzata.

Al momento, sono al punto in cui posso aggiungere nuovi campi all'entità aziendale. Questo funziona bene al momento. Il mio problema è che ho bisogno che tutti questi campi siano presenti non appena il modulo è installato, quindi aggiungerli tramite l'interfaccia non è un'opzione.

Mi chiedevo come posso avvicinarmi a questo? Suppongo che si tratti di riuscire a fare ciò che può essere fatto utilizzando l'interfaccia utente "Gestisci campi" a livello di codice.


Non sono chiaro sull'intero ambito delle tue esigenze, ma penso che questo thread ti sarà utile: drupal.org/node/721552 Mostra il codice di esempio per la creazione di un tipo di contenuto personalizzato con campi quando un modulo viene installato per la prima volta. Probabilmente dovrai scavare attraverso l'API per ottenere le impostazioni del campo esatte di cui hai bisogno, ma questo sarebbe un buon punto di partenza. Fondamentalmente, dovrai esaminare node_type_set_defaults()e node_type_save(), ovviamente, anche hook_install().
Handsofaten,

Se stai eseguendo questa operazione nel codice anziché in Funzionalità, dai un'occhiata all'esempio dei campi e all'esempio del nodo nel progetto Esempi .
rfay

Alcune parole di guida. Se si desidera mantenere un livello di controllo sulla configurazione dei campi, utilizzare le funzionalità per registrarli e applicarli. Se si desidera definirli come un'operazione one-shot e lasciare che la loro configurazione venga sovrascritta liberamente in futuro, scegliere una soluzione di codice in un file .install.
Alfred Armstrong,

Risposte:


41

Utilizzare field_create_field () per creare il campo stesso e field_create_instance () per avere un'istanza per il pacchetto di entità specificato.

Quando si creano campi come parte di un modulo personalizzato, è possibile o meno voler eliminare il campo quando il modulo viene disinstallato. Per fare ciò, è possibile utilizzare field_delete_field () se si desidera eliminare il campo e tutte le istanze del campo oppure se si desidera eliminare istanze specifiche, è possibile utilizzare field_delete_instance () .


Come eliminiamo i campi che abbiamo creato quando disinstalliamo il modulo?
Ashok KS,

Ashok, ho aggiunto un chiarimento per te in una modifica che ho appena apportato alla risposta.
Lester Peabody,

9

Esempio su come aggiungere a livello di programmazione campi al profilo utente e su come utilizzarli o meno nel modulo Registrazione utente.


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

3
Questo dovrebbe essere implementato in hook_install ().
rievoca il

Se tutto ciò che vuoi fare è aggiungere un nuovo campo a un tipo di contenuto esistente e da lì in poi continuare nel backend, quell'approccio va benissimo. Attiva il modulo, disattivalo, fatto. Il nuovo campo è lì, modificabile, il modulo può essere eliminato.
leymannx,

8

Se è necessario creare / eliminare rapidamente campi da un tipo di contenuto o o Entità esistente, senza utilizzare né l'interfaccia utente né la programmazione, è possibile utilizzare questi comandi Drush poco noti:

drush field-create <bundle(for nodes)> <field_name>,<field_type>,[widget_name] --entity_type: Tipo di entità (ad es. Nodo, utente, commento). Il valore predefinito è nodo.

Ad esempio: creare due nuovi campi per l'articolo:

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

Altri comandi:

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>

4

Come indicato da altri, è possibile utilizzare le funzioni API Field dall'implementazione hook_install () del modulo per creare campi e le relative istanze per il tipo di contenuto. Vedere node_example_install () per esempio sull'uso della funzione.

Un'altra soluzione è utilizzare il modulo Caratteristiche . Le funzionalità possono esportare vari componenti del sito per codificare in un modulo. Tipi di contenuto e campi sono tra questi esportabili. Puoi generare un modulo Caratteristiche e sovrascrivere il tuo codice esistente, Funzionalità farà del suo meglio per evitare di violare il tuo codice. Oppure puoi generare un modulo fittizio e copiarlo ./Invia il codice relativo ai campi al tuo modulo. Ciò richiede una conoscenza di base di come funzionano le funzionalità.


3

Nel tuo file di installazione dovrai definire sia 'hook_install' che 'hook_uninstall'. Esempio incluso ma leggi tutto sulle chiavi extra nei riferimenti API (il codice non è testato, quindi potrebbero esserci degli errori di battitura).

Nel hook_installpuoi aggiungere i campi usando:

field_create_field , questa funzione crea un modello per un campo.

field_create_instance Può essere utilizzato dopo aver creato il campo per aggiungerlo a content_types (noto anche come bundle).

NOTA I nomi dei vari tipi di campo si trovano nei moduli che li generano (è la chiave dell'elemento dell'array nel loro hook_field_info). Puoi trovare tutti i moduli di implementazione del campo principale nella cartella modules / field / modules.

Le impostazioni possono anche essere derivate dai moduli di campo. Le impostazioni che hai impostato field_create_fieldsono quelle del sito. Quelli che hai impostato field_instance_createsono quelli specifici di 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); 
      }
    }

Nel hook_uninstall

field_delete_instance e field_delete_field possono essere utilizzati per rimuoverli di nuovo, field_delete_fieldviene chiamato automaticamente se si elimina l'ultima istanza (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);
        }
      }
    }

2

Di recente ho avuto un bisogno simile di un progetto, ecco come mi sono avvicinato, spero che aiuti qualcuno.

Fondamentalmente creerai i campi di cui hai bisogno utilizzando l'interfaccia utente dei campi, esportali in codice e quindi includili nel tuo modulo personalizzato. Sarà necessario il modulo Devel abilitato.

Ho anche creato un Gist con queste informazioni.

Eccoci qui....

  1. Crea i campi che ti servono, usando la solita UI di Drupal.
  2. Sullo stesso sito, vai a example.com/devel/php
  3. Incolla il seguente codice nella casella di testo "Codice PHP da eseguire".
  4. Impostare le prime 3 variabili e quindi fare clic su Esegui

    $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. Otterrai 2 array, qualcosa del genere, si spera con tutte le proprietà compilate.

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

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

Ora aggiungi il seguente codice al tuo file .install. Sostituisci tutte le istanze di mymodule con il nome effettivo del modulo. Incollare il codice dall'output di sviluppo in _mymodule_field_data e _mymodule_instance_data, come indicato nelle rispettive funzioni di seguito. Puoi farlo per tutti i campi che vuoi, basta inserire tutti gli array $ field nella funzione _mymodule_field_data e tutte le $ $ istanze nella funzione _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;
}


0

Si potrebbe anche considerare l'utilizzo del modulo Caratteristiche per creare i campi al momento dell'installazione.

Poiché Funzioni genera codice per i campi, un'opzione è solo quella di utilizzare il modulo Funzione per generare il codice in un modulo fittizio e quindi copiare e incollare nel file .install del modulo.

Il vantaggio è che il modulo non dipende dal modulo Caratteristiche nell'ambiente di destinazione.


1
Anche le caratteristiche sono un buon modo per esportare i campi in codice, non è così che si usano le caratteristiche. Le funzionalità non utilizzano l'API di campo CRUD per creare campi dalla .install generata.
Pierre Buyle,

0

È possibile utilizzare il codice del modulo di società personalizzato indicato di seguito per creare programmaticamente un tipo di contenuto con i suoi vari campi.

Puoi aggiungere questo codice in un file .install del tuo modulo personalizzato. Aggiungerà a livello di codice un tipo di contenuto chiamato "azienda" e i suoi vari tipi di campi (testo, numerico, data (nota: sarà necessario installare il modulo Data poiché il campo Data non è fornito per impostazione predefinita), immagine, elenco).

Ho anche aggiunto il codice di disinstallazione che rimuoverà il tipo di contenuto "azienda" insieme a tutti i suoi campi e dati quando disinstallerai il modulo "customcompanymodule".

È possibile modificare / rimuovere questi campi in base alle proprie esigenze:

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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.