default services conflit ?
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
{{ field_id }}:
|
||||
css:
|
||||
component:
|
||||
css/{{ field_id|u2h }}-widget.css: {}
|
@@ -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 %}
|
@@ -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];
|
||||
}
|
||||
|
||||
}
|
@@ -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 constraints 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 %}
|
||||
}
|
@@ -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 %}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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));
|
@@ -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]
|
@@ -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 %}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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 %}
|
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Drush\Commands;
|
||||
|
||||
use Consolidation\AnnotatedCommand\CommandData;
|
||||
|
||||
/**
|
||||
* Site policy.
|
||||
*/
|
||||
class PolicyCommands extends DrushCommands {
|
||||
|
||||
/**
|
||||
* Limit sql-sync operations to remote sites.
|
||||
*
|
||||
* @hook validate sql:sync
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function sqlSyncValidate(CommandData $commandData) {
|
||||
$target = $commandData->input()->getArgument('target');
|
||||
if ($target != '@local') {
|
||||
throw new \Exception(dt('Per !file, you may never overwrite the remote database.', ['!file' => __FILE__]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit rsync operations to remote sites.
|
||||
*
|
||||
* @hook validate core:rsync
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function rsyncValidate(CommandData $commandData) {
|
||||
$target = $commandData->input()->getArgument('target');
|
||||
if (strpos($target, '@prod') == 0) {
|
||||
throw new \Exception(dt('Per !file, you may never rsync to the remote site.', ['!file' => __FILE__]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
# Edit or remove this file as needed.
|
||||
# Docs at https://github.com/drush-ops/drush/blob/master/examples/example.site.yml
|
||||
prod:
|
||||
host: example.com
|
||||
user: prod-user
|
||||
root: /path/to/drupal
|
||||
uri: http://www.example.com
|
||||
|
||||
stage:
|
||||
host: stage.example.com
|
||||
user: stage-user
|
||||
root: /path/to/drupal
|
||||
uri: http://stage.example.com
|
||||
|
||||
local:
|
||||
uri: http://localhost
|
@@ -0,0 +1,28 @@
|
||||
# Copy and rename this file to .env at root of this project.
|
||||
#
|
||||
# A common use case is to supply database credentials via the environment.
|
||||
# Edit settings.php like so:
|
||||
#
|
||||
# $databases['default']['default'] = [
|
||||
# 'database' => getenv('MYSQL_DATABASE'),
|
||||
# 'driver' => 'mysql',
|
||||
# 'host' => getenv('MYSQL_HOST'),
|
||||
# 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
|
||||
# 'password' => getenv('MYSQL_PASSWORD'),
|
||||
# 'port' => getenv('MYSQL_PORT'),
|
||||
# 'prefix' => '',
|
||||
# 'username' => getenv('MYSQL_USER'),
|
||||
# ];
|
||||
#
|
||||
# Uncomment and populate as needed.
|
||||
# MYSQL_DATABASE=
|
||||
# MYSQL_HOST=
|
||||
# MYSQL_PASSWORD=
|
||||
# MYSQL_PORT=
|
||||
# MYSQL_USER=
|
||||
|
||||
{% if drush %}
|
||||
# Another common use case is to set Drush's --uri via environment.
|
||||
# DRUSH_OPTIONS_URI=http://localhost
|
||||
|
||||
{% endif %}
|
@@ -0,0 +1,26 @@
|
||||
# Ignore directories generated by Composer.
|
||||
{% if drush %}
|
||||
/drush/contrib/
|
||||
{% endif %}
|
||||
/vendor/
|
||||
/{{ document_root_path }}core/
|
||||
/{{ document_root_path }}modules/contrib/
|
||||
/{{ document_root_path }}themes/contrib/
|
||||
/{{ document_root_path }}profiles/contrib/
|
||||
/{{ document_root_path }}libraries/
|
||||
|
||||
# Ignore sensitive information.
|
||||
/{{ document_root_path }}sites/*/settings.php
|
||||
/{{ document_root_path }}sites/*/settings.local.php
|
||||
|
||||
# Ignore Drupal's file directory.
|
||||
/{{ document_root_path }}sites/*/files/
|
||||
|
||||
# Ignore SimpleTest multi-site environment.
|
||||
/{{ document_root_path }}sites/simpletest/
|
||||
|
||||
# Ignore files generated by PhpStorm.
|
||||
/.idea/
|
||||
|
||||
# Ignore .env files as they are personal.
|
||||
/.env
|
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Loads environment variables from .env files.
|
||||
*
|
||||
* This file is included very early.
|
||||
* @see composer.json For autoload section.
|
||||
*/
|
||||
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
|
||||
$file = __DIR__ . '/.env';
|
||||
if (file_exists($file)) {
|
||||
(new Dotenv())->load($file);
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="Default">
|
||||
<description>PHP CodeSniffer configuration for "{{ name }}" project.</description>
|
||||
<config name="installed_paths" value="vendor/drupal/coder/coder_sniffer"/>
|
||||
<arg name="colors"/>
|
||||
<arg value="p"/>
|
||||
<file>./{{ document_root_path }}modules/custom</file>
|
||||
{% if drush %}
|
||||
<file>./drush/Commands</file>
|
||||
{% endif %}
|
||||
<rule ref="Drupal"/>
|
||||
<rule ref="DrupalPractice"/>
|
||||
</ruleset>
|
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- Copy the samples below into your own phpunit.xml file.-->
|
||||
|
||||
<!-- Using this project's bootstrap file allows tests in `ExistingSite`,
|
||||
`ExistingSiteSelenium2DriverTest`, and `ExistingSiteWebDriverTest`
|
||||
to run alongside core's test types. -->
|
||||
<phpunit bootstrap="vendor/weitzman/drupal-test-traits/src/bootstrap-fast.php">
|
||||
<php>
|
||||
<env name="DTT_BASE_URL" value="http://example.com"/>
|
||||
<env name="DTT_API_URL" value="http://localhost:9222"/>
|
||||
<!-- <env name="DTT_MINK_DRIVER_ARGS" value='["chrome", { "chromeOptions" : { "w3c": false } }, "http://localhost:4444/wd/hub"]'/> -->
|
||||
<env name="DTT_MINK_DRIVER_ARGS" value='["firefox", null, "http://localhost:4444/wd/hub"]'/>
|
||||
<env name="DTT_API_OPTIONS" value='{"socketTimeout": 360, "domWaitTimeout": 3600000}' />
|
||||
<!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /tmp
|
||||
Specify a temporary directory for storing debug images and html documents.
|
||||
These artifacts get copied to /sites/simpletest/browser_output by BrowserTestBase. -->
|
||||
<env name="BROWSERTEST_OUTPUT_DIRECTORY" value=""/>
|
||||
<!-- To disable deprecation testing completely uncomment the next line. -->
|
||||
<!--<env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled"/>-->
|
||||
<!-- Specify the default directory screenshots should be placed. -->
|
||||
<!--<env name="DTT_SCREENSHOT_REPORT_DIRECTORY" value=""/>-->
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="unit">
|
||||
<directory>./{{ document_root_path }}modules/custom/*/tests/src/Unit</directory>
|
||||
<!--<directory>./web/profiles/custom/*/tests/src/Unit</directory>-->
|
||||
</testsuite>
|
||||
<testsuite name="kernel">
|
||||
<directory>./{{ document_root_path }}modules/custom/*/tests/src/Kernel</directory>
|
||||
<!--<directory>./web/profiles/custom/*/tests/src/Kernel</directory>-->
|
||||
</testsuite>
|
||||
<testsuite name="existing-site">
|
||||
<!-- Assumes tests are namespaced as \Drupal\Tests\custom_foo\ExistingSite. -->
|
||||
<directory>./{{ document_root_path }}modules/custom/*/tests/src/ExistingSite</directory>
|
||||
<!--<directory>./web/profiles/custom/*/tests/src/ExistingSite</directory>-->
|
||||
</testsuite>
|
||||
<testsuite name="existing-site-javascript">
|
||||
<!-- Assumes tests are namespaced as \Drupal\Tests\custom_foo\ExistingSiteJavascript. -->
|
||||
<directory>./{{ document_root_path }}modules/custom/*/tests/src/ExistingSiteJavascript</directory>
|
||||
<!--<directory>./web/profiles/custom/*/tests/src/ExistingSiteJavascript</directory>-->
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Synchronize local site instance with remote one.
|
||||
|
||||
set -e
|
||||
|
||||
ROOT_DIR=$(dirname "$(readlink -f "$0")")/..
|
||||
|
||||
function label {
|
||||
echo -e "\n\e[1;47;44m $* \e[0m"
|
||||
}
|
||||
|
||||
function local_drush {
|
||||
"$ROOT_DIR"/vendor/drush/drush/drush --root "$ROOT_DIR"/{{ document_root_path }} "$@"
|
||||
}
|
||||
|
||||
SOURCE_ENVIRONMENT=$1
|
||||
|
||||
# Source environment from which we copy the database and files.
|
||||
if [[ -z $SOURCE_ENVIRONMENT ]]; then
|
||||
read -r -p "Source environment: " SOURCE_ENVIRONMENT
|
||||
fi
|
||||
|
||||
label 'Empty current database'
|
||||
local_drush sql:drop -y
|
||||
|
||||
label "Import database from $SOURCE_ENVIRONMENT"
|
||||
# @DCG gzip does not make much sense for small databases.
|
||||
local_drush "@$SOURCE_ENVIRONMENT" sql:dump --gzip | gunzip | local_drush sql:cli
|
||||
|
||||
label "Synchronize files with $SOURCE_ENVIRONMENT"
|
||||
# @DCG To save time and disk space consider using Stage File Proxy module.
|
||||
TARGET_DIR=$(realpath "$ROOT_DIR"/{{ document_root_path }}sites/default/files)
|
||||
local_drush core:rsync -y "@$SOURCE_ENVIRONMENT:sites/default/files/" "$TARGET_DIR" || true
|
||||
|
||||
label 'Apply DB updates'
|
||||
local_drush updatedb -y
|
||||
|
||||
label 'Import configuration'
|
||||
local_drush config:import -y
|
||||
|
||||
label 'Check config status'
|
||||
local_drush config:status
|
||||
|
||||
label 'Rebuild caches'
|
||||
local_drush cache:rebuild
|
||||
|
||||
label 'Run CRON hooks'
|
||||
local_drush core:cron
|
||||
|
||||
label 'Delete log records'
|
||||
local_drush watchdog:delete all -y
|
||||
|
||||
label 'Warm cache'
|
||||
URL=$(local_drush core:status --field=uri)
|
||||
if [[ $URL == *"default"* ]]; then
|
||||
echo -e "\n\e[91mURL is not set. Skipping.\e[0m" >&2
|
||||
else
|
||||
curl -s -o /dev/null -w "URL: %{url_effective}\nStatus code: %{http_code}\nTime total: %{time_total} sec.\n $URL"
|
||||
fi
|
||||
|
||||
label 'Check site status'
|
||||
local_drush core:status
|
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace {{ namespace }}\Tests;
|
||||
|
||||
use weitzman\DrupalTestTraits\ExistingSiteBase;
|
||||
|
||||
/**
|
||||
* A test for home page.
|
||||
*/
|
||||
class HomePageTest extends ExistingSiteBase {
|
||||
|
||||
/**
|
||||
* Test callback.
|
||||
*/
|
||||
public function testHomePage() {
|
||||
$this->drupalGet('');
|
||||
$this->assertSession()->pageTextContains('Welcome');
|
||||
}
|
||||
|
||||
}
|
@@ -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 %}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
{{ route_name }}:
|
||||
path: '{{ route_path }}'
|
||||
defaults:
|
||||
_title: '{{ route_title }}'
|
||||
_controller: '\Drupal\{{ machine_name }}\Controller\{{ class }}::build'
|
||||
requirements:
|
||||
_permission: '{{ route_permission }}'
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the {{ name }} module.
|
||||
*/
|
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Primary module hooks for {{ name }} module.
|
||||
*/
|
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Post update functions for the {{ name }} module.
|
||||
*/
|
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Builds tokens for the {{ name }} module.
|
||||
*/
|
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Views hooks for the {{ name }} module.
|
||||
*/
|
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provide views runtime hooks for the {{ name }} module.
|
||||
*/
|
@@ -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);
|
||||
}
|
||||
|
||||
}
|
@@ -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());
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
{{ route_name }}:
|
||||
title: {{ link_title }}
|
||||
{% if link_description %}
|
||||
description: {{ link_description }}
|
||||
{% endif %}
|
||||
{% if link_parent %}
|
||||
parent: {{ link_parent }}
|
||||
{% endif %}
|
||||
route_name: {{ route_name }}
|
||||
weight: 10
|
@@ -0,0 +1,7 @@
|
||||
{{ route_name }}:
|
||||
path: '{{ route_path }}'
|
||||
defaults:
|
||||
_title: '{{ route_title }}'
|
||||
_form: 'Drupal\{{ machine_name }}\Form\{{ class }}'
|
||||
requirements:
|
||||
_permission: '{{ route_permission }}'
|
@@ -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>');
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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) {
|
||||
|
||||
}
|
@@ -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()]);
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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';
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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'));
|
||||
}
|
||||
}
|
@@ -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'));
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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()]);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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',
|
||||
];
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Implements hook_archiver_info_alter().
|
||||
*/
|
||||
function {{ machine_name }}_archiver_info_alter(&$info) {
|
||||
$info['tar']['extensions'][] = 'tgz';
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Implements hook_batch_alter().
|
||||
*/
|
||||
function {{ machine_name }}_batch_alter(&$batch) {
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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';
|
||||
}
|
||||
}
|
@@ -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');
|
||||
}
|
@@ -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']);
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Implements hook_cache_flush().
|
||||
*/
|
||||
function {{ machine_name }}_cache_flush() {
|
||||
if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
|
||||
_update_cache_clear();
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -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');
|
||||
}
|
@@ -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")]]),
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
@@ -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';
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Implements hook_config_translation_info().
|
||||
*/
|
||||
function {{ machine_name }}_config_translation_info(&$info) {
|
||||
$entity_type_manager = \Drupal::entityTypeManager();
|
||||
$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_type_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,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -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::entityTypeManager()->getStorage('menu')->load($route_parameters['menu']);
|
||||
$links['menu_edit']['title'] = t('Edit menu: @label', ['@label' => $menu->label()]);
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -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::entityTypeManager()->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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -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']);
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -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');
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -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'];
|
||||
}
|
||||
}
|
@@ -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';
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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');
|
||||
}
|
||||
}
|
@@ -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) {
|
||||
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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 = [];
|
||||
$storage_definitions = mymodule_entity_field_storage_info($entity_type);
|
||||
$fields['mymodule_bundle_field'] = FieldDefinition::createFromFieldStorageDefinition($storage_definitions['mymodule_bundle_field'])
|
||||
->setLabel(t('Bundle Field'));
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
@@ -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');
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Implements hook_entity_bundle_info().
|
||||
*/
|
||||
function {{ machine_name }}_entity_bundle_info() {
|
||||
$bundles['user']['user']['label'] = t('User');
|
||||
return $bundles;
|
||||
}
|
@@ -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');
|
||||
}
|
@@ -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()]);
|
||||
}
|
@@ -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();
|
||||
}
|
@@ -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();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user