commerce_product_bundles-8.x-1.0/src/Access/ProductBundleVariationAccessControlHandler.php
src/Access/ProductBundleVariationAccessControlHandler.php
<?php
namespace Drupal\commerce_product_bundles\Access;
use Drupal\commerce_product_bundles\Service\ProductBundleVariationFieldManagerInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\commerce_product_bundles\Entity\ProductBundleInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides an access control handler for Product Bundle Variations.
*/
class ProductBundleVariationAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface {
/**
* The current store.
*
* @var \Drupal\commerce_product_bundles\Service\ProductBundleVariationFieldManager
*/
protected $bundleVariationMapper;
/**
* ProductBundleVariationAccessControlHandler constructor.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* @param \Drupal\commerce_product_bundles\Service\ProductBundleVariationFieldManagerInterface $bundle_variation_mapper
*/
public function __construct(EntityTypeInterface $entity_type, ProductBundleVariationFieldManagerInterface $bundle_variation_mapper) {
parent::__construct($entity_type);
$this->bundleVariationMapper = $bundle_variation_mapper;
}
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static(
$entity_type,
$container->get('commerce_product_bundles.bundle_variation_mapper')
);
}
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
if ($account->hasPermission($this->entityType->getAdminPermission())) {
return AccessResult::allowed()->cachePerPermissions();
}
$bundle = $entity->bundle();
/** @var \Drupal\commerce_product_bundles\Entity\ProductBundleVariationInterface $entity */
$product_bundle = $entity->getBundleProduct();
// If parent product is NOT available do not show bundle variations.
if (!$product_bundle instanceof ProductBundleInterface) {
return AccessResult::forbidden()->addCacheableDependency($entity);
}
if (!$product_bundle->access('view', $account)) {
// If we do not have access to parent product do not allow access to variation.
return AccessResult::forbidden()->addCacheableDependency($entity);
}
/** @var \Drupal\commerce_product_bundles\Entity\ProductBundleVariationInterface $entity */
if ($operation === 'view') {
// Allow view access for users with 'Access the products bundles overview page'
if($account->hasPermission('access commerce_product_bundles overview')){
return AccessResult::allowed()->addCacheableDependency($entity);
}
// Check if ref. variations are restricted.
if(!$this->checkRefVariationsAccess($entity, $account)){
return AccessResult::forbidden()->addCacheableDependency($entity);
}
return AccessResult::allowedIfHasPermission($account, "view $bundle commerce_product_bundles");
}
return AccessResult::allowedIfHasPermission($account, "manage $bundle commerce_bundle_variation");
}
/**
* Check access to bundle variation based on ref. variations.
* If one variation has no access bundle has no access.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* @param \Drupal\Core\Session\AccountInterface $account
*
* @return bool
*/
protected function checkRefVariationsAccess(EntityInterface $entity, AccountInterface $account){
$bundle_var_ref = $this->bundleVariationMapper->prepareBundleVariations($entity, TRUE, $account);
$referenced_products = $entity->getProductVariations();
// If we do not have access to one or more ref. products, deny access!
if(count($referenced_products) !== count($bundle_var_ref)){
return FALSE;
}
if($bundle_var_ref){
foreach ($bundle_var_ref as $product_id => $variation){
$ref_variations = $variation->getRefVariations(TRUE, $account);
$variations_array = $variation->toArray();
if(count($ref_variations) < count($variations_array['ref_variations'])) {
return FALSE;
}
}
}
// If there is no available product variation deny access.
else {
return FALSE;
}
return TRUE;
}
/**
* {@inheritdoc}
*/
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
// Create access depends on the "manage" permission because the full entity
// is not passed, making it impossible to determine the parent product.
$result = AccessResult::allowedIfHasPermissions($account, [
$this->entityType->getAdminPermission(),
"manage $entity_bundle commerce_bundle_variation",
], 'OR');
return $result;
}
}
