og-8.x-1.x-dev/src/Plugin/Field/FieldFormatter/GroupSubscribeFormatter.php
src/Plugin/Field/FieldFormatter/GroupSubscribeFormatter.php
<?php
declare(strict_types=1);
namespace Drupal\og\Plugin\Field\FieldFormatter;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Attribute\FieldFormatter;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\RedirectDestinationTrait;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\og\GroupTypeManagerInterface;
use Drupal\og\OgAccessInterface;
use Drupal\user\EntityOwnerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation for the OG subscribe formatter.
*/
#[FieldFormatter(
id: 'og_group_subscribe',
label: new TranslatableMarkup('OG Group subscribe'),
description: new TranslatableMarkup('Display OG Group subscribe and un-subscribe links.'),
field_types: [
'og_group',
],
)]
class GroupSubscribeFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
use RedirectDestinationTrait;
public function __construct(
$plugin_id,
$plugin_definition,
FieldDefinitionInterface $field_definition,
array $settings,
$label,
$view_mode,
array $third_party_settings,
protected readonly AccountInterface $currentUser,
protected readonly OgAccessInterface $ogAccess,
protected readonly EntityTypeManagerInterface $entityTypeManager,
protected readonly GroupTypeManagerInterface $groupTypeManager,
) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
$configuration['field_definition'],
$configuration['settings'],
$configuration['label'],
$configuration['view_mode'],
$configuration['third_party_settings'],
$container->get('current_user'),
$container->get('og.access'),
$container->get('entity_type.manager'),
$container->get('og.group_type_manager')
);
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
// Cache by the OG membership state. Anonymous users are handled below.
$elements['#cache']['contexts'] = [
'og_membership_state',
'user.roles:authenticated',
];
$cache_meta = CacheableMetadata::createFromRenderArray($elements);
$group = $items->getEntity();
$entity_type_id = $group->getEntityTypeId();
$cache_meta->merge(CacheableMetadata::createFromObject($group));
$cache_meta->applyTo($elements);
$user = $this->entityTypeManager->getStorage('user')->load(($this->currentUser->id()));
if (($group instanceof EntityOwnerInterface) && ($group->getOwnerId() == $user->id())) {
// User is the group manager.
$elements[0] = [
'#type' => 'html_tag',
'#tag' => 'span',
'#attributes' => [
'title' => $this->t('You are the group manager'),
'class' => ['group', 'manager'],
],
'#value' => $this->t('You are the group manager'),
];
return $elements;
}
$storage = $this->entityTypeManager->getStorage('og_membership');
$props = [
'uid' => $user ? $user->id() : 0,
'entity_type' => $group->getEntityTypeId(),
'entity_bundle' => $group->bundle(),
'entity_id' => $group->id(),
];
$memberships = $storage->loadByProperties($props);
/** @var \Drupal\og\OgMembershipInterface $membership */
$membership = reset($memberships);
if ($membership) {
$cache_meta->merge(CacheableMetadata::createFromObject($membership));
$cache_meta->applyTo($elements);
if ($membership->isBlocked()) {
// If user is blocked, they should not be able to apply for
// membership.
return $elements;
}
// Member is pending or active.
$link['title'] = $this->t('Unsubscribe from group');
$link['url'] = Url::fromRoute('og.unsubscribe', [
'entity_type_id' => $entity_type_id,
'group' => $group->id(),
]);
$link['class'] = ['unsubscribe'];
}
else {
// If the user is authenticated, set up the subscribe link.
if ($user->isAuthenticated()) {
$parameters = [
'entity_type_id' => $group->getEntityTypeId(),
'group' => $group->id(),
'og_membership_type' => $this->groupTypeManager->getGroupDefaultMembershipType($group->getEntityTypeId(), $group->bundle()),
];
$url = Url::fromRoute('og.subscribe', $parameters);
}
else {
$cache_meta->setCacheContexts(['user.roles:anonymous']);
// User is anonymous, link to user login and redirect back to here.
$url = Url::fromRoute('user.login', [], ['query' => $this->getDestinationArray()]);
}
$cache_meta->applyTo($elements);
/** @var \Drupal\Core\Access\AccessResult $access */
if (($access = $this->ogAccess->userAccess($group, 'subscribe without approval', $user)) && $access->isAllowed()) {
$link['title'] = $this->t('Subscribe to group');
$link['class'] = ['subscribe'];
$link['url'] = $url;
}
elseif (($access = $this->ogAccess->userAccess($group, 'subscribe', $user)) && $access->isAllowed()) {
$link['title'] = $this->t('Request group membership');
$link['class'] = ['subscribe', 'request'];
$link['url'] = $url;
}
else {
$elements[0] = [
'#type' => 'html_tag',
'#tag' => 'span',
'#attributes' => [
'title' => $this->t('This is a closed group. Only a group administrator can add you.'),
'class' => ['group', 'closed'],
],
'#value' => $this->t('This is a closed group. Only a group administrator can add you.'),
];
return $elements;
}
}
if (!empty($link['title'])) {
$link += [
'options' => [
'attributes' => [
'title' => $link['title'],
'class' => ['group'] + $link['class'],
],
],
];
$elements[0] = [
'#type' => 'link',
'#title' => $link['title'],
'#url' => $link['url'],
];
}
return $elements;
}
}
