如何将商店页面的访问权限限制为商店所有者?

时间:2020-07-26 00:09:30

标签: php drupal drupal-8 drupal-modules drupal-commerce

我创建了一个自定义模块来创建一个/store/ID/tasks页面

https://www.drupal.org/project/commerce

如何限制商店所有者只能访问此页面?

如果当前用户是商店ID 76的所有者,则他可以访问此页面:

/store/76/tasks

但是,如果他去另一家商店,他必须拒绝访问:

/store/89/tasks

https://git.drupalcode.org/sandbox/zenimagine-3076032

task_notify / task_notify.routing.yml

task_notify.store_page.tasks:
  path: '/store/{store}/tasks'
  defaults:
    _controller: '\Drupal\task_notify\Controller\TaskNotifyStoreController::Tasks'
    _title: 'Liste des tâches'
  requirements:
    _custom_access: '\Drupal\task_notify\Controller\TaskNotifyStoreController::taskAccess'

task_notify / src / Controller / TaskNotifyStoreController.php

<?php

namespace Drupal\task_notify\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;
use Drupal\commerce_store\Entity\StoreInterface;

class TaskNotifyStoreController extends ControllerBase {

  public function Tasks() {
    return [
      '#theme' => 'task_notify_store_template',
    ];
  }

  public function taskAccess(StoreInterface $store, AccountInterface $account = NULL, $return_as_object = FALSE) {
    $result = $store->access('edit', $account, TRUE);
    return $return_as_object ? $result : $result->isAllowed();
  }

}

仅当当前用户可以编辑商店(站点管理员和商店所有者)时,才可以访问此页面。

模块代码中的访问必须具有与该视图相同的条件:

https://i.stack.imgur.com/ZfUMo.png

我受到以下两个文件的启发:

https://git.drupalcode.org/project/commerce_marketplace/-/blob/8.x-1.x/src/Plugin/Action/MarketplaceIncreaseStoreLimitByOne.php

https://git.drupalcode.org/project/commerce_marketplace/-/blob/8.x-1.x/src/Plugin/Action/MarketplaceMarkAsDefault.php

1 个答案:

答案 0 :(得分:0)

在这种情况下,我们可以告诉Drupal {store}是一个实体,它将加载该对象。因此,我们不必在Controller函数中执行此操作。

因此,您的路由文件可以包含“参数”设置。

task_notify.store_page.tasks:
  path: '/store/{store}/tasks'
  defaults:
    _controller: '\Drupal\task_notify\Controller\TaskNotifyStoreController::Tasks'
    _title: 'Liste des tâches'
  requirements:
    _custom_access: '\Drupal\task_notify\Controller\TaskNotifyStoreController::taskAccess'
  options:
    parameters:
      store:
        type: entity:commerce_store

现在您的控制器功能可以访问该对象。

  public function Tasks(StoreInterface $store) { ...

根据我的经验,access()方法并非如此(至少当我们在此处使用类型提示的参数时)。您会得到一个字符串,因此必须手动加载商店。

  public function taskAccess(string $store, AccountInterface $account) {
    $store = \Drupal\commerce_store\Entity\Store::load($store);
    // Check store owner against current user.
    if ($store->access('edit', $account)) {
      return AccessResult::allowed();
    }
    else {
      return AccessResult::forbidden();
    }

我们还需要在路由文件中定义$ account,因为我们正在使用类型提示参数(我认为)。因此,将其添加到选项:。

task_notify.store_page.tasks:
  path: '/store/{store}/tasks'
  defaults:
    _controller: '\Drupal\task_notify\Controller\TaskNotifyStoreController::Tasks'
    _title: 'Liste des tâches'
  requirements:
    _custom_access: '\Drupal\task_notify\Controller\TaskNotifyStoreController::taskAccess'
  options:
    parameters:
      store:
        type: entity:commerce_store
      account: \Drupal\Core\Session\AccountProxy

$ account是我们可以以这种方式键入提示的一些特殊参数之一。更多信息:https://www.drupal.org/docs/8/api/routing-system/access-checking-on-routes/advanced-route-access-checking

相关问题