field_collection.module in Field collection 8
Same filename and directory in other branches
Module implementing field collection field type.
File
field_collection.moduleView 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
Name | 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. |