Skip to content
This repository was archived by the owner on Aug 18, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
03c0969
First sketch of the OG context module.
Jul 17, 2016
b267014
Adding files.
Jul 19, 2016
bd4bbcd
Moving OG context to OG core.
Jul 22, 2016
b17e50f
Commit more work.
Jul 22, 2016
ed2f4a2
Iterate over plugins easily.
Jul 22, 2016
f4439c6
Get list of plugins by a logic you desire.
Jul 22, 2016
2ca93c8
Minor fixes.
Jul 22, 2016
273dd20
Get the plugins in the right order.
Jul 22, 2016
9f5d251
Get the group from the url.
Jul 22, 2016
55e06bb
Pushing work.
Jul 22, 2016
bc82a45
Get the group from a group content.
Jul 22, 2016
1666774
Get all the groups.
Jul 22, 2016
27c3fac
Remove a line in the end of the file.
Jul 23, 2016
b263d46
My own CR fixes.
Jul 23, 2016
a2f5eb7
Adding some tests.
Jul 24, 2016
70da07b
Merge master
Jul 24, 2016
6e0b1e5
CS fixes(hope)
Jul 24, 2016
c00439b
More CS.
Jul 24, 2016
245cc8a
she's into a typical riff.
Jul 24, 2016
ddb9d7f
Hmm...
Jul 24, 2016
ec3f732
Return the first group for now.
Jul 26, 2016
cb4bf5a
Keep entity as the only plugin.
Jul 27, 2016
3a6d73e
Testing the context it self.
Jul 27, 2016
1753887
Rename the plugin to GroupResolver.
Aug 6, 2016
603fffe
Refactor the entity name [skip ci]
Aug 6, 2016
113b402
More renaming [skip ci]
Aug 6, 2016
f3c98a8
More renaming [skip ci]
Aug 6, 2016
0a0f5e4
Down with renaming.
Aug 6, 2016
5aea9ee
Fix code sniffer.
Aug 6, 2016
becdcf7
Merge branch '8.x-1.x' into 242
Aug 6, 2016
9fce221
Fix tests.
Aug 6, 2016
5ee68e9
Fix conflicts
Aug 26, 2016
f59e521
Extend from the correct class and fix a service.
Aug 26, 2016
23a59c7
Make CS happy.
Aug 26, 2016
e9c7f0a
Adding test.
Aug 27, 2016
e7cad2d
Merge remote-tracking branch 'origin/8.x-1.x' into 242
pfrenssen Sep 14, 2016
a65d814
Merge remote-tracking branch 'origin/8.x-1.x' into 242
pfrenssen Sep 15, 2016
5e0f89b
Simplify the way we will resolve groups to determine group context.
pfrenssen Sep 15, 2016
a447c99
Use the standard naming scheme for plugin managers.
pfrenssen Sep 15, 2016
9081809
Provide an updated interface for group resolver plugins.
pfrenssen Sep 15, 2016
09c1797
Rename the GroupResolver plugin type to OgGroupResolver.
pfrenssen Sep 15, 2016
31ba598
Use correct name for the property containing a reference to the group…
pfrenssen Sep 15, 2016
b265bf5
Initial untested implementation of OgContext.
pfrenssen Sep 16, 2016
8be29c7
OgGroupResolver plugins need to declare which cache contexts are affe…
pfrenssen Sep 16, 2016
885996d
Update plugin name, this has been renamed to OgGroupResolver.
pfrenssen Sep 16, 2016
8cff83a
Document how the discovery of the group context works.
pfrenssen Sep 19, 2016
277eb20
Exploring the first OgResolver plugin.
pfrenssen Sep 19, 2016
999820f
Fix bugs popping up after actually trying to run the code :)
pfrenssen Sep 19, 2016
23d3024
Add schema for the group resolvers configuration entry.
pfrenssen Sep 19, 2016
72ce165
Initial version of the RouteGroupContentResolver.
pfrenssen Sep 20, 2016
7d10f44
Initial version of the RequestQueryArgumentResolver.
pfrenssen Sep 20, 2016
dc4e7e7
Use the correct method name.
pfrenssen Sep 20, 2016
eb363ee
Don't let plugins decide which is the best candidate. This is the res…
pfrenssen Sep 21, 2016
8ca2cba
Merge remote-tracking branch 'origin/8.x-1.x' into 242-simplified
pfrenssen Sep 21, 2016
cf137c9
Remove the tests for the initial approach. They are no longer valid.
pfrenssen Sep 21, 2016
d5cae35
The original Entity plugin has been replaced by RouteGroupResolver an…
pfrenssen Sep 21, 2016
46143f8
Fix coding standards.
pfrenssen Sep 22, 2016
80f5d88
Account for the difference between plugins that provide actual groups…
pfrenssen Sep 22, 2016
e5c28de
Start on unit tests for the OgGroupResolver plugins.
pfrenssen Sep 22, 2016
57afdad
Test RouteGroupResolver::getGroups().
pfrenssen Sep 27, 2016
84c0b9d
Fix PHP_CodeSniffer warnings.
pfrenssen Sep 27, 2016
3847ecd
Moar PHP_CodeSniffer warning fixes.
pfrenssen Sep 27, 2016
736f110
Remove the notion of a OgResolver plugin type.
pfrenssen Sep 28, 2016
5b625a0
Initial implementation of the OgResolvedGroupCollection.
pfrenssen Oct 3, 2016
0ff6952
Use an OgResolvedGroupCollection to gather the resolved groups, inste…
pfrenssen Oct 3, 2016
d130c00
Convert RouteGroupResolver to use OgResolvedGroupCollection.
pfrenssen Oct 3, 2016
af8f2e1
Partially start using the OgResolvedGroupCollection in the context pr…
pfrenssen Oct 3, 2016
2a5615a
Fix PHP_CodeSniffer warnings.
pfrenssen Oct 3, 2016
b0815e1
Refactor group resolver test so its functionality can be reused in ot…
pfrenssen Oct 4, 2016
e72348a
Convert RouteGroupContentResolver to use the group collection.
pfrenssen Oct 4, 2016
cf3a2a8
Start on a test for the RouteGroupContentResolver.
pfrenssen Oct 4, 2016
a48da8e
Convert RequestQueryArgumentResolver to use the resolved group collec…
pfrenssen Oct 4, 2016
d3ef86f
Update documentation.
pfrenssen Oct 4, 2016
c37f100
Merge remote-tracking branch 'gizra/8.x-1.x' into 242-simplified
pfrenssen Oct 4, 2016
13330de
Fix coding standards violation.
pfrenssen Oct 4, 2016
58412ab
Merge branch 'convert-group-audience-helper-to-service' into 242-simp…
pfrenssen Oct 4, 2016
c36670f
Merge remote-tracking branch 'gizra/8.x-1.x' into 242-simplified
pfrenssen Oct 5, 2016
aa06968
Finish the unit test of the RouteGroupContentResolver now that GroupA…
pfrenssen Oct 5, 2016
5e3cdac
Store all properties in a single array.
pfrenssen Oct 5, 2016
355cd70
Store cache context information in the resolved group collection.
pfrenssen Oct 5, 2016
ffe8bed
Remove empty method.
pfrenssen Oct 5, 2016
bb4a95c
Refactor shared code for the route based plugin tests to the base class.
pfrenssen Oct 5, 2016
d0be60c
Do not forget to call your parent.
pfrenssen Oct 5, 2016
5bffde3
Maintain identical ordering for the dependencies.
pfrenssen Oct 5, 2016
8038951
Let the base test class handle dependency injection.
pfrenssen Oct 5, 2016
7cdfe5c
Refactor code to make it reusable in tests.
pfrenssen Oct 5, 2016
154a090
Add a test for the RequestQueryArgumentResolver plugin.
pfrenssen Oct 5, 2016
4c895b5
Change method name to better reflect what it actually returns.
pfrenssen Oct 6, 2016
9c9346e
Move the hardcoded filtering by user access to a dedicated plugin.
pfrenssen Oct 6, 2016
b1f244a
Refactor the sorting of the resolved groups into the collection class.
pfrenssen Oct 6, 2016
bb193ee
Simplify the handling of cache contexts now that the heavy lifting is…
pfrenssen Oct 6, 2016
b2cbdbf
Update documentation.
pfrenssen Oct 6, 2016
bad78ed
Fix coding standards.
pfrenssen Oct 6, 2016
646fa0c
Rename property so that it is clearer what it contains.
pfrenssen Oct 7, 2016
68edfe2
Make it possible to override the way mocked test group entities are c…
pfrenssen Oct 7, 2016
57ff754
Mark the method that returns test entity properties as abstract so th…
pfrenssen Oct 7, 2016
3da581b
Update documentation.
pfrenssen Oct 7, 2016
f9cb560
Add a test for the UserGroupAccessResolver plugin.
pfrenssen Oct 7, 2016
2cc4844
Fix coding standards.
pfrenssen Oct 7, 2016
9a24ff7
Start on a test for OgResolvedGroupCollection.
pfrenssen Oct 10, 2016
4d4983d
Add more test coverage for OgResolvedGroupCollection.
pfrenssen Oct 11, 2016
78cde1e
Test the sorting of groups in a collection and fix bugs discovered by…
pfrenssen Oct 11, 2016
6d0b4e3
Sorting items with the same value is undefined, we can't test this.
pfrenssen Oct 13, 2016
1077495
Merge remote-tracking branch 'origin/8.x-1.x' into 242-simplified
pfrenssen Oct 14, 2016
1f72be2
Start on a test for OgContext.
pfrenssen Oct 17, 2016
43284d4
Merge remote-tracking branch 'upstream/8.x-1.x' into 242-simplified
pfrenssen Nov 3, 2016
b79ce83
Start testing the logic in OgContext::getBestCandidate().
pfrenssen Nov 3, 2016
5897952
Add a standard test case, a single group resolver returning a single …
pfrenssen Nov 5, 2016
d962300
Fix PHP_CodeSniffer warnings.
pfrenssen Nov 5, 2016
0c5185d
Test if cache contexts are correctly provided in the cacheability met…
pfrenssen Nov 5, 2016
1cd8d87
Add a test case for two resolver plugins that each return a different…
pfrenssen Nov 5, 2016
1dc75d8
Add a complex test case, and test if propagation can be stopped.
pfrenssen Nov 5, 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
16 changes: 9 additions & 7 deletions og.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ services:
og.access:
class: Drupal\og\OgAccess
arguments: ['@config.factory', '@current_user', '@module_handler', '@og.group_type_manager', '@og.permission_manager', '@og.membership_manager']
og.membership_manager:
class: Drupal\og\MembershipManager
arguments: ['@entity_type.manager']
og.event_subscriber:
class: Drupal\og\EventSubscriber\OgEventSubscriber
arguments: ['@og.permission_manager', '@entity_type.manager', '@entity_type.bundle.info']
Expand All @@ -18,24 +15,29 @@ services:
og.group_type_manager:
class: Drupal\og\GroupTypeManager
arguments: ['@config.factory', '@entity_type.manager', '@entity_type.bundle.info', '@event_dispatcher', '@state', '@og.permission_manager', '@og.role_manager', '@router.builder']
og.membership_manager:
class: Drupal\og\MembershipManager
arguments: ['@entity_type.manager']
og.permissions:
class: Drupal\og\OgPermissionHandler
arguments: ['@module_handler', '@string_translation', '@controller_resolver']
og.permission_manager:
class: Drupal\og\PermissionManager
arguments: ['@event_dispatcher']
og.role_manager:
class: Drupal\og\OgRoleManager
arguments: ['@entity_type.manager', '@event_dispatcher', '@og.permission_manager']
og.route_subscriber:
class: Drupal\og\Routing\RouteSubscriber
arguments: ['@entity_type.manager', '@router.route_provider', '@event_dispatcher']
tags:
- { name: event_subscriber }
og.role_manager:
class: Drupal\og\OgRoleManager
arguments: ['@entity_type.manager', '@event_dispatcher', '@og.permission_manager']
plugin.manager.og.delete_orphans:
class: Drupal\og\OgDeleteOrphansPluginManager
parent: default_plugin_manager
plugin.manager.og.fields:
class: Drupal\og\OgFieldsPluginManager
parent: default_plugin_manager

plugin.manager.og.group_resolver:
class: Drupal\og\OgGroupResolverPluginManager
parent: default_plugin_manager
33 changes: 33 additions & 0 deletions src/Annotation/OgGroupResolver.php
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;

}
67 changes: 67 additions & 0 deletions src/OgGroupResolverInterface.php
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();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice solution - 👍

Copy link
Copy Markdown
Contributor Author

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.


/**
* Returns whether the group resolving process can be stopped.
*
* @return bool
* TRUE if no further group resolving is necessary. FALSE otherwise.
*/
public function isPropagationStopped();

}
32 changes: 32 additions & 0 deletions src/OgGroupResolverPluginManager.php
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');
}

}
91 changes: 91 additions & 0 deletions src/Plugin/OgGroupResolver/Entity.php
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;

@claudiu-cristea claudiu-cristea Sep 15, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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 return [$parameter];?

@pfrenssen pfrenssen Sep 16, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to inject MembershipManager directly (would make unit tests a bit easier)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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:

/search/related/{entity}/{entity}/{entity}

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(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=> @OgGroupResolver? (Just because there could be other group of different things - happened already in D7 even with the vertical tabs module or something similar)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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() {
}

}
Loading