Update Composer, update everything

This commit is contained in:
Oliver Davies 2018-11-23 12:29:20 +00:00
parent ea3e94409f
commit dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions

View file

@ -0,0 +1,148 @@
<?php
namespace Drupal\{{ machine_name }}\Plugin\Field\FieldFormatter;
{% sort %}
{% if datetime %}
use Drupal\Core\Datetime\DrupalDateTime;
{% endif %}
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
{% if formatter_settings %}
use Drupal\Core\Form\FormStateInterface;
{% endif %}
{% if link %}
use Drupal\Core\Url;
{% endif %}
{% if list %}
use Drupal\{{ machine_name }}\Plugin\Field\FieldType\{{ type_class }};
{% endif %}
{% endsort %}
/**
* Plugin implementation of the '{{ field_id }}_default' formatter.
*
* @FieldFormatter(
* id = "{{ field_id }}_default",
* label = @Translation("Default"),
* field_types = {"{{ field_id }}"}
* )
*/
class {{ formatter_class }} extends FormatterBase {
{% if formatter_settings %}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return ['foo' => 'bar'] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$settings = $this->getSettings();
$element['foo'] = [
'#type' => 'textfield',
'#title' => $this->t('Foo'),
'#default_value' => $settings['foo'],
];
return $element;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$settings = $this->getSettings();
$summary[] = $this->t('Foo: @foo', ['@foo' => $settings['foo']]);
return $summary;
}
{% endif %}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$element = [];
foreach ($items as $delta => $item) {
{% for subfield in subfields %}
{% if subfield.type == 'boolean' %}
$element[$delta]['{{ subfield.machine_name }}'] = [
'#type' => 'item',
'#title' => $this->t('{{ subfield.name }}'),
'#markup' => $item->{{ subfield.machine_name }} ? $this->t('Yes') : $this->t('No'),
];
{% else %}
if ($item->{{ subfield.machine_name }}) {
{% if subfield.list %}
$allowed_values = {{ type_class }}::{{ subfield.allowed_values_method }}();
{% endif %}
{% set item_value %}
{% if subfield.list %}$allowed_values[$item->{{ subfield.machine_name }}]{% else %}$item->{{ subfield.machine_name }}{% endif %}
{% endset %}
{% if subfield.type == 'datetime' %}
$date = DrupalDateTime::createFromFormat('{{ subfield.date_storage_format }}', $item->{{ subfield.machine_name }});
// @DCG: Consider injecting the date formatter service.
// @codingStandardsIgnoreStart
$date_formatter = \Drupal::service('date.formatter');
// @codingStandardsIgnoreStart
$timestamp = $date->getTimestamp();
{% if subfield.list %}
$formatted_date = {{ item_value }};
{% else %}
$formatted_date = $date_formatter->format($timestamp, 'long');
{% endif %}
$iso_date = $date_formatter->format($timestamp, 'custom', 'Y-m-d\TH:i:s') . 'Z';
$element[$delta]['{{ subfield.machine_name }}'] = [
'#type' => 'item',
'#title' => $this->t('{{ subfield.name }}'),
'content' => [
'#theme' => 'time',
'#text' => $formatted_date,
'#html' => FALSE,
'#attributes' => [
'datetime' => $iso_date,
],
'#cache' => [
'contexts' => [
'timezone',
],
],
],
];
{% else %}
$element[$delta]['{{ subfield.machine_name }}'] = [
'#type' => 'item',
'#title' => $this->t('{{ subfield.name }}'),
{% if subfield.link %}
'content' => [
'#type' => 'link',
'#title' => {{ item_value }},
{% if subfield.type == 'email' %}
'#url' => Url::fromUri('mailto:' . $item->{{ subfield.machine_name }}),
{% elseif subfield.type == 'telephone' %}
'#url' => Url::fromUri('tel:' . rawurlencode(preg_replace('/\s+/', '', $item->{{ subfield.machine_name }}))),
{% elseif subfield.type == 'uri' %}
'#url' => Url::fromUri($item->{{ subfield.machine_name }}),
{% endif %}
],
{% else %}
'#markup' => {{ item_value }},
{% endif %}
];
{% endif %}
}
{% endif %}
{% endfor %}
}
return $element;
}
}

View file

@ -0,0 +1,105 @@
<?php
namespace Drupal\{{ machine_name }}\Plugin\Field\FieldFormatter;
{% sort %}
{% if datetime %}
use Drupal\Core\Datetime\DrupalDateTime;
{% endif %}
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
{% if list %}
use Drupal\{{ machine_name }}\Plugin\Field\FieldType\{{ type_class }};
{% endif %}
{% endsort %}
/**
* Plugin implementation of the '{{ field_id }}_key_value' formatter.
*
* @FieldFormatter(
* id = "{{ field_id }}_key_value",
* label = @Translation("Key-value"),
* field_types = {"{{ field_id }}"}
* )
*/
class {{ key_value_formatter_class }} extends FormatterBase {
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$element = [];
foreach ($items as $delta => $item) {
$table = [
'#type' => 'table',
];
{% for subfield in subfields %}
// {{ subfield.name }}.
if ($item->{{ subfield.machine_name }}) {
{% if subfield.type == 'datetime' %}
$date = DrupalDateTime::createFromFormat('{{ subfield.date_storage_format }}', $item->{{ subfield.machine_name }});
$date_formatter = \Drupal::service('date.formatter');
$timestamp = $date->getTimestamp();
{% if subfield.list %}
$allowed_values = {{ type_class }}::{{ subfield.allowed_values_method }}();
$formatted_date = $allowed_values[$item->{{ subfield.machine_name }}];
{% else %}
$formatted_date = $date_formatter->format($timestamp, 'long');
{% endif %}
$iso_date = $date_formatter->format($timestamp, 'custom', 'Y-m-d\TH:i:s') . 'Z';
{% elseif subfield.list %}
$allowed_values = {{ type_class }}::{{ subfield.allowed_values_method }}();
{% endif %}
$table['#rows'][] = [
'data' => [
[
'header' => TRUE,
'data' => [
'#markup' => $this->t('{{ subfield.name }}'),
],
],
[
'data' => [
{% if subfield.type == 'boolean' %}
'#markup' => $item->{{ subfield.machine_name }} ? $this->t('Yes') : $this->t('No'),
{% elseif subfield.type == 'datetime' %}
'#theme' => 'time',
'#text' => $formatted_date,
'#html' => FALSE,
'#attributes' => [
'datetime' => $iso_date,
],
'#cache' => [
'contexts' => [
'timezone',
],
],
{% else %}
{% if subfield.list %}
'#markup' => $allowed_values[$item->{{ subfield.machine_name }}],
{% else %}
'#markup' => $item->{{ subfield.machine_name }},
{% endif %}
{% endif %}
],
],
],
'no_striping' => TRUE,
];
}
{% endfor %}
$element[$delta] = $table;
}
return $element;
}
}

View file

@ -0,0 +1,4 @@
{{ field_id }}:
css:
component:
css/{{ field_id|u2h }}-widget.css: {}

View file

@ -0,0 +1,50 @@
{% if storage_settings %}
# Field storage.
field.storage_settings.{{ field_id }}:
type: mapping
label: Example storage settings
mapping:
foo:
type: string
label: Foo
{% endif %}
{% if instance_settings %}
# Field instance.
field.field_settings.{{ field_id }}:
type: mapping
label: Example field settings
mapping:
bar:
type: string
label: Bar
{% endif %}
# Default value.
field.value.{{ field_id }}:
type: mapping
label: Default value
mapping:
{% for subfield in subfields %}
{{ subfield.machine_name }}:
type: {{ subfield.type }}
label: {{ subfield.name }}
{% endfor %}
{% if widget_settings %}
# Field widget.
field.widget.settings.{{ field_id }}:
type: mapping
label: Example widget settings
mapping:
foo:
type: string
label: Foo
{% endif %}
{% if formatter_settings %}
# Field formatter.
field.formatter.settings.{{ field_id }}_default:
type: mapping
label: Example formatter settings
mapping:
foo:
type: string
label: Foo
{% endif %}

View file

@ -0,0 +1,102 @@
<?php
namespace Drupal\{{ machine_name }}\Plugin\Field\FieldFormatter;
{% sort %}
{% if datetime %}
use Drupal\Core\Datetime\DrupalDateTime;
{% endif %}
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
{% if list %}
use Drupal\{{ machine_name }}\Plugin\Field\FieldType\{{ type_class }};
{% endif %}
{% endsort %}
/**
* Plugin implementation of the '{{ field_id }}_table' formatter.
*
* @FieldFormatter(
* id = "{{ field_id }}_table",
* label = @Translation("Table"),
* field_types = {"{{ field_id }}"}
* )
*/
class {{ table_formatter_class }} extends FormatterBase {
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$header[] = '#';
{% for subfield in subfields %}
$header[] = $this->t('{{ subfield.name }}');
{% endfor %}
$table = [
'#type' => 'table',
'#header' => $header,
];
foreach ($items as $delta => $item) {
$row = [];
$row[]['#markup'] = $delta + 1;
{% for subfield in subfields %}
{% if subfield.type == 'boolean' %}
$row[]['#markup'] = $item->{{ subfield.machine_name }} ? $this->t('Yes') : $this->t('No');
{% elseif subfield.type == 'datetime' %}
if ($item->{{ subfield.machine_name }}) {
$date = DrupalDateTime::createFromFormat('{{ subfield.date_storage_format }}', $item->{{ subfield.machine_name }});
$date_formatter = \Drupal::service('date.formatter');
$timestamp = $date->getTimestamp();
{% if subfield.list %}
$allowed_values = {{ type_class }}::{{ subfield.allowed_values_method }}();
$formatted_date = $allowed_values[$item->{{ subfield.machine_name }}];
{% else %}
$formatted_date = $date_formatter->format($timestamp, 'long');
{% endif %}
$iso_date = $date_formatter->format($timestamp, 'custom', 'Y-m-d\TH:i:s') . 'Z';
$row[] = [
'#theme' => 'time',
'#text' => $formatted_date,
'#html' => FALSE,
'#attributes' => [
'datetime' => $iso_date,
],
'#cache' => [
'contexts' => [
'timezone',
],
],
];
}
else {
$row[]['#markup'] = '';
}
{% else %}
{% if subfield.list %}
if ($item->{{ subfield.machine_name }}) {
$allowed_values = {{ type_class }}::{{ subfield.allowed_values_method }}();
$row[]['#markup'] = $allowed_values[$item->{{ subfield.machine_name }}];
}
else {
$row[]['#markup'] = '';
}
{% else %}
$row[]['#markup'] = $item->{{ subfield.machine_name }};
{% endif %}
{% endif %}
{% endfor %}
$table[$delta] = $row;
}
return [$table];
}
}

View file

@ -0,0 +1,316 @@
<?php
namespace Drupal\{{ machine_name }}\Plugin\Field\FieldType;
{% if random %}
use Drupal\Component\Utility\Random;
{% endif %}
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
{% if storage_settings or instance_settings %}
use Drupal\Core\Form\FormStateInterface;
{% endif %}
{% if email %}
use Drupal\Core\Render\Element\Email;
{% endif %}
use Drupal\Core\TypedData\DataDefinition;
/**
* Defines the '{{ field_id }}' field type.
*
* @FieldType(
* id = "{{ field_id }}",
* label = @Translation("{{ field_label }}"),
* category = @Translation("General"),
* default_widget = "{{ field_id }}",
* default_formatter = "{{ field_id }}_default"
* )
*/
class {{ type_class }} extends FieldItemBase {
{% if storage_settings %}
/**
* {@inheritdoc}
*/
public static function defaultStorageSettings() {
$settings = ['foo' => 'example'];
return $settings + parent::defaultStorageSettings();
}
/**
* {@inheritdoc}
*/
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
$settings = $this->getSettings();
$element['foo'] = [
'#type' => 'textfield',
'#title' => $this->t('Foo'),
'#default_value' => $settings['foo'],
'#disabled' => $has_data,
];
return $element;
}
{% endif %}
{% if instance_settings %}
/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
$settings = ['bar' => 'example'];
return $settings + parent::defaultFieldSettings();
}
/**
* {@inheritdoc}
*/
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$settings = $this->getSettings();
$element['bar'] = [
'#type' => 'textfield',
'#title' => $this->t('Foo'),
'#default_value' => $settings['bar'],
];
return $element;
}
{% endif %}
/**
* {@inheritdoc}
*/
public function isEmpty() {
{% for subfield in subfields %}
{% set condition %}
{% if subfield.type == 'boolean' %}$this->{{ subfield.machine_name }} == 1{% else %}$this->{{ subfield.machine_name }} !== NULL{% endif %}
{% endset %}
{% if loop.index == 1 %}
if ({{ condition }}) {
{% else %}
elseif ({{ condition }}) {
{% endif %}
return FALSE;
}
{% endfor %}
return TRUE;
}
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
{% for subfield in subfields %}
$properties['{{ subfield.machine_name }}'] = DataDefinition::create('{{ subfield.data_type }}')
->setLabel(t('{{ subfield.name }}'));
{% endfor %}
return $properties;
}
/**
* {@inheritdoc}
*/
public function getConstraints() {
$constraints = parent::getConstraints();
{% for subfield in subfields %}
{% if subfield.list %}
$options['{{ subfield.machine_name }}']['AllowedValues'] = array_keys({{ type_class }}::{{ subfield.allowed_values_method }}());
{% endif %}
{% if subfield.required %}
{% if subfield.type == 'boolean' %}
// NotBlank validator is not suitable for booleans because it does not
// recognize '0' as an empty value.
$options['{{ subfield.machine_name }}']['AllowedValues']['choices'] = [1];
$options['{{ subfield.machine_name }}']['AllowedValues']['message'] = $this->t('This value should not be blank.');
{% else %}
$options['{{ subfield.machine_name }}']['NotBlank'] = [];
{% if subfield.type == 'email' %}
$options['{{ subfield.machine_name }}']['Length']['max'] = Email::EMAIL_MAX_LENGTH;
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% if list or required %}
$constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
$constraints[] = $constraint_manager->create('ComplexData', $options);
{% endif %}
// @todo Add more constrains here.
return $constraints;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
$columns = [
{% for subfield in subfields %}
'{{ subfield.machine_name }}' => [
{% if subfield.type == 'boolean' %}
'type' => 'int',
'size' => 'tiny',
{% elseif subfield.type == 'string' %}
'type' => 'varchar',
'length' => 255,
{% elseif subfield.type == 'text' %}
'type' => 'text',
'size' => 'big',
{% elseif subfield.type == 'integer' %}
'type' => 'int',
'size' => 'normal',
{% elseif subfield.type == 'float' %}
'type' => 'float',
'size' => 'normal',
{% elseif subfield.type == 'numeric' %}
'type' => 'numeric',
'precision' => 10,
'scale' => 2,
{% elseif subfield.type == 'email' %}
'type' => 'varchar',
'length' => Email::EMAIL_MAX_LENGTH,
{% elseif subfield.type == 'telephone' %}
'type' => 'varchar',
'length' => 255,
{% elseif subfield.type == 'uri' %}
'type' => 'varchar',
'length' => 2048,
{% elseif subfield.type == 'datetime' %}
'type' => 'varchar',
'length' => 20,
{% endif %}
],
{% endfor %}
];
$schema = [
'columns' => $columns,
// @DCG Add indexes here if necessary.
];
return $schema;
}
/**
* {@inheritdoc}
*/
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
{% if random %}
$random = new Random();
{% endif %}
{% for subfield in subfields %}
{% if subfield.list %}
$values['{{ subfield.machine_name }}'] = array_rand(self::{{ subfield.allowed_values_method }}());
{% elseif subfield.type == 'boolean' %}
$values['{{ subfield.machine_name }}'] = (bool) mt_rand(0, 1);
{% elseif subfield.type == 'string' %}
$values['{{ subfield.machine_name }}'] = $random->word(mt_rand(1, 255));
{% elseif subfield.type == 'text' %}
$values['{{ subfield.machine_name }}'] = $random->paragraphs(5);
{% elseif subfield.type == 'integer' %}
$values['{{ subfield.machine_name }}'] = mt_rand(-1000, 1000);
{% elseif subfield.type == 'float' %}
$scale = rand(1, 5);
$random_decimal = mt_rand() / mt_getrandmax() * (1000 - 0);
$values['{{ subfield.machine_name }}'] = floor($random_decimal * pow(10, $scale)) / pow(10, $scale);
{% elseif subfield.type == 'numeric' %}
$scale = rand(10, 2);
$random_decimal = -1000 + mt_rand() / mt_getrandmax() * (-1000 - 1000);
$values['{{ subfield.machine_name }}'] = floor($random_decimal * pow(10, $scale)) / pow(10, $scale);
{% elseif subfield.type == 'email' %}
$values['{{ subfield.machine_name }}'] = strtolower($random->name()) . '@example.com';
{% elseif subfield.type == 'telephone' %}
$values['{{ subfield.machine_name }}'] = mt_rand(pow(10, 8), pow(10, 9) - 1);
{% elseif subfield.type == 'uri' %}
$tlds = ['com', 'net', 'gov', 'org', 'edu', 'biz', 'info'];
$domain_length = mt_rand(7, 15);
$protocol = mt_rand(0, 1) ? 'https' : 'http';
$www = mt_rand(0, 1) ? 'www' : '';
$domain = $random->word($domain_length);
$tld = $tlds[mt_rand(0, (count($tlds) - 1))];
$values['{{ subfield.machine_name }}'] = "$protocol://$www.$domain.$tld";
{% elseif subfield.type == 'datetime' %}
$timestamp = \Drupal::time()->getRequestTime() - mt_rand(0, 86400 * 365);
$values['{{ subfield.machine_name }}'] = gmdate('{{ subfield.date_storage_format }}', $timestamp);
{% endif %}
{% endfor %}
return $values;
}
{% for subfield in subfields %}
{% if subfield.list %}
/**
* Returns allowed values for '{{ subfield.machine_name }}' sub-field.
*
* @return array
* The list of allowed values.
*/
public static function {{ subfield.allowed_values_method }}() {
return [
{% if subfield.type == 'string' %}
'alpha' => t('Alpha'),
'beta' => t('Beta'),
'gamma' => t('Gamma'),
{% elseif subfield.type == 'integer' %}
123 => 123,
456 => 456,
789 => 789,
{% elseif subfield.type == 'float' %}
'12.3' => '12.3',
'4.56' => '4.56',
'0.789' => '0.789',
{% elseif subfield.type == 'numeric' %}
'12.35' => '12.35',
'45.65' => '45.65',
'78.95' => '78.95',
{% elseif subfield.type == 'email' %}
'alpha@example.com' => 'alpha@example.com',
'beta@example.com' => 'beta@example.com',
'gamma@example.com' => 'gamma@example.com',
{% elseif subfield.type == 'telephone' %}
'71234567001' => '+7(123)45-67-001',
'71234567002' => '+7(123)45-67-002',
'71234567003' => '+7(123)45-67-003',
{% elseif subfield.type == 'uri' %}
'https://example.com' => 'https://example.com',
'http://www.php.net' => 'http://www.php.net',
'https://www.drupal.org' => 'https://www.drupal.org',
{% elseif subfield.type == 'datetime' %}
{% if subfield.date_type == 'date' %}
'2018-01-01' => '1 January 2018',
'2018-02-01' => '1 February 2018',
'2018-03-01' => '1 March 2018',
{% else %}
'2018-01-01T00:10:10' => '1 January 2018, 00:10:10',
'2018-02-01T00:20:20' => '1 February 2018, 00:20:20',
'2018-03-01T00:30:30' => '1 March 2018, 00:30:30',
{% endif %}
{% endif %}
];
}
{% endif %}
{% endfor %}
}

View file

@ -0,0 +1,13 @@
{% set class = field_id|u2h ~ '-elements' %}
{% if inline %}
.container-inline.{{ class }} .form-item {
margin: 0 3px;
}
.container-inline.{{ class }} label {
display: block;
}
{% else %}
tr.odd .{{ class }} .form-item {
margin-bottom: 8px;
}
{% endif %}

View file

@ -0,0 +1,202 @@
<?php
namespace Drupal\{{ machine_name }}\Plugin\Field\FieldWidget;
{% sort %}
{% if datetime %}
use Drupal\Core\Datetime\DrupalDateTime;
{% endif %}
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
{% if list %}
use Drupal\{{ machine_name }}\Plugin\Field\FieldType\{{ type_class }};
{% endif %}
{% endsort %}
/**
* Defines the '{{ field_id }}' field widget.
*
* @FieldWidget(
* id = "{{ field_id }}",
* label = @Translation("{{ field_label }}"),
* field_types = {"{{ field_id }}"},
* )
*/
class {{ widget_class }} extends WidgetBase {
{% if widget_settings %}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return ['foo' => 'bar'] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$settings = $this->getSettings();
$element['foo'] = [
'#type' => 'textfield',
'#title' => $this->t('Foo'),
'#default_value' => $settings['foo'],
];
return $element;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$settings = $this->getSettings();
$summary[] = $this->t('Foo: @foo', ['@foo' => $settings['foo']]);
return $summary;
}
{% endif %}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
{% for subfield in subfields %}
{% set title %}'#title' => $this->t('{{ subfield.name }}'),{% endset %}
{% set default_value %}'#default_value' => isset($items[$delta]->{{ subfield.machine_name }}) ? $items[$delta]->{{ subfield.machine_name }} : NULL,{% endset %}
{% set size %}'#size' => 20,{% endset %}
{% if subfield.list %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'select',
{{ title }}
'#options' => ['' => $this->t('- {{ subfield.required ? 'Select a value' : 'None' }} -')] + {{ type_class }}::{{ subfield.allowed_values_method }}(),
{{ default_value }}
];
{% else %}
{% if subfield.type == 'boolean' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'checkbox',
{{ title }}
{{ default_value }}
];
{% elseif subfield.type == 'string' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'textfield',
{{ title }}
{{ default_value }}
{% if inline %}
{{ size }}
{% endif %}
];
{% elseif subfield.type == 'text' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'textarea',
{{ title }}
{{ default_value }}
];
{% elseif subfield.type == 'integer' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'number',
{{ title }}
{{ default_value }}
];
{% elseif subfield.type == 'float' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'number',
{{ title }}
{{ default_value }}
'#step' => 0.001,
];
{% elseif subfield.type == 'numeric' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'number',
{{ title }}
{{ default_value }}
'#step' => 0.01,
];
{% elseif subfield.type == 'email' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'email',
{{ title }}
{{ default_value }}
{% if inline %}
{{ size }}
{% endif %}
];
{% elseif subfield.type == 'telephone' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'tel',
{{ title }}
{{ default_value }}
{% if inline %}
{{ size }}
{% endif %}
];
{% elseif subfield.type == 'uri' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'url',
{{ title }}
{{ default_value }}
{% if inline %}
{{ size }}
{% endif %}
];
{% elseif subfield.type == 'datetime' %}
$element['{{ subfield.machine_name }}'] = [
'#type' => 'datetime',
{{ title }}
'#default_value' => NULL,
{% if subfield.date_type == 'date' %}
'#date_time_element' => 'none',
'#date_time_format' => '',
{% endif %}
];
if (isset($items[$delta]->{{ subfield.machine_name }})) {
$element['{{ subfield.machine_name }}']['#default_value'] = DrupalDateTime::createFromFormat(
'{{ subfield.date_storage_format }}',
$items[$delta]->{{ subfield.machine_name }},
'UTC'
);
}
{% endif %}
{% endif %}
{% endfor %}
$element['#theme_wrappers'] = ['container', 'form_element'];
{% if inline %}
$element['#attributes']['class'][] = 'container-inline';
{% endif %}
$element['#attributes']['class'][] = '{{ field_id|u2h }}-elements';
$element['#attached']['library'][] = '{{ machine_name }}/{{ field_id }}';
return $element;
}
/**
* {@inheritdoc}
*/
public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
return isset($violation->arrayPropertyPath[0]) ? $element[$violation->arrayPropertyPath[0]] : $element;
}
/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
foreach ($values as $delta => $value) {
{% for subfield in subfields %}
if ($value['{{ subfield.machine_name }}'] === '') {
$values[$delta]['{{ subfield.machine_name }}'] = NULL;
}
{% if subfield.type == 'datetime' %}
if ($value['{{ subfield.machine_name }}'] instanceof DrupalDateTime) {
$values[$delta]['{{ subfield.machine_name }}'] = $value['{{ subfield.machine_name }}']->format('{{ subfield.date_storage_format }}');
}
{% endif %}
{% endfor %}
}
return $values;
}
}

View file

@ -0,0 +1,18 @@
/**
* @file
* Custom behaviors for {{ layout_name|lower }} layout.
*/
(function (Drupal) {
'use strict';
Drupal.behaviors.{{ layout_machine_name|camelize(false) }} = {
attach: function (context, settings) {
console.log('It works!');
}
};
} (Drupal));

View file

@ -0,0 +1,16 @@
{{ machine_name }}_{{ layout_machine_name }}:
label: '{{ layout_name }}'
category: '{{ category }}'
path: layouts/{{ layout_machine_name }}
template: {{ layout_machine_name|u2h }}
{% if js or css %}
library: {{ machine_name }}/{{ layout_machine_name }}
{% endif %}
regions:
main:
label: Main content
sidebar:
label: Sidebar
default_region: main
icon_map:
- [main, main, sidebar]

View file

@ -0,0 +1,10 @@
{{ layout_machine_name }}:
{% if js %}
js:
layouts/{{ layout_machine_name }}/{{ layout_machine_name|u2h }}.js: {}
{% endif %}
{% if css %}
css:
component:
layouts/{{ layout_machine_name }}/{{ layout_machine_name|u2h }}.css: {}
{% endif %}

View file

@ -0,0 +1,28 @@
.layout--{{ layout_machine_name|u2h }} {
outline: solid 1px orange;
display: flex;
padding: 10px;
}
.layout--{{ layout_machine_name|u2h }} > .layout__region {
outline: solid 1px orange;
margin: 10px;
padding: 20px;
}
.layout--{{ layout_machine_name|u2h }} .layout__region--main {
width: 66%;
}
.layout--{{ layout_machine_name|u2h }} .layout__region--sidebar {
width: 33%;
}
@media all and (max-width: 850px) {
.layout--{{ layout_machine_name|u2h }} {
flex-direction: column;
}
.layout--{{ layout_machine_name|u2h }} > .layout__region {
width: auto;
}
}

View file

@ -0,0 +1,37 @@
{{ '{' }}#
/**
* @file
* Default theme implementation to display {{ layout_name|lower }} layout.
*
* Available variables:
* - content: The content for this layout.
* - attributes: HTML attributes for the layout wrapper.
*
* @ingroup themeable
*/
#{{ '}' }}
{{ '{' }}%
set classes = [
'layout',
'layout--{{ layout_machine_name|u2h }}',
]
%{{ '}' }}
{% verbatim %}
{% if content %}
<div{{ attributes.addClass(classes) }}>
{% if content.main %}
<div {{ region_attributes.main.addClass('layout__region', 'layout__region--main') }}>
{{ content.main }}
</div>
{% endif %}
{% if content.sidebar %}
<div {{ region_attributes.sidebar.addClass('layout__region', 'layout__region--sidebar') }}>
{{ content.sidebar }}
</div>
{% endif %}
</div>
{% endif %}
{% endverbatim %}

View file

@ -0,0 +1,26 @@
{
"name": "drupal/{{ machine_name }}",
"type": "{{ type }}",
"description": "{{ description }}",
"keywords": ["Drupal"]{{ drupal_org ? ',' }}
{% if (drupal_org) %}
"license": "GPL-2.0+",
"homepage": "https://www.drupal.org/project/{{ machine_name }}",
"authors": [
{
"name": "Your name here",
"homepage": "https://www.drupal.org/u/your_name_here",
"role": "Maintainer"
},
{
"name": "Contributors",
"homepage": "https://www.drupal.org/node/NID/committers",
"role": "Contributors"
}
],
"support": {
"issues": "https://www.drupal.org/project/issues/{{ machine_name }}",
"source": "http://cgit.drupalcode.org/{{ machine_name }}"
}
{% endif %}
}

View file

@ -0,0 +1,7 @@
{{ route_name }}:
path: '{{ route_path }}'
defaults:
_title: '{{ route_title }}'
_controller: '\Drupal\{{ machine_name }}\Controller\{{ class }}::build'
requirements:
_permission: '{{ route_permission }}'

View file

@ -0,0 +1,54 @@
{% import 'lib/di.twig' as di %}
<?php
namespace Drupal\{{ machine_name }}\Controller;
{% sort %}
use Drupal\Core\Controller\ControllerBase;
{% if services %}
use Symfony\Component\DependencyInjection\ContainerInterface;
{{ di.use(services) }}
{% endif %}
{% endsort %}
/**
* Returns responses for {{ name }} routes.
*/
class {{ class }} extends ControllerBase {
{% if services %}
{{ di.properties(services) }}
/**
* The controller constructor.
*
{{ di.annotation(services) }}
*/
public function __construct({{ di.signature(services) }}) {
{{ di.assignment(services) }}
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
{{ di.container(services) }}
);
}
{% endif %}
/**
* Builds the response.
*/
public function build() {
$build['content'] = [
'#type' => 'item',
'#markup' => $this->t('It works!'),
];
return $build;
}
}

View file

@ -0,0 +1,6 @@
<?php
/**
* @file
* Install, update and uninstall functions for the {{ name }} module.
*/

View file

@ -0,0 +1,6 @@
<?php
/**
* @file
* Primary module hooks for {{ name }} module.
*/

View file

@ -0,0 +1,6 @@
<?php
/**
* @file
* Post update functions for the {{ name }} module.
*/

View file

@ -0,0 +1,6 @@
<?php
/**
* @file
* Builds tokens for the {{ name }} module.
*/

View file

@ -0,0 +1,6 @@
<?php
/**
* @file
* Views hooks for the {{ name }} module.
*/

View file

@ -0,0 +1,59 @@
<?php
namespace Drupal\{{ machine_name }}\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Configure {{ name }} settings for this site.
*/
class {{ class }} extends ConfigFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return '{{ form_id }}';
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return ['{{ machine_name }}.settings'];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['example'] = [
'#type' => 'textfield',
'#title' => $this->t('Example'),
'#default_value' => $this->config('{{ machine_name }}.settings')->get('example'),
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
if ($form_state->getValue('example') != 'example') {
$form_state->setErrorByName('example', $this->t('The value is not correct.'));
}
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('{{ machine_name }}.settings')
->set('example', $form_state->getValue('example'))
->save();
parent::submitForm($form, $form_state);
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace Drupal\{{ machine_name }}\Form;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
/**
* Provides a confirmation form before clearing out the examples.
*/
class {{ class }} extends ConfirmFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return '{{ form_id }}';
}
/**
* {@inheritdoc}
*/
public function getQuestion() {
return $this->t('Are you sure you want to do this?');
}
/**
* {@inheritdoc}
*/
public function getCancelUrl() {
return new Url('system.admin_config');
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// @DCG Place your code here.
$this->messenger()->addStatus($this->t('Done!'));
$form_state->setRedirectUrl($this->getCancelUrl());
}
}

View file

@ -0,0 +1,7 @@
{{ route_name }}:
path: '{{ route_path }}'
defaults:
_title: '{{ route_title }}'
_form: 'Drupal\{{ machine_name }}\Form\{{ class }}'
requirements:
_permission: '{{ route_permission }}'

View file

@ -0,0 +1,59 @@
<?php
namespace Drupal\{{ machine_name }}\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Provides a {{ name }} form.
*/
class {{ class }} extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return '{{ form_id }}';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['message'] = [
'#type' => 'textarea',
'#title' => $this->t('Message'),
'#required' => TRUE,
];
$form['actions'] = [
'#type' => 'actions',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Send'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
if (mb_strlen($form_state->getValue('message')) < 10) {
$form_state->setErrorByName('name', $this->t('Message should be at least 10 characters.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->messenger()->addStatus($this->t('The message has been sent.'));
$form_state->setRedirect('<front>');
}
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_ENTITY_TYPE_access().
*/
function {{ machine_name }}_ENTITY_TYPE_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
// No opinion.
return AccessResult::neutral();
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_ENTITY_TYPE_build_defaults_alter().
*/
function {{ machine_name }}_ENTITY_TYPE_build_defaults_alter(array &$build, \Drupal\Core\Entity\EntityInterface $entity, $view_mode) {
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_ENTITY_TYPE_create().
*/
function {{ machine_name }}_ENTITY_TYPE_create(\Drupal\Core\Entity\EntityInterface $entity) {
\Drupal::logger('example')->info('ENTITY_TYPE created: @label', ['@label' => $entity->label()]);
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_ENTITY_TYPE_create_access().
*/
function {{ machine_name }}_ENTITY_TYPE_create_access(\Drupal\Core\Session\AccountInterface $account, array $context, $entity_bundle) {
// No opinion.
return AccessResult::neutral();
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_ENTITY_TYPE_delete().
*/
function {{ machine_name }}_ENTITY_TYPE_delete(Drupal\Core\Entity\EntityInterface $entity) {
// Delete the entity's entry from a fictional table of all entities.
\Drupal::database()->delete('example_entity')
->condition('type', $entity->getEntityTypeId())
->condition('id', $entity->id())
->execute();
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_ENTITY_TYPE_field_values_init().
*/
function {{ machine_name }}_ENTITY_TYPE_field_values_init(\Drupal\Core\Entity\FieldableEntityInterface $entity) {
if (!$entity->foo->value) {
$entity->foo->value = 'some_initial_value';
}
}

View file

@ -0,0 +1,13 @@
/**
* Implements hook_ENTITY_TYPE_insert().
*/
function {{ machine_name }}_ENTITY_TYPE_insert(Drupal\Core\Entity\EntityInterface $entity) {
// Insert the new entity into a fictional table of this type of entity.
\Drupal::database()->insert('example_entity')
->fields([
'id' => $entity->id(),
'created' => REQUEST_TIME,
'updated' => REQUEST_TIME,
])
->execute();
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_ENTITY_TYPE_load().
*/
function {{ machine_name }}_ENTITY_TYPE_load($entities) {
foreach ($entities as $entity) {
$entity->foo = mymodule_add_something($entity);
}
}

View file

@ -0,0 +1,22 @@
/**
* Implements hook_ENTITY_TYPE_predelete().
*/
function {{ machine_name }}_ENTITY_TYPE_predelete(Drupal\Core\Entity\EntityInterface $entity) {
$connection = \Drupal::database();
// Count references to this entity in a custom table before they are removed
// upon entity deletion.
$id = $entity->id();
$type = $entity->getEntityTypeId();
$count = \Drupal::database()->select('example_entity_data')
->condition('type', $type)
->condition('id', $id)
->countQuery()
->execute()
->fetchField();
// Log the count in a table that records this statistic for deleted entities.
$connection->merge('example_deleted_entity_statistics')
->key(['type' => $type, 'id' => $id])
->fields(['count' => $count])
->execute();
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_ENTITY_TYPE_prepare_form().
*/
function {{ machine_name }}_ENTITY_TYPE_prepare_form(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Form\FormStateInterface $form_state) {
if ($operation == 'edit') {
$entity->label->value = 'Altered label';
$form_state->set('label_altered', TRUE);
}
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_ENTITY_TYPE_presave().
*/
function {{ machine_name }}_ENTITY_TYPE_presave(Drupal\Core\Entity\EntityInterface $entity) {
if ($entity->isTranslatable()) {
$route_match = \Drupal::routeMatch();
\Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->getId(), $route_match->getParameter('source_langcode'));
}
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_ENTITY_TYPE_revision_create().
*/
function {{ machine_name }}_ENTITY_TYPE_revision_create(Drupal\Core\Entity\EntityInterface $new_revision, Drupal\Core\Entity\EntityInterface $entity, $keep_untranslatable_fields) {
// Retain the value from an untranslatable field, which are by default
// synchronized from the default revision.
$new_revision->set('untranslatable_field', $entity->get('untranslatable_field'));
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_ENTITY_TYPE_revision_delete().
*/
function {{ machine_name }}_ENTITY_TYPE_revision_delete(Drupal\Core\Entity\EntityInterface $entity) {
$referenced_files_by_field = _editor_get_file_uuids_by_field($entity);
foreach ($referenced_files_by_field as $field => $uuids) {
_editor_delete_file_usage($uuids, $entity, 1);
}
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_ENTITY_TYPE_storage_load().
*/
function {{ machine_name }}_ENTITY_TYPE_storage_load(array $entities) {
foreach ($entities as $entity) {
$entity->foo = mymodule_add_something_uncached($entity);
}
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_ENTITY_TYPE_translation_create().
*/
function {{ machine_name }}_ENTITY_TYPE_translation_create(\Drupal\Core\Entity\EntityInterface $translation) {
\Drupal::logger('example')->info('ENTITY_TYPE translation created: @label', ['@label' => $translation->label()]);
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_ENTITY_TYPE_translation_delete().
*/
function {{ machine_name }}_ENTITY_TYPE_translation_delete(\Drupal\Core\Entity\EntityInterface $translation) {
$variables = [
'@language' => $translation->language()->getName(),
'@label' => $translation->label(),
];
\Drupal::logger('example')->notice('The @language translation of @label has just been deleted.', $variables);
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_ENTITY_TYPE_translation_insert().
*/
function {{ machine_name }}_ENTITY_TYPE_translation_insert(\Drupal\Core\Entity\EntityInterface $translation) {
$variables = [
'@language' => $translation->language()->getName(),
'@label' => $translation->getUntranslated()->label(),
];
\Drupal::logger('example')->notice('The @language translation of @label has just been stored.', $variables);
}

View file

@ -0,0 +1,12 @@
/**
* Implements hook_ENTITY_TYPE_update().
*/
function {{ machine_name }}_ENTITY_TYPE_update(Drupal\Core\Entity\EntityInterface $entity) {
// Update the entity's entry in a fictional table of this type of entity.
\Drupal::database()->update('example_entity')
->fields([
'updated' => REQUEST_TIME,
])
->condition('id', $entity->id())
->execute();
}

View file

@ -0,0 +1,14 @@
/**
* Implements hook_ENTITY_TYPE_view().
*/
function {{ machine_name }}_ENTITY_TYPE_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) {
// Only do the extra work if the component is configured to be displayed.
// This assumes a 'mymodule_addition' extra field has been defined for the
// entity bundle in hook_entity_extra_field_info().
if ($display->getComponent('mymodule_addition')) {
$build['mymodule_addition'] = [
'#markup' => mymodule_addition($entity),
'#theme' => 'mymodule_my_additional_field',
];
}
}

View file

@ -0,0 +1,12 @@
/**
* Implements hook_ENTITY_TYPE_view_alter().
*/
function {{ machine_name }}_ENTITY_TYPE_view_alter(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display) {
if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) {
// Change its weight.
$build['an_additional_field']['#weight'] = -10;
// Add a #post_render callback to act on the rendered HTML of the entity.
$build['#post_render'][] = 'my_module_node_post_render';
}
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_aggregator_fetcher_info_alter().
*/
function {{ machine_name }}_aggregator_fetcher_info_alter(array &$info) {
if (empty($info['foo_fetcher'])) {
return;
}
$info['foo_fetcher']['class'] = Drupal\foo\Plugin\aggregator\fetcher\FooDefaultFetcher::class;
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_aggregator_parser_info_alter().
*/
function {{ machine_name }}_aggregator_parser_info_alter(array &$info) {
if (empty($info['foo_parser'])) {
return;
}
$info['foo_parser']['class'] = Drupal\foo\Plugin\aggregator\parser\FooDefaultParser::class;
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_aggregator_processor_info_alter().
*/
function {{ machine_name }}_aggregator_processor_info_alter(array &$info) {
if (empty($info['foo_processor'])) {
return;
}
$info['foo_processor']['class'] = Drupal\foo\Plugin\aggregator\processor\FooDefaultProcessor::class;
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_ajax_render_alter().
*/
function {{ machine_name }}_ajax_render_alter(array &$data) {
// Inject any new status messages into the content area.
$status_messages = ['#type' => 'status_messages'];
$command = new \Drupal\Core\Ajax\PrependCommand('#block-system-main .content', \Drupal::service('renderer')->renderRoot($status_messages));
$data[] = $command->render();
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_archiver_info_alter().
*/
function {{ machine_name }}_archiver_info_alter(&$info) {
$info['tar']['extensions'][] = 'tgz';
}

View file

@ -0,0 +1,5 @@
/**
* Implements hook_batch_alter().
*/
function {{ machine_name }}_batch_alter(&$batch) {
}

View file

@ -0,0 +1,13 @@
/**
* Implements hook_block_access().
*/
function {{ machine_name }}_block_access(\Drupal\block\Entity\Block $block, $operation, \Drupal\Core\Session\AccountInterface $account) {
// Example code that would prevent displaying the 'Powered by Drupal' block in
// a region different than the footer.
if ($operation == 'view' && $block->getPluginId() == 'system_powered_by_block') {
return AccessResult::forbiddenIf($block->getRegion() != 'footer')->addCacheableDependency($block);
}
// No opinion.
return AccessResult::neutral();
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_block_build_BASE_BLOCK_ID_alter().
*/
function {{ machine_name }}_block_build_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
// Explicitly enable placeholdering of the specific block.
$build['#create_placeholder'] = TRUE;
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_block_build_alter().
*/
function {{ machine_name }}_block_build_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
// Add the 'user' cache context to some blocks.
if ($block->label() === 'some condition') {
$build['#cache']['contexts'][] = 'user';
}
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_block_view_BASE_BLOCK_ID_alter().
*/
function {{ machine_name }}_block_view_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
// Change the title of the specific block.
$build['#title'] = t('New title of the block');
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_block_view_alter().
*/
function {{ machine_name }}_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
// Remove the contextual links on all blocks that provide them.
if (isset($build['#contextual_links'])) {
unset($build['#contextual_links']);
}
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_cache_flush().
*/
function {{ machine_name }}_cache_flush() {
if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
_update_cache_clear();
}
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_ckeditor_css_alter().
*/
function {{ machine_name }}_ckeditor_css_alter(array &$css, Editor $editor) {
$css[] = drupal_get_path('module', 'mymodule') . '/css/mymodule-ckeditor.css';
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_ckeditor_plugin_info_alter().
*/
function {{ machine_name }}_ckeditor_plugin_info_alter(array &$plugins) {
$plugins['someplugin']['label'] = t('Better name');
}

View file

@ -0,0 +1,15 @@
/**
* Implements hook_comment_links_alter().
*/
function {{ machine_name }}_comment_links_alter(array &$links, CommentInterface $entity, array &$context) {
$links['mymodule'] = [
'#theme' => 'links__comment__mymodule',
'#attributes' => ['class' => ['links', 'inline']],
'#links' => [
'comment-report' => [
'title' => t('Report'),
'url' => Url::fromRoute('comment_test.report', ['comment' => $entity->id()], ['query' => ['token' => \Drupal::getContainer()->get('csrf_token')->get("comment/{$entity->id()}/report")]]),
],
],
];
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_config_import_steps_alter().
*/
function {{ machine_name }}_config_import_steps_alter(&$sync_steps, \Drupal\Core\Config\ConfigImporter $config_importer) {
$deletes = $config_importer->getUnprocessedConfiguration('delete');
if (isset($deletes['field.storage.node.body'])) {
$sync_steps[] = '_additional_configuration_step';
}
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_config_schema_info_alter().
*/
function {{ machine_name }}_config_schema_info_alter(&$definitions) {
// Enhance the text and date type definitions with classes to generate proper
// form elements in ConfigTranslationFormBase. Other translatable types will
// appear as a one line textfield.
$definitions['text']['form_element_class'] = '\Drupal\config_translation\FormElement\Textarea';
$definitions['date_format']['form_element_class'] = '\Drupal\config_translation\FormElement\DateFormat';
}

View file

@ -0,0 +1,34 @@
/**
* Implements hook_config_translation_info().
*/
function {{ machine_name }}_config_translation_info(&$info) {
$entity_manager = \Drupal::entityManager();
$route_provider = \Drupal::service('router.route_provider');
// If field UI is not enabled, the base routes of the type
// "entity.field_config.{$entity_type}_field_edit_form" are not defined.
if (\Drupal::moduleHandler()->moduleExists('field_ui')) {
// Add fields entity mappers to all fieldable entity types defined.
foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) {
$base_route = NULL;
try {
$base_route = $route_provider->getRouteByName('entity.field_config.' . $entity_type_id . '_field_edit_form');
}
catch (RouteNotFoundException $e) {
// Ignore non-existent routes.
}
// Make sure entity type has field UI enabled and has a base route.
if ($entity_type->get('field_ui_base_route') && !empty($base_route)) {
$info[$entity_type_id . '_fields'] = [
'base_route_name' => 'entity.field_config.' . $entity_type_id . '_field_edit_form',
'entity_type' => 'field_config',
'title' => t('Title'),
'class' => '\Drupal\config_translation\ConfigFieldMapper',
'base_entity_type' => $entity_type_id,
'weight' => 10,
];
}
}
}
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_config_translation_info_alter().
*/
function {{ machine_name }}_config_translation_info_alter(&$info) {
// Add additional site settings to the site information screen, so it shows
// up on the translation screen. (Form alter in the elements whose values are
// stored in this config file using regular form altering on the original
// configuration form.)
$info['system.site_information_settings']['names'][] = 'example.site.setting';
}

View file

@ -0,0 +1,11 @@
/**
* Implements hook_contextual_links_alter().
*/
function {{ machine_name }}_contextual_links_alter(array &$links, $group, array $route_parameters) {
if ($group == 'menu') {
// Dynamically use the menu name for the title of the menu_edit contextual
// link.
$menu = \Drupal::entityManager()->getStorage('menu')->load($route_parameters['menu']);
$links['menu_edit']['title'] = t('Edit menu: @label', ['@label' => $menu->label()]);
}
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_contextual_links_plugins_alter().
*/
function {{ machine_name }}_contextual_links_plugins_alter(array &$contextual_links) {
$contextual_links['menu_edit']['title'] = 'Edit the menu';
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_contextual_links_view_alter().
*/
function {{ machine_name }}_contextual_links_view_alter(&$element, $items) {
// Add another class to all contextual link lists to facilitate custom
// styling.
$element['#attributes']['class'][] = 'custom-class';
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_countries_alter().
*/
function {{ machine_name }}_countries_alter(&$countries) {
// Elbonia is now independent, so add it to the country list.
$countries['EB'] = 'Elbonia';
}

View file

@ -0,0 +1,34 @@
/**
* Implements hook_cron().
*/
function {{ machine_name }}_cron() {
// Short-running operation example, not using a queue:
// Delete all expired records since the last cron run.
$expires = \Drupal::state()->get('mymodule.last_check', 0);
\Drupal::database()->delete('mymodule_table')
->condition('expires', $expires, '>=')
->execute();
\Drupal::state()->set('mymodule.last_check', REQUEST_TIME);
// Long-running operation example, leveraging a queue:
// Queue news feeds for updates once their refresh interval has elapsed.
$queue = \Drupal::queue('aggregator_feeds');
$ids = \Drupal::entityManager()->getStorage('aggregator_feed')->getFeedIdsToRefresh();
foreach (Feed::loadMultiple($ids) as $feed) {
if ($queue->createItem($feed)) {
// Add timestamp to avoid queueing item more than once.
$feed->setQueuedTime(REQUEST_TIME);
$feed->save();
}
}
$ids = \Drupal::entityQuery('aggregator_feed')
->condition('queued', REQUEST_TIME - (3600 * 6), '<')
->execute();
if ($ids) {
$feeds = Feed::loadMultiple($ids);
foreach ($feeds as $feed) {
$feed->setQueuedTime(0);
$feed->save();
}
}
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_css_alter().
*/
function {{ machine_name }}_css_alter(&$css, \Drupal\Core\Asset\AttachedAssetsInterface $assets) {
// Remove defaults.css file.
unset($css[drupal_get_path('module', 'system') . '/defaults.css']);
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_data_type_info_alter().
*/
function {{ machine_name }}_data_type_info_alter(&$data_types) {
$data_types['email']['class'] = '\Drupal\mymodule\Type\Email';
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_display_variant_plugin_alter().
*/
function {{ machine_name }}_display_variant_plugin_alter(array &$definitions) {
$definitions['full_page']['admin_label'] = t('Block layout');
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_editor_info_alter().
*/
function {{ machine_name }}_editor_info_alter(array &$editors) {
$editors['some_other_editor']['label'] = t('A different name');
$editors['some_other_editor']['library']['module'] = 'myeditoroverride';
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_editor_js_settings_alter().
*/
function {{ machine_name }}_editor_js_settings_alter(array &$settings) {
if (isset($settings['editor']['formats']['basic_html'])) {
$settings['editor']['formats']['basic_html']['editor'] = 'MyDifferentEditor';
$settings['editor']['formats']['basic_html']['editorSettings']['buttons'] = ['strong', 'italic', 'underline'];
}
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_editor_xss_filter_alter().
*/
function {{ machine_name }}_editor_xss_filter_alter(&$editor_xss_filter_class, FilterFormatInterface $format, FilterFormatInterface $original_format = NULL) {
$filters = $format->filters()->getAll();
if (isset($filters['filter_wysiwyg']) && $filters['filter_wysiwyg']->status) {
$editor_xss_filter_class = '\Drupal\filter_wysiwyg\EditorXssFilter\WysiwygFilter';
}
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_element_info_alter().
*/
function {{ machine_name }}_element_info_alter(array &$info) {
// Decrease the default size of textfields.
if (isset($info['textfield']['#size'])) {
$info['textfield']['#size'] = 40;
}
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_entity_access().
*/
function {{ machine_name }}_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
// No opinion.
return AccessResult::neutral();
}

View file

@ -0,0 +1,15 @@
/**
* Implements hook_entity_base_field_info().
*/
function {{ machine_name }}_entity_base_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {
if ($entity_type->id() == 'node') {
$fields = [];
$fields['mymodule_text'] = BaseFieldDefinition::create('string')
->setLabel(t('The text'))
->setDescription(t('A text property added by mymodule.'))
->setComputed(TRUE)
->setClass('\Drupal\mymodule\EntityComputedText');
return $fields;
}
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_entity_base_field_info_alter().
*/
function {{ machine_name }}_entity_base_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type) {
// Alter the mymodule_text field to use a custom class.
if ($entity_type->id() == 'node' && !empty($fields['mymodule_text'])) {
$fields['mymodule_text']->setClass('\Drupal\anothermodule\EntityComputedText');
}
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_entity_build_defaults_alter().
*/
function {{ machine_name }}_entity_build_defaults_alter(array &$build, \Drupal\Core\Entity\EntityInterface $entity, $view_mode) {
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_entity_bundle_create().
*/
function {{ machine_name }}_entity_bundle_create($entity_type_id, $bundle) {
// When a new bundle is created, the menu needs to be rebuilt to add the
// Field UI menu item tabs.
\Drupal::service('router.builder')->setRebuildNeeded();
}

View file

@ -0,0 +1,12 @@
/**
* Implements hook_entity_bundle_delete().
*/
function {{ machine_name }}_entity_bundle_delete($entity_type_id, $bundle) {
// Remove the settings associated with the bundle in my_module.settings.
$config = \Drupal::config('my_module.settings');
$bundle_settings = $config->get('bundle_settings');
if (isset($bundle_settings[$entity_type_id][$bundle])) {
unset($bundle_settings[$entity_type_id][$bundle]);
$config->set('bundle_settings', $bundle_settings);
}
}

View file

@ -0,0 +1,14 @@
/**
* Implements hook_entity_bundle_field_info().
*/
function {{ machine_name }}_entity_bundle_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
// Add a property only to nodes of the 'article' bundle.
if ($entity_type->id() == 'node' && $bundle == 'article') {
$fields = [];
$fields['mymodule_text_more'] = BaseFieldDefinition::create('string')
->setLabel(t('More text'))
->setComputed(TRUE)
->setClass('\Drupal\mymodule\EntityComputedMoreText');
return $fields;
}
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_entity_bundle_field_info_alter().
*/
function {{ machine_name }}_entity_bundle_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle) {
if ($entity_type->id() == 'node' && $bundle == 'article' && !empty($fields['mymodule_text'])) {
// Alter the mymodule_text field to use a custom class.
$fields['mymodule_text']->setClass('\Drupal\anothermodule\EntityComputedText');
}
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_entity_bundle_info().
*/
function {{ machine_name }}_entity_bundle_info() {
$bundles['user']['user']['label'] = t('User');
return $bundles;
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_entity_bundle_info_alter().
*/
function {{ machine_name }}_entity_bundle_info_alter(&$bundles) {
$bundles['user']['user']['label'] = t('Full account');
}

View file

@ -0,0 +1,6 @@
/**
* Implements hook_entity_create().
*/
function {{ machine_name }}_entity_create(\Drupal\Core\Entity\EntityInterface $entity) {
\Drupal::logger('example')->info('Entity created: @label', ['@label' => $entity->label()]);
}

View file

@ -0,0 +1,7 @@
/**
* Implements hook_entity_create_access().
*/
function {{ machine_name }}_entity_create_access(\Drupal\Core\Session\AccountInterface $account, array $context, $entity_bundle) {
// No opinion.
return AccessResult::neutral();
}

View file

@ -0,0 +1,10 @@
/**
* Implements hook_entity_delete().
*/
function {{ machine_name }}_entity_delete(Drupal\Core\Entity\EntityInterface $entity) {
// Delete the entity's entry from a fictional table of all entities.
\Drupal::database()->delete('example_entity')
->condition('type', $entity->getEntityTypeId())
->condition('id', $entity->id())
->execute();
}

View file

@ -0,0 +1,20 @@
/**
* Implements hook_entity_display_build_alter().
*/
function {{ machine_name }}_entity_display_build_alter(&$build, $context) {
// Append RDF term mappings on displayed taxonomy links.
foreach (Element::children($build) as $field_name) {
$element = &$build[$field_name];
if ($element['#field_type'] == 'entity_reference' && $element['#formatter'] == 'entity_reference_label') {
foreach ($element['#items'] as $delta => $item) {
$term = $item->entity;
if (!empty($term->rdf_mapping['rdftype'])) {
$element[$delta]['#options']['attributes']['typeof'] = $term->rdf_mapping['rdftype'];
}
if (!empty($term->rdf_mapping['name']['predicates'])) {
$element[$delta]['#options']['attributes']['property'] = $term->rdf_mapping['name']['predicates'];
}
}
}
}
}

View file

@ -0,0 +1,34 @@
/**
* Implements hook_entity_extra_field_info().
*/
function {{ machine_name }}_entity_extra_field_info() {
$extra = [];
$module_language_enabled = \Drupal::moduleHandler()->moduleExists('language');
$description = t('Node module element');
foreach (NodeType::loadMultiple() as $bundle) {
// Add also the 'language' select if Language module is enabled and the
// bundle has multilingual support.
// Visibility of the ordering of the language selector is the same as on the
// node/add form.
if ($module_language_enabled) {
$configuration = ContentLanguageSettings::loadByEntityTypeBundle('node', $bundle->id());
if ($configuration->isLanguageAlterable()) {
$extra['node'][$bundle->id()]['form']['language'] = [
'label' => t('Language'),
'description' => $description,
'weight' => 0,
];
}
}
$extra['node'][$bundle->id()]['display']['language'] = [
'label' => t('Language'),
'description' => $description,
'weight' => 0,
'visible' => FALSE,
];
}
return $extra;
}

View file

@ -0,0 +1,11 @@
/**
* Implements hook_entity_extra_field_info_alter().
*/
function {{ machine_name }}_entity_extra_field_info_alter(&$info) {
// Force node title to always be at the top of the list by default.
foreach (NodeType::loadMultiple() as $bundle) {
if (isset($info['node'][$bundle->id()]['form']['title'])) {
$info['node'][$bundle->id()]['form']['title']['weight'] = -20;
}
}
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_entity_field_access().
*/
function {{ machine_name }}_entity_field_access($operation, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, \Drupal\Core\Session\AccountInterface $account, \Drupal\Core\Field\FieldItemListInterface $items = NULL) {
if ($field_definition->getName() == 'field_of_interest' && $operation == 'edit') {
return AccessResult::allowedIfHasPermission($account, 'update field of interest');
}
return AccessResult::neutral();
}

View file

@ -0,0 +1,16 @@
/**
* Implements hook_entity_field_access_alter().
*/
function {{ machine_name }}_entity_field_access_alter(array &$grants, array $context) {
/** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
$field_definition = $context['field_definition'];
if ($field_definition->getName() == 'field_of_interest' && $grants['node']->isForbidden()) {
// Override node module's restriction to no opinion (neither allowed nor
// forbidden). We don't want to provide our own access hook, we only want to
// take out node module's part in the access handling of this field. We also
// don't want to switch node module's grant to
// AccessResultInterface::isAllowed() , because the grants of other modules
// should still decide on their own if this field is accessible or not
$grants['node'] = AccessResult::neutral()->inheritCacheability($grants['node']);
}
}

View file

@ -0,0 +1,20 @@
/**
* Implements hook_entity_field_storage_info().
*/
function {{ machine_name }}_entity_field_storage_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type) {
if (\Drupal::entityManager()->getStorage($entity_type->id()) instanceof DynamicallyFieldableEntityStorageInterface) {
// Query by filtering on the ID as this is more efficient than filtering
// on the entity_type property directly.
$ids = \Drupal::entityQuery('field_storage_config')
->condition('id', $entity_type->id() . '.', 'STARTS_WITH')
->execute();
// Fetch all fields and key them by field name.
$field_storages = FieldStorageConfig::loadMultiple($ids);
$result = [];
foreach ($field_storages as $field_storage) {
$result[$field_storage->getName()] = $field_storage;
}
return $result;
}
}

View file

@ -0,0 +1,9 @@
/**
* Implements hook_entity_field_storage_info_alter().
*/
function {{ machine_name }}_entity_field_storage_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type) {
// Alter the max_length setting.
if ($entity_type->id() == 'node' && !empty($fields['mymodule_text'])) {
$fields['mymodule_text']->setSetting('max_length', 128);
}
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_entity_field_values_init().
*/
function {{ machine_name }}_entity_field_values_init(\Drupal\Core\Entity\FieldableEntityInterface $entity) {
if ($entity instanceof \Drupal\Core\Entity\ContentEntityInterface && !$entity->foo->value) {
$entity->foo->value = 'some_initial_value';
}
}

View file

@ -0,0 +1,11 @@
/**
* Implements hook_entity_form_display_alter().
*/
function {{ machine_name }}_entity_form_display_alter(\Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display, array $context) {
// Hide the 'user_picture' field from the register form.
if ($context['entity_type'] == 'user' && $context['form_mode'] == 'register') {
$form_display->setComponent('user_picture', [
'region' => 'hidden',
]);
}
}

View file

@ -0,0 +1,14 @@
/**
* Implements hook_entity_insert().
*/
function {{ machine_name }}_entity_insert(Drupal\Core\Entity\EntityInterface $entity) {
// Insert the new entity into a fictional table of all entities.
\Drupal::database()->insert('example_entity')
->fields([
'type' => $entity->getEntityTypeId(),
'id' => $entity->id(),
'created' => REQUEST_TIME,
'updated' => REQUEST_TIME,
])
->execute();
}

View file

@ -0,0 +1,8 @@
/**
* Implements hook_entity_load().
*/
function {{ machine_name }}_entity_load(array $entities, $entity_type_id) {
foreach ($entities as $entity) {
$entity->foo = mymodule_add_something($entity);
}
}

Some files were not shown because too many files have changed in this diff Show more