Showing posts with label field. Show all posts
Showing posts with label field. Show all posts

Wednesday, June 19, 2013

Creating a link field programmatically for a profile2 user entity and deleting it upon disable or uninstall

In this example I have a profile2 profile called "werkgever"

The field I'm creating is a field used for that profile to input a website link.

required modules are
link
profile2

My module name is more_werkgever_fields

Using hook_enable I create the field:
/**
 * Implementation of hook_enable().
 */
function more_werkgever_fields_enable() {
  // Check if our field is not already created and if not create the field.
  if (!field_info_field('field_website')) {
    $field = array(
        'field_name' => 'field_website',
        'type' => 'link_field', // text
    );
    field_create_field($field);

    // Create the instance on the bundle.
    $instance = array(
      'field_name' => 'field_website',
      'entity_type' => 'profile2',
      'label' => 'Website',
      'bundle' => 'werkgever',
      'required' => FALSE, // default: FALSE
      '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' => 'link',
      // ),
    );
    field_create_instance($instance);
  }
}

This needs to be put in your modulename.install file

Also in the .install file you can implement a hook_disable or hook_uninstall
hook_disable is called when you disable the module. So this is handy if you are in a developing stage.
Just disable de module and your field should be gone.
An implementation of hook_disable:
/**
 * Implements hook_disable
 */
function more_werkgever_fields_disable(){
  // removes field when module is disabled
  field_delete_field('field_website');
}
As said this goes into your module.install file as well
Finally there is the Implementation of hook_uninstall:
/**
 * Implements hook_uninstall
 */
function more_werkgever_fields_uninstall(){
  field_delete_field('field_website'); // removes field from the system
}
The uninstall hook is only called upon uninstalling the module. I recommend putting your delete field in here. Or don't delete your field. Depending if your your module can be reused by others and maybe causing problems if that field is to be deleted. In my case I don't want it to clutter my database so I put it in my uninstall hook.

Friday, October 26, 2012

adding a city autotagging field to an user by creating a custom drupal 7 module

This posts tells you about how to programmatically create a field, instance, taxonomy library and create an autotagging widget in the form with it.

First in your module.install file create a hook_enable() function.
In the final version this would be hook_install() but while testing the module I find it easier to use hook enable so you can do: drush en mymodule -y and drush dis my module -y to enable and disable the module.

My module is called popover so that's the name I'll be using next.


/**
 * Implements hook_enable
 * runs every time this module is enabled, to run only at install use hook_install
 * Once the module has been enabled ( even only once ) hook_install won't be called anymore.
 */
function popover_enable() {
        // starting with the taxonomy library ( vocabulary ) first:

$vocabulary = (object) array(
'name' => 'City',
'description' => 'Pick your city :)',
'machine_name' => 'city',
);
taxonomy_vocabulary_save($vocabulary);
$terms = array(
'Amsterdam',
'Rotterdam',
'Rosmalen',
'Driebergen',
'Zeist',
'Utrecht',
);
        // I've created a custom function to save multiple terms to one vocabulary:
_popover_taxonomy_terms_save($terms,$vocabulary->vid);

        // building the field
$field = array(
'field_name' => 'field_' .$vocabulary->machine_name,
'type' => 'taxonomy_term_reference',
'settings' => array(
'allowed_values' => array(
array(
'vocabulary' => $vocabulary->machine_name,
'parent' => 0,
),
),
),
);
field_create_field($field);

        // connecting the user to the field I've just created
$instance = array(
'field_name' => 'field_' . $vocabulary->machine_name,
'entity_type' => 'user',
'label' => $vocabulary->name,
'bundle' => 'user',
'required' => TRUE,
'widget' => array(
'type' => 'taxonomy_autocomplete',
'weight' => -4,
),
'display' => array(
'default' => array(
'type' => 'taxonomy_term_reference_link',
'weight' => 10,
),
'teaser' => array(
'type' => 'taxonomy_term_reference_link',
'weight' => 10,
),
),
);
        // another custom field creator function
popover_field_create_update_instance($instance);
}



And the function I'm calling from the code above:

/**
 * save multiple terms to one taxonomy Vocabulary
 * @param  array $terms array of term names
 * @param  int   $vid   Vocabulary id
 */
function _popover_taxonomy_terms_save($terms,$vid) {
foreach($terms as $term) {
taxonomy_term_save(
(object) array(
'name' => $term,
'vid' => $vid,
)
);
}
}

/**
 * field creater helper function checks if field already is in this bundle if so do update instead of create
 */
function popover_field_create_update_instance($instance) {
if( field_info_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']) == NULL) {
return field_create_instance($instance);
}
else{
return field_update_instance($instance);
}
}



Now because the instance is in the user bundle the field should now be showing up on the user edit form.

To delete the instance, field and vocabulary upon uninstall of the module. I've written the following:


/**
 * Implements hook_disable()
 * TODO: needs to be hook_uninstall in the future but again for testing using the hook_disable
 */
function popover_disable() {
// create array with instances/fields/vocabularies to cleanup
  $cleanups = array(
  'city',
  // you can add more fields here...
  );
  foreach($cleanups as $name) {
  _popover_cleanup_instance_field_vocabulary($name);
  }

  // force field purge ( so it is really deleted without waiting for cron )
  // I think I would remove this in the final version as well since your not going to uninstall a
  // module and then reinstall it again immediately after. besides opening the module page 
  // and then the unistall page calls cron if I remember correctly but not sure about that... anyway:
field_purge_batch(5000); // not sure if this is a to high number...
}

/**
 * cleanup helper function
 * @param  String $name machine_name of the vocabulary ( 'field_' is added for the field/instance)
 */
function _popover_cleanup_instance_field_vocabulary($name) {
$instance = field_info_instance('user','field_' . $name,'user');
// removing instance of field_$name in the user bundle
field_delete_instance($instance, true);
// deleting field
field_delete_field('field_' . $name);

// delete city vocabulary
$vid = db_select('taxonomy_vocabulary', 'v')
    ->fields('v', array('vid'))
    ->condition("v.machine_name", $name)
    ->execute()
 ->fetchField();
  taxonomy_vocabulary_delete($vid);
}

You can see the whole module on my github But I'm still working on it so don't expect it to work 100%