简体   繁体   English

如何限制店主访问商店页面?

[英]How to limit access to a store page to the store owner?

I created a custom module to create a /store/ID/tasks page我创建了一个自定义模块来创建/store/ID/tasks页面

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

How to limit access to this page to the store owner?如何限制店主访问此页面?

If the current user is owner of store ID 76, he can access this page:如果当前用户是商店 ID 76 的所有者,他可以访问此页面:

/store/76/tasks

But if he goes to another store, he must have denied access:但如果他去另一家商店,他一定是拒绝了访问:

/store/89/tasks

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

task_notify/task_notify.routing.yml 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 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();
  }

}

This page should be accessible only if the current user can edit the store (the site administrator and the store owner).仅当当前用户可以编辑商店(站点管理员和商店所有者)时,该页面才应该可以访问。

Access in the module code must have the same conditions as in this view:模块代码中的访问必须与此视图中的条件相同:

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

I was inspired by the two files below:我受到以下两个文件的启发:

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/MarketplaceIncreaseStoreLimitByOne.php

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

In this case, we can tell Drupal that {store} is an entity and it will load the object.在这种情况下,我们可以告诉 Drupal {store} 是一个实体,它将加载 object。 So we don't have to do that in the Controller function.所以我们不必在 Controller function 中这样做。

So your routing file can include "parameters" settings to do that.所以你的路由文件可以包含“参数”设置来做到这一点。

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

Now your controller function has access to that object.现在您的 controller function 可以访问该 object。

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

In my experience, that is NOT true of the access() method (at least when using a type-hinted parameter as we are doing here).根据我的经验,access() 方法并非如此(至少在我们在这里使用类型提示参数时)。 You get a string, so you'll have to load the store manually.你得到一个字符串,所以你必须手动加载商店。

  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();
    }

Also we need to define $account in the routing file now, as we are using type-hinted parameters (I think).此外,我们现在需要在路由文件中定义 $account,因为我们正在使用类型提示参数(我认为)。 So add that to the options:.因此,将其添加到选项中:。

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 is one of a few special parameters that we can type-hint this way. $account 是我们可以通过这种方式输入提示的几个特殊参数之一。 More info: https://www.drupal.org/docs/8/api/routing-system/access-checking-on-routes/advanced-route-access-checking更多信息: https://www.drupal.org/docs/8/api/routing-system/access-checking-on-routes/advanced-route-access-checking

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM