我创建了一个自定义模块来创建一个/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
我受到以下两个文件的启发:
答案 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