diff --git a/modules/bpc_display/bpc_display.module b/modules/bpc_display/bpc_display.module index 5fcebf4..43cafd4 100644 --- a/modules/bpc_display/bpc_display.module +++ b/modules/bpc_display/bpc_display.module @@ -159,8 +159,251 @@ function bpc_display_form_commerce_bpc_create_bulk_form_alter(&$form, &$form_sta } } + +/** + * Implements hook_field_widget_form_alter(). + * + * @todo + * A lot of this code is copied from the function + * inline_entity_form_field_widget_form in inline_entity_form.module. It would + * be nice if that could be abstracted out into a different helper function so + * we could just call that function here instead. + */ +function bpc_display_field_widget_form_alter(&$element, &$form_state, $context) { + if (isset($_GET['bulk_creation_id']) + && isset($_SESSION['bulk_product_ids'][$_GET['bulk_creation_id']])) { + $entity_ids = $_SESSION['bulk_product_ids'][$_GET['bulk_creation_id']]; + $type = $element['#entity']->type; + $field_name = _bpc_display_get_reference_field($type); + if ($element['#field_name'] == $field_name) { + $ief_id = $element['#ief_id']; + $wrapper = 'inline-entity-form-' . $ief_id; + $instance = $form_state['inline_entity_form'][$ief_id]['instance']; + $controller = inline_entity_form_get_controller($instance); + $settings = $form_state['inline_entity_form'][$ief_id]['settings']; + $cardinality = $form_state['field'][$field_name][LANGUAGE_NONE]['field']['cardinality']; + + // Get the entity type labels for the UI strings. + $labels = $controller->labels(); + + // Build a parents array for this element's values in the form. + $parents = array_merge($element['#field_parents'], array($element['#field_name'], $element['#language'])); + + // Get the langcode of the parent entity. + $parent_langcode = entity_language($element['#entity_type'], $element['#entity']); + + $delta = 0; + $weight_delta = max(ceil(count($entity_ids) * 1.2), 50); + foreach (entity_load($settings['entity_type'], $entity_ids) as $entity_id => $entity) { + $form_state['inline_entity_form'][$ief_id]['entities'][$delta] = $value = array( + 'entity' => $entity, + 'weight' => $delta, + 'form' => NULL, + 'needs_save' => FALSE, + ); + + // Data used by theme_inline_entity_form_entity_table(). + $element['entities'][$delta]['#entity'] = $entity = $value['entity']; + $element['entities'][$delta]['#needs_save'] = $value['needs_save']; + + // Handle row weights. + $element['entities'][$delta]['#weight'] = $value['weight']; + + $row = &$element['entities'][$delta]; + $row['delta'] = array( + '#type' => 'weight', + '#delta' => $weight_delta, + '#default_value' => $value['weight'], + '#attributes' => array('class' => array('ief-entity-delta')), + ); + + // Add an actions container with edit and delete buttons for the entity. + $row['actions'] = array( + '#type' => 'container', + '#attributes' => array('class' => array('ief-entity-operations')), + ); + + // Make sure entity_access is not checked for unsaved entities. + 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-' . $delta, + '#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' => $delta, + '#ief_row_form' => 'edit', + ); + } + + // If 'allow_existing' is on, the default removal operation is unlink + // and the access check for deleting happens inside the controller + // removeForm() method. + 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-' . $delta, + '#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' => $delta, + '#ief_row_form' => 'remove', + ); + } + + $delta++; + } + + if ($cardinality > 1) { + // Add a visual cue of cardinality count. + $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' => '
' . $message . '
', + ); + } + // Do not return the rest of the form if cardinality count has been + // reached. + if ($cardinality > 0 && $entity_count == $cardinality) { + return $element; + } + + // Try to open the add form (if it's the only allowed action, the + // field is required and empty, and there's only one allowed bundle). + if (empty($form_state['inline_entity_form'][$ief_id]['entities'])) { + if (count($settings['create_bundles']) == 1 && $instance['required'] && !$controller->getSetting('allow_existing')) { + $bundle = reset($settings['create_bundles']); + + // The parent entity type and bundle must not be the same as the + // inline entity type and bundle, to prevent recursion. + 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, + ); + } + } + } + + // If no form is open, show buttons that open one. + if (empty($form_state['inline_entity_form'][$ief_id]['form'])) { + $element['actions'] = array( + '#attributes' => array('class' => array('container-inline')), + '#type' => 'container', + '#weight' => 100, + ); + + // The user is allowed to create an entity of at least one bundle. + if (count($settings['create_bundles'])) { + // Let the user select the bundle, if multiple are available. + 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']; + } + } + + $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 { + // There's a form open, show it. + $element['form'] = array( + '#type' => 'fieldset', + '#attributes' => array('class' => array('ief-form', 'ief-form-bottom')), + // Identifies the IEF widget to which the form belongs. + '#ief_id' => $ief_id, + // Used by Field API and controller methods to find the relevant + // values in $form_state. + '#parents' => array_merge($parents, array('form')), + // Pass the current entity type. + '#entity_type' => $settings['entity_type'], + // Pass the langcode of the parent entity, + '#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); + + // Hide the cancel button if the reference field is required but + // contains no values. That way the user is forced to create an + // entity. + if (!$controller->getSetting('allow_existing') && $instance['required'] + && empty($form_state['inline_entity_form'][$ief_id]['entities']) + && count($settings['create_bundles']) == 1) { + $element['form']['actions']['ief_add_cancel']['#access'] = FALSE; + } + } + elseif ($form_state['inline_entity_form'][$ief_id]['form'] == 'ief_add_existing') { + $element['form'] += inline_entity_form_reference_form($controller, $element['form'], $form_state); + } + + // No entities have been added. Remove the outer fieldset to reduce + // visual noise caused by having two titles. + if (empty($form_state['inline_entity_form'][$ief_id]['entities'])) { + $element['#type'] = 'container'; + } + } + } + } +} + /** - * Implements hook_form_BASE_FORM_ID_alter(). + * Implements hook_form_BASE_FORM_ID_alter(). * * Prepopulate product reference fields in the node creation form after * bulk creation. @@ -197,6 +440,7 @@ function bpc_display_form_node_form_alter(&$form, &$form_state, $form_id) { } } } + /** * Determine the node types that can serve as display nodes. *