Skip to content
Snippets Groups Projects
Commit 194968f7 authored by Dieter Holvoet's avatar Dieter Holvoet
Browse files

Issue #3491632 by dieterholvoet: Add Gitlab CI

parent 887525dc
No related branches found
No related tags found
1 merge request!11Add .gitlab-ci.yml
Pipeline #359229 failed
Showing
with 205 additions and 111 deletions
################
# GitLabCI template for Drupal projects.
#
# This template is designed to give any Contrib maintainer everything they need to test, without requiring modification.
# It is also designed to keep up to date with Core Development automatically through the use of include files that can be centrally maintained.
# As long as you include the project, ref and three files below, any future updates added by the Drupal Association will be used in your
# pipelines automatically. However, you can modify this template if you have additional needs for your project.
# The full documentation is on https://project.pages.drupalcode.org/gitlab_templates/
################
# For information on alternative values for 'ref' see https://project.pages.drupalcode.org/gitlab_templates/info/templates-version/
# To test a Drupal 7 project, change the first include filename from .main.yml to .main-d7.yml
include:
- project: $_GITLAB_TEMPLATES_REPO
ref: $_GITLAB_TEMPLATES_REF
file:
- '/includes/include.drupalci.main.yml'
- '/includes/include.drupalci.variables.yml'
- '/includes/include.drupalci.workflows.yml'
#
################
# Pipeline configuration variables are defined with default values and descriptions in the file
# https://git.drupalcode.org/project/gitlab_templates/-/blob/main/includes/include.drupalci.variables.yml
# Uncomment the lines below if you want to override any of the variables. The following is just an example.
################
# variables:
# SKIP_ESLINT: '1'
# OPT_IN_TEST_NEXT_MAJOR: '1'
# _CURL_TEMPLATES_REF: 'main'
{
"name": "drupal/required_api",
"type": "drupal-module",
"description": "Provides an unified API to managed required property on fields.",
"keywords": ["Drupal"],
"license": "GPL-2.0+",
"homepage": "https://www.drupal.org/project/required_api",
"minimum-stability": "dev",
"support": {
"issues": "https://www.drupal.org/project/issues/required_api",
"source": "http://cgit.drupalcode.org/required_api"
},
"require": {
"drupal/core": "^8.8 || ^9"
}
}
......@@ -7,19 +7,18 @@
* Determines if a widget should be required or not based on contexts.
*/
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_help().
*/
function required_api_help($path, $arg) {
switch ($path) {
case 'admin/help#required_api':
$output = '';
$output .= '<p>' . t('The Required API module provides an API to find out
if a widget is requried or not.') . '</p>';
if a widget is required or not.') . '</p>';
return $output;
}
}
......@@ -41,12 +40,10 @@ function required_api_permission() {
*
* Applies to FORM_ID field_config_edit_form.
*/
function required_api_form_field_config_edit_form_alter(&$form, FormStateInterface $form_state) {
function required_api_form_field_config_edit_form_alter(array &$form, FormStateInterface $form_state) {
$field_definition = $form_state->getFormObject()->getEntity();
$field_name = $field_definition->getName();
$parents = ['third_party_settings', 'required_api', 'required_plugin'];
$manager = \Drupal::service('plugin.manager.required_api.required');
if (!$plugin_id = $form_state->getValue($parents)) {
......@@ -56,7 +53,6 @@ function required_api_form_field_config_edit_form_alter(&$form, FormStateInterfa
$plugins = $manager->getDefinitionsAsOptions();
if (count($plugins) > 1) {
$form['required_plugin'] = [
'#title' => t('Choose a required strategy:'),
'#type' => 'radios',
......@@ -64,14 +60,13 @@ function required_api_form_field_config_edit_form_alter(&$form, FormStateInterfa
'#default_value' => $plugin_id,
'#weight' => $form['required']['#weight'] - 1,
'#ajax' => [
'callback' => 'require_api_element_ajax_callback',
'callback' => 'required_api_element_ajax_callback',
'wrapper' => 'required-ajax-wrapper',
'effect' => 'fade',
'speed' => 'fast',
],
'#parents' => $parents,
];
}
$form['required']['#access'] = FALSE;
......@@ -88,10 +83,7 @@ function required_api_form_field_config_edit_form_alter(&$form, FormStateInterfa
$form['required_plugin_options']['#weight'] = $form['required']['#weight'];
// Default value needs always to be NOT required.
if (
isset($form['default_value'])
&& isset($form['default_value'][$field_name])
) {
if (isset($form['default_value'][$field_name])) {
$form['default_value'][$field_name]['widget'][0]['#required'] = FALSE;
$form['default_value'][$field_name]['widget'][0]['value']['#required'] = FALSE;
}
......@@ -104,7 +96,7 @@ function required_api_form_field_config_edit_form_alter(&$form, FormStateInterfa
* @return array
* The rendered element.
*/
function require_api_element_ajax_callback($form, $form_state) {
function required_api_element_ajax_callback($form, FormStateInterface $form_state): array {
return $form['required_plugin_options'];
}
......
......@@ -2,6 +2,6 @@ required_api.default_plugin:
path: '/admin/config/user-interface/required'
defaults:
_form: 'Drupal\required_api\Form\RequiredDefaultPluginForm'
_title: 'Required stratety'
_title: 'Required strategy'
requirements:
_permission: 'administer required settings'
services:
plugin.manager.required_api.required:
class: Drupal\required_api\RequiredManager
arguments: ['@container.namespaces', '@cache.discovery', '@language_manager', '@module_handler']
#parent: default_plugin_manager
arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@config.factory']
# Replaces the core field.plugin service
plugin.manager.field.widget:
class: Drupal\required_api\RequiredApiWidgetPluginManager
arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@plugin.manager.field.field_type']
calls:
- [setRequiredManager, ['@plugin.manager.required_api.required']]
- [setRequiredManager, ['@plugin.manager.required_api.required']]
......@@ -32,7 +32,7 @@ class Required extends Plugin {
/**
* A brief description of the api.
*
* @var \Drupal\Core\Annotation\Translationoptional
* @var \Drupal\Core\Annotation\Translation
*
* @ingroup plugin_translatable
*/
......
......@@ -4,27 +4,42 @@ namespace Drupal\required_api\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Configure default required stratety for this site.
* Configure default required strategy for this site.
*/
class RequiredDefaultPluginForm extends ConfigFormBase {
/**
* Required method to provide the form_id.
* The required plugin manager.
*
* @var \Drupal\required_api\RequiredManager
*/
protected $requiredManager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->requiredManager = $container->get('plugin.manager.required_api.required');
return $instance;
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'required_default_plugin';
}
/**
* Required method to provide the actual form.
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$manager = \Drupal::service('plugin.manager.required_api.required');
$plugins = $manager->getDefinitionsAsOptions();
$plugins = $this->requiredManager->getDefinitionsAsOptions();
$config = $this->configFactory->get('required_api.plugins');
$plugin = $config->get('default_plugin');
......@@ -39,14 +54,12 @@ class RequiredDefaultPluginForm extends ConfigFormBase {
}
/**
* Submit function for the form.
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('required_api.plugins');
$config->set('default_plugin', $form_state->getValue('default_plugin'))
->save();
$config->set('default_plugin', $form_state->getValue('default_plugin'));
$config->save();
parent::submitForm($form, $form_state);
}
......
......@@ -2,8 +2,8 @@
namespace Drupal\required_api\Plugin\Required;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\required_api\Plugin\RequiredPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -29,7 +29,6 @@ abstract class RequiredBase extends PluginBase implements RequiredPluginInterfac
* Form element to configure the required property.
*/
public function formElement(FieldDefinitionInterface $field) {
$element = $this->requiredFormElement($field);
return $element + [
......@@ -43,13 +42,6 @@ abstract class RequiredBase extends PluginBase implements RequiredPluginInterfac
];
}
/**
* Helper method to get the label.
*/
public function getLabel() {
return $this->label;
}
/**
* Required method to get the configuration.
*/
......
......@@ -2,8 +2,8 @@
namespace Drupal\required_api\Plugin\Required;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Default required plugin using core implementation.
......
......@@ -2,11 +2,11 @@
namespace Drupal\required_api\Plugin;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Defines the interface for image effects.
......
......@@ -2,8 +2,8 @@
namespace Drupal\required_api;
use Drupal\Core\Field\WidgetPluginManager;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\WidgetPluginManager;
/**
* Plugin type manager for field widgets.
......
......@@ -3,10 +3,10 @@
namespace Drupal\required_api;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManager;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
/**
* Manages required by role plugins.
......@@ -14,32 +14,50 @@ use Drupal\Core\Field\FieldDefinitionInterface;
class RequiredManager extends DefaultPluginManager {
/**
* DefaultPluginManager overriden.
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
parent::__construct('Plugin/Required', $namespaces, $module_handler, 'Drupal\required_api\Plugin\RequiredPluginInterface', 'Drupal\required_api\Annotation\Required');
$this->setCacheBackend($cache_backend, 'required_api_required_plugins');
protected $configFactory;
/**
* Constructs a new RequiredManager object.
*
* @param \Traversable $namespaces
* An object that implements \Traversable which contains the root paths
* keyed by the corresponding namespace to look for plugin implementations.
* @param \Drupal\Core\Cache\CacheBackendInterface $cacheBackend
* Cache backend instance to use.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
* The module handler.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
*/
public function __construct(
\Traversable $namespaces,
CacheBackendInterface $cacheBackend,
ModuleHandlerInterface $moduleHandler,
ConfigFactoryInterface $configFactory,
) {
parent::__construct(
'Plugin/Required',
$namespaces,
$moduleHandler,
'Drupal\required_api\Plugin\RequiredPluginInterface',
'Drupal\required_api\Annotation\Required'
);
$this->setCacheBackend($cacheBackend, 'required_api_required_plugins');
$this->configFactory = $configFactory;
}
/**
* Overrides PluginManagerBase::getInstance().
*/
public function getInstance(array $options) {
if (isset($options['plugin_id'])) {
$plugin_id = $options['plugin_id'];
}
else {
$plugin_id = $this->getPluginId($options['field_definition']);
}
$plugin_id = $options['plugin_id'] ?? $this->getPluginId($options['field_definition']);
$options['plugin_id'] = $plugin_id;
$plugin = $this->createInstance($plugin_id, $options);
return $plugin;
return $this->createInstance($plugin_id, $options);
}
/**
......@@ -52,11 +70,7 @@ class RequiredManager extends DefaultPluginManager {
* The plugin id.
*/
public function getPluginId(FieldDefinitionInterface $field) {
$default_plugin = $plugin_id = $this->getDefaultPluginId();
$plugin_id = $field->getThirdPartySetting('required_api', 'required_plugin', $default_plugin);
return $plugin_id;
return $field->getThirdPartySetting('required_api', 'required_plugin', $this->getDefaultPluginId());
}
/**
......@@ -66,11 +80,13 @@ class RequiredManager extends DefaultPluginManager {
* The plugin id.
*/
public function getDefaultPluginId() {
return \Drupal::config('required_api.plugins')->get('default_plugin');
return $this->configFactory
->get('required_api.plugins')
->get('default_plugin');
}
/**
* Provides the defintions ids.
* Provides the definition ids.
*/
public function getDefinitionsIds() {
return array_keys($this->getDefinitions());
......@@ -80,15 +96,11 @@ class RequiredManager extends DefaultPluginManager {
* Provides the definitions as options just to inject to a select element.
*/
public function getDefinitionsAsOptions() {
$definitions = $this->getDefinitions();
$plugins = [];
foreach ($definitions as $plugin_id => $definition) {
$plugins[$plugin_id] = $definition['label'];
}
return $plugins;
return array_map(function ($definition) {
return $definition['label'];
}, $definitions);
}
}
<?php
namespace Drupal\required_api_test\Tests;
namespace Drupal\Tests\required_api\Functional;
use Drupal\Core\StringTranslation\StringTranslationTrait;
......@@ -8,22 +8,76 @@ use Drupal\Core\StringTranslation\StringTranslationTrait;
* Tests the functionality of the 'Manage fields' screen.
*/
class RequiredApiTest extends RequiredApiTestBase {
use StringTranslationTrait;
/**
* {@inheritdoc}
*/
public function setUp() {
protected $defaultTheme = 'stark';
/**
* The field name.
*
* @var string
*/
protected $fieldName;
/**
* The field instance.
*
* @var \Drupal\field\Entity\FieldConfig
*/
protected $instance;
/**
* The required manager.
*
* @var \Drupal\required_api\RequiredManager
*/
protected $manager;
/**
* The admin path.
*
* @var string
*/
protected $adminPath;
/**
* The node type.
*
* @var string
*/
protected $type;
/**
* The node type label.
*
* @var string
*/
protected $typeLabel;
/**
* The node type label.
*
* @var string
*/
protected $container;
/**
* {@inheritdoc}
*/
public function setUp(): void {
parent::setUp();
// Create a test field and instance.
$this->field_name = 'test';
$this->fieldName = 'test';
$this->container->get('entity_type.manager')
->getStorage('field_entity')
->create([
'name' => $this->field_name,
'name' => $this->fieldName,
'entity_type' => 'node',
'type' => 'test_field',
])
......@@ -32,7 +86,7 @@ class RequiredApiTest extends RequiredApiTestBase {
$this->instance = $this->container->get('entity_type.manager')
->getStorage('field_instance')
->create([
'field_name' => $this->field_name,
'field_name' => $this->fieldName,
'entity_type' => 'node',
'bundle' => $this->type,
])
......@@ -42,19 +96,16 @@ class RequiredApiTest extends RequiredApiTestBase {
$form_display = $this->container->get('entity_display.repository')
->getFormDisplay('node', $this->type, 'default');
$form_display->setComponent($this->field_name)->save();
$form_display->setComponent($this->fieldName)->save();
$this->manager = $form_display->get('pluginManager')->getRequiredManager();
$this->admin_path = 'admin/structure/types/manage/' . $this->type . '/fields/' . $this->instance->id();
$this->adminPath = 'admin/structure/types/manage/' . $this->type . '/fields/' . $this->instance->id();
}
/**
* Tests that default value is correctly validated and saved.
*/
public function testExpectedPluginDefinitions() {
$expected_definitions = [
// Core behavior plugin replacement.
'default',
......@@ -64,14 +115,12 @@ class RequiredApiTest extends RequiredApiTestBase {
$diff = array_diff($this->manager->getDefinitionsIds(), $expected_definitions);
$this->assertEqual([], $diff, 'Definitions match expected.');
}
/**
* Tests the default Required Plugin.
*/
public function testRequiredDefaultPlugin() {
// Setting default (FALSE) and checking the form.
$this->setRequiredPlugin('default', FALSE);
......@@ -86,7 +135,7 @@ class RequiredApiTest extends RequiredApiTestBase {
$this->drupalPostForm(NULL, $edit, $this->t('Save'));
$message = $this->t('!label !title has been created.', [
'!label' => $this->type_label,
'!label' => $this->typeLabel,
'!title' => $title,
]
);
......@@ -98,7 +147,6 @@ class RequiredApiTest extends RequiredApiTestBase {
* Tests that default value is correctly validated and saved.
*/
public function testRequiredTestTruePlugin() {
// Setting true and checking the form.
$this->setRequiredPlugin('required_true', 1);
$this->drupalGet('node/add/' . $this->type);
......@@ -108,7 +156,7 @@ class RequiredApiTest extends RequiredApiTestBase {
];
$this->drupalPostForm(NULL, $edit, $this->t('Save'));
$this->assertText($this->t('!field field is required.', ['!field' => $this->field_name]));
$this->assertText($this->t('!field field is required.', ['!field' => $this->fieldName]));
}
/**
......@@ -120,16 +168,13 @@ class RequiredApiTest extends RequiredApiTestBase {
* TRUE if the plugin is required.
*/
public function setRequiredPlugin($plugin_id, $plugin_value) {
$fieldname = "required_api[third_party_settings][required_plugin]";
$edit = [
$fieldname => $plugin_id,
'instance[required]' => $plugin_value,
];
$this->drupalPostForm($this->admin_path, $edit, $this->t('Save settings'));
$this->drupalPostForm($this->adminPath, $edit, $this->t('Save settings'));
}
}
<?php
namespace Drupal\required_api_test\Tests;
namespace Drupal\Tests\required_api\Functional;
use Drupal\Tests\BrowserTestBase;
......@@ -14,7 +14,7 @@ abstract class RequiredApiTestBase extends BrowserTestBase {
*
* @var array
*/
public static $modules = [
protected static $modules = [
'node',
'field_ui',
'field_test',
......@@ -25,7 +25,7 @@ abstract class RequiredApiTestBase extends BrowserTestBase {
/**
* {@inheritdoc}
*/
public function setUp() {
public function setUp(): void {
parent::setUp();
// Create test user.
......@@ -44,11 +44,9 @@ abstract class RequiredApiTestBase extends BrowserTestBase {
$this->drupalLogin($admin_user);
// Create Article node type.
$this->type = 'article';
$this->type_label = 'Article';
$this->drupalCreateContentType([
'type' => $this->type,
'name' => $this->type_label,
'type' => 'article',
'name' => 'Article',
]);
}
......
<?php
namespace Drupal\required_api_test\Tests\Plugin\Required;
namespace Drupal\Tests\required_api\Unit;
use Drupal\required_api\RequiredManager;
use Drupal\Tests\UnitTestCase;
use Drupal\required_api\RequiredManager;
/**
* Tests the breadcrumb manager.
......@@ -23,19 +23,17 @@ class RequiredManagerTest extends UnitTestCase {
/**
* {@inheritdoc}
*/
protected function setUp() {
protected function setUp(): void {
parent::setUp();
$namespaces = new \ArrayObject([]);
$cache_backend = $this->getMockBuilder('Drupal\Core\Cache\MemoryBackend')
->disableOriginalConstructor()
->getMock();
$module_handler = $this->createMock('Drupal\Core\Extension\ModuleHandlerInterface');
$config_factory = $this->createMock('Drupal\Core\Config\ConfigFactoryInterface');
$this->requiredManager = new RequiredManager($namespaces, $cache_backend, $module_handler);
$this->requiredManager = new RequiredManager($namespaces, $cache_backend, $module_handler, $config_factory);
}
/**
......
<?php
namespace Drupal\required_api_test\Plugin\Required;
namespace Drupal\Tests\required_api\Unit;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\required_api\Plugin\Required\RequiredBase;
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment