Drupal无Contrib实现用户代操作及实体引用字段方案咨询
Great questions—let's break this down step by step, since you're aiming for a clean, no-contrib solution that covers all your use cases.
1. Global Hook to Make All Actions Appear as Another User
Drupal has a built-in way to switch the active user context that covers most operations out of the box, without needing scattered hooks. The key tool here is the account_switcher service, which safely swaps the current user for another during a request, and automatically switches back when the request ends.
Implementation Steps:
- First, you'll need to check if the current user has a designated proxy user (we'll cover setting up that field in the next section).
- Use
hook_init()(orhook_user_login()if you only want to switch after login) to trigger the user switch:
function mycustommodule_init() { $current_user = \Drupal::currentUser(); // Skip anonymous users and users without the proxy field if ($current_user->isAnonymous() || !$current_user->hasField('field_proxy_user')) { return; } // Load the proxy user from the entity reference field $proxy_user = $current_user->get('field_proxy_user')->entity; if ($proxy_user instanceof \Drupal\user\UserInterface) { // Safely switch the active user context \Drupal::service('account_switcher')->switchTo($proxy_user); } }
This handles:
- Node creation/edit (owner/revision user will automatically be the proxy user)
- Flagging operations (the flag will be recorded under the proxy user)
- Comment submissions (comment author will show as the proxy user)
- Rules actions/conditions that use "Current User" (they'll target the proxy user)
For edge cases like custom log entries or non-entity operations, you can use hook_watchdog() to adjust the logged user if needed, but the account_switcher covers 90% of standard Drupal actions.
2. Setting Up the Proxy User Entity Reference Field
Adding an entity reference field to users is straightforward, and you won't need massive amounts of hook_presave if you pair it with the account_switcher approach above.
Best Practices for the Field:
- Add the Field:
- Go to
/admin/config/people/accounts/fields - Add a new "Entity reference" field, set the target type to "User"
- Name it something like
field_proxy_user, and limit selection to 1 user (since you want one proxy per user)
- Go to
- Control Access:
- Restrict who can edit this field (e.g., only admins, or specific roles) via the field's permissions settings
- Optionally, use
hook_entity_field_access()to add custom logic (e.g., prevent users from selecting a proxy with higher permissions)
- Avoid Overusing
hook_presave:- The
account_switcherautomatically handles most entity ownership/audit fields. You'll only needhook_presave()if you have custom fields that explicitly reference the current user and aren't picked up by the context switch. For example:function mycustommodule_node_presave(Drupal\node\NodeInterface $node) { // If you have a custom "last_edited_by_custom" field if (\Drupal::currentUser()->id() != $node->getOwnerId()) { $node->set('field_last_edited_by_custom', \Drupal::currentUser()->id()); } } - But this should be rare—stick to the
account_switcherfor core and standard contrib entity operations.
- The
Final Notes
- Permissions: Make sure the original user has permission to act as the proxy (e.g., if the proxy has "edit any article" permissions, the original user should still have that permission too, or use a custom access check to allow the switch only when appropriate)
- Testing: Test all your target scenarios (node edits, flags, comments, rules) to confirm the proxy user is being used consistently
- Cleanup: The
account_switcherautomatically reverts the user context after the request finishes, so you don't have to worry about leftover user states
内容的提问来源于stack exchange,提问作者Niall Murphy

