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
相关产品推荐
相关产品推荐

