You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SonataUserBundle5.10扩展UserAdmin类遇构造参数及TokenStorage问题求助

解决SonataUserBundle UserAdmin扩展及依赖注入问题

环境

  • Symfony 6.4
  • SonataAdminBundle 4.29
  • SonataUserBundle 5.10
  • PHP 8.3.2

问题

扩展SonataUserBundle的UserAdmin类时,自定义类继承Sonata\UserBundle\Admin\Model\UserAdmin会因构造函数参数与基类不匹配抛出异常;改用set方法注入依赖后,configureQuery方法中TokenStorage始终为null,无法实现按用户所属组织过滤查询的逻辑。

解决方案

1. 正确定义自定义UserAdmin类

基类UserAdmin的构造函数包含4个固定参数,自定义类必须对齐参数结构,再添加自定义依赖。同时增加异常判断避免无token场景报错:

use Sonata\UserBundle\Admin\Model\UserAdmin as BaseAdmin;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Sonata\UserBundle\Model\UserManagerInterface;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;

class UserAdmin extends BaseAdmin
{
    private TokenStorageInterface $tokenStorage;
    private EntityManagerInterface $entityManager;

    // 严格对齐基类构造函数参数,追加自定义依赖
    public function __construct(
        string $code,
        string $class,
        string $baseControllerName,
        UserManagerInterface $userManager,
        TokenStorageInterface $tokenStorage,
        EntityManagerInterface $entityManager
    ) {
        parent::__construct($code, $class, $baseControllerName, $userManager);
        $this->tokenStorage = $tokenStorage;
        $this->entityManager = $entityManager;
    }

    protected function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface
    {
        $query = parent::configureQuery($query);
        $rootAlias = current($query->getRootAliases());
        
        // 增加空值判断,避免无token或非法用户场景报错
        $token = $this->tokenStorage->getToken();
        if (!$token) {
            return $query;
        }

        $currentUser = $token->getUser();
        if (!$currentUser instanceof \App\Entity\User) {
            return $query;
        }

        $organisation = $currentUser->getOrganisation();
        if ($organisation) {
            $query->andWhere(sprintf('%s.organisation = :organisation', $rootAlias))
                  ->setParameter('organisation', $organisation);
        }
        
        return $query;
    }
}

2. 修正服务配置

Sonata Admin服务需要code、实体类、控制器三个基础参数,必须在配置中补充,确保依赖正确注入:

# config/services.yaml
app.admin.user:
    class: App\Admin\UserAdmin
    arguments:
        - '' # code参数留空,框架会自动从类名推断
        - App\Entity\User # 关联的实体类
        - '%sonata.admin.configuration.default_controller%' # 默认控制器
        - '@sonata.user.manager.user'
        - '@security.token_storage'
        - '@doctrine.orm.entity_manager'
    tags:
        - { name: sonata.admin, model_class: App\Entity\User, manager_type: orm, group: sonata_user, label: User, pager_type: "simple" }
    public: true

如果倾向于使用setter注入,需在自定义类中添加对应set方法,再调整服务配置:

// 在UserAdmin类中添加set方法
public function setTokenStorage(TokenStorageInterface $tokenStorage): void
{
    $this->tokenStorage = $tokenStorage;
}

public function setEntityManager(EntityManagerInterface $entityManager): void
{
    $this->entityManager = $entityManager;
}
# 调整后的服务配置
app.admin.user:
    class: App\Admin\UserAdmin
    arguments:
        - ''
        - App\Entity\User
        - '%sonata.admin.configuration.default_controller%'
        - '@sonata.user.manager.user'
    calls:
        - [ setTokenStorage, ["@security.token_storage"] ]
        - [ setEntityManager, ["@doctrine.orm.entity_manager"] ]
    tags:
        - { name: sonata.admin, model_class: App\Entity\User, manager_type: orm, group: sonata_user, label: User, pager_type: "simple" }
    public: true

3. 确认SonataUser配置

保持sonata_user.yaml中admin配置指向自定义类即可:

# config/packages/sonata_user.yaml
sonata_user:
    security_acl: false
    manager_type: orm
    impersonating:
        route: sonata_admin_dashboard
    class:
        user: App\Entity\User
    resetting:
        email:
            address: sonata@localhost
            sender_name: Sonata Admin
    admin:
        user:
            class: App\Admin\UserAdmin
            controller: '%sonata.admin.configuration.default_controller%'
            translation: SonataUserBundle

关键说明

  • 构造函数冲突根源:基类UserAdmin的构造函数有4个固定参数,之前的自定义类参数数量/类型不匹配,导致初始化异常。
  • TokenStorage为null原因:服务配置缺少Sonata Admin必需的基础参数,导致依赖注入流程异常,未完成赋值。
  • 增加空值判断:避免后台无登录状态、用户身份非法时抛出致命错误,提升代码健壮性。

内容的提问来源于stack exchange,提问作者71k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:56:31