Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
ddddfd2
Added EventHandlerEntityBundle.
milkovsky Feb 5, 2016
52317fd
Added EventHandlerEntityBundle to events yml.
milkovsky Feb 5, 2016
b60b780
Started writing EventHandlerTest. WIP.
milkovsky Feb 5, 2016
753833d
EventHandlerTest WIP.
milkovsky Feb 5, 2016
46f1fbe
Improved EventHandlerTest WIP.
milkovsky Feb 5, 2016
066e4ec
PR fixes.
milkovsky Feb 10, 2016
0f1a9e5
Dispatch events by base name of a configured event name.
milkovsky Feb 10, 2016
ecce557
Implemented testEntityBundleHandlerExecution.
milkovsky Feb 10, 2016
54c3cd4
PR fixes.
milkovsky Feb 11, 2016
03ecf3a
PR fixes.
milkovsky Feb 11, 2016
7fbae65
PR fixes.
milkovsky Feb 11, 2016
8e4af1b
PR fixes.
milkovsky Feb 11, 2016
b57e33d
Change rules config to have multiple events.
milkovsky Feb 11, 2016
7d0d7e2
Tests for multiple events.
milkovsky Feb 11, 2016
87dca7d
PR fixes.
milkovsky Feb 15, 2016
a58f03a
Inject the Rules event manager.
milkovsky Feb 15, 2016
cb7f762
Code formatting.
milkovsky Feb 16, 2016
6fecbad
Merge branch '8.x-3.x' of github.com:fago/rules into feature/RUL-45
milkovsky Feb 18, 2016
944aa09
After merge fix.
milkovsky Feb 18, 2016
9ead81e
Initialize events [].
milkovsky Feb 18, 2016
7332b45
Merge branch '8.x-3.x' into feature/2658842-event-handler-per-bundle
milkovsky Feb 18, 2016
346ec1d
Merge branch 'feature/2658842-event-handler-per-bundle' into feature/…
milkovsky Feb 18, 2016
92aacdc
Fix test after merge.
milkovsky Feb 18, 2016
b866850
Added ajax reload.
milkovsky Feb 18, 2016
5b1a9c3
Bundle select + handler. WIP.
milkovsky Feb 19, 2016
c14b531
Merge branch '8.x-3.x' into feature/RUL-44
milkovsky Feb 26, 2016
df48c33
After merge fixes.
milkovsky Feb 26, 2016
8e0c714
Merge branch '8.x-3.x' into feature/RUL-45
milkovsky Feb 26, 2016
3378725
Merge branch 'feature/RUL-45' into feature/RUL-44
milkovsky Feb 26, 2016
1b353fb
Fixed event discovery by base name.
milkovsky Feb 26, 2016
d179fcf
Fixed expression set in rules handler test.
milkovsky Feb 26, 2016
0c297b6
Merge branch '8.x-3.x' into feature/RUL-45
milkovsky Feb 26, 2016
5eea48c
Fix testMultipleEvents test.
milkovsky Feb 26, 2016
ab4e106
Merge branch 'feature/RUL-45' into feature/RUL-44
milkovsky Feb 26, 2016
c936dfc
Implemented summary().
milkovsky Feb 26, 2016
8a0f988
Issue #2666200 by a.milkovsky: Change reaction-rule config to save th…
fago Feb 26, 2016
a341b28
Refactoring.
milkovsky Feb 26, 2016
fa7d831
Refactoring.
milkovsky Feb 26, 2016
d44f026
Issue #2677018 by fago: Condition and Action expression plugins have …
Feb 27, 2016
660a505
Issue #2677042 by fago: Test that using provided variables passes int…
fago Feb 27, 2016
7f51cd4
Issue #2677034: Add a test case to ensure context is refined when che…
fago Feb 27, 2016
f3234cf
Issue #2677034: Add test case to verify provided variables use refine…
fago Feb 27, 2016
ef0aa79
Re-factored to move context-related integrity checks below Context na…
fago Feb 27, 2016
0632db5
Issue #2677034 by fago: Simplify preparation of metadata state logic …
fago Feb 27, 2016
3c17965
Issue #2677034 by fago: Make checking integrity work with preparing m…
fago Feb 27, 2016
44d1880
Issue #2677034: Update ContextHandlerTraitTest to recent changes.
fago Feb 27, 2016
3a24053
Issue #2677034 by fago: Make type checking strict while there is no t…
fago Feb 27, 2016
fe2186e
Issue #2677034 by fago: Document how integrity checks and exeuction m…
fago Feb 27, 2016
c5c0c06
Issue 2677028 by fago: Make VariableAddTest properly refine context.
fago Feb 27, 2016
acf0fc6
Issue #2676996 by fago: Allow contextual plugins to fetch metadata of…
fago Feb 28, 2016
4878568
Fix integrity checks of required context to respect default values.
fago Feb 28, 2016
8093abb
Improve work-around for #2677162 to only silently catch exception for…
fago Feb 28, 2016
bd51c6e
Re-name data comparison operator context to operation and make it req…
fago Feb 28, 2016
7f0d1a7
Issue #2676996 by fago: Add test coverage for checking integrity base…
fago Feb 28, 2016
eee4fc6
Issue #2281079 by fago: Add test-coverage for refining context defin…
fago Feb 28, 2016
67aea83
Improve prepareContextWithMetadata() documentation to mention possibl…
fago Feb 28, 2016
cc04db6
Enabled Drupal 8.2.x dev in testing
klausi Mar 5, 2016
691dbeb
Removed duplicate config schema definition
klausi Feb 29, 2016
3a0d230
Issue #2664700: Expose Rules components as action plugin
klausi Mar 6, 2016
86476df
Issue #2681733 by fago: Allow context-aware plugins to assert metadata.
fago Mar 5, 2016
7d22771
Issue #2681733 by fago: Add metadata assertion support to expressions.
fago Mar 5, 2016
e0ad506
Issue #2681733 by fago: Add test coverage for metadata assertions.
fago Mar 6, 2016
2f4d041
Issue #2681733 by fago: Improve docs to clarify the difference betwee…
fago Mar 7, 2016
d95464c
Issue #2681733 by fago: Improve metadata assertions test coverage.
fago Mar 7, 2016
f6266e3
Merge branch 'feature/RUL-44' of git://github.com/milkovsky/rules int…
fago Mar 7, 2016
7fecba2
Worked over bundle configurable event.
fago Mar 7, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ php:
env:
- DRUPAL_CORE=8.0.x
- DRUPAL_CORE=8.1.x
- DRUPAL_CORE=8.2.x

matrix:
allow_failures:
Expand Down Expand Up @@ -59,7 +60,9 @@ before_script:

# Run composer install for Drupal 8.1. We need an up-to-date composer when
# installing Drupal 8.1.
- if [ "$DRUPAL_CORE" = "8.1.x" ]; then composer self-update && composer install; fi
# Disabled for now because core still includes the vendor directory, see
# https://www.drupal.org/node/1475510
# - if [ "$DRUPAL_CORE" = "8.1.x" ]; then composer self-update && composer install; fi

# Start a web server on port 8888, run in the background.
- php -S localhost:8888 &
Expand Down
7 changes: 7 additions & 0 deletions config/schema/rules.action.schema.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Per default the schema of arbitrary context values of an action cannot be
# typed. Actions that need translatability or other features of the config
# system must specify their context value schema explicitly, see examples below.
rules.action.context_values.*:
type: ignore
label: Context values

rules.action.context_values.rules_system_message:
type: mapping
label: Message action context values
Expand Down
6 changes: 0 additions & 6 deletions config/schema/rules.context.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ rules.context.values:
# The entries depend on the plugin here. Plugins have to extend this and
# provide a suiting schema.

rules.context.mapping:
type: sequence
label: 'Context mapping'
sequence:
- type: string

rules.context.processors:
type: sequence
label: 'Context processors'
Expand Down
6 changes: 3 additions & 3 deletions config/schema/rules.data_types.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ rules_component:
label: 'Context definitions'
sequence:
- type: rules.context.definition
provided_context:
provided_context_definitions:
type: sequence
label: 'Names of provided context'
label: 'Provided context definitions'
sequence:
- type: string
- type: rules.context.definition
expression:
type: rules_expression.[id]
label: 'Expression configuration'
18 changes: 15 additions & 3 deletions config/schema/rules.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,21 @@ rules.reaction.*:
label:
type: label
label: 'Label'
event:
type: string
label: 'Event'
events:
type: sequence
label: 'Events'
sequence:
type: mapping
label: 'Event'
mapping:
event_name:
type: string
label: 'Name'
configuration:
type: sequence
label: 'Configuration'
sequence:
type: mapping
module:
type: string
label: 'Module'
Expand Down
41 changes: 40 additions & 1 deletion src/Context/ContextAwarePluginInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,46 @@ interface ContextAwarePluginInterface extends CoreContextAwarePluginInterface {
* When a plugin is configured half-way or even fully, some context values are
* already available upon which the definition of subsequent or provided
* context can be refined.
*
* Implement this method, when the plugin's context definitions need to be
* refined. When the selected data definitions should be refined, implement
* ::assertMetadata() instead.
*
* Note that context gets refined at configuration and execution time of the
* plugin.
*
* @param \Drupal\Core\TypedData\DataDefinitionInterface[] $selected_data
* An array of data definitions for context that is mapped using a data
* selector, keyed by context name.
*/
public function refineContextDefinitions(array $selected_data);

/**
* Asserts additional metadata for the selected data.
*
* Allows the plugin to assert additional metadata that is in place when the
* plugin has been successfully executed. A typical use-case would be
* asserting the node type for a "Node is of type" condition. By doing so,
* sub-sequent executed plugins are aware of the metadata and can build upon
* it.
*
* Implement this method, when the selected data definitions need to be
* refined. When the plugin's context definitions should be refined, implement
* ::refineContextDefinitions() instead.
*
* Note that metadata is only asserted on configuration time. The plugin has
* to ensure that the run-time data matches the asserted configuration if it
* has been executed successfully.
*
* @param \Drupal\Core\TypedData\DataDefinitionInterface[] $selected_data
* An array of data definitions for context that is mapped using a data
* selector, keyed by context name.
*
* @return \Drupal\Core\TypedData\DataDefinitionInterface[]
* An array of modified data definitions, keyed as the passed array. Note
* data definitions need to be cloned *before* they are modified, such that
* the changes do not propagate unintentionally.
*/
public function refineContextDefinitions();
public function assertMetadata(array $selected_data);

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@

/**
* @file
* Contains \Drupal\rules\Engine\IntegrityCheckTrait.
* Contains \Drupal\rules\Engine\ContextHandlerIntegrityTrait.
*/

namespace Drupal\rules\Engine;
namespace Drupal\rules\Context;

use Drupal\Core\Plugin\Context\ContextDefinitionInterface;
use Drupal\Core\Plugin\Context\ContextDefinitionInterface as CoreContextDefinitionInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface as CoreContextAwarePluginInterface;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\ListInterface;
use Drupal\Core\TypedData\PrimitiveInterface;
use Drupal\rules\Context\ContextDefinitionInterface as RulesContextDefinitionInterface;
use Drupal\rules\Context\ContextProviderInterface;
use Drupal\rules\Engine\ExecutionMetadataStateInterface;
use Drupal\rules\Engine\IntegrityViolation;
use Drupal\rules\Engine\IntegrityViolationList;
use Drupal\rules\Exception\RulesIntegrityException;

/**
* Provides shared integrity checking methods for conditions and actions.
* Extends the context handler trait with support for checking integrity.
*/
trait IntegrityCheckTrait {
trait ContextHandlerIntegrityTrait {

use ContextHandlerTrait;

/**
* Performs the integrity check.
Expand All @@ -34,16 +35,19 @@ trait IntegrityCheckTrait {
* @return \Drupal\rules\Engine\IntegrityViolationList
* The list of integrity violations.
*/
protected function doCheckIntegrity(CoreContextAwarePluginInterface $plugin, ExecutionMetadataStateInterface $metadata_state) {
protected function checkContextConfigIntegrity(CoreContextAwarePluginInterface $plugin, ExecutionMetadataStateInterface $metadata_state) {
$violation_list = new IntegrityViolationList();
$context_definitions = $plugin->getContextDefinitions();

// Make sure that all provided variables by this plugin are added to the
// execution metadata state.
$this->addProvidedContextDefinitions($plugin, $metadata_state);

foreach ($context_definitions as $name => $context_definition) {
// Check if a data selector is configured that maps to the state.
if (isset($this->configuration['context_mapping'][$name])) {
try {
$data_definition = $metadata_state->fetchDefinitionByPropertyPath($this->configuration['context_mapping'][$name]);

$data_definition = $this->getMappedDefinition($name, $metadata_state);
$this->checkDataTypeCompatible($context_definition, $data_definition, $name, $violation_list);
}
catch (RulesIntegrityException $e) {
Expand Down Expand Up @@ -83,7 +87,7 @@ protected function doCheckIntegrity(CoreContextAwarePluginInterface $plugin, Exe
$violation_list->add($violation);
}
}
elseif ($context_definition->isRequired()) {
elseif ($context_definition->isRequired() && $context_definition->getDefaultValue() === NULL) {
$violation = new IntegrityViolation();
$violation->setMessage($this->t('The required context %context_name is missing.', [
'%context_name' => $context_definition->getLabel(),
Expand Down Expand Up @@ -112,10 +116,6 @@ protected function doCheckIntegrity(CoreContextAwarePluginInterface $plugin, Exe
}
}

// Make sure that all provided variables by this plugin are added to the
// execution metadata state.
$this->addProvidedVariablesToExecutionMetadataState($plugin, $metadata_state);

return $violation_list;
}

Expand All @@ -131,28 +131,17 @@ protected function doCheckIntegrity(CoreContextAwarePluginInterface $plugin, Exe
* @param \Drupal\rules\Engine\IntegrityViolationList $violation_list
* The list of violations where new ones will be added.
*/
protected function checkDataTypeCompatible(ContextDefinitionInterface $context_definition, DataDefinitionInterface $provided, $context_name, IntegrityViolationList $violation_list) {
$expected_class = $context_definition->getDataDefinition()->getClass();
$provided_class = $provided->getClass();
$expected_type_problem = NULL;

if (is_subclass_of($expected_class, PrimitiveInterface::class)
&& !is_subclass_of($provided_class, PrimitiveInterface::class)
) {
$expected_type_problem = $this->t('primitive');
}
elseif (is_subclass_of($expected_class, ListInterface::class)
&& !is_subclass_of($provided_class, ListInterface::class)
) {
$expected_type_problem = $this->t('list');
}
elseif (is_subclass_of($expected_class, ComplexDataInterface::class)
&& !is_subclass_of($provided_class, ComplexDataInterface::class)
) {
$expected_type_problem = $this->t('complex');
protected function checkDataTypeCompatible(CoreContextDefinitionInterface $context_definition, DataDefinitionInterface $provided, $context_name, IntegrityViolationList $violation_list) {
// Compare data types. For now, fail if they are not equal.
// @todo: Add support for matching based upon type-inheritance.
$target_type = $context_definition->getDataDefinition()->getDataType();

// Special case any and entity target types for now.
if ($target_type == 'any' || ($target_type == 'entity' && strpos($provided->getDataType(), 'entity:') !== FALSE)) {
return;
}

if ($expected_type_problem) {
if ($target_type != $provided->getDataType()) {
$expected_type_problem = $context_definition->getDataDefinition()->getDataType();
$violation = new IntegrityViolation();
$violation->setMessage($this->t('Expected a @expected_type data type for context %context_name but got a @provided_type data type instead.', [
'@expected_type' => $expected_type_problem,
Expand All @@ -165,33 +154,4 @@ protected function checkDataTypeCompatible(ContextDefinitionInterface $context_d
}
}

/**
* Adds provided variables to the execution metadata state.
*
* @param CoreContextAwarePluginInterface $plugin
* The action or condition plugin that may provide variables.
* @param \Drupal\rules\Engine\ExecutionMetadataStateInterface $metadata_state
* The excution metadata state to add variables to.
*/
public function addProvidedVariablesToExecutionMetadataState(CoreContextAwarePluginInterface $plugin, ExecutionMetadataStateInterface $metadata_state) {
if ($plugin instanceof ContextProviderInterface) {
$provided_context_definitions = $plugin->getProvidedContextDefinitions();

foreach ($provided_context_definitions as $name => $context_definition) {
if (isset($this->configuration['provides_mapping'][$name])) {
// Populate the state with the new variable that is provided by this
// plugin. That is necessary so that the integrity check in subsequent
// actions knows about the variable and does not throw violations.
$metadata_state->setDataDefinition(
$this->configuration['provides_mapping'][$name],
$context_definition->getDataDefinition()
);
}
else {
$metadata_state->setDataDefinition($name, $context_definition->getDataDefinition());
}
}
}
}

}
Loading