View source
<?php
define('IEF_ENTITY_UNLINK', 1);
define('IEF_ENTITY_UNLINK_DELETE', 2);
function inline_entity_form_menu() {
$items = array();
$items['inline_entity_form/autocomplete'] = array(
'title' => 'Inline Entity Form Autocomplete',
'page callback' => 'inline_entity_form_autocomplete',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function inline_entity_form_autocomplete($entity_type, $field_name, $bundle, $string = '') {
$field = field_info_field($field_name);
$instance = field_info_instance($entity_type, $field_name, $bundle);
$settings = inline_entity_form_settings($field, $instance);
$controller = inline_entity_form_get_controller($instance);
if (!$field || !$instance || !$controller || !strlen($string)) {
return MENU_ACCESS_DENIED;
}
$results = array();
if ($field['type'] == 'commerce_product_reference') {
$match_operator = strtolower($controller
->getSetting('match_operator'));
$products = commerce_product_match_products($field, $instance, $string, $match_operator, array(), 10, TRUE);
foreach ($products as $product_id => $data) {
$results[] = t('@label (!entity_id)', array(
'@label' => $data['title'],
'!entity_id' => $product_id,
));
}
}
elseif ($field['type'] == 'entityreference') {
$handler = entityreference_get_selection_handler($field, $instance, $settings['entity_type']);
$entity_labels = $handler
->getReferencableEntities($string, $controller
->getSetting('match_operator'), 10);
foreach ($entity_labels as $bundle => $labels) {
foreach ($labels as $entity_id => $label) {
$results[] = t('!label (!entity_id)', array(
'!label' => $label,
'!entity_id' => $entity_id,
));
}
}
}
$matches = array();
foreach ($results as $result) {
$key = preg_replace('/\\s\\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($result)))));
$matches[$key] = '<div class="reference-autocomplete">' . $result . '</div>';
}
drupal_json_output($matches);
}
function inline_entity_form_get_controller($instance) {
$field = field_info_field($instance['field_name']);
$type_settings = $instance['widget']['settings']['type_settings'];
$ief_settings = inline_entity_form_settings($field, $instance);
$entity_info = entity_get_info($ief_settings['entity_type']);
if (!isset($entity_info['inline entity form'])) {
return FALSE;
}
return new $entity_info['inline entity form']['controller']($ief_settings['entity_type'], $type_settings);
}
function inline_entity_form_entity_info_alter(&$entity_info) {
$entity_info['node']['inline entity form'] = array(
'controller' => 'NodeInlineEntityFormController',
);
if (isset($entity_info['taxonomy_term'])) {
$entity_info['taxonomy_term']['inline entity form'] = array(
'controller' => 'TaxonomyTermInlineEntityFormController',
);
}
if (isset($entity_info['commerce_product'])) {
$entity_info['commerce_product']['inline entity form'] = array(
'controller' => 'CommerceProductInlineEntityFormController',
);
}
if (isset($entity_info['commerce_line_item'])) {
$entity_info['commerce_line_item']['inline entity form'] = array(
'controller' => 'CommerceLineItemInlineEntityFormController',
);
}
}
function inline_entity_form_entity_delete($entity, $type) {
$entity_info = entity_get_info($type);
list(, , $bundle) = entity_extract_ids($type, $entity);
foreach (field_info_instances($type, $bundle) as $field_name => $instance) {
if (strpos($instance['widget']['type'], 'inline_entity_form') === 0) {
$controller = inline_entity_form_get_controller($instance);
if ($controller && $controller
->getSetting('delete_references')) {
$items = field_get_items($type, $entity, $field_name);
if ($items) {
$field = field_info_field($field_name);
$ief_settings = inline_entity_form_settings($field, $instance);
$ids = array();
foreach ($items as $item) {
$ids[] = $item[$ief_settings['column']];
}
$context = array(
'parent_entity_type' => $type,
'parent_entity' => $entity,
);
$controller
->delete($ids, $context);
}
}
}
}
}
function _inline_entity_form_attach_css($theme_css, &$css) {
if (empty($theme_css)) {
return;
}
if (!empty($theme_css['base'])) {
$css[] = $theme_css['base'];
}
$theme_key = $GLOBALS['theme'];
if (!empty($theme_css[$theme_key])) {
$css[] = $theme_css[$theme_key];
}
}
function inline_entity_form_theme() {
return array(
'inline_entity_form_entity_table' => array(
'render element' => 'form',
),
);
}
function inline_entity_form_field_widget_info() {
$widgets = array();
$widgets['inline_entity_form_single'] = array(
'label' => t('Inline entity form - Single value'),
'field types' => array(
'commerce_line_item_reference',
'commerce_product_reference',
'entityreference',
),
'settings' => array(
'fields' => array(),
'type_settings' => array(),
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
'default value' => FIELD_BEHAVIOR_NONE,
),
);
$widgets['inline_entity_form'] = array(
'label' => t('Inline entity form - Multiple values'),
'field types' => array(
'commerce_line_item_reference',
'commerce_product_reference',
'entityreference',
),
'settings' => array(
'fields' => array(),
'type_settings' => array(),
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
'default value' => FIELD_BEHAVIOR_NONE,
),
);
return $widgets;
}
function inline_entity_form_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$settings = $widget['settings'];
$controller = inline_entity_form_get_controller($instance);
if (!$controller) {
return array();
}
$element = array();
$element['fields'] = array(
'#type' => 'value',
'#value' => $settings['fields'],
);
$settings_form = $controller
->settingsForm($field, $instance);
if (!empty($settings_form)) {
$entity_info = entity_get_info($controller
->entityType());
$element['type_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Inline Entity Form: %type', array(
'%type' => $entity_info['label'],
)),
);
$element['type_settings'] += $settings_form;
}
return $element;
}
function inline_entity_form_field_widget_properties_alter(&$widget, $context) {
if (strpos($widget['type'], 'inline_entity_form') !== 0) {
return;
}
if (!module_exists('views') || !module_exists('views_bulk_operations')) {
return;
}
if ($view = views_get_current_view()) {
$vbo = _views_bulk_operations_get_field($view);
if ($vbo) {
$field = $context['field'];
$field_type = field_info_field_types($field['type']);
$widget_type = field_info_widget_types($field_type['default_widget']);
$widget_type += array(
'settings',
);
$widget['type'] = $field_type['default_widget'];
$widget['module'] = $widget_type['module'];
$widget['settings'] = $widget_type['settings'];
}
}
}
function inline_entity_form_settings($field, $instance) {
$settings = array(
'entity_type' => NULL,
'bundles' => array(),
'create_bundles' => array(),
'column' => NULL,
);
if ($field['type'] == 'commerce_product_reference') {
$settings['entity_type'] = 'commerce_product';
$settings['column'] = 'product_id';
$types = array_filter($instance['settings']['referenceable_types']);
if (!empty($types)) {
$settings['bundles'] = array_values($types);
}
}
elseif ($field['type'] == 'entityreference') {
$settings['entity_type'] = $field['settings']['target_type'];
$settings['column'] = 'target_id';
if (!empty($field['settings']['handler_settings']['target_bundles'])) {
$bundles = array_filter($field['settings']['handler_settings']['target_bundles']);
if (!empty($bundles)) {
$settings['bundles'] = array_values($bundles);
}
}
}
elseif ($field['type'] == 'commerce_line_item_reference') {
$settings['entity_type'] = 'commerce_line_item';
$settings['column'] = 'line_item_id';
}
drupal_alter('inline_entity_form_settings', $settings, $field, $instance);
if (empty($settings['bundles'])) {
$info = entity_get_info($settings['entity_type']);
foreach ($info['bundles'] as $bundle_name => $bundle_info) {
$settings['bundles'][] = $bundle_name;
}
}
foreach ($settings['bundles'] as $bundle) {
$new_entity = inline_entity_form_create_entity($settings['entity_type'], $bundle);
if (entity_access('create', $settings['entity_type'], $new_entity)) {
$settings['create_bundles'][] = $bundle;
}
}
return $settings;
}
function inline_entity_form_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$widget = $instance['widget'];
$settings = inline_entity_form_settings($field, $instance);
$entity_info = entity_get_info($settings['entity_type']);
$controller = inline_entity_form_get_controller($instance);
if (!$controller) {
return array();
}
$labels = $controller
->labels();
$parents = array_merge($element['#field_parents'], array(
$element['#field_name'],
$element['#language'],
));
$parent_langcode = entity_language($element['#entity_type'], $element['#entity']);
$ief_id = sha1(implode('-', $parents));
$wrapper = 'inline-entity-form-' . $ief_id;
$element = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#description' => filter_xss_admin($instance['description']),
'#prefix' => '<div id="' . $wrapper . '">',
'#suffix' => '</div>',
'#attached' => array(
'css' => array(),
),
'#ief_id' => $ief_id,
'#ief_root' => TRUE,
) + $element;
if (module_exists('file')) {
$element['#attached']['js'] = array(
drupal_get_path('module', 'file') . '/file.js',
drupal_get_path('module', 'inline_entity_form') . '/inline_entity_form.js',
);
}
$base_css = array(
'base' => drupal_get_path('module', 'inline_entity_form') . '/theme/inline_entity_form.css',
'seven' => drupal_get_path('module', 'inline_entity_form') . '/theme/inline_entity_form.seven.css',
);
_inline_entity_form_attach_css($base_css, $element['#attached']['css']);
_inline_entity_form_attach_css($controller
->css(), $element['#attached']['css']);
if (empty($form_state['inline_entity_form'][$ief_id])) {
$form_state['inline_entity_form'][$ief_id] = array(
'form' => NULL,
'settings' => $settings,
'instance' => $instance,
);
$form_state['inline_entity_form'][$ief_id]['entities'] = array();
$entity_ids = array();
foreach ($items as $item) {
$entity_ids[] = $item[$settings['column']];
}
$delta = 0;
foreach (entity_load($settings['entity_type'], $entity_ids) as $entity) {
$form_state['inline_entity_form'][$ief_id]['entities'][$delta] = array(
'entity' => $entity,
'weight' => $delta,
'form' => NULL,
'needs_save' => FALSE,
);
$delta++;
}
}
$cardinality = $field['cardinality'];
$entity_count = count($form_state['inline_entity_form'][$ief_id]['entities']);
$cardinality_reached = $cardinality > 0 && $entity_count == $cardinality;
if ($widget['type'] == 'inline_entity_form_single') {
$bundle = reset($settings['bundles']);
if ($element['#entity_type'] == $settings['entity_type'] && $element['#bundle'] == $bundle) {
return array();
}
$form_state['inline_entity_form'][$ief_id]['form settings'] = array(
'bundle' => $bundle,
);
$element['form'] = array(
'#type' => 'container',
'#op' => 'add',
'#parents' => array_merge($parents, array(
'form',
)),
'#entity_type' => $settings['entity_type'],
'#parent_language' => $parent_langcode,
'#ief_id' => $ief_id,
);
if (!empty($form_state['inline_entity_form'][$ief_id]['entities'])) {
$element['form']['#op'] = 'edit';
$element['form']['#entity'] = $form_state['inline_entity_form'][$ief_id]['entities'][0]['entity'];
$element['form']['#ief_row_delta'] = 0;
}
$element['form'] = inline_entity_form_entity_form($controller, $element['form'], $form_state);
$element['form']['actions']['#access'] = FALSE;
}
else {
$element['#element_validate'] = array(
'inline_entity_form_update_row_weights',
);
if ($element['#required']) {
$element['#title'] .= ' ' . theme('form_required_marker', array(
'element' => $element,
));
$element['#element_validate'][] = 'inline_entity_form_required_field';
}
$element['entities'] = array(
'#tree' => TRUE,
'#theme' => 'inline_entity_form_entity_table',
'#entity_type' => $settings['entity_type'],
'#cardinality' => (int) $cardinality,
);
$fields = $controller
->tableFields($settings['bundles']);
$context = array(
'parent_entity_type' => $instance['entity_type'],
'parent_bundle' => $instance['bundle'],
'field_name' => $instance['field_name'],
'entity_type' => $settings['entity_type'],
'allowed_bundles' => $settings['bundles'],
);
drupal_alter('inline_entity_form_table_fields', $fields, $context);
$element['entities']['#table_fields'] = $fields;
$weight_delta = max(ceil(count($form_state['inline_entity_form'][$ief_id]['entities']) * 1.2), 50);
foreach ($form_state['inline_entity_form'][$ief_id]['entities'] as $key => $value) {
$element['entities'][$key]['#entity'] = $entity = $value['entity'];
$element['entities'][$key]['#needs_save'] = $value['needs_save'];
$element['entities'][$key]['#weight'] = $value['weight'];
if (!empty($value['form'])) {
$element['entities'][$key]['delta'] = array(
'#type' => 'value',
'#value' => $value['weight'],
);
$element['entities'][$key]['form'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'ief-form',
'ief-form-row',
),
),
'#op' => $value['form'],
'#parents' => array_merge($parents, array(
'entities',
$key,
'form',
)),
'#entity' => $entity,
'#entity_type' => $settings['entity_type'],
'#parent_language' => $parent_langcode,
'#ief_id' => $ief_id,
'#ief_row_delta' => $key,
);
$form =& $element['entities'][$key]['form'];
if ($value['form'] == 'edit') {
$form += inline_entity_form_entity_form($controller, $form, $form_state);
}
elseif ($value['form'] == 'remove') {
$form += inline_entity_form_remove_form($controller, $form, $form_state);
}
}
else {
$row =& $element['entities'][$key];
$row['delta'] = array(
'#type' => 'weight',
'#delta' => $weight_delta,
'#default_value' => $value['weight'],
'#attributes' => array(
'class' => array(
'ief-entity-delta',
),
),
);
$row['actions'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'ief-entity-operations',
),
),
);
list($entity_id) = entity_extract_ids($controller
->entityType(), $entity);
if (empty($entity_id) || entity_access('update', $controller
->entityType(), $entity)) {
$row['actions']['ief_entity_edit'] = array(
'#type' => 'submit',
'#value' => t('Edit'),
'#name' => 'ief-' . $ief_id . '-entity-edit-' . $key,
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => $wrapper,
),
'#submit' => array(
'inline_entity_form_open_row_form',
),
'#ief_row_delta' => $key,
'#ief_row_form' => 'edit',
);
}
if ($controller
->getSetting('allow_clone') && !$cardinality_reached && entity_access('create', $controller
->entityType(), $entity)) {
$row['actions']['ief_entity_clone'] = array(
'#type' => 'submit',
'#value' => t('Clone'),
'#name' => 'ief-' . $ief_id . '-entity-clone-' . $key,
'#limit_validation_errors' => array(
array_merge($parents, array(
'actions',
)),
),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => $wrapper,
),
'#submit' => array(
'inline_entity_form_open_form',
),
'#ief_row_delta' => $key,
'#ief_form' => 'clone',
);
}
if (empty($entity_id) || $controller
->getSetting('allow_existing') || entity_access('delete', $controller
->entityType(), $entity)) {
$row['actions']['ief_entity_remove'] = array(
'#type' => 'submit',
'#value' => t('Remove'),
'#name' => 'ief-' . $ief_id . '-entity-remove-' . $key,
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => $wrapper,
),
'#submit' => array(
'inline_entity_form_open_row_form',
),
'#ief_row_delta' => $key,
'#ief_row_form' => 'remove',
);
}
}
}
if ($cardinality > 1) {
$message = t('You have added @entities_count out of @cardinality_count allowed @label.', array(
'@entities_count' => $entity_count,
'@cardinality_count' => $cardinality,
'@label' => $labels['plural'],
));
$element['cardinality_count'] = array(
'#markup' => '<div class="ief-cardinality-count">' . $message . '</div>',
);
}
if ($cardinality_reached) {
return $element;
}
$hide_cancel = FALSE;
if (empty($form_state['inline_entity_form'][$ief_id]['entities']) && $instance['required']) {
if ($controller
->getSetting('allow_existing') && !$controller
->getSetting('allow_new')) {
$form_state['inline_entity_form'][$ief_id]['form'] = 'ief_add_existing';
$hide_cancel = TRUE;
}
elseif (count($settings['create_bundles']) == 1 && $controller
->getSetting('allow_new') && !$controller
->getSetting('allow_existing')) {
$bundle = reset($settings['create_bundles']);
if ($element['#entity_type'] != $settings['entity_type'] || $element['#bundle'] != $bundle) {
$form_state['inline_entity_form'][$ief_id]['form'] = 'add';
$form_state['inline_entity_form'][$ief_id]['form settings'] = array(
'bundle' => $bundle,
);
$hide_cancel = TRUE;
}
}
}
if (empty($form_state['inline_entity_form'][$ief_id]['form'])) {
$element['actions'] = array(
'#attributes' => array(
'class' => array(
'container-inline',
),
),
'#type' => 'container',
'#weight' => 100,
);
if (count($settings['create_bundles'])) {
if (count($settings['create_bundles']) > 1) {
$bundles = array();
foreach ($entity_info['bundles'] as $bundle_name => $bundle_info) {
if (in_array($bundle_name, $settings['create_bundles'])) {
$bundles[$bundle_name] = $bundle_info['label'];
}
}
asort($bundles);
$element['actions']['bundle'] = array(
'#type' => 'select',
'#options' => $bundles,
);
}
else {
$element['actions']['bundle'] = array(
'#type' => 'value',
'#value' => reset($settings['create_bundles']),
);
}
if ($controller
->getSetting('allow_new')) {
$element['actions']['ief_add'] = array(
'#type' => 'submit',
'#value' => t('Add new @type_singular', array(
'@type_singular' => $labels['singular'],
)),
'#name' => 'ief-' . $ief_id . '-add',
'#limit_validation_errors' => array(
array_merge($parents, array(
'actions',
)),
),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => $wrapper,
),
'#submit' => array(
'inline_entity_form_open_form',
),
'#ief_form' => 'add',
);
}
}
if ($controller
->getSetting('allow_existing')) {
$element['actions']['ief_add_existing'] = array(
'#type' => 'submit',
'#value' => t('Add existing @type_singular', array(
'@type_singular' => $labels['singular'],
)),
'#name' => 'ief-' . $ief_id . '-add-existing',
'#limit_validation_errors' => array(
array_merge($parents, array(
'actions',
)),
),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => $wrapper,
),
'#submit' => array(
'inline_entity_form_open_form',
),
'#ief_form' => 'ief_add_existing',
);
}
}
else {
$element['form'] = array(
'#type' => 'fieldset',
'#attributes' => array(
'class' => array(
'ief-form',
'ief-form-bottom',
),
),
'#ief_id' => $ief_id,
'#parents' => array_merge($parents, array(
'form',
)),
'#entity_type' => $settings['entity_type'],
'#parent_language' => $parent_langcode,
);
if ($form_state['inline_entity_form'][$ief_id]['form'] == 'add') {
$element['form']['#op'] = 'add';
$element['form'] += inline_entity_form_entity_form($controller, $element['form'], $form_state);
}
elseif ($form_state['inline_entity_form'][$ief_id]['form'] == 'ief_add_existing') {
$element['form'] += inline_entity_form_reference_form($controller, $element['form'], $form_state);
}
elseif ($form_state['inline_entity_form'][$ief_id]['form'] == 'clone') {
$element['form']['#op'] = 'clone';
$element['form'] += inline_entity_form_entity_form($controller, $element['form'], $form_state);
}
if ($hide_cancel) {
if (isset($element['form']['actions']['ief_add_cancel'])) {
$element['form']['actions']['ief_add_cancel']['#access'] = FALSE;
}
elseif (isset($element['form']['actions']['ief_reference_cancel'])) {
$element['form']['actions']['ief_reference_cancel']['#access'] = FALSE;
}
}
if (empty($form_state['inline_entity_form'][$ief_id]['entities'])) {
$element['#type'] = 'container';
}
}
}
return $element;
}
function inline_entity_form_form_alter(&$form, &$form_state, $form_id) {
if (!empty($form_state['inline_entity_form'])) {
$submit_element = NULL;
if (!empty($form['submit'])) {
$submit_element =& $form['submit'];
}
elseif (!empty($form['actions']['submit'])) {
$submit_element =& $form['actions']['submit'];
}
if ($submit_element) {
if (!empty($submit_element['#submit'])) {
$submit = array_merge(array(
'inline_entity_form_trigger_submit',
), (array) $submit_element['#submit']);
}
else {
$submit = array_merge(array(
'inline_entity_form_trigger_submit',
), (array) $form['#submit']);
}
$submit_element['#submit'] = array_unique($submit);
$submit_element['#ief_submit_all'] = TRUE;
}
}
}
function inline_entity_form_update_row_weights($element, &$form_state, $form) {
$ief_id = $element['#ief_id'];
foreach (element_children($element['entities']) as $key) {
$form_state['inline_entity_form'][$ief_id]['entities'][$key]['weight'] = $element['entities'][$key]['delta']['#value'];
}
}
function inline_entity_form_entity_form($controller, $entity_form, &$form_state) {
$labels = $controller
->labels();
$delta = $entity_form['#ief_id'];
if ($entity_form['#op'] == 'edit') {
$delta .= '-' . $entity_form['#ief_row_delta'];
$save_label = t('Update @type_singular', array(
'@type_singular' => $labels['singular'],
));
}
elseif ($entity_form['#op'] == 'add') {
$form_settings = $form_state['inline_entity_form'][$entity_form['#ief_id']]['form settings'];
$entity_form['#entity'] = inline_entity_form_create_entity($entity_form['#entity_type'], $form_settings['bundle'], $entity_form['#parent_language']);
$entity_form['#title'] = t('Add new @type_singular', array(
'@type_singular' => $labels['singular'],
));
$save_label = t('Create @type_singular', array(
'@type_singular' => $labels['singular'],
));
}
elseif ($entity_form['#op'] == 'clone') {
$form_settings = $form_state['inline_entity_form'][$entity_form['#ief_id']]['form settings'];
$entity = $form_state['inline_entity_form'][$entity_form['#ief_id']]['entities'][$form_settings['source']]['entity'];
$entity_form['#entity'] = $controller
->createClone($entity);
$entity_form['#title'] = t('Clone @type_singular', array(
'@type_singular' => $labels['singular'],
));
$save_label = t('Clone @type_singular', array(
'@type_singular' => $labels['singular'],
));
}
$entity_form = $controller
->entityForm($entity_form, $form_state);
$entity_form['actions'] = array(
'#type' => 'container',
'#weight' => 100,
);
$entity_form['actions']['ief_' . $entity_form['#op'] . '_save'] = array(
'#type' => 'submit',
'#value' => $save_label,
'#name' => 'ief-' . $entity_form['#op'] . '-submit-' . $delta,
'#limit_validation_errors' => array(
$entity_form['#parents'],
),
'#attributes' => array(
'class' => array(
'ief-entity-submit',
),
),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => 'inline-entity-form-' . $entity_form['#ief_id'],
),
);
$entity_form['actions']['ief_' . $entity_form['#op'] . '_cancel'] = array(
'#type' => 'submit',
'#value' => t('Cancel'),
'#name' => 'ief-' . $entity_form['#op'] . '-cancel-' . $delta,
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => 'inline-entity-form-' . $entity_form['#ief_id'],
),
);
if (in_array($entity_form['#op'], array(
'add',
'clone',
))) {
$entity_form['actions']['ief_' . $entity_form['#op'] . '_save']['#submit'] = array(
'inline_entity_form_trigger_submit',
'inline_entity_form_close_child_forms',
'inline_entity_form_close_form',
);
$entity_form['actions']['ief_' . $entity_form['#op'] . '_cancel']['#submit'] = array(
'inline_entity_form_close_child_forms',
'inline_entity_form_close_form',
'inline_entity_form_cleanup_form_state',
);
}
else {
$entity_form['actions']['ief_edit_save']['#ief_row_delta'] = $entity_form['#ief_row_delta'];
$entity_form['actions']['ief_edit_cancel']['#ief_row_delta'] = $entity_form['#ief_row_delta'];
$entity_form['actions']['ief_edit_save']['#submit'] = array(
'inline_entity_form_trigger_submit',
'inline_entity_form_close_child_forms',
'inline_entity_form_close_row_form',
);
$entity_form['actions']['ief_edit_cancel']['#submit'] = array(
'inline_entity_form_close_child_forms',
'inline_entity_form_close_row_form',
'inline_entity_form_cleanup_row_form_state',
);
}
$entity_form['#element_validate'][] = 'inline_entity_form_entity_form_validate';
$entity_form['#ief_element_submit'][] = 'inline_entity_form_entity_form_submit';
$entity_form['#pre_render'][] = 'inline_entity_form_pre_render_add_fieldset_markup';
drupal_alter('inline_entity_form_entity_form', $entity_form, $form_state);
return $entity_form;
}
function inline_entity_form_entity_form_validate(&$entity_form, &$form_state) {
$ief_id = $entity_form['#ief_id'];
$instance = $form_state['inline_entity_form'][$ief_id]['instance'];
$controller = inline_entity_form_get_controller($instance);
$controller
->entityFormValidate($entity_form, $form_state);
$errors = form_get_errors();
if ($errors && !empty($form_state['conditional_fields_untriggered_dependents'])) {
foreach ($form_state['conditional_fields_untriggered_dependents'] as $untriggered_dependents) {
if (!empty($untriggered_dependents['errors'])) {
foreach (array_keys($untriggered_dependents['errors']) as $key) {
unset($errors[$key]);
}
}
}
}
}
function inline_entity_form_entity_form_submit($entity_form, &$form_state) {
$ief_id = $entity_form['#ief_id'];
$instance = $form_state['inline_entity_form'][$ief_id]['instance'];
$controller = inline_entity_form_get_controller($instance);
$controller
->entityFormSubmit($entity_form, $form_state);
inline_entity_form_cleanup_entity_form_state($entity_form, $form_state);
if (in_array($entity_form['#op'], array(
'add',
'clone',
))) {
$weight = 0;
if (!empty($form_state['inline_entity_form'][$ief_id]['entities'])) {
$weight = max(array_keys($form_state['inline_entity_form'][$ief_id]['entities'])) + 1;
}
$form_state['inline_entity_form'][$ief_id]['entities'][] = array(
'entity' => $entity_form['#entity'],
'weight' => $weight,
'form' => NULL,
'needs_save' => TRUE,
);
}
else {
$delta = $entity_form['#ief_row_delta'];
$form_state['inline_entity_form'][$ief_id]['entities'][$delta]['entity'] = $entity_form['#entity'];
$form_state['inline_entity_form'][$ief_id]['entities'][$delta]['needs_save'] = TRUE;
}
}
function inline_entity_form_reference_form($controller, $reference_form, &$form_state) {
$labels = $controller
->labels();
$ief_id = $reference_form['#ief_id'];
$instance = $form_state['inline_entity_form'][$ief_id]['instance'];
$autocomplete_path = 'inline_entity_form/autocomplete/' . $instance['entity_type'];
$autocomplete_path .= '/' . $instance['field_name'] . '/' . $instance['bundle'];
$reference_form['#title'] = t('Add existing @type_singular', array(
'@type_singular' => $labels['singular'],
));
$reference_form['entity_id'] = array(
'#type' => 'textfield',
'#title' => t('@label', array(
'@label' => ucwords($labels['singular']),
)),
'#autocomplete_path' => $autocomplete_path,
'#element_validate' => array(
'_inline_entity_form_autocomplete_validate',
),
'#required' => TRUE,
'#maxlength' => 255,
);
$reference_form['actions'] = array(
'#type' => 'container',
'#weight' => 100,
);
$reference_form['actions']['ief_reference_save'] = array(
'#type' => 'submit',
'#value' => t('Add @type_singular', array(
'@type_singular' => $labels['singular'],
)),
'#name' => 'ief-reference-submit-' . $reference_form['#ief_id'],
'#limit_validation_errors' => array(
$reference_form['#parents'],
),
'#attributes' => array(
'class' => array(
'ief-entity-submit',
),
),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => 'inline-entity-form-' . $reference_form['#ief_id'],
),
'#submit' => array(
'inline_entity_form_trigger_submit',
'inline_entity_form_close_form',
),
);
$reference_form['actions']['ief_reference_cancel'] = array(
'#type' => 'submit',
'#value' => t('Cancel'),
'#name' => 'ief-reference-cancel-' . $reference_form['#ief_id'],
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => 'inline-entity-form-' . $reference_form['#ief_id'],
),
'#submit' => array(
'inline_entity_form_close_form',
),
);
$reference_form['#element_validate'][] = 'inline_entity_form_reference_form_validate';
$reference_form['#ief_element_submit'][] = 'inline_entity_form_reference_form_submit';
drupal_alter('inline_entity_form_reference_form', $reference_form, $form_state);
return $reference_form;
}
function _inline_entity_form_autocomplete_validate($element, &$form_state, $form) {
$value = '';
if (!empty($element['#value'])) {
if (preg_match("/.+\\((\\d+)\\)/", $element['#value'], $matches)) {
$value = $matches[1];
}
}
form_set_value($element, $value, $form_state);
}
function inline_entity_form_reference_form_validate(&$reference_form, &$form_state) {
$ief_id = $reference_form['#ief_id'];
$entity_type = $reference_form['#entity_type'];
$parents_path = implode('][', $reference_form['#parents']);
$instance = $form_state['inline_entity_form'][$ief_id]['instance'];
$controller = inline_entity_form_get_controller($instance);
$labels = $controller
->labels();
$form_values = drupal_array_get_nested_value($form_state['values'], $reference_form['#parents']);
$attach_entity = entity_load_single($entity_type, $form_values['entity_id']);
if (!empty($attach_entity)) {
foreach ($form_state['inline_entity_form'][$ief_id]['entities'] as $key => $value) {
if ($value['entity'] == $attach_entity) {
form_set_error($parents_path . '][existing_entity', t('The selected @label has already been added.', array(
'@label' => $labels['singular'],
)));
break;
}
}
}
else {
form_set_error($parents_path . '][existing_entity', t('The selected @label is not valid.', array(
'@label' => $labels['singular'],
)));
}
}
function inline_entity_form_reference_form_submit($reference_form, &$form_state) {
$ief_id = $reference_form['#ief_id'];
$entity_type = $reference_form['#entity_type'];
$form_values = drupal_array_get_nested_value($form_state['values'], $reference_form['#parents']);
$attach_entity = entity_load_single($entity_type, $form_values['entity_id']);
$weight = 0;
if (!empty($form_state['inline_entity_form'][$ief_id]['entities'])) {
$weight = max(array_keys($form_state['inline_entity_form'][$ief_id]['entities'])) + 1;
}
$form_state['inline_entity_form'][$ief_id]['entities'][] = array(
'entity' => $attach_entity,
'weight' => $weight,
'form' => NULL,
'needs_save' => FALSE,
);
}
function inline_entity_form_remove_form($controller, $remove_form, &$form_state) {
$delta = $remove_form['#ief_id'] . '-' . $remove_form['#ief_row_delta'];
$remove_form = $controller
->removeForm($remove_form, $form_state);
$remove_form['actions'] = array(
'#type' => 'container',
'#weight' => 100,
);
$remove_form['actions']['ief_remove_confirm'] = array(
'#type' => 'submit',
'#value' => t('Remove'),
'#name' => 'ief-remove-confirm-' . $delta,
'#limit_validation_errors' => array(
$remove_form['#parents'],
),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => 'inline-entity-form-' . $remove_form['#ief_id'],
),
'#submit' => array(
'inline_entity_form_remove_confirm',
),
'#ief_row_delta' => $remove_form['#ief_row_delta'],
);
$remove_form['actions']['ief_remove_cancel'] = array(
'#type' => 'submit',
'#value' => t('Cancel'),
'#name' => 'ief-remove-cancel-' . $delta,
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => 'inline_entity_form_get_element',
'wrapper' => 'inline-entity-form-' . $remove_form['#ief_id'],
),
'#submit' => array(
'inline_entity_form_close_row_form',
),
'#ief_row_delta' => $remove_form['#ief_row_delta'],
);
return $remove_form;
}
function inline_entity_form_remove_confirm($form, &$form_state) {
$form_state['rebuild'] = TRUE;
$element = inline_entity_form_get_element($form, $form_state);
$ief_id = $element['#ief_id'];
$instance = $form_state['inline_entity_form'][$ief_id]['instance'];
$delta = $form_state['triggering_element']['#ief_row_delta'];
$remove_form = $element['entities'][$delta]['form'];
$controller = inline_entity_form_get_controller($instance);
$status = $controller
->removeFormSubmit($remove_form, $form_state);
if ($status == IEF_ENTITY_UNLINK_DELETE) {
$settings = $form_state['inline_entity_form'][$ief_id]['settings'];
list($entity_id) = entity_extract_ids($settings['entity_type'], $remove_form['#entity']);
$form_state['inline_entity_form'][$ief_id]['delete'][] = $entity_id;
unset($form_state['inline_entity_form'][$ief_id]['entities'][$delta]);
}
elseif ($status == IEF_ENTITY_UNLINK) {
unset($form_state['inline_entity_form'][$ief_id]['entities'][$delta]);
}
}
function inline_entity_form_trigger_submit($form, &$form_state) {
if (!empty($form_state['triggering_element']['#ief_submit_all'])) {
inline_entity_form_submit($form, $form_state);
}
else {
$array_parents = $form_state['triggering_element']['#array_parents'];
$array_parents = array_slice($array_parents, 0, -2);
$element = drupal_array_get_nested_value($form, $array_parents);
inline_entity_form_submit($element, $form_state);
}
}
function inline_entity_form_submit($elements, &$form_state) {
foreach (element_children($elements) as $key) {
if (!empty($elements[$key])) {
inline_entity_form_submit($elements[$key], $form_state);
}
}
if (!empty($elements['#ief_element_submit'])) {
foreach ($elements['#ief_element_submit'] as $function) {
$function($elements, $form_state);
}
}
}
function inline_entity_form_open_form($form, &$form_state) {
$element = inline_entity_form_get_element($form, $form_state);
$ief_id = $element['#ief_id'];
$form_state['rebuild'] = TRUE;
$parents = array_merge($element['#field_parents'], array(
$element['#field_name'],
$element['#language'],
));
$form_values = drupal_array_get_nested_value($form_state['values'], $parents);
$form_state['inline_entity_form'][$ief_id]['form'] = $form_state['triggering_element']['#ief_form'];
$form_state['inline_entity_form'][$ief_id]['form settings'] = array();
if (!empty($form_values['actions']['bundle'])) {
$form_state['inline_entity_form'][$ief_id]['form settings']['bundle'] = $form_values['actions']['bundle'];
}
if (isset($form_state['triggering_element']['#ief_row_delta'])) {
$form_state['inline_entity_form'][$ief_id]['form settings']['source'] = $form_state['triggering_element']['#ief_row_delta'];
}
}
function inline_entity_form_close_form($form, &$form_state) {
$element = inline_entity_form_get_element($form, $form_state);
$ief_id = $element['#ief_id'];
$form_state['rebuild'] = TRUE;
$form_state['inline_entity_form'][$ief_id]['form'] = NULL;
}
function inline_entity_form_cleanup_form_state($form, &$form_state) {
$element = inline_entity_form_get_element($form, $form_state);
inline_entity_form_cleanup_entity_form_state($element['form'], $form_state);
}
function inline_entity_form_open_row_form($form, &$form_state) {
$element = inline_entity_form_get_element($form, $form_state);
$ief_id = $element['#ief_id'];
$delta = $form_state['triggering_element']['#ief_row_delta'];
$form_state['rebuild'] = TRUE;
$form_state['inline_entity_form'][$ief_id]['entities'][$delta]['form'] = $form_state['triggering_element']['#ief_row_form'];
}
function inline_entity_form_close_row_form($form, &$form_state) {
$element = inline_entity_form_get_element($form, $form_state);
$ief_id = $element['#ief_id'];
$delta = $form_state['triggering_element']['#ief_row_delta'];
$form_state['rebuild'] = TRUE;
$form_state['inline_entity_form'][$ief_id]['entities'][$delta]['form'] = NULL;
}
function inline_entity_form_close_child_forms($form, &$form_state) {
$element = inline_entity_form_get_element($form, $form_state);
foreach (element_children($element) as $key) {
if (!empty($element[$key])) {
inline_entity_form_close_all_forms($element[$key], $form_state);
}
}
}
function inline_entity_form_close_all_forms($elements, &$form_state) {
foreach (element_children($elements) as $key) {
if (!empty($elements[$key])) {
inline_entity_form_close_all_forms($elements[$key], $form_state);
}
}
if (!empty($elements['#ief_id'])) {
$ief_id = $elements['#ief_id'];
$form_state['inline_entity_form'][$ief_id]['form'] = NULL;
foreach ($form_state['inline_entity_form'][$ief_id]['entities'] as &$value) {
$value['form'] = NULL;
}
}
}
function inline_entity_form_cleanup_row_form_state($form, &$form_state) {
$element = inline_entity_form_get_element($form, $form_state);
$delta = $form_state['triggering_element']['#ief_row_delta'];
$entity_form = $element['entities'][$delta]['form'];
inline_entity_form_cleanup_entity_form_state($entity_form, $form_state);
}
function inline_entity_form_required_field($element, &$form_state, $form) {
$ief_id = $element['#ief_id'];
$has_children = !empty($form_state['inline_entity_form'][$ief_id]['entities']);
$form_open = !empty($form_state['inline_entity_form'][$ief_id]['form']);
if (!$has_children && !$form_open) {
$instance = $form_state['inline_entity_form'][$ief_id]['instance'];
form_error($element, t('!name field is required.', array(
'!name' => $instance['label'],
)));
}
}
function inline_entity_form_field_attach_submit($parent_entity_type, $parent_entity, $form, &$form_state) {
list(, , $bundle_name) = entity_extract_ids($parent_entity_type, $parent_entity);
foreach (field_info_instances($parent_entity_type, $bundle_name) as $instance_name => $instance) {
if (isset($instance['widget']) && strpos($instance['widget']['type'], 'inline_entity_form') === 0) {
$field_name = $instance['field_name'];
if (!isset($form[$field_name])) {
continue;
}
$langcode = $form[$field_name]['#language'];
if (!isset($form[$field_name][$langcode]['#ief_id'])) {
continue;
}
$ief_id = $form[$field_name][$langcode]['#ief_id'];
if (empty($form_state['inline_entity_form'][$ief_id])) {
continue;
}
$values = $form_state['inline_entity_form'][$ief_id];
$entity_type = $values['settings']['entity_type'];
$controller = inline_entity_form_get_controller($instance);
$context = array(
'parent_entity_type' => $parent_entity_type,
'parent_entity' => $parent_entity,
);
if (!empty($values['delete'])) {
$controller
->delete(array_values($values['delete']), $context);
}
uasort($values['entities'], 'drupal_sort_weight');
$entity_ids = array();
$need_reset = FALSE;
foreach ($values['entities'] as $item) {
if ($item['needs_save']) {
$controller
->save($item['entity'], $context);
$need_reset = TRUE;
}
list($entity_id) = entity_extract_ids($entity_type, $item['entity']);
$entity_ids[] = array(
$values['settings']['column'] => $entity_id,
);
}
if (isset($form['#op']) && $form['#op'] == 'add' && $need_reset) {
$form_state['inline_entity_form'][$ief_id]['entities'] = array();
}
if (!empty($entity_ids)) {
$parent_entity->{$field_name}[$langcode] = $entity_ids;
}
}
}
}
function inline_entity_form_cleanup_entity_form_state($entity_form, &$form_state) {
$info = entity_get_info($entity_form['#entity_type']);
if (empty($info['fieldable'])) {
return;
}
list(, , $bundle) = entity_extract_ids($entity_form['#entity_type'], $entity_form['#entity']);
$instances = field_info_instances($entity_form['#entity_type'], $bundle);
foreach ($instances as $instance) {
$field_name = $instance['field_name'];
if (!empty($entity_form[$field_name]['#parents'])) {
$parents = $entity_form[$field_name]['#parents'];
array_pop($parents);
$langcode = $entity_form[$field_name]['#language'];
$field_state = array();
field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state);
}
}
}
function inline_entity_form_get_element($form, $form_state) {
$element = array();
$array_parents = $form_state['triggering_element']['#array_parents'];
$array_parents = array_slice($array_parents, 0, -2);
while (!isset($element['#ief_root'])) {
$element = drupal_array_get_nested_value($form, $array_parents);
array_pop($array_parents);
}
return $element;
}
function inline_entity_form_create_entity($entity_type, $bundle, $language = NULL) {
$entity_info = entity_get_info($entity_type);
$bundle_key = $entity_info['entity keys']['bundle'];
$default_values = array();
if (!empty($bundle_key)) {
$default_values[$bundle_key] = $bundle;
}
if (isset($language) && !empty($entity_info['entity keys']['language'])) {
$language_key = $entity_info['entity keys']['language'];
$default_values[$language_key] = $language;
}
return entity_create($entity_type, $default_values);
}
function theme_inline_entity_form_entity_table($variables) {
$form = $variables['form'];
$entity_type = $form['#entity_type'];
$fields = $form['#table_fields'];
$has_tabledrag = inline_entity_form_has_tabledrag($form);
uasort($fields, 'drupal_sort_weight');
$header = array();
if ($has_tabledrag) {
$header[] = array(
'data' => '',
'class' => array(
'ief-tabledrag-header',
),
);
$header[] = array(
'data' => t('Sort order'),
'class' => array(
'ief-sort-order-header',
),
);
}
$first = TRUE;
foreach ($fields as $field_name => $field) {
$column = array(
'data' => $field['label'],
);
if ($first) {
$column['class'] = array(
'ief-first-column-header',
);
$first = FALSE;
}
$header[] = $column;
}
$header[] = t('Operations');
$rows = array();
foreach (element_children($form) as $key) {
$entity = $form[$key]['#entity'];
list($entity_id) = entity_extract_ids($entity_type, $entity);
if ($form[$key]['#needs_save']) {
_field_invoke_multiple('load', $entity_type, array(
$entity_id => $entity,
));
}
$row_classes = array(
'ief-row-entity',
);
$cells = array();
if ($has_tabledrag) {
$cells[] = array(
'data' => '',
'class' => array(
'ief-tabledrag-handle',
),
);
$cells[] = drupal_render($form[$key]['delta']);
$row_classes[] = 'draggable';
}
if (!empty($form[$key]['form'])) {
$row_classes[] = 'ief-row-entity-form';
}
$wrapper = entity_metadata_wrapper($entity_type, $entity);
foreach ($fields as $field_name => $field) {
$data = '';
if ($field['type'] == 'property') {
$property = $wrapper->{$field_name};
$data = $property
->label() ? $property
->label() : $property
->value();
$data = empty($field['sanitized']) ? check_plain($data) : $data;
}
elseif ($field['type'] == 'field' && isset($entity->{$field_name})) {
$display = array(
'label' => 'hidden',
) + $field;
if (isset($display['formatter'])) {
$display['type'] = $display['formatter'];
unset($display['formatter']);
}
$renderable_data = field_view_field($entity_type, $entity, $field_name, $display);
if (isset($field['delta'])) {
if (!empty($renderable_data[$field['delta']])) {
$renderable_data = $renderable_data[$field['delta']];
}
else {
$renderable_data = array();
}
}
$data = drupal_render($renderable_data);
}
elseif ($field['type'] == 'callback' && isset($field['render_callback']) && is_callable($field['render_callback'])) {
$data = call_user_func($field['render_callback'], $entity_type, $entity);
}
$cells[] = array(
'data' => $data,
'class' => array(
'inline-entity-form-' . $entity_type . '-' . $field_name,
),
);
}
$cells[] = drupal_render($form[$key]['actions']);
$rows[] = array(
'data' => $cells,
'class' => $row_classes,
);
if (!empty($form[$key]['form'])) {
$row = array(
array(
'data' => drupal_render($form[$key]['form']),
'colspan' => count($fields) + 1,
),
);
$rows[] = array(
'data' => $row,
'class' => array(
'ief-row-form',
),
'no_striping' => TRUE,
);
}
}
if (!empty($rows)) {
$id = 'ief-entity-table-' . $form['#id'];
if ($has_tabledrag) {
drupal_add_tabledrag($id, 'order', 'sibling', 'ief-entity-delta');
}
$table_attributes = array(
'id' => $id,
'class' => array(
'ief-entity-table',
),
);
return theme('table', array(
'header' => $header,
'rows' => $rows,
'sticky' => FALSE,
'attributes' => $table_attributes,
));
}
}
function inline_entity_form_has_tabledrag($element) {
$children = element_children($element);
if (count($children) == 1) {
return FALSE;
}
foreach ($children as $key) {
if (!empty($element[$key]['form'])) {
return FALSE;
}
}
return TRUE;
}
function inline_entity_form_field_widget_error($element, $error) {
form_error($element, $error['message']);
}
function inline_entity_form_pre_render_add_fieldset_markup($form) {
$sort = array();
foreach (element_children($form) as $key) {
$element = $form[$key];
if (isset($element['#fieldset']) && isset($form[$element['#fieldset']])) {
$form[$element['#fieldset']][$key] = $element;
unset($form[$key]);
if (!in_array($key, $sort)) {
$sort[] = $element['#fieldset'];
}
}
}
foreach ($sort as $key) {
uasort($form[$key], 'element_sort');
}
return $form;
}