Skip to content

Commit

Permalink
Merge pull request #149 from amitaibu/207-cleanup
Browse files Browse the repository at this point in the history
Add Group tab
  • Loading branch information
amitaibu authored Sep 2, 2016
2 parents d83bdb4 + 5037766 commit 0402e17
Show file tree
Hide file tree
Showing 22 changed files with 1,683 additions and 19 deletions.
408 changes: 408 additions & 0 deletions config/optional/views.view.og_members_overview.yml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions og.links.task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
og.og_admin_routes:
deriver: \Drupal\og\Plugin\Derivative\OgLocalTask
19 changes: 19 additions & 0 deletions og.module
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Enable users to create and manage groups with roles and permissions.
*/

use Drupal\og\GroupTypeManager;
use Drupal\user\UserInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\ContentEntityInterface;
Expand Down Expand Up @@ -227,3 +228,21 @@ function og_field_formatter_info_alter(array &$info) {
$info[$key]['field_types'][] = OgGroupAudienceHelper::GROUP_REFERENCE;
}
}

/**
* Implements hook_entity_type_alter().
*
* Add link template to groups. We add it to all the entity types, and later on
* return the correct access, depending if the bundle is indeed a group and
* accessible. We do not filter here the entity type by groups, so whenever
* GroupTypeManager::addGroup is called, it's enough to mark route to be rebuilt
* via RouteBuilder::setRebuildNeeded.
*/
function og_entity_type_alter(array &$entity_types) {
/** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
foreach ($entity_types as $entity_type_id => $entity_type) {
$entity_type->setLinkTemplate('og-admin-routes', "/group/$entity_type_id/{{$entity_type_id}}/admin");
}
}


8 changes: 7 additions & 1 deletion og.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ services:
- { name: 'event_subscriber' }
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']
arguments: ['@config.factory', '@entity_type.manager', '@entity_type.bundle.info', '@event_dispatcher', '@state', '@og.permission_manager', '@og.role_manager', '@router.builder']
og.permissions:
class: Drupal\og\OgPermissionHandler
arguments: ['@module_handler', '@string_translation', '@controller_resolver']
og.permission_manager:
class: Drupal\og\PermissionManager
arguments: ['@event_dispatcher']
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']
Expand All @@ -33,3 +38,4 @@ services:
plugin.manager.og.fields:
class: Drupal\og\OgFieldsPluginManager
parent: default_plugin_manager

36 changes: 31 additions & 5 deletions src/Access/GroupCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\og\Og;
use Drupal\og\OgAccess;
Expand All @@ -13,6 +14,9 @@

/**
* Determines access to routes based on group access for the current user.
*
* This is a general service that can be used to determine if a user has access
* to a certain route.
*/
class GroupCheck implements AccessInterface {

Expand Down Expand Up @@ -44,28 +48,50 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, OgA
}

/**
* Checks access.
* Checks access by OG related permissions.
*
* If the route parameter names don't have {entity_type_id} or {entity_id} you
* can still use this access check, by passing the "entity_type_id" definition
* using the Route::setOption method.
* see \Drupal\og\Routing\RouteSubscriber::alterRoutes as an example.
*
* @param \Drupal\Core\Session\AccountInterface $user
* The currently logged in user.
* @param \Symfony\Component\Routing\Route $route
* The route to check against.
* @param string $entity_type_id
* The entity type.
* (optional) The entity type ID.
* @param string $entity_id
* The entity ID.
* (optional) The entity ID. If the ID is not sent, the access method will
* try to extract it from the route matcher.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function access(AccountInterface $user, Route $route, $entity_type_id, $entity_id) {
public function access(AccountInterface $user, Route $route, RouteMatchInterface $route_match, $entity_type_id = NULL, $entity_id = NULL) {
$group = NULL;
if (!$entity_type_id) {
$parameter_name = $route_match->getRouteObject()->getOption('_og_entity_type_id');

if (!$parameter_name) {
throw new \BadMethodCallException('Group definition is missing from the router. Did you define $route->setOption(\'_og_entity_type_id\', $entity_type_id) in your route declaration?');
}

/** @var \Drupal\Core\Entity\EntityInterface $group */
if (!$group = $route_match->getParameter($parameter_name)) {
return AccessResult::forbidden();
}

$entity_type_id = $group->getEntityTypeId();
}

// No access if the entity type doesn't exist.
if (!$this->entityTypeManager->getDefinition($entity_type_id, FALSE)) {
return AccessResult::forbidden();
}

$entity_storage = $this->entityTypeManager->getStorage($entity_type_id);
$group = $entity_storage->load($entity_id);
$group = $group ?: $entity_storage->load($entity_id);

// No access if no entity was loaded or it's not a group.
if (!$group || !Og::isGroup($entity_type_id, $group->bundle())) {
Expand Down
33 changes: 33 additions & 0 deletions src/Controller/OgAdminMembersController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Drupal\og\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\views\Views;

/**
* OgAdminMembersController class.
*/
class OgAdminMembersController extends ControllerBase {

/**
* Display list of members that belong to the group.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match service.
*
* @return array
* The members overview View.
*/
public function membersList(RouteMatchInterface $route_match) {
$parameter_name = $route_match->getRouteObject()->getOption('_og_entity_type_id');

/** @var \Drupal\Core\Entity\EntityInterface $group */
$group = $route_match->getParameter($parameter_name);

$arguments = [$group->getEntityTypeId(), $group->id()];
return Views::getView('og_members_overview')->executeDisplay('default', $arguments);
}

}
107 changes: 107 additions & 0 deletions src/Controller/OgAdminRoutesController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

namespace Drupal\og\Controller;

use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Drupal\Core\Access\AccessManagerInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\og\Event\OgAdminRoutesEvent;
use Drupal\og\Event\OgAdminRoutesEventInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* The OG admin routes controller.
*/
class OgAdminRoutesController extends ControllerBase {

/**
* The event dispatcher service.
*
* @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
*/
protected $eventDispatcher;

/**
* The access manager service.
*
* @var \Drupal\Core\Access\AccessManagerInterface
*/
protected $accessManager;

/**
* Constructs an OgAdminController object.
*
* @param \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher $event_dispatcher
* The event dispatcher service.
* @param \Drupal\Core\Access\AccessManagerInterface $access_manager
* The access manager service.
*/
public function __construct(ContainerAwareEventDispatcher $event_dispatcher, AccessManagerInterface $access_manager) {
$this->eventDispatcher = $event_dispatcher;
$this->accessManager = $access_manager;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('event_dispatcher'),
$container->get('access_manager')
);
}

/**
* Show all the available admin routes.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match service.
*
* @return array
* List of available admin routes for the current group.
*/
public function overview(RouteMatchInterface $route_match) {
$parameter_name = $route_match->getRouteObject()->getOption('_og_entity_type_id');

/** @var \Drupal\Core\Entity\EntityInterface $group */
$group = $route_match->getParameter($parameter_name);

$entity_type_id = $group->getEntityTypeId();

// Get list from routes.
$content = [];

$event = new OgAdminRoutesEvent();
$event = $this->eventDispatcher->dispatch(OgAdminRoutesEventInterface::EVENT_NAME, $event);

foreach ($event->getRoutes($entity_type_id) as $name => $info) {
$route_name = "entity.$entity_type_id.og_admin_routes.$name";
$parameters = [$entity_type_id => $group->id()];

// We don't use Url::fromRoute() here for the access check, as it will
// prevent us from unit testing this method.
if (!$this->accessManager->checkNamedRoute($route_name, $parameters)) {
// User doesn't have access to the route.
continue;
}

$content[$name]['title'] = $info['title'];
$content[$name]['description'] = $info['description'];
$content[$name]['url'] = Url::fromRoute($route_name, $parameters);
}

if (!$content) {
return ['#markup' => $this->t('You do not have any administrative items.')];
}

return [
'og_admin_routes' => [
'#theme' => 'admin_block_content',
'#content' => $content,
],
];
}

}
4 changes: 2 additions & 2 deletions src/Entity/OgMembership.php
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
->setDescription(t('The entity type of the group.'));

$fields['entity_id'] = BaseFieldDefinition::create('string')
->setLabel(t('Group entity id.'))
->setLabel(t('Group entity id'))
->setDescription(t("The entity ID of the group."));

$fields['state'] = BaseFieldDefinition::create('string')
Expand All @@ -281,7 +281,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Create'))
->setDescription(t('The Unix timestamp when the group content was created.'));
->setDescription(t('The Unix timestamp when the membership was created.'));

$fields['language'] = BaseFieldDefinition::create('language')
->setLabel(t('Language'))
Expand Down
65 changes: 65 additions & 0 deletions src/Event/OgAdminRoutesEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Drupal\og\Event;

use Symfony\Component\EventDispatcher\Event;

/**
* Event that is fired when OG admin routes are being compiled.
*/
class OgAdminRoutesEvent extends Event implements OgAdminRoutesEventInterface {

/**
* The routes info array.
*
* @var array
*/
protected $routesInfo = [];

/**
* {@inheritdoc}
*/
public function setRoutes(array $routes_info) {
$this->routesInfo = $routes_info;
}

/**
* {@inheritdoc}
*/
public function getRoutes($entity_type_id) {
$routes_info = [];

foreach ($this->routesInfo as $name => $route_info) {

$routes_info[$name] = $route_info;

// Add default values.
$routes_info[$name] += [
'description' => '',

'requirements' => [
'_og_user_access_group' => 'administer group',
],

'options' => [
'parameters' => [
$entity_type_id => ['type' => 'entity:' . $entity_type_id],
],
// The above parameters doesn't send the entity,
// so we will have to use the Route matcher to extract it.
'_og_entity_type_id' => $entity_type_id,
'_admin_route' => TRUE,
],

// Move the title and controller under the "defaults" key.
'defaults' => [
'_controller' => $route_info['controller'],
'_title' => $route_info['title'],
],
];
}

return $routes_info;
}

}
41 changes: 41 additions & 0 deletions src/Event/OgAdminRoutesEventInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Drupal\og\Event;

/**
* Interface for OgAdminRoutesEvent classes.
*
* This event allows implementing modules to provide their own OG Admin routes
* or alter existing definitions that are provided by other modules.
*/
interface OgAdminRoutesEventInterface {

/**
* The event name.
*/
const EVENT_NAME = 'og.og_admin_routes';

/**
* Set routes info.
*
* Array with the routes to create with the following keys:
* - title
* - controller.
*
* @param array $routes_info
* The routes info array.
*/
public function setRoutes(array $routes_info);

/**
* Get routes.
*
* @param string $entity_type_id
* The entity type ID.
*
* @return array
* Array with the routes info.
*/
public function getRoutes($entity_type_id);

}
Loading

0 comments on commit 0402e17

Please sign in to comment.