simple_grouped_content-2.0.x-dev/modules/sgc_support_module/sgc_support_module.module
modules/sgc_support_module/sgc_support_module.module
<?php
/**
* @file
* Contains supporting customizations for the Simple Grouped Content module.
*/
use Drupal\group\Entity\GroupRelationshipInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\group\Entity\GroupRelationshipType;
use Drupal\group\Entity\GroupInterface;
use Drupal\node\Entity\Node;
use Drupal\value_fetcher\ValueFetcher;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\group_content_menu\GroupContentMenuInterface;
/**
* Implements hook_entity_extra_field_info().
*
* PURPOSE: Establish psuedo field for rendering node using full view mode.
*/
function sgc_support_module_entity_extra_field_info() {
$extra = [];
$container = \Drupal::getContainer();
if ($container) {
$bundleInfo = $container->get('entity_type.bundle.info');
$group_content_bundles_info = $bundleInfo->getBundleInfo('group_content');
// Load all group content plugin ids for node entity bundles/types.
// Ensures we only modify group content fields if the related content
// is a node bundle/type (as opposed to media for example).
$groupRelationTypeManager = $container->get('group_relation_type.manager');
$group_content_node_plugins = $groupRelationTypeManager->getPluginIdsByEntityTypeId('node');
foreach ($group_content_node_plugins as $group_content_node_plugin_id) {
// Load all relationship type ids for group content node plugin id.
// Not entirely sure what this is, but it gives us the expected id to
// compare to ids in $group_content_bundles_info.
$relationship_type_ids = $groupRelationTypeManager->getRelationshipTypeIds($group_content_node_plugin_id);
foreach ($relationship_type_ids as $relationship_type_id) {
foreach ($group_content_bundles_info as $bundle_id => $info) {
if ($relationship_type_id === $bundle_id) {
$extra['group_content'][$bundle_id]['display']['related_content_node'] = [
'label' => t('Related Node'),
'description' => t('Display of the related node'),
'weight' => 100,
'visible' => TRUE,
];
}
}
}
}
}
return $extra;
}
/**
* Implements hook_ENTITY_TYPE_view().
*
* PURPOSE: Render the actual node entity on group content node relationships.
*/
function sgc_support_module_group_content_view(array &$build, GroupRelationshipInterface $group_content_entity, EntityViewDisplay $display, $view_mode) {
if ($view_mode === 'full') {
if ($display->getComponent('related_content_node')) {
$entity = $group_content_entity->getEntity();
if ($entity->getEntityType()->id() == 'node') {
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
// Get all of the revision ids.
$revision_ids = \Drupal::entityTypeManager()
->getStorage('node')
->revisionIds($entity);
$last_revision_id = end($revision_ids);
$last_revision = \Drupal::entityTypeManager()
->getStorage('node')
->loadRevision($last_revision_id);
// Authenticated users always see the latest revision.
if (
!\Drupal::currentUser()->isAnonymous()
&& (
\Drupal::currentUser()->hasPermission('Bypass group access control')
|| $group_content_entity->getGroup()->getMember(\Drupal::currentUser())
)
) {
$build['related_content_node'] =
$view_builder->view($last_revision, 'default');
}
else {
$build['related_content_node'] =
$view_builder->view($entity, 'default');
}
}
}
}
}
/**
* Implements hook_local_tasks_alter().
*
* PURPOSE: Adjust group content tabs naming for simplification / clarity.
*/
function sgc_support_module_local_tasks_alter(&$local_tasks) {
$local_tasks['group.edit_form']['title'] = t('Edit Group');
$local_tasks['group_content.edit']['title'] = t('Edit Metadata');
}
/**
* Helper function to get a node's group content item.
*
* @param int $nid
* Integer for NID.
* @param string $bundle
* Machine name of the node bundle to look for.
*
* @return bool|\Drupal\Core\Entity\EntityInterface|mixed
* FALSE if no group content or multiple, if one returns the group content.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
function sgc_support_module_load_group_content_from_node_values($nid, $bundle) {
$group_content = [];
// Skip profiles as they are known to have multiple pieces of group content.
if ($bundle !== 'profile') {
$plugin_id = 'group_node:' . $bundle;
$group_content_types = GroupRelationshipType::loadByPluginId($plugin_id);
if (!empty($group_content_types)) {
// Load all the group content for this node.
$entities = \Drupal::entityTypeManager()
->getStorage('group_content')
->loadByProperties([
'type' => array_keys($group_content_types),
'entity_id' => $nid,
]);
// Return singular result.
if (count($entities) === 1) {
$group_content = reset($entities);
}
if (count($entities) > 1) {
\Drupal::logger('sgc_support_module')->notice(
'Multiple group content found for NID: @nid (in sgc_support_module_load_group_content_from_node_values)',
['@nid' => $nid]
);
}
}
}
return $group_content;
}
/**
* Implements hook_ENTITY_TYPE_insert().
*
* PURPOSE: On insert with field_group_rendered_content populated, create
* group content association.
*/
function sgc_support_module_group_insert(GroupInterface $entity) {
if ($entity->hasField('field_group_homepage') ) {
$referenced_group_values = ValueFetcher::getAllValues($entity, 'field_group_homepage');
if ($referenced_group_values) {
/** @var \Drupal\node\Entity\Node $node */
$node = Node::load($referenced_group_values['target_id']);
$entity->addRelationship($node, 'group_node:' . $node->bundle(), []);
}
}
}
/**
* Implements hook_ENTITY_TYPE_update().
*
* PURPOSE: On update of group with field_group_rendered_content, create
* group content association if it does not already exist.
*/
function sgc_support_module_group_update(GroupInterface $entity) {
if ($entity->hasField('field_group_homepage')) {
$current_ref = ValueFetcher::getAllValues($entity, 'field_group_homepage');
$previous_ref = ValueFetcher::getAllValues($entity->original, 'field_group_homepage');
if (
isset($current_ref['target_id']) && (
!isset($previous_ref['target_id']) || (
$previous_ref['target_id'] !== $current_ref['target_id'])
)
) {
/** @var \Drupal\node\Entity\Node $node */
$node = Node::load($current_ref['target_id']);
$entity->addRelationship($node, 'group_node:' . $node->bundle(), []);
}
}
}
/**
* Implements hook_entity_field_access().
*
* PURPOSE: Allow menu link to display for users with group permission.
*
*/
function sgc_support_module_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
if (
$field_definition->getName() == 'field_group_content_menu_link'
&& $operation == 'edit'
) {
$group = \Drupal::routeMatch()->getParameter('group');
if (!is_null($group) && is_object($group)) {
return AccessResult::allowedIf($group->hasPermission('access group menu field', $account));
}
}
return AccessResult::neutral();
}
/**
* Implement hook_entity_access().
*
* PURPOSE: Make sure users have access to create group content menu links.
*/
function sgc_support_module_entity_access(\Drupal\Core\Entity\EntityInterface $entity, $operation, \Drupal\Core\Session\AccountInterface $account) {
if (
in_array($entity->getEntityType()->id() ,[
'menu_link_content',
'group_content_menu'
])
) {
// If there is a group param, this is easy!
$group = \Drupal::routeMatch()->getParameter('group');
if (!is_null($group) && is_object($group)) {
return AccessResult::allowedIf($group->hasPermission('manage group_content_menu', $account));
}
// If there is no group param, we gotta try and derive the group from values.
$menu_item = ValueFetcher::getFirstValue($entity, 'menu_name');
if ($menu_item && str_contains($menu_item, 'group_menu_link_content-')) {
$gconent_entity_id = explode('group_menu_link_content-', $menu_item)[1];
$entities = \Drupal::entityTypeManager()->getStorage('group_content')->loadByProperties(['entity_id' => $gconent_entity_id]);
if (count($entities) === 1) {
$group = reset($entities)->getGroup();
return AccessResult::allowedIf($group->hasPermission('manage group_content_menu', $account));;
}
}
}
// No opinion on aother entity access checks.
return AccessResult::neutral();
}
/**
* Implement hook_entity_operation_alter().
*
* PURPOSE: Disable the groups operation link to menus. No one needs this!
*/
function sgc_support_module_entity_operation_alter(array &$operations, \Drupal\Core\Entity\EntityInterface $entity) {
if (
isset($operations['menus'])
&& $entity instanceof Drupal\group\Entity\Group
&& !in_array('administrator', \Drupal::currentUser()->getRoles())
) {
unset($operations['menus']);
}
}
