Correct way to use Drupal 7 Entities and Field API - drupal

I'm trying to use Drupal 7's entities and field API to correctly build a new module. What I have been unable to understand from the documentation is the correct way to use the new API to create a 'content type' (not a node type) with a number of set fields, such as Body.
I'm trying to set up the entity using hook_entity_info, then I believe I need to add the body field using field_create_instance, but I can't seem to get it to work.
In mycontenttype.module:
/**
* Implements hook_entity_info().
*/
function mycontenttype_entity_info() {
$return = array(
'mycontenttype' => array(
'label' => t('My Content Type'),
'controller class' => 'MyContentTypeEntityController',
'base table' => 'content_type',
'uri callback' => 'content_type_uri',
'entity keys' => array(
'id' => 'cid',
'label' => 'title',
),
'bundles' => array(
'mycontenttype' => array(
'label' => 'My Content Type',
'admin' => array(
'path' => 'admin/contenttype',
'access arguments' => array('administer contenttype'),
),
),
),
'fieldable' => true,
),
);
return $return;
}
/**
* Implements hook_field_extra_fields().
*/
function mycontenttype_field_extra_fields() {
$return['mycontenttype']['mycontenttype'] = array(
'form' => array(
'body' => array(
'label' => 'Body',
'description' => t('Body content'),
'weight' => 0,
),
),
);
return $return;
}
Then does this go in the .install file?
function mycontenttype_install() {
$field = array(
'field_name' => 'body',
'type' => 'text_with_summary',
'entity_types' => array('survey'),
'translatable' => TRUE,
);
field_create_field($field);
$instance = array(
'entity_type' => 'mycontenttype',
'field_name' => 'body',
'bundle' => 'mycontenttype',
'label' => 'Body',
'widget_type' => 'text_textarea_with_summary',
'settings' => array('display_summary' => TRUE),
'display' => array(
'default' => array(
'label' => 'hidden',
'type' => 'text_default',
),
'teaser' => array(
'label' => 'hidden',
'type' => 'text_summary_or_trimmed',
),
),
);
field_create_instance($instance);
}

I think your problem is that if node module is installed, there is already a field named 'body'. You should either re-name your field to something like 'mycontenttype_body' (comment.module uses comment_body), or re-use the 'body' field and skip the adding the field part and skip to adding the instance of it. The former is recommended over the latter.

Every field has an array property, entity_types, which limits the entities to which the field can be attached.
The best Drupal solution I can find, hook_field_create_field, can alter fields as they are created, but that's no good for the body field which is created on installation.
So my solution is just to edit the database directly in my hook_install
$data_col = db_query("SELECT data from field_config where field_name = 'body'")->fetchAssoc();
$data = unserialize($data_col['data']);
$data['entity_types'][] = 'MY_ENTITY_TYPE';
db_update('field_config')
->fields(array('data' => array('data' => serialize($data))))
->condition('field_name', 'body')
->execute();

just started down the same path here is a video from fago

Here's a nice repo to start: Lawmakers entity

Related

New fields aren't created after updating a custom module. DRUPAL 7

I have a custom module on my site. I try to install an update with a new field for my vocabulary, but the field doesn't appear.
hook_update:
function mymodule_update_7118()
{
$field_name = 'field_newfield';
if ( field_info_field( $field_name ) ) {
return;
}
$field = array(
'field_name' => $field_name,
'type' => 'list_integer',
'settings' => array(
'allowed_values' => array(
'Yes' => 1, //heard that adding a NO value may cause problems, although it doesn't work with a no value either.
),
),
);
$field = field_create_field( $field );
$instance = array(
'field_name' => $field['field_name'],
'entity_type' => 'taxonomy',
'bundle' => 'vocab_name',
'label' => 'Label',
'widget' => array(
'active' => 1,
'module' => 'options',
'settings' => array(),
'type' => 'options_select',
'weight' => '3',
),
);
field_create_instance($instance);
}
Logs contain several recordings of Internalization module creating a string to translate this field. Also all needed tables are created in the database, but they are all empty.
For creating a new custom field you must do it like a custom module. The steps can be found out at https://drupal.stackexchange.com/questions/140517/how-to-create-new-field-type
You can find the excellent field_example module from the Examples Module which is always the first place to look. Examples module can be downloaded from https://www.drupal.org/project/examples

Drupal 7 custom module form validate

I'm new to Drupal 7 enviroment. I want to create a custom module form and validate it. I'm facing problems in custom validating the form. Please help. I am providing the code below.
<?php
//implementing hook permissions
function userform_2_permission(){
return array(
'submit userform_2' => array(
'title' => t('Submit Userform_2'),
'description' => t('Submit username in the field'),
),
);
}
// implementing hook menu
function userform_2_menu(){
$items = array();
$items['userform_2'] = array(
'title' => 'Userform 2',
'description' => 'Input the username',
'type' => MENU_NORMAL_ITEM,
'access arguments' => array('access userform_2'),
'page callback' => 'drupal_get_form',
'page arguments' => array('userform_2_form'),
);
return $items;
}
// implementing form
function userform_2_form($form,&$form_state){
$form['username'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#description' => t('Please provide your username'),
'#size' => 60,
'#maxlength' => 128,
);
$form['password'] = array(
'#title' => t('Password'),
'#type' => 'password', // it provdes the password + password_confirm field
'#size' => 60,
'#description' => 'Please provide a password',
'#maxlength' => 128,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Login'),
);
return $form;
}
I want to add form validation here. Please provide the solution for this.
function useform_2_form_validate($form,&$form_state){
// please provide solution
}
// implementing submit handler
function userform_2_form_submit($form, &$form_state){
$u_id = db_insert('userform_2') -> fields(array(
'username' => $form_state['values']['username'],
'password' => $form_state['values']['password'],
)) ->execute();
drupal_set_message(t('the username has been added'));
}
?>
Attach custom validation :
$form['#validate'][] = 'useform_2_form_validate';
But I think if you search a little more you can do it alone ;)
https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7.x/#validation

How to make conditional field on cmb2 plugin?

I want to make a condition for my members info page.
$biometabox[] = array(
'id' => 'first-section',
'title' => 'Member Data',
'object_types' => array('dausfmembers'),
'fields' => array(
array(
'name' => 'Gender',
'type' => 'radio',
'id' => $dausf.'gender',
'options' => array(
'Male' => 'Male',
'Female' => 'Female'
)
),
array(
'name' => 'Gender',
'type' => 'radio',
'id' => $dausf.'mstatus',
'options' => array(
'Married' => 'Married',
'Single' => 'Single'
)
),
i want to make if female and married show this fileds in admin panel.
array(
'name' => 'Husband Name',
'type' => 'text',
'id' => $dausf.'hname',
),
can anyone help me out from this ??
"Conditional fields" seem not to be integrated within CMB2 core yet. However, there's a plugin called CMB2 Conditionals which might help you achieve the functionality you want.
After installing and setting up the plugin, it'd be simply achieved by setting up your fields as follows:
A special attention to the 'attributes' key, you can play with it as per the plugin's instructions.
$biometabox[] = array(
'id' => 'first-section',
'title' => 'Member Data',
'object_types' => array('dausfmembers'),
'fields' => array(
array(
'name' => 'Gender',
'type' => 'radio',
'id' => $dausf.'gender',
'options' => array(
'Male' => 'Male',
'Female' => 'Female',
),
'attributes' => array(
'required' => 'required',
)
),
array(
'name' => 'Gender',
'type' => 'radio',
'id' => $dausf.'mstatus',
'options' => array(
'Married' => 'Married',
'Single' => 'Single',
),
'attributes' => array(
'required' => 'required',
)
),
array(
'name' => 'Husband Name',
'type' => 'text',
'id' => $dausf.'hname',
'required' => true,
),
'attributes' => array(
'required' => true, // Will be required only if visible.
'data-conditional-id' => $prefix . 'gender',
'data-conditional-value' => 'Female',
),
'attributes' => array(
'required' => true, // Will be required only if visible.
'data-conditional-id' => $prefix . 'mstatus',
'data-conditional-value' => 'Married',
),
...
) );
You'll want to check the plugin's example functions here: https://github.com/jcchavezs/cmb2-conditionals/blob/master/example-functions.php
I hope you manage to make it you work. Good luck.
Although this might be a bit convoluted you can also write a custom jQuery script to show and hide fields based on the options selected:
In your theme directory add two folders called "js" and "css" if they aren't already there.
Then create a file in /js called "admin_scripts.js". And create a file in /css called "admin.css".
So you'll have:
theme_directory/css/admin.css
theme_directory/js/admin_scripts.js
In your functions.php add the following:
function admin_scripts() {
// Adding custom admin scripts file
wp_enqueue_script( 'admin-js', get_template_directory_uri() . '/js/admin_scripts.js', array( 'jquery' ));
// Registering and adding custom admin css
wp_register_style( 'custom_wp_admin_css', get_template_directory_uri() . '/css/admin.css', false, '1.0.0' );
wp_enqueue_style( 'custom_wp_admin_css' );
}
Then just below this function add:
add_action( 'admin_enqueue_scripts', 'admin_scripts' );
In js/admin_scripts.js add the following (remember to change the ids and classes to your field's ids and classes)
jQuery(document).ready( function() {
if( jQuery('#cmb2_select_field_id').val() == 'conditional_option') {
jQuery('.cmb2-field-to-display-on-select').show();
}
jQuery('#cmb2_select_field_id').bind('change', function (e) {
if( jQuery('#cmb2_select_field_id').val() == 'conditional_option') {
jQuery('.cmb2-field-to-display-on-select').show();
}
else{
jQuery('.cmb2-field-to-display-on-select').hide();
}
});
});
And in css/admin.css add the following:
.cmb2-field-to-display-on-select {
display:none;
}

set default value for custom field type: list_boolean / options_onoff

$instance = array(
'field_name' => $field_name,
'entity_type' => $entity,
'bundle' => $bundle,
'field types' => 'list_boolean',
'widget' => array(
'type' => 'options_onoff',
'settings' => array('display_label' => 1)
),
'default_value' => array(array('value' => 1)),
);
this is not taken, and i have to save it twice in the admin contenttype - field/edit,
until it takes it ...
i now exported the finished field with the features module,
and took the generated code - suddenly it works, with default_value
i guess i was missing the property module on the field, also field types is inexistant ..
In your field definition, you have to set the allowed_values in the settings array in order for the default_value in the instance to get picked up.
so like this assuming you are doing this in a module
$fields[] = array(
'field_name' => '$field_name',
'type' => 'list_boolean',
'settings' => array(
'allowed_values' => drupal_map_assoc(range(0, 1)),
),
);
Instead of using 'default_value', I got it to work by using 'default_value_function' and creating a function that returns array(array('value' => 1)).

drupal 7. how to refactor a form array

I am creating a wizard from the Drupal example file and would like to refactor the segments of code that are repeated when setting up items like options and radios.
I have already tried a simple function passing "ordinary" and "preferential" but can't find a way to make it work.
Can someone give me an idea of the best way to do this?
unfactored code is as below:
function services_wizard_share_capital_classes($form, &$form_state) {
$form['share_classes']['type_of_class'] = array(
'#type' => 'select',
'#title' => t('What type of share will this class be?'),
'#options' => array(
1 => t('Ordinary'),
2 => t('Preferential'),
),
);
$form['ordinary']['share_type'] = array(
'#type' => 'item',
'#description' => t("You chose Ordinary Shares"),
'#states' => array(
'visible' => array(
':input[name="type_of_class"]' => array('value' => '1'),
),
),
);
$form['preferential']['share_type'] = array(
'#type' => 'item',
'#description' => t("You chose Preferential Shares"),
'#states' => array(
'visible' => array(
':input[name="type_of_class"]' => array('value' => '2'),
),
),
);
return $form;
}
I'm not sure about this being the best way but it's certainly a way to refactor your code:
function _services_wizard_share_capital_classes_add_el(&$form, $name, $description, $index) {
$form[$name]['share_type'] = array(
'#type' => 'item',
'#description' => t($description),
'#states' => array(
'visible' => array(
':input[name="type_of_class"]' => array('value' => "$index"),
),
)
);
}
function services_wizard_share_capital_classes($form, &$form_state) {
// Other code
_services_wizard_share_capital_classes_add_el($form, 'ordinary', 'You chose Ordinary Shares', 1);
_services_wizard_share_capital_classes_add_el($form, 'preferential', 'You chose Preferential Shares', 2);
// etc...
}

Resources