Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions modules/product/commerce_product.install
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* @file
* Contains install and update functions for Product.
*/

use Drupal\Core\Session\AccountInterface;

/**
* Implements hook_install().
*/
function commerce_product_install() {
// Allow all roles to view published products.
user_role_grant_permissions(AccountInterface::ANONYMOUS_ROLE, ['view published commerce_product']);
user_role_grant_permissions(AccountInterface::AUTHENTICATED_ROLE, ['view published commerce_product']);
}
18 changes: 0 additions & 18 deletions modules/product/commerce_product.module
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

use Drupal\commerce\BundleFieldDefinition;
use Drupal\commerce_product\Entity\ProductTypeInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityInterface;
Expand Down Expand Up @@ -44,23 +43,6 @@ function commerce_product_entity_view_display_update(EntityInterface $entity) {
}
}

/**
* Implements hook_entity_access().
*/
function commerce_product_entity_access(EntityInterface $entity, $operation, $account) {
// Allow published products to be viewed by all users for now.
// @todo Remove once we implement the full product permissions.
if ($operation == 'view') {
if ($entity->getEntityTypeId() == 'commerce_product' && $entity->isPublished()) {
return AccessResult::allowed();
}
elseif ($entity->getEntityTypeId() == 'commerce_product_variation' && $entity->isActive()) {
return AccessResult::allowed();
}
}
return AccessResult::neutral();
}

/**
* Implements hook_theme().
*/
Expand Down
4 changes: 2 additions & 2 deletions modules/product/src/Entity/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
* handlers = {
* "event" = "Drupal\commerce_product\Event\ProductEvent",
* "storage" = "Drupal\commerce\CommerceContentEntityStorage",
* "access" = "Drupal\commerce\EntityAccessControlHandler",
* "permission_provider" = "Drupal\commerce\EntityPermissionProvider",
* "access" = "Drupal\commerce_product\ProductAccessControlHandler",
* "permission_provider" = "Drupal\commerce_product\ProductPermissionProvider",
* "view_builder" = "Drupal\commerce_product\ProductViewBuilder",
* "list_builder" = "Drupal\commerce_product\ProductListBuilder",
* "views_data" = "Drupal\views\EntityViewsData",
Expand Down
2 changes: 1 addition & 1 deletion modules/product/src/Entity/ProductVariation.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* handlers = {
* "event" = "Drupal\commerce_product\Event\ProductVariationEvent",
* "storage" = "Drupal\commerce_product\ProductVariationStorage",
* "access" = "Drupal\commerce\EmbeddedEntityAccessControlHandler",
* "access" = "Drupal\commerce_product\ProductVariationAccessControlHandler",
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "views_data" = "Drupal\views\EntityViewsData",
* "form" = {
Expand Down
31 changes: 31 additions & 0 deletions modules/product/src/ProductAccessControlHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Drupal\commerce_product;

use Drupal\commerce\EntityAccessControlHandler;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;

/**
* Controls access based on the Product entity permissions.
*/
class ProductAccessControlHandler extends EntityAccessControlHandler {

/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\commerce_product\Entity\ProductInterface $entity */
/** @var \Drupal\Core\Access\AccessResult $result */
$result = parent::checkAccess($entity, $operation, $account);

if ($result->isNeutral() && $entity->isPublished()) {
$result = AccessResult::allowedIfHasPermission($account, 'view published commerce_product');
$result->addCacheableDependency($entity);
}

return $result;
}

}
28 changes: 28 additions & 0 deletions modules/product/src/ProductPermissionProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Drupal\commerce_product;

use Drupal\commerce\EntityPermissionProvider;
use Drupal\Core\Entity\EntityTypeInterface;

/**
* Provides Product entity permissions.
*/
class ProductPermissionProvider extends EntityPermissionProvider {

/**
* {@inheritdoc}
*/
public function buildPermissions(EntityTypeInterface $entity_type) {
$permissions = parent::buildPermissions($entity_type);

$permissions["view published {$entity_type->id()}"] = [
'title' => $this->t('View published @type', [
'@type' => $entity_type->getSingularLabel(),
]),
];

return $permissions;
}

}
31 changes: 31 additions & 0 deletions modules/product/src/ProductVariationAccessControlHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Drupal\commerce_product;

use Drupal\commerce\EmbeddedEntityAccessControlHandler;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;

/**
* Controls access based on the Product entity permissions.
*/
class ProductVariationAccessControlHandler extends EmbeddedEntityAccessControlHandler {

/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface $entity */
/** @var \Drupal\Core\Access\AccessResult $result */
$result = parent::checkAccess($entity, $operation, $account);

if ($result->isNeutral()) {
$result = AccessResult::allowedIf($entity->isActive());
$result->addCacheableDependency($entity);
}

return $result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ abstract class ProductBrowserTestBase extends CommerceBrowserTestBase {
/**
* The product to test against.
*
* @var \Drupal\commerce_product\Entity\ProductInterface[]
* @var \Drupal\commerce_product\Entity\ProductInterface
*/
protected $product;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace Drupal\Tests\commerce_product\Functional;

use Drupal\Core\Session\AccountInterface;

/**
* Tests product access for published and unpublished products.
*
* @group commerce
*/
class ProductPublishedAccessTest extends ProductBrowserTestBase {

/**
* The product to test against.
*
* @var \Drupal\commerce_product\Entity\ProductInterface
*/
protected $product;

/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();

$this->product = $this->createEntity('commerce_product', [
'type' => 'default',
'title' => $this->randomMachineName(),
'stores' => $this->stores,
'body' => ['value' => 'Testing product variation field injection!'],
'variations' => [
$this->createEntity('commerce_product_variation', [
'type' => 'default',
'sku' => 'TEST001',
'price' => [
'number' => 999,
'currency_code' => 'USD',
],
]),
$this->createEntity('commerce_product_variation', [
'type' => 'default',
'sku' => 'TEST002',
'price' => [
'number' => 999,
'currency_code' => 'USD',
],
]),
],
]);
}

/**
* Tests the view published permission.
*/
public function testPublishedAccess() {
$this->drupalLogout();
$this->drupalGet($this->product->toUrl());
$this->assertSession()->statusCodeEquals(200);

$this->drupalLogin($this->createUser());
$this->drupalGet($this->product->toUrl());
$this->assertSession()->statusCodeEquals(200);

user_role_revoke_permissions(AccountInterface::ANONYMOUS_ROLE, ['view published commerce_product']);
$this->drupalLogout();
$this->drupalGet($this->product->toUrl());
$this->assertSession()->statusCodeEquals(403);

$this->drupalLogin($this->createUser());
$this->drupalGet($this->product->toUrl());
$this->assertSession()->statusCodeEquals(200);

user_role_revoke_permissions(AccountInterface::AUTHENTICATED_ROLE, ['view published commerce_product']);
$this->drupalLogin($this->createUser());
$this->drupalGet($this->product->toUrl());
$this->assertSession()->statusCodeEquals(403);

$this->drupalLogin($this->adminUser);
$this->drupalGet($this->product->toUrl());
$this->assertSession()->statusCodeEquals(200);
}

}