Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #2671056 by fago: Add RulesUiComponentProviderInterface for con… #409

Closed
wants to merge 6 commits into from
50 changes: 27 additions & 23 deletions config/schema/rules.schema.yml
Expand Up @@ -22,22 +22,8 @@ rules.component.*:
core:
type: string
label: 'Drupal version'
expression_id:
type: string
label: 'Rules expression plugin ID'
context_definitions:
type: sequence
label: 'Context definitions'
sequence:
- type: rules.context.definition
provided_context_definitions:
type: sequence
label: 'Provided context definitions'
sequence:
- type: rules.context.definition
configuration:
type: rules_expression.[%parent.expression_id]
label: 'Configuration'
component:
type: rules_component

rules.reaction.*:
type: config_entity
Expand All @@ -64,12 +50,27 @@ rules.reaction.*:
core:
type: string
label: 'Drupal version'
expression_id:
type: string
label: 'Rules expression plugin ID'
configuration:
type: rules_expression.[%parent.expression_id]
label: 'Configuration'
expression:
type: rules_expression.[id]
label: 'Expression configuration'

rules_component:
type: mapping
label: 'Rules component (embedded)'
mapping:
context_definitions:
type: sequence
label: 'Context definitions'
sequence:
- type: rules.context.definition
provided_context:
type: sequence
label: 'Names of provided context'
sequence:
- type: string
expression:
type: rules_expression.[id]
label: 'Expression configuration'

rules_expression:
type: mapping
Expand Down Expand Up @@ -212,8 +213,11 @@ rules.context.definition:
type: string
label: 'Type'
label:
type: string
type: text
label: 'Label'
description:
type: text
label: 'Description'

rules.settings:
type: config_object
Expand Down
37 changes: 37 additions & 0 deletions src/Core/RulesUiComponentProviderInterface.php
@@ -0,0 +1,37 @@
<?php

/**
* @file
* Contains \Drupal\rules\Core\RulesUiComponentProviderInterface.
*/

namespace Drupal\rules\Core;

use Drupal\rules\Engine\RulesComponent;

/**
* Interface for objects providing components for editing.
*
* Usually, this would be implemented by a config entity storing the component.
*/
interface RulesUiComponentProviderInterface {

/**
* Gets the Rules component to be edited.
*
* @return \Drupal\rules\Engine\RulesComponent
* The Rules component.
*/
public function getComponent();

/**
* Updates the configuration based upon the given component.
*
* @param \Drupal\rules\Engine\RulesComponent $component
* The component containing the configuration to set.
*
* @return $this
*/
public function updateFromComponent(RulesComponent $component);

}
85 changes: 75 additions & 10 deletions src/Core/RulesUiConfigHandler.php
Expand Up @@ -7,6 +7,7 @@

namespace Drupal\rules\Core;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase;
Expand All @@ -21,7 +22,16 @@
*
* It follows a list of supported settings. Note that settings that are not
* marked as optional are required.
* - config_parameter: The name of the routing parameter holding the config.
* - config_parameter: The name of the routing parameter holding a config
* object providing the edited component. The parameter object must implement
* \Drupal\rules\Core\RulesUiComponentProviderInterface. Required, unless
* config_name and config_key are provided.
* - config_name: The name of a (simple) configuration object containing the
* configuration data of the edited component. For example,
* 'your_module.your_config'. Required if 'config_parameter' is omitted.
* - config_key: The key used to get/set the configuration of the edited
* component. For example, 'conditions' or 'foo.conditions'. Required if
* 'config_parameter' is omitted.
*
* @see RulesUiDefinition::settings
*/
Expand All @@ -43,34 +53,51 @@ class RulesUiConfigHandler extends PluginBase implements RulesUiHandlerInterface
*/
protected $currentRouteMatch;

/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;


/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container->get('current_route_match'));
return new static($configuration, $plugin_id, $plugin_definition, $container->get('current_route_match'), $container->get('config.factory'));
}

/**
* {@inheritdoc}
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The current route match.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match, ConfigFactoryInterface $config_factory) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->currentRouteMatch = $route_match;
$this->configFactory = $config_factory;
}

/**
* Gets the edited config object.
*
* @return \Drupal\Core\Config\Entity\ConfigEntityBase|\Drupal\Core\Config\Config
* The config entity or config object.
* @return \Drupal\rules\Core\RulesUiComponentProviderInterface|\Drupal\Core\Config\Config
* The component provider object (usually a config entity) or the editable
* config object.
*/
public function getConfig() {
$config = $this->fetchFromTempStore();
if (!$config) {
$config = $this->currentRouteMatch->getParameter($this->pluginDefinition->settings['config_parameter']);
if (isset($this->pluginDefinition->settings['config_parameter'])) {
$config = $this->currentRouteMatch->getParameter($this->pluginDefinition->settings['config_parameter']);
}
else {
$config = $this->configFactory->getEditable($this->pluginDefinition->settings['config_name']);
}
}
return $config;
}
Expand All @@ -94,24 +121,62 @@ public function getComponentLabel() {
* {@inheritdoc}
*/
public function getComponent() {
return $this->getConfig()->getComponent();
$config = $this->getConfig();
if ($config instanceof RulesUiComponentProviderInterface) {
return $config->getComponent();
}
else {
$configuration = $config->get($this->pluginDefinition->settings['config_key']);
return RulesComponent::createFromConfiguration($configuration);
}
}

/**
* {@inheritdoc}
*/
public function updateComponent(RulesComponent $component) {
$config = $this->getConfig();
$config->updateFromComponent($component);
if ($config instanceof RulesUiComponentProviderInterface) {
$config->updateFromComponent($component);
}
else {
$config->set($this->pluginDefinition->settings['config_key'], $component->getConfiguration());
}
$this->storeToTempStore($config);
}

/**
* {@inheritdoc}
*/
public function getBaseRouteUrl() {
public function getBaseRouteUrl(array $options = []) {
// See Url::fromRouteMatch()
return Url::fromRoute($this->pluginDefinition->base_route, $this->currentRouteMatch->getRawParameters()->all());
return Url::fromRoute(
$this->pluginDefinition->base_route,
$this->currentRouteMatch->getRawParameters()->all(),
$options
);
}

/**
* {@inheritdoc}
*/
public function getUrlFromRoute($route_suffix, array $route_parameters, array $options = []) {
// See Url::fromRouteMatch()
return Url::fromRoute(
$this->pluginDefinition->base_route . '.' . $route_suffix,
$route_parameters + $this->currentRouteMatch->getRawParameters()->all(),
$options
);
}

/**
* Gets the form handler for the component's expression.
*
* @return \Drupal\rules\Form\Expression\ExpressionFormInterface|null
* The form handling object if there is one, NULL otherwise.
*/
public function getFormHandler() {
return $this->getComponent()->getExpression()->getFormHandler();
}

}
42 changes: 40 additions & 2 deletions src/Core/RulesUiHandlerInterface.php
Expand Up @@ -54,6 +54,14 @@ public function getComponent();
*/
public function updateComponent(RulesComponent $component);

/**
* Gets the form handler for the component's expression.
*
* @return \Drupal\rules\Form\Expression\ExpressionFormInterface|null
* The form handling object if there is one, NULL otherwise.
*/
public function getFormHandler();

/**
* Clears any temporary storage.
*
Expand All @@ -65,10 +73,40 @@ public function clearTemporaryStorage();
/**
* Returns the URL of the base route, based on the current URL.
*
* @param array $options
* (optional) Options for generating the URL, as supported by
* \Drupal\Core\Url::fromRoute().
*
* @return \Drupal\Core\Url
* The URL of the base route.
*/
public function getBaseRouteUrl(array $options = []);

/**
* Gets an URL for a Rules UI route.
*
* @param string $route_suffix
* The Rules UI route suffix that is appended to the base route. Supported
* routes are:
* - expression.add: The add expression form.
* - expression.edit: The edit expression form.
* - expression.delete: The delete expression form.
* - break.lock: The break lock form.
* @param array $route_parameters
* (optional) An associative array of route parameter names and values.
* Depending on the route, the required parameters are:
* - expression-id: The expression plugin to add on expression.add.
* - uuid: The UUID of the expression to be edited or deleted.
* @param array $options
* (optional) Options for generating the URL, as supported by
* \Drupal\Core\Url::fromRoute().
*
* @return \Drupal\Core\Url
* The url of the base route.
* The URL of the given route.
*
* @see \Drupal\rules\Routing\RulesUiRouteSubscriber::registerRoutes()
*/
public function getBaseRouteUrl();
public function getUrlFromRoute($route_suffix, array $route_parameters, array $options = []);

/**
* Determines if the component is locked for the current user.
Expand Down
36 changes: 36 additions & 0 deletions src/Core/RulesUiHandlerTrait.php
@@ -0,0 +1,36 @@
<?php

/**
* @file
* Contains \Drupal\rules\Core\RulesUiHandlerTrait.
*/

namespace Drupal\rules\Core;

/**
* Trait for getting the rules_ui handler of the current request.
*
* Note that the current route must have the _rules_ui option set for the
* handler being available. This is done automatically for routes generated for
* the rules_ui (via \Drupal\rules\Routing\RulesUiRouteSubscriber).
*/
trait RulesUiHandlerTrait {

/**
* The rules UI handler.
*
* @var \Drupal\rules\Core\RulesUiHandlerInterface
*/
protected $rulesUiHandler;

/**
* Gets the rules UI handler of the current route.
*
* @return \Drupal\rules\Core\RulesUiHandlerInterface|null
* The handler, or NULL if this is no rules_ui enabled route.
*/
public function getRulesUiHandler() {
return \Drupal::request()->attributes->get('rules_ui_handler');
}

}