This repository was archived by the owner on Aug 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 130
Port OG-Context module as OgContext provider #180
Merged
Merged
Changes from 87 commits
Commits
Show all changes
112 commits
Select commit
Hold shift + click to select a range
03c0969
First sketch of the OG context module.
b267014
Adding files.
bd4bbcd
Moving OG context to OG core.
b17e50f
Commit more work.
ed2f4a2
Iterate over plugins easily.
f4439c6
Get list of plugins by a logic you desire.
2ca93c8
Minor fixes.
273dd20
Get the plugins in the right order.
9f5d251
Get the group from the url.
55e06bb
Pushing work.
bc82a45
Get the group from a group content.
1666774
Get all the groups.
27c3fac
Remove a line in the end of the file.
b263d46
My own CR fixes.
a2f5eb7
Adding some tests.
70da07b
Merge master
6e0b1e5
CS fixes(hope)
c00439b
More CS.
245cc8a
she's into a typical riff.
ddb9d7f
Hmm...
ec3f732
Return the first group for now.
cb4bf5a
Keep entity as the only plugin.
3a6d73e
Testing the context it self.
1753887
Rename the plugin to GroupResolver.
603fffe
Refactor the entity name [skip ci]
113b402
More renaming [skip ci]
f3c98a8
More renaming [skip ci]
0a0f5e4
Down with renaming.
5aea9ee
Fix code sniffer.
becdcf7
Merge branch '8.x-1.x' into 242
9fce221
Fix tests.
5ee68e9
Fix conflicts
f59e521
Extend from the correct class and fix a service.
23a59c7
Make CS happy.
e9c7f0a
Adding test.
e7cad2d
Merge remote-tracking branch 'origin/8.x-1.x' into 242
pfrenssen a65d814
Merge remote-tracking branch 'origin/8.x-1.x' into 242
pfrenssen 5e0f89b
Simplify the way we will resolve groups to determine group context.
pfrenssen a447c99
Use the standard naming scheme for plugin managers.
pfrenssen 9081809
Provide an updated interface for group resolver plugins.
pfrenssen 09c1797
Rename the GroupResolver plugin type to OgGroupResolver.
pfrenssen 31ba598
Use correct name for the property containing a reference to the group…
pfrenssen b265bf5
Initial untested implementation of OgContext.
pfrenssen 8be29c7
OgGroupResolver plugins need to declare which cache contexts are affe…
pfrenssen 885996d
Update plugin name, this has been renamed to OgGroupResolver.
pfrenssen 8cff83a
Document how the discovery of the group context works.
pfrenssen 277eb20
Exploring the first OgResolver plugin.
pfrenssen 999820f
Fix bugs popping up after actually trying to run the code :)
pfrenssen 23d3024
Add schema for the group resolvers configuration entry.
pfrenssen 72ce165
Initial version of the RouteGroupContentResolver.
pfrenssen 7d10f44
Initial version of the RequestQueryArgumentResolver.
pfrenssen dc4e7e7
Use the correct method name.
pfrenssen eb363ee
Don't let plugins decide which is the best candidate. This is the res…
pfrenssen 8ca2cba
Merge remote-tracking branch 'origin/8.x-1.x' into 242-simplified
pfrenssen cf137c9
Remove the tests for the initial approach. They are no longer valid.
pfrenssen d5cae35
The original Entity plugin has been replaced by RouteGroupResolver an…
pfrenssen 46143f8
Fix coding standards.
pfrenssen 80f5d88
Account for the difference between plugins that provide actual groups…
pfrenssen e5c28de
Start on unit tests for the OgGroupResolver plugins.
pfrenssen 57afdad
Test RouteGroupResolver::getGroups().
pfrenssen 84c0b9d
Fix PHP_CodeSniffer warnings.
pfrenssen 3847ecd
Moar PHP_CodeSniffer warning fixes.
pfrenssen 736f110
Remove the notion of a OgResolver plugin type.
pfrenssen 5b625a0
Initial implementation of the OgResolvedGroupCollection.
pfrenssen 0ff6952
Use an OgResolvedGroupCollection to gather the resolved groups, inste…
pfrenssen d130c00
Convert RouteGroupResolver to use OgResolvedGroupCollection.
pfrenssen af8f2e1
Partially start using the OgResolvedGroupCollection in the context pr…
pfrenssen 2a5615a
Fix PHP_CodeSniffer warnings.
pfrenssen b0815e1
Refactor group resolver test so its functionality can be reused in ot…
pfrenssen e72348a
Convert RouteGroupContentResolver to use the group collection.
pfrenssen cf3a2a8
Start on a test for the RouteGroupContentResolver.
pfrenssen a48da8e
Convert RequestQueryArgumentResolver to use the resolved group collec…
pfrenssen d3ef86f
Update documentation.
pfrenssen c37f100
Merge remote-tracking branch 'gizra/8.x-1.x' into 242-simplified
pfrenssen 13330de
Fix coding standards violation.
pfrenssen 58412ab
Merge branch 'convert-group-audience-helper-to-service' into 242-simp…
pfrenssen c36670f
Merge remote-tracking branch 'gizra/8.x-1.x' into 242-simplified
pfrenssen aa06968
Finish the unit test of the RouteGroupContentResolver now that GroupA…
pfrenssen 5e3cdac
Store all properties in a single array.
pfrenssen 355cd70
Store cache context information in the resolved group collection.
pfrenssen ffe8bed
Remove empty method.
pfrenssen bb4a95c
Refactor shared code for the route based plugin tests to the base class.
pfrenssen d0be60c
Do not forget to call your parent.
pfrenssen 5bffde3
Maintain identical ordering for the dependencies.
pfrenssen 8038951
Let the base test class handle dependency injection.
pfrenssen 7cdfe5c
Refactor code to make it reusable in tests.
pfrenssen 154a090
Add a test for the RequestQueryArgumentResolver plugin.
pfrenssen 4c895b5
Change method name to better reflect what it actually returns.
pfrenssen 9c9346e
Move the hardcoded filtering by user access to a dedicated plugin.
pfrenssen b1f244a
Refactor the sorting of the resolved groups into the collection class.
pfrenssen bb193ee
Simplify the handling of cache contexts now that the heavy lifting is…
pfrenssen b2cbdbf
Update documentation.
pfrenssen bad78ed
Fix coding standards.
pfrenssen 646fa0c
Rename property so that it is clearer what it contains.
pfrenssen 68edfe2
Make it possible to override the way mocked test group entities are c…
pfrenssen 57ff754
Mark the method that returns test entity properties as abstract so th…
pfrenssen 3da581b
Update documentation.
pfrenssen f9cb560
Add a test for the UserGroupAccessResolver plugin.
pfrenssen 2cc4844
Fix coding standards.
pfrenssen 9a24ff7
Start on a test for OgResolvedGroupCollection.
pfrenssen 4d4983d
Add more test coverage for OgResolvedGroupCollection.
pfrenssen 78cde1e
Test the sorting of groups in a collection and fix bugs discovered by…
pfrenssen 6d0b4e3
Sorting items with the same value is undefined, we can't test this.
pfrenssen 1077495
Merge remote-tracking branch 'origin/8.x-1.x' into 242-simplified
pfrenssen 1f72be2
Start on a test for OgContext.
pfrenssen 43284d4
Merge remote-tracking branch 'upstream/8.x-1.x' into 242-simplified
pfrenssen b79ce83
Start testing the logic in OgContext::getBestCandidate().
pfrenssen 5897952
Add a standard test case, a single group resolver returning a single …
pfrenssen d962300
Fix PHP_CodeSniffer warnings.
pfrenssen 0c5185d
Test if cache contexts are correctly provided in the cacheability met…
pfrenssen 1cd8d87
Add a test case for two resolver plugins that each return a different…
pfrenssen 1dc75d8
Add a complex test case, and test if propagation can be stopped.
pfrenssen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,209 @@ | ||
| <?php | ||
|
|
||
| namespace Drupal\og\ContextProvider; | ||
|
|
||
| use Drupal\Component\Plugin\PluginManagerInterface; | ||
| use Drupal\Core\Cache\CacheableMetadata; | ||
| use Drupal\Core\Config\ConfigFactoryInterface; | ||
| use Drupal\Core\Plugin\Context\Context; | ||
| use Drupal\Core\Plugin\Context\ContextDefinition; | ||
| use Drupal\Core\Plugin\Context\ContextProviderInterface; | ||
| use Drupal\Core\StringTranslation\StringTranslationTrait; | ||
| use Drupal\og\OgResolvedGroupCollection; | ||
|
|
||
| /** | ||
| * Provides the group that best matches the current context. | ||
| */ | ||
| class OgContext implements ContextProviderInterface { | ||
|
|
||
| use StringTranslationTrait; | ||
|
|
||
| /** | ||
| * The OgGroupResolver plugin manager. | ||
| * | ||
| * @var \Drupal\Component\Plugin\PluginManagerInterface | ||
| */ | ||
| protected $pluginManager; | ||
|
|
||
| /** | ||
| * The config factory. | ||
| * | ||
| * @var \Drupal\Core\Config\ConfigFactoryInterface | ||
| */ | ||
| protected $configFactory; | ||
|
|
||
| /** | ||
| * IDs of cache contexts that are relevant for the current group context. | ||
| * | ||
| * @var string[] | ||
| */ | ||
| protected $cacheContextIds = []; | ||
|
|
||
| /** | ||
| * Constructs a new OgContext. | ||
| * | ||
| * @param \Drupal\Component\Plugin\PluginManagerInterface $plugin_manager | ||
| * The OgGroupResolver plugin manager. | ||
| * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory | ||
| * The config factory. | ||
| */ | ||
| public function __construct(PluginManagerInterface $plugin_manager, ConfigFactoryInterface $config_factory) { | ||
| $this->pluginManager = $plugin_manager; | ||
| $this->configFactory = $config_factory; | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function getRuntimeContexts(array $unqualified_context_ids) { | ||
| // Don't bother to resolve the group context if it is not requested. | ||
| if (!in_array('og', $unqualified_context_ids)) { | ||
| return []; | ||
| } | ||
|
|
||
| return ['og' => $this->getOgContext()]; | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function getAvailableContexts() { | ||
| $context = new Context(new ContextDefinition('entity', $this->t('Active group'))); | ||
| return ['og' => $context]; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the context object containing the relevant group. | ||
| * | ||
| * @return \Drupal\Core\Plugin\Context\Context | ||
| * A context object containing the group which is relevant in the current | ||
| * context as a value. If there is no relevant group in the current context | ||
| * then the value will be empty. | ||
| */ | ||
| protected function getOgContext() { | ||
| $context_definition = new ContextDefinition('entity', $this->t('Active group'), FALSE); | ||
| $context = new Context($context_definition, $this->getBestCandidate()); | ||
|
|
||
| $cacheability = new CacheableMetadata(); | ||
| $cacheability->setCacheContexts($this->cacheContextIds); | ||
|
|
||
| $context->addCacheableDependency($cacheability); | ||
|
|
||
| return $context; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the group which best matches the current context. | ||
| * | ||
| * There might be several groups that are relevant in the current context, and | ||
| * this method tries to determine which is the best possible candidate. | ||
| * | ||
| * For example, if we are on a page that displays a group content entity that | ||
| * belongs to two groups, then both groups are relevant in the current | ||
| * context. We might then decide which group is the better candidate by | ||
| * looking at a URL query argument or inspecting the user's browsing history | ||
| * to see if they are coming from a group page. | ||
| * | ||
| * This discovery of groups is handled by OgGroupResolver plugins. Each plugin | ||
| * is responsible for discovering groups in a specific domain (e.g. find all | ||
| * groups belonging to the current route). The plugins that will be used for | ||
| * the discovery are configurable; they are listed under the 'group_resolvers' | ||
| * key in the 'og.settings' config. The plugins are ordered by priority, | ||
| * meaning that if two groups are relevant to the current context, then the | ||
| * plugin with the highest priority will decide which group is going to 'win'. | ||
| * | ||
| * Developers can customize the group context result by providing their own | ||
| * plugins and by activating, disabling or reordering the default ones. | ||
| * | ||
| * @return \Drupal\Core\Entity\EntityInterface|null | ||
| * The group entity which is most relevant in the current context, or NULL | ||
| * if no relevant group was found. | ||
| * | ||
| * @see \Drupal\og\OgGroupResolverInterface | ||
| */ | ||
| protected function getBestCandidate() { | ||
| $collection = new OgResolvedGroupCollection(); | ||
| $plugins = []; | ||
|
|
||
| // Retrieve the list of group resolvers. These are stored in config, and are | ||
| // ordered by priority. | ||
| $group_resolvers = $this->configFactory->get('og.settings')->get('group_resolvers'); | ||
| $priority = 0; | ||
| foreach ($group_resolvers as $plugin_id) { | ||
| /** @var \Drupal\og\OgGroupResolverInterface $plugin */ | ||
| if ($plugin = $this->pluginManager->createInstance($plugin_id)) { | ||
| $plugins[$plugin_id] = $plugin; | ||
|
|
||
| // Set the default vote weight according to the plugin's priority. | ||
| $collection->setVoteWeight($priority); | ||
|
|
||
| // Let the plugin do its magic. | ||
| $plugin->resolve($collection); | ||
|
|
||
| // If the plugin is certain that the candidate belongs to the current | ||
| // context, it can declare the search to be over. | ||
| if ($plugin->isPropagationStopped()) { | ||
| break; | ||
| } | ||
|
|
||
| // The next plugin we try will have a lower priority. | ||
| $priority--; | ||
| } | ||
| } | ||
|
|
||
| // @todo This should be moved to a plugin. | ||
| // Filter out inappropriate results. | ||
| array_filter($collection, function (array $candidate) { | ||
| // Filter out results that are not accessible by the current user. | ||
| return $candidate['entity']->access('view'); | ||
| }); | ||
|
|
||
| // @todo This should be handled in the collection. | ||
| // Since we have filtered the results by the current user, we need to add | ||
| // the user as a cache context. | ||
| $this->addCacheContextIds(['user']); | ||
|
|
||
| // @todo Move this in the collection? Seems to make sense, since the | ||
| // collection has knowledge about the groups and votes. | ||
| // Find the best matching group by iterating over the candidates and return | ||
| // the one that has the most "votes". If there are multiple candidates with | ||
| // the same number of votes then the candidate that was resolved by the | ||
| // plugin(s) with the highest priority will be returned. | ||
| uasort($collection, function ($a, $b) { | ||
| if (count($a['votes']) == count($b['votes'])) { | ||
| return array_sum($a['votes']) < array_sum($b['votes']) ? -1 : 1; | ||
| } | ||
| return count($a['votes']) < count($b['votes']) ? -1 : 1; | ||
| }); | ||
|
|
||
| // We found the best candidate. | ||
| $candidate = reset($collection); | ||
|
|
||
| if (empty($candidate)) { | ||
| return NULL; | ||
| } | ||
|
|
||
| // Compile the cache contexts that were used by the plugins that voted for | ||
| // our chosen candidate. | ||
| foreach (array_keys($candidate['votes']) as $plugin_id) { | ||
| $this->addCacheContextIds($plugins[$plugin_id]->getCacheContextIds()); | ||
| }; | ||
|
|
||
| return $candidate['entity']; | ||
| } | ||
|
|
||
| /** | ||
| * Adds a list of cache context IDs to be included in the context object. | ||
| * | ||
| * @param string[] $contexts | ||
| * An array of cache context IDs. | ||
| */ | ||
| protected function addCacheContextIds($contexts) { | ||
| foreach ($contexts as $context) { | ||
| if (!in_array($context, $this->cacheContextIds)) { | ||
| $this->cacheContextIds[] = $context; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| <?php | ||
|
|
||
| namespace Drupal\og; | ||
|
|
||
| use Drupal\Core\Plugin\PluginBase; | ||
|
|
||
| /** | ||
| * Base class for OgGroupResolver plugins. | ||
| */ | ||
| abstract class OgGroupResolverBase extends PluginBase implements OgGroupResolverInterface { | ||
|
|
||
| /** | ||
| * Whether the group resolving process can be stopped. | ||
| * | ||
| * @var bool | ||
| */ | ||
| protected $propagationStopped = FALSE; | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function stopPropagation() { | ||
| $this->propagationStopped = TRUE; | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function isPropagationStopped() { | ||
| return $this->propagationStopped; | ||
| } | ||
|
|
||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
so, is
voteslike +1 that each plugin may give?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.
Yes, with a small difference, their vote will be depending on their position in the list, so the first plugin's vote will count for more than the second plugin's vote. This will allow us to easily choose the correct "winner" if we have two groups with the same number of votes.
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.
Note that the OgContext code still needs to be cleaned up and tested, it still contains parts from the original implementation. But the basic idea will remain the same.