-
Notifications
You must be signed in to change notification settings - Fork 130
Port OG-Context module as OgContext provider #180
Changes from 42 commits
03c0969
b267014
bd4bbcd
b17e50f
ed2f4a2
f4439c6
2ca93c8
273dd20
9f5d251
55e06bb
bc82a45
1666774
27c3fac
b263d46
a2f5eb7
70da07b
6e0b1e5
c00439b
245cc8a
ddb9d7f
ec3f732
cb4bf5a
3a6d73e
1753887
603fffe
113b402
f3c98a8
0a0f5e4
5aea9ee
becdcf7
9fce221
5ee68e9
f59e521
23a59c7
e9c7f0a
e7cad2d
a65d814
5e0f89b
a447c99
9081809
09c1797
31ba598
b265bf5
8be29c7
885996d
8cff83a
277eb20
999820f
23d3024
72ce165
7d10f44
dc4e7e7
eb363ee
8ca2cba
cf137c9
d5cae35
46143f8
80f5d88
e5c28de
57afdad
84c0b9d
3847ecd
736f110
5b625a0
0ff6952
d130c00
af8f2e1
2a5615a
b0815e1
e72348a
cf3a2a8
a48da8e
d3ef86f
c37f100
13330de
58412ab
c36670f
aa06968
5e3cdac
355cd70
ffe8bed
bb4a95c
d0be60c
5bffde3
8038951
7cdfe5c
154a090
4c895b5
9c9346e
b1f244a
bb193ee
b2cbdbf
bad78ed
646fa0c
68edfe2
57ff754
3da581b
f9cb560
2cc4844
9a24ff7
4d4983d
78cde1e
6d0b4e3
1077495
1f72be2
43284d4
b79ce83
5897952
d962300
0c5185d
1cd8d87
1dc75d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| <?php | ||
|
|
||
| namespace Drupal\og\Annotation; | ||
|
|
||
| use Drupal\Component\Annotation\Plugin; | ||
|
|
||
| /** | ||
| * Defines the OgGroupResolver annotation object. | ||
| * | ||
| * @see \Drupal\og\OgGroupResolverPluginManager | ||
| * @see plugin_api | ||
| * | ||
| * @Annotation | ||
| */ | ||
| class OgGroupResolver extends Plugin { | ||
|
|
||
| /** | ||
| * The plugin ID. | ||
| * | ||
| * @var string | ||
| */ | ||
| public $id; | ||
|
|
||
| /** | ||
| * The label of the plugin. | ||
| * | ||
| * @var \Drupal\Core\Annotation\Translation | ||
| * | ||
| * @ingroup plugin_translatable | ||
| */ | ||
| public $label; | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| <?php | ||
|
|
||
| namespace Drupal\og; | ||
|
|
||
| use Drupal\Component\Plugin\PluginInspectionInterface; | ||
|
|
||
| /** | ||
| * Defines an interface for OgGroupResolver plugins. | ||
| * | ||
| * These plugins are used to discover which groups are relevant in the current | ||
| * context. Each plugin is responsible for finding groups in a particular | ||
| * domain. For example, we can have a plugin that checks if we are on the | ||
| * canonical URL of a group entity, and can take the group entity from the | ||
| * route object. | ||
| * | ||
| * Sometimes a plugin might return multiple relevant groups, for example if it | ||
| * finds a group content entity on the route that belongs to multiple groups. | ||
| * | ||
| * These plugins are invoked by OgContext::getRuntimeContexts() which then | ||
| * interprets the results and makes an educated guess at the group which is most | ||
| * relevant in the current context. | ||
| * | ||
| * @see \Drupal\og\ContextProvider\OgContext::getRuntimeContexts() | ||
| */ | ||
| interface OgGroupResolverInterface { | ||
|
|
||
| /** | ||
| * Returns the groups that were resolved by the plugin. | ||
| * | ||
| * @return \Drupal\Core\Entity\EntityInterface[] | ||
| * An array of groups. | ||
| */ | ||
| public function getGroups(); | ||
|
|
||
| /** | ||
| * Returns the group that is most relevant in the plugin's context. | ||
| * | ||
| * A plugin can have enough domain specific knowledge to determine with | ||
| * certainty that a particular group is the most relevant in a certain domain. | ||
| * This method can be used to return that group. | ||
| * | ||
| * If the plugin doesn't have absolute certainty that a particular group is | ||
| * the most relevant, this will return NULL. | ||
| * | ||
| * @return \Drupal\Core\Entity\EntityInterface|null | ||
| * The group that is the best candidate, or NULL if there is no best | ||
| * candidate. | ||
| */ | ||
| public function getBestCandidate(); | ||
|
|
||
| /** | ||
| * Declares that no further group resolving is necessary. | ||
| * | ||
| * Use this if the plugin has determined the relevant group in the current | ||
| * context with 100% certainty. | ||
| */ | ||
| public function stopPropagation(); | ||
|
|
||
| /** | ||
| * Returns whether the group resolving process can be stopped. | ||
| * | ||
| * @return bool | ||
| * TRUE if no further group resolving is necessary. FALSE otherwise. | ||
| */ | ||
| public function isPropagationStopped(); | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| <?php | ||
|
|
||
| namespace Drupal\og; | ||
|
|
||
| use Drupal\Core\Cache\CacheBackendInterface; | ||
| use Drupal\Core\Extension\ModuleHandlerInterface; | ||
| use Drupal\Core\Plugin\DefaultPluginManager; | ||
|
|
||
| /** | ||
| * Plugin manager for OgGroupResolver plugins. | ||
| */ | ||
| class OgGroupResolverPluginManager extends DefaultPluginManager { | ||
|
|
||
| /** | ||
| * Constructs an OgGroupResolverPluginManager service. | ||
| * | ||
| * @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 $cache_backend | ||
| * Cache backend instance to use. | ||
| * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler | ||
| * The module handler to invoke the alter hook with. | ||
| */ | ||
| public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { | ||
| parent::__construct('Plugin/OgGroupResolver', $namespaces, $module_handler, 'Drupal\og\OgGroupResolverInterface', 'Drupal\og\Annotation\OgGroupResolver'); | ||
|
|
||
| $this->alterInfo('og_group_resolver_info'); | ||
| $this->setCacheBackend($cache_backend, 'og_group_resolver'); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| <?php | ||
|
|
||
| namespace Drupal\og\Plugin\OgGroupResolver; | ||
|
|
||
| use Drupal\Core\Entity\ContentEntityBase; | ||
| use Drupal\Core\Routing\RouteMatchInterface; | ||
| use Drupal\og\GroupTypeManager; | ||
| use Drupal\og\Og; | ||
| use Drupal\og\OgGroupResolverBase; | ||
| use Symfony\Component\DependencyInjection\ContainerInterface; | ||
|
|
||
| /** | ||
| * Get the group from the given viewed entity. | ||
| * | ||
| * @OgGroupResolver( | ||
| * id = "entity", | ||
| * label = "Entity", | ||
| * description = @Translation("Get the group from the current entity, by checking if it is a group or a group content entity.") | ||
| * ) | ||
| */ | ||
| class Entity extends OgGroupResolverBase { | ||
|
|
||
| /** | ||
| * The route match service. | ||
| * | ||
| * @var RouteMatchInterface | ||
| */ | ||
| protected $routeMatch; | ||
|
|
||
| /** | ||
| * The group type manager service. | ||
| * | ||
| * @var \Drupal\og\GroupTypeManager | ||
| */ | ||
| protected $groupTypeManager; | ||
|
|
||
| /** | ||
| * Constructs a Drupal\Component\Plugin\PluginBase object. | ||
| * | ||
| * @param array $configuration | ||
| * A configuration array containing information about the plugin instance. | ||
| * @param string $plugin_id | ||
| * The plugin_id for the plugin instance. | ||
| * @param mixed $plugin_definition | ||
| * The plugin implementation definition. | ||
| * @param \Drupal\Core\Routing\RouteMatchInterface $route_match | ||
| * The route match service. | ||
| * @param \Drupal\og\GroupTypeManager $group_type_manager | ||
| * The group type manager service. | ||
| */ | ||
| public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match, GroupTypeManager $group_type_manager) { | ||
| parent::__construct($configuration, $plugin_id, $plugin_definition); | ||
| $this->routeMatch = $route_match; | ||
| $this->groupTypeManager = $group_type_manager; | ||
| } | ||
|
|
||
| /** | ||
| * {@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'), | ||
| $container->get('og.group_type_manager') | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function getGroup() { | ||
| foreach ($this->routeMatch->getParameters() as $parameter) { | ||
| if (!($parameter instanceof ContentEntityBase)) { | ||
| continue; | ||
| } | ||
|
|
||
| if ($this->groupTypeManager->isGroup($parameter->getEntityTypeId(), $parameter->bundle())) { | ||
| return $parameter; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The interface states that ::getGroups() should return EntityInterface[] but here returns a single item. Shouldn't be
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still left from the original approach, this is still adhering to the previous implementation of the interface. I think this plugin should probably be entirely removed. This is not a reliable way of discovering entities on routes. I am planning on using the entity paths instead. This code as well as the test code is still to be refactored, it's better to wait a bit with reviewing. I can't manage the labels on this issue, but I'll remove the "WIP" from the title and post a comment when it is ready to be reviewed. |
||
| } | ||
|
|
||
| if (!Og::isGroupContent($parameter->getEntityTypeId(), $parameter->bundle())) { | ||
| continue; | ||
| } | ||
|
|
||
| return Og::getGroups($parameter); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's better to inject
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am thinking of replacing this plugin with a more reliable solution. We can get a list of entity paths from the entity definition and check if the current route matches any of these entity paths. This would avoid false positives on routes that have multiple arguments and happen to have a group in one of them. Imagine you have a search page that allows to filter on related content:
Imagine the 3rd entity is an article that happens to be group content. If we blindly loop over the route parameters then we will suddenly decide that this search results page belongs to the group of the 3rd entity. This could cause all kinds of unexpected behaviour. |
||
| } | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <?php | ||
|
|
||
| namespace Drupal\og_test\Plugin\GroupResolver; | ||
|
|
||
| /** | ||
| * @file | ||
| * Contains \Drupal\og_test\Plugin\OgResolver\UserGroupReference. | ||
| */ | ||
|
|
||
| use Drupal\og\OgContextBase; | ||
|
|
||
| /** | ||
| * Get the group from a field reference attached to the current user. | ||
| * | ||
| * @GroupResolver( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. =>
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 I had already fixed this but I hadn't yet pushed my changes. |
||
| * id = "user_group_reference", | ||
| * label = "User group reference", | ||
| * description = @Translation("A dummy plugin to return the first group from a field attach to the user.") | ||
| * ) | ||
| */ | ||
| class UserGroupReference extends OgContextBase { | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function getGroup() { | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice solution - 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was an idea from @sandervd! There are some cases where you really don't want other plugins influencing the outcome, for example if you are on the canonical path for a group, or if you have a dedicated plugin written for a project that handles the resolving in a custom way.