You are here

field_collection.module in Field collection 8

Same filename and directory in other branches
  1. 8.3 field_collection.module
  2. 7 field_collection.module

Module implementing field collection field type.

File

field_collection.module
View source
<?php

/**
 * @file
 * Module implementing field collection field type.
 */
use Drupal\field\FieldStorageConfigInterface;
use Drupal\field_collection\Entity\FieldCollection;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Url;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Render\Element;

/**
 * Implements hook_help().
 */
function field_collection_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.field_collection':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('The field collection module provides a field, to which any number of fields can be attached. See the <a href="@field-help">Field module help page</a> for more information about fields.', [
        '@field-help' => Url::fromRoute('help.page', [
          'name' => 'field',
        ])
          ->toString(),
      ]) . '</p>';
      return $output;
  }
}

/**
 * Implements hook_ENTITY_TYPE_insert() for field_storage_config.
 *
 * Create a field collection bundle when a new field collection field is made.
 */
function field_collection_field_storage_config_insert(FieldStorageConfigInterface $field) {
  if (Drupal::isConfigSyncing()) {
    return;
  }
  if ($field
    ->getType() == 'field_collection') {
    $field_collection_exists = \Drupal::entityQuery('field_collection')
      ->condition('id', $field
      ->getName())
      ->count()
      ->execute();
    if (!$field_collection_exists) {
      $values = [
        'label' => $field
          ->getName(),
        'id' => $field
          ->getName(),
      ];
      $field_collection = \Drupal::service('entity.manager')
        ->getStorage('field_collection')
        ->create($values);
      $field_collection
        ->enforceIsNew();
      $field_collection
        ->save();
    }

    // TODO: entity_invoke_bundle_hook in post save like in nodeType ?
    // Clear caches.

    //entity_info_cache_clear();

    // Do not directly issue menu rebuilds here to avoid potentially multiple
    // rebuilds. Instead, let menu_get_item() issue the rebuild on the next
    // request.
    //
    // TODO: Figure out whether this is still needed and replace it with the
    // new API if it is.
    // https://drupal.org/node/2183531
    //
    // variable_set('menu_rebuild_needed', TRUE);
  }
}

/**
 * Implements hook_ENTITY_TYPE_delete() for field_storage_config.
 *
 * Delete the field collection bundle when it's corrosponding field no longer
 * exists in any bundle.
 */
function field_collection_field_storage_config_delete(EntityInterface $field) {
  if ($field
    ->getType() == 'field_collection') {

    // If this was called through field API bulk data deletion there may still
    // be a few field collection items from field data that hasn't been purged
    // yet.  Delete them here because Entity::delete() won't work after the
    // bundle is deleted.
    $field_collection_item_ids = \Drupal::entityQuery('field_collection_item')
      ->condition('field_name', $field
      ->getName())
      ->execute();
    $controller = \Drupal::entityTypeManager()
      ->getStorage('field_collection_item');
    $field_collection_items = $controller
      ->loadMultiple($field_collection_item_ids);
    $controller
      ->delete($field_collection_items);

    // Do the bundle delete.
    $field_collection_bundle = FieldCollection::load($field
      ->getName());
    $field_collection_bundle
      ->delete();
  }
}

/**
 * Implements hood_form_FORM_ID_alter() for field_collection_edit_form.
 *
 * Remove the save button since there are no options to save.
 */
function field_collection_form_field_collection_edit_form_alter(&$form, FormStateInterface $form_state) {
  unset($form['actions']);
}
function field_collection_page_attachments(array &$attachments) {
  $s = \Drupal::service('user.permissions');
}

/**
 * Implements hood_form_FORM_ID_alter() for field_ui_field_edit_form.
 *
 * Remove default value from field collection field settings.
 */
function field_collection_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state) {
  if ($form_state
    ->getFormObject()
    ->getEntity()
    ->getType() == 'field_collection') {
    unset($form['default_value']['widget']);
    $url = Url::fromRoute('entity.field_collection.edit_form', [
      'field_collection' => $form_state
        ->getFormObject()
        ->getEntity()
        ->getName(),
    ])
      ->setAbsolute()
      ->toString();
    $form['default_value']['#description'] = t('To specify a default value, configure it via the regular default value setting of each field that is part of the field collection. To do so, go to the <a href=":url/fields">manage fields</a> screen of the field collection.', [
      ':url' => $url,
    ]);
  }
}

/**
 * Sort function for items order.
 *
 * Copied from D7 '_field_sort_items_helper'.
 *
 * TODO: Replace this and references to it with whatever that function was
 * replaced with in Drupal 8.
 */
function _field_collection_sort_items_helper($a, $b) {
  $a_weight = is_array($a) ? $a['_weight'] : 0;
  $b_weight = is_array($b) ? $b['_weight'] : 0;
  return $a_weight - $b_weight;
}

/**
 * Returns whether or not the FieldItemList is full.
 *
 * TODO: Find the standard way to do this and replace calls to it.
 */
function _field_collection_field_item_list_full(FieldItemListInterface $field_list) {
  $cardinality = $field_list
    ->getFieldDefinition()
    ->getFieldStorageDefinition()
    ->getCardinality();
  $total = $field_list
    ->count();
  return $cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && $cardinality <= $total;
}

/**
 * Implements hook_theme to define field_collection templates
 */
function field_collection_theme() {
  return [
    'field_collection_item' => [
      'render element' => 'item',
    ],
  ];
}

/**
 * Implements hook_theme_suggestions_HOOK().
 */
function field_collection_theme_suggestions_field_collection_item(array $variables) {
  $suggestions = [];
  $item = $variables['item']['#field_collection_item'];
  $sanitized_view_mode = strtr($variables['item']['#view_mode'], '.', '_');
  $suggestions[] = 'field_collection_item__' . $sanitized_view_mode;
  $suggestions[] = 'field_collection_item__' . $item
    ->bundle();
  $suggestions[] = 'field_collection_item__' . $item
    ->bundle() . '__' . $sanitized_view_mode;
  $suggestions[] = 'field_collection_item__' . $item
    ->id();
  $suggestions[] = 'field_collection_item__' . $item
    ->id() . '__' . $sanitized_view_mode;
  return $suggestions;
}

/**
 * Prepares variables for field_collection_item templates.
 *
 * Default template: field-collection-item.html.twig.
 *
 * @param array $variables
 * An associative array containing:
 *   - item: An array of information about the field_collection_item to display.
 */
function template_preprocess_field_collection_item(&$variables) {
  $item = $variables['item']['#field_collection_item'];

  // Supply useful metadata for the item.
  $variables['field_collection_item'] = [
    'name' => $item
      ->bundle(),
    'view_mode' => $variables['item']['#view_mode'],
  ];

  // Provide field_collection_item $content variable for the template.
  $variables += [
    'content' => [],
  ];
  foreach (Element::children($variables['item']) as $key) {
    $variables['content'][$key] = $variables['item'][$key];
  }
}

Functions

Namesort descending Description
field_collection_field_storage_config_delete Implements hook_ENTITY_TYPE_delete() for field_storage_config.
field_collection_field_storage_config_insert Implements hook_ENTITY_TYPE_insert() for field_storage_config.
field_collection_form_field_collection_edit_form_alter Implements hood_form_FORM_ID_alter() for field_collection_edit_form.
field_collection_form_field_config_edit_form_alter Implements hood_form_FORM_ID_alter() for field_ui_field_edit_form.
field_collection_help Implements hook_help().
field_collection_page_attachments
field_collection_theme Implements hook_theme to define field_collection templates
field_collection_theme_suggestions_field_collection_item Implements hook_theme_suggestions_HOOK().
template_preprocess_field_collection_item Prepares variables for field_collection_item templates.
_field_collection_field_item_list_full Returns whether or not the FieldItemList is full.
_field_collection_sort_items_helper Sort function for items order.