mutual_credit-5.0.x-dev/src/Entity/Access/TransactionAccessControlHandler.php
src/Entity/Access/TransactionAccessControlHandler.php
<?php namespace Drupal\mcapi\Entity\Access; use Drupal\mcapi\TransactionOperations; use Drupal\mcapi\Entity\Storage\WalletStorage; use Drupal\user\Entity\User; use Drupal\Core\Entity\EntityAccessControlHandler; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityHandlerInterface; use Drupal\mcapi\Entity\Query\WalletQuery; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Access\AccessResult; use Drupal\Core\Messenger\Messenger; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Defines an access controller option for the mcapi_transaction entity. */ class TransactionAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface { /** * @var Drupal\mcapi\Entity\Query\WalletQuery */ protected $walletQuery; /** * @var Drupal\Core\Messenger\Messenger */ protected $messenger; /** * * @param EntityTypeInterface $entity_type * @param WalletQuery $wallet_query * @param Messenger $messenger */ public function __construct(EntityTypeInterface $entity_type, WalletQuery $wallet_query, Messenger $messenger) { parent::__construct($entity_type); $this->walletQuery = $wallet_query; $this->messenger = $messenger; } /** * * @param ContainerInterface $container * @param EntityTypeInterface $entity_type * @return \static */ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { return new static( $entity_type, $container->get('entity_type.manager')->getStorage('mcapi_wallet')->getQuery(), $container->get('messenger') ); } /** * {@inheritdoc} */ public function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { if ($this->walletQuery->accessCheck(TRUE)->count()->execute() < 2) { // There must be at least 2 wallets on the system. // Would be great not to have to bother with this check. $this->messenger->addWarning('Transaction forms cannot be accessed until at least 2 wallets exist.'); $result = AccessResult::forbidden('At least 2 wallets needed to transact.'); } elseif ($account->hasPermission('create 3rdparty transaction')) { $result = AccessResult::allowed(); } elseif (WalletStorage::hasWallet(User::load($account->id()))) { $result = AccessResult::allowed(); } else { $result = AccessResult::forbidden('User has no wallet.'); } return $result->cachePerUser(); } /** * {@inheritdoc} * * @note operation can be any of the names of transaction action Plugins */ public function access(EntityInterface $transaction, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) { $account = $this->prepareUser($account); if ($operation == 'view label') { $operation = 'view'; } $cid = 'mcapi_transaction:' . $transaction->id(); if (($return = $this->getCache($cid, $operation, 'und', $account)) !== NULL) { // Cache hit, no work necessary. return $return_as_object ? $return : $return->isAllowed(); } if ($operation === 'view' && $account->hasPermission('view all transactions')) { $access = AccessResult::allowed()->cachePerUser(); } elseif ($action = TransactionOperations::loadOperation($operation)) { $access = $action->getPlugin() ->access($transaction, $account, TRUE) ->cachePerUser() ->addCacheableDependency($transaction); } else { $access = AccessResult::forbidden("Unknown transaction operation: $operation"); } $others = $this->moduleHandler()->invokeAll('mcapi_transaction_access', [$transaction, $operation, $account]); $return = $this->processAccessHookResults(array_merge($others, [$access])); $result = $this->setCache($return, $cid, $operation, 'und', $account); return $return_as_object ? $result : $result->isAllowed(); } }