7

I have a Drupal Queue worker class that fetches the Entity objects from Drupal to index to Elasticsearch.

The following command is causing the lesser documents to show up in Elasticsearch since by Access system unpublished; some entities couldn't be retrieved by anonymous users.

drush queue:run category_index_worker --debug

The --user argument seems removed from Drush. I'm trying to use the EventSubscriber to execute any Drush command as user #1 using AccountSwitcher, but I'm not sure what's the right event to use.

$accountSwitcher = \Drupal::service('account_switcher');
$accountSwitcher->switchTo(new \Drupal\Core\Session\UserSession(['uid' => 1]));

KernelEvents::REQUEST works in the web browser but not from the command line, like ConsoleEvents::COMMAND and StackMiddleware.

3 Answers 3

5

You could use the pre-command and post-command hooks to achieve this.

By using these hooks you can target a specific drush command such as queue:run. Here is an example implementation:

<?php

namespace Drupal\drush_queue_run_super_user\Commands;

use Consolidation\AnnotatedCommand\CommandData;
use Drupal\Core\Session\AccountSwitcherInterface;
use Drupal\Core\Session\UserSession;
use Drush\Commands\DrushCommands;

/**
 * A Drush commandfile.
 */
class DrushQueueRunSuperUserCommands extends DrushCommands {

  /**
   * The account switcher service.
   *
   * @var \Drupal\Core\Session\AccountSwitcherInterface
   */
  protected $accountSwitcher;

  /**
   * @param \Drupal\Core\Session\AccountSwitcherInterface $account_switcher
   *   The account switching service.
   */
  public function __construct(AccountSwitcherInterface $account_switcher) {
    $this->accountSwitcher = $account_switcher;
  }

  /**
   * @hook pre-command queue:run
   */
  public function preCommand(CommandData $commandData) {
    $this->accountSwitcher->switchTo(new UserSession(['uid' => 1]));
  }

  /**
   * @hook post-command queue:run
   */
  public function postCommand($result, CommandData $commandData) {
    $this->accountSwitcher->switchBack();
  }

}

Good luck!

1
  • This was really useful! Would also add that you need to add '@account_switcher' to your drush service. Jul 14 at 14:39
1

In continuation to @rémy's comment here

// Switching back not possible

It is possible to switch back the user account. As per discussion here

drush.services.yml

services:
  my_demo.commands:
    class: \Drupal\my_demo\Commands\DemoCommands
    arguments: ['@account_switcher']
    tags:
      - { name: drush.command }

DemoCommands.php

<?php

namespace Drupal\my_demo\Commands;

use Drupal\Core\Session\UserSession;
use Drush\Commands\DrushCommands;
use Drupal\Core\Session\AccountSwitcherInterface;

/**
 * A Drush commandfile.
 *
 * In addition to this file, you need a drush.services.yml
 * in root of your module, and a composer.json file that provides the name
 * of the services file to use.
 *
 * See these files for an example of injecting Drupal services:
 *   - http://cgit.drupalcode.org/devel/tree/src/Commands/DevelCommands.php
 *   - http://cgit.drupalcode.org/devel/tree/drush.services.yml
 */
class DemoCommands extends DrushCommands {

  /**
   * The account switcher service.
   *
   * @var \Drupal\Core\Session\AccountSwitcherInterface
   */
  protected $accountSwitcher;

  /**
   * SimplesitemapCommands constructor.
   *
   * @param \Drupal\Core\Session\AccountSwitcherInterface $account_switcher
   *   The account switching service.
   */
  public function __construct(AccountSwitcherInterface $account_switcher) {
    $this->accountSwitcher = $account_switcher;
  }

  /**
   * Some demo drush command.
   *
   * @usage drush run-demo
   *   Run demo command.
   *
   * @command run:demo
   * @aliases run-demo
   */
  public function demo() {
    // Switch to root user (--user option was removed from drush 9).
    $this->accountSwitcher->switchTo(new UserSession(['uid' => 1]));
    // Do here logic related to command.
    // ...
    // Switch account back.
    $this->accountSwitcher->switchBack();
  }

}
0
+50

It's meant to be used in a custom drush command.

If you really want to set it in an event I haven't found one neither ...

But - you could hook a drush command in your own custom command. See https://www.drush.org/latest/hooks/#core-hooks

So you could create a drush command, that does nothing but implements of a hook, for your desired one(s), fe.

<?php

namespace Drupal\my_demo\Commands;

use Drupal\Core\Session\UserSession;
use Drush\Commands\DrushCommands;
use Drupal\Core\Session\AccountSwitcherInterface;

/**
 * A Drush commandfile.
 *
 * In addition to this file, you need a drush.services.yml
 * in root of your module, and a composer.json file that provides the name
 * of the services file to use.
 *
 * See these files for an example of injecting Drupal services:
 *   - http://cgit.drupalcode.org/devel/tree/src/Commands/DevelCommands.php
 *   - http://cgit.drupalcode.org/devel/tree/drush.services.yml
 */
class DemoCommands extends DrushCommands {

  /**
   * The account switcher service.
   *
   * @var \Drupal\Core\Session\AccountSwitcherInterface
   */
  protected $accountSwitcher;

  /**
   * SimplesitemapCommands constructor.
   *
   * @param \Drupal\Core\Session\AccountSwitcherInterface $account_switcher
   *   The account switching service.
   */
  public function __construct(AccountSwitcherInterface $account_switcher) {
    $this->accountSwitcher = $account_switcher;
  }

     /**
     * @hook script
     */
    public function runEveryScriptAsUserOne(CommandData $commandData): void {
      // Switch to root user (--user option was removed from drush 9).
      $this->accountSwitcher->switchTo(new UserSession(['uid' => 1]));

      // Switching back not possible ..
    }

}

but - I would not really recommend this, as you cannot switch back, so the account switch is not targeted.

I would really suggest you implement a full custom command!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.