DrupalBoot.php

  1. 8.0.x lib/Drush/Boot/DrupalBoot.php
  2. 7.x lib/Drush/Boot/DrupalBoot.php
  3. master lib/Drush/Boot/DrupalBoot.php

Namespace

Drush\Boot

Classes

Namesort descending Description
DrupalBoot

File

lib/Drush/Boot/DrupalBoot.php
View source
  1. <?php
  2. namespace Drush\Boot;
  3. use Drush\Log\LogLevel;
  4. use Psr\Log\LoggerInterface;
  5. abstract class DrupalBoot extends BaseBoot {
  6. function valid_root($path) {
  7. }
  8. function get_version($drupal_root) {
  9. }
  10. function get_profile() {
  11. }
  12. function conf_path($require_settings = TRUE, $reset = FALSE) {
  13. return conf_path($require_settings = TRUE, $reset = FALSE);
  14. }
  15. /**
  16. * Bootstrap phases used with Drupal:
  17. *
  18. * DRUSH_BOOTSTRAP_DRUSH = Only Drush.
  19. * DRUSH_BOOTSTRAP_DRUPAL_ROOT = Find a valid Drupal root.
  20. * DRUSH_BOOTSTRAP_DRUPAL_SITE = Find a valid Drupal site.
  21. * DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION = Load the site's settings.
  22. * DRUSH_BOOTSTRAP_DRUPAL_DATABASE = Initialize the database.
  23. * DRUSH_BOOTSTRAP_DRUPAL_FULL = Initialize Drupal fully.
  24. * DRUSH_BOOTSTRAP_DRUPAL_LOGIN = Log into Drupal with a valid user.
  25. *
  26. * The value is the name of the method of the Boot class to
  27. * execute when bootstrapping. Prior to bootstrapping, a "validate"
  28. * method is called, if defined. The validate method name is the
  29. * bootstrap method name with "_validate" appended.
  30. */
  31. function bootstrap_phases() {
  32. return array(
  33. DRUSH_BOOTSTRAP_DRUSH => 'bootstrap_drush',
  34. DRUSH_BOOTSTRAP_DRUPAL_ROOT => 'bootstrap_drupal_root',
  35. DRUSH_BOOTSTRAP_DRUPAL_SITE => 'bootstrap_drupal_site',
  36. DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION => 'bootstrap_drupal_configuration',
  37. DRUSH_BOOTSTRAP_DRUPAL_DATABASE => 'bootstrap_drupal_database',
  38. DRUSH_BOOTSTRAP_DRUPAL_FULL => 'bootstrap_drupal_full',
  39. DRUSH_BOOTSTRAP_DRUPAL_LOGIN => 'bootstrap_drupal_login');
  40. }
  41. /**
  42. * List of bootstrap phases where Drush should stop and look for commandfiles.
  43. *
  44. * For Drupal, we try at these bootstrap phases:
  45. *
  46. * - Drush preflight: to find commandfiles in any system location,
  47. * out of a Drupal installation.
  48. * - Drupal root: to find commandfiles based on Drupal core version.
  49. * - Drupal full: to find commandfiles defined within a Drupal directory.
  50. *
  51. * Once a command is found, Drush will ensure a bootstrap to the phase
  52. * declared by the command.
  53. *
  54. * @return array of PHASE indexes.
  55. */
  56. function bootstrap_init_phases() {
  57. return array(DRUSH_BOOTSTRAP_DRUSH, DRUSH_BOOTSTRAP_DRUPAL_ROOT, DRUSH_BOOTSTRAP_DRUPAL_FULL);
  58. }
  59. function enforce_requirement(&$command) {
  60. parent::enforce_requirement($command);
  61. $this->drush_enforce_requirement_drupal_dependencies($command);
  62. }
  63. function report_command_error($command) {
  64. // If we reach this point, command doesn't fit requirements or we have not
  65. // found either a valid or matching command.
  66. // If no command was found check if it belongs to a disabled module.
  67. if (!$command) {
  68. $command = $this->drush_command_belongs_to_disabled_module();
  69. }
  70. parent::report_command_error($command);
  71. }
  72. function command_defaults() {
  73. return array(
  74. 'drupal dependencies' => array(),
  75. 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
  76. );
  77. }
  78. /**
  79. * @return array of strings - paths to directories where contrib
  80. * modules can be found
  81. */
  82. abstract function contrib_modules_paths();
  83. /**
  84. * @return array of strings - paths to directories where contrib
  85. * themes can be found
  86. */
  87. abstract function contrib_themes_paths();
  88. function commandfile_searchpaths($phase, $phase_max = FALSE) {
  89. if (!$phase_max) {
  90. $phase_max = $phase;
  91. }
  92. $container = \Drush::getContainer();
  93. $discovery = $container->get('commandDiscovery');
  94. $commandFiles = [];
  95. $searchpath = [];
  96. switch ($phase) {
  97. case DRUSH_BOOTSTRAP_DRUPAL_ROOT:
  98. $drupal_root = \Drush::bootstrapManager()->getRoot();
  99. $searchpath[] = $drupal_root . '/../drush';
  100. $searchpath[] = $drupal_root . '/drush';
  101. $searchpath[] = $drupal_root . '/sites/all/drush';
  102. $commandFiles = $discovery->discover($searchpath, '\Drupal');
  103. break;
  104. case DRUSH_BOOTSTRAP_DRUPAL_SITE:
  105. // If we are going to stop bootstrapping at the site, then
  106. // we will quickly add all commandfiles that we can find for
  107. // any extension associated with the site, whether it is enabled
  108. // or not. If we are, however, going to continue on to bootstrap
  109. // all the way to DRUSH_BOOTSTRAP_DRUPAL_FULL, then we will
  110. // instead wait for that phase, which will more carefully add
  111. // only those Drush commandfiles that are associated with
  112. // enabled modules.
  113. if ($phase_max < DRUSH_BOOTSTRAP_DRUPAL_FULL) {
  114. $searchpath = array_merge($searchpath, $this->contrib_modules_paths());
  115. // Adding commandfiles located within /profiles. Try to limit to one profile for speed. Note
  116. // that Drupal allows enabling modules from a non-active profile so this logic is kinda dodgy.
  117. $cid = drush_cid_install_profile();
  118. if ($cached = drush_cache_get($cid)) {
  119. $profile = $cached->data;
  120. $searchpath[] = "profiles/$profile/modules";
  121. $searchpath[] = "profiles/$profile/themes";
  122. }
  123. else {
  124. // If install_profile is not available, scan all profiles.
  125. $searchpath[] = "profiles";
  126. $searchpath[] = "sites/all/profiles";
  127. }
  128. $searchpath = array_merge($searchpath, $this->contrib_themes_paths());
  129. // Drupal 8 uses the modules' services files to find commandfiles. Should we allow
  130. // redundant find-module-by-location for Drupal 8? (Maybe not.)
  131. if (drush_drupal_major_version() < 8) {
  132. $commandFiles = $discovery->discoverNamespaced($searchpath, '\Drupal');
  133. }
  134. }
  135. break;
  136. case DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION:
  137. // Nothing to do here anymore. Left for documentation.
  138. break;
  139. case DRUSH_BOOTSTRAP_DRUPAL_FULL:
  140. // Add enabled module paths, excluding the install profile. Since we are bootstrapped,
  141. // we can use the Drupal API.
  142. $ignored_modules = drush_get_option_list('ignored-modules', array());
  143. $cid = drush_cid_install_profile();
  144. if ($cached = drush_cache_get($cid)) {
  145. $ignored_modules[] = $cached->data;
  146. }
  147. foreach (array_diff(drush_module_list(), $ignored_modules) as $module) {
  148. $filepath = drupal_get_path('module', $module);
  149. if ($filepath && $filepath != '/') {
  150. $searchpath[] = $filepath;
  151. }
  152. }
  153. // Check all enabled themes including non-default and non-admin.
  154. foreach (drush_theme_list() as $key => $value) {
  155. $searchpath[] = drupal_get_path('theme', $key);
  156. }
  157. // Drupal 8 uses the modules' services files to find commandfiles. Should we allow
  158. // redundant find-module-by-location for Drupal 8? (Maybe not.)
  159. if (drush_drupal_major_version() < 8) {
  160. $commandFiles = $discovery->discoverNamespaced($searchpath, '\Drupal');
  161. }
  162. break;
  163. }
  164. // A little inelegant, but will do for now.
  165. drush_init_register_command_files($container, $commandFiles);
  166. return $searchpath;
  167. }
  168. /**
  169. * Check if the given command belongs to a disabled module.
  170. *
  171. * @return array
  172. * Array with a command-like bootstrap error or FALSE if Drupal was not
  173. * bootstrapped fully or the command does not belong to a disabled module.
  174. */
  175. function drush_command_belongs_to_disabled_module() {
  176. if (drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) {
  177. _drush_find_commandfiles(DRUSH_BOOTSTRAP_DRUPAL_SITE, DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION);
  178. drush_get_commands(TRUE);
  179. $commands = drush_get_commands();
  180. $arguments = drush_get_arguments();
  181. $command_name = array_shift($arguments);
  182. if (isset($commands[$command_name])) {
  183. // We found it. Load its module name and set an error.
  184. if (is_array($commands[$command_name]['drupal dependencies']) && count($commands[$command_name]['drupal dependencies'])) {
  185. $modules = implode(', ', $commands[$command_name]['drupal dependencies']);
  186. }
  187. else {
  188. // The command does not define Drupal dependencies. Derive them.
  189. $command_files = commandfiles_cache()->get();
  190. $command_path = $commands[$command_name]['path'] . DIRECTORY_SEPARATOR . $commands[$command_name]['commandfile'] . '.drush.inc';
  191. $modules = array_search($command_path, $command_files);
  192. }
  193. return array(
  194. 'bootstrap_errors' => array(
  195. 'DRUSH_COMMAND_DEPENDENCY_ERROR' => dt('Command !command needs the following extension(s) enabled to run: !dependencies.', array(
  196. '!command' => $command_name,
  197. '!dependencies' => $modules,
  198. )),
  199. ),
  200. );
  201. }
  202. }
  203. return FALSE;
  204. }
  205. /**
  206. * Check that a command has its declared dependencies available or have no
  207. * dependencies.
  208. *
  209. * @param $command
  210. * Command to check. Any errors will be added to the 'bootstrap_errors' element.
  211. *
  212. * @return
  213. * TRUE if command is valid.
  214. */
  215. function drush_enforce_requirement_drupal_dependencies(&$command) {
  216. // If the command bootstrap is DRUSH_BOOTSTRAP_MAX, then we will
  217. // allow the requirements to pass if we have not successfully
  218. // bootstrapped Drupal. The combination of DRUSH_BOOTSTRAP_MAX
  219. // and 'drupal dependencies' indicates that the drush command
  220. // will use the dependent modules only if they are available.
  221. if ($command['bootstrap'] == DRUSH_BOOTSTRAP_MAX) {
  222. // If we have not bootstrapped, then let the dependencies pass;
  223. // if we have bootstrapped, then enforce them.
  224. if (drush_get_context('DRUSH_BOOTSTRAP_PHASE') < DRUSH_BOOTSTRAP_DRUPAL_FULL) {
  225. return TRUE;
  226. }
  227. }
  228. // If there are no drupal dependencies, then do nothing
  229. if (!empty($command['drupal dependencies'])) {
  230. foreach ($command['drupal dependencies'] as $dependency) {
  231. drush_include_engine('drupal', 'environment');
  232. if(!drush_module_exists($dependency)) {
  233. $command['bootstrap_errors']['DRUSH_COMMAND_DEPENDENCY_ERROR'] = dt('Command !command needs the following modules installed/enabled to run: !dependencies.', array('!command' => $command['command'], '!dependencies' => implode(', ', $command['drupal dependencies'])));
  234. return FALSE;
  235. }
  236. }
  237. }
  238. return TRUE;
  239. }
  240. /**
  241. * Validate the DRUSH_BOOTSTRAP_DRUPAL_ROOT phase.
  242. *
  243. * In this function, we will check if a valid Drupal directory is available.
  244. * We also determine the value that will be stored in the DRUSH_DRUPAL_ROOT
  245. * context and DRUPAL_ROOT constant if it is considered a valid option.
  246. */
  247. function bootstrap_drupal_root_validate() {
  248. $drupal_root = \Drush::bootstrapManager()->getRoot();
  249. if (empty($drupal_root)) {
  250. return drush_bootstrap_error('DRUSH_NO_DRUPAL_ROOT', dt("A Drupal installation directory could not be found"));
  251. }
  252. if (!$signature = drush_valid_root($drupal_root)) {
  253. return drush_bootstrap_error('DRUSH_INVALID_DRUPAL_ROOT', dt("The directory !drupal_root does not contain a valid Drupal installation", array('!drupal_root' => $drupal_root)));
  254. }
  255. $version = drush_drupal_version($drupal_root);
  256. $major_version = drush_drupal_major_version($drupal_root);
  257. if ($major_version <= 6) {
  258. return drush_set_error('DRUSH_DRUPAL_VERSION_UNSUPPORTED', dt('Drush !drush_version does not support Drupal !major_version.', array('!drush_version' => \Drush::getMajorVersion(), '!major_version' => $major_version)));
  259. }
  260. drush_bootstrap_value('drupal_root', $drupal_root);
  261. define('DRUSH_DRUPAL_SIGNATURE', $signature);
  262. return TRUE;
  263. }
  264. /**
  265. * Bootstrap Drush with a valid Drupal Directory.
  266. *
  267. * In this function, the pwd will be moved to the root
  268. * of the Drupal installation.
  269. *
  270. * The DRUSH_DRUPAL_ROOT context, DRUSH_DRUPAL_CORE context, DRUPAL_ROOT, and the
  271. * DRUSH_DRUPAL_CORE constants are populated from the value that we determined during
  272. * the validation phase.
  273. *
  274. * We also now load the drushrc.php for this specific Drupal site.
  275. * We can now include files from the Drupal Tree, and figure
  276. * out more context about the platform, such as the version of Drupal.
  277. */
  278. function bootstrap_drupal_root() {
  279. // Load the config options from Drupal's /drush and sites/all/drush directories.
  280. drush_load_config('drupal');
  281. $drupal_root = drush_set_context('DRUSH_DRUPAL_ROOT', drush_bootstrap_value('drupal_root'));
  282. chdir($drupal_root);
  283. $version = drush_drupal_version();
  284. $major_version = drush_drupal_major_version();
  285. $core = $this->bootstrap_drupal_core($drupal_root);
  286. // DRUSH_DRUPAL_CORE should point to the /core folder in Drupal 8+ or to DRUPAL_ROOT
  287. // in prior versions.
  288. drush_set_context('DRUSH_DRUPAL_CORE', $core);
  289. define('DRUSH_DRUPAL_CORE', $core);
  290. _drush_preflight_global_options();
  291. $this->logger->log(LogLevel::BOOTSTRAP, dt("Initialized Drupal !version root directory at !drupal_root", array("!version" => $version, '!drupal_root' => $drupal_root)));
  292. }
  293. /**
  294. * VALIDATE the DRUSH_BOOTSTRAP_DRUPAL_SITE phase.
  295. *
  296. * In this function we determine the URL used for the command,
  297. * and check for a valid settings.php file.
  298. *
  299. * To do this, we need to set up the $_SERVER environment variable,
  300. * to allow us to use conf_path to determine what Drupal will load
  301. * as a configuration file.
  302. */
  303. function bootstrap_drupal_site_validate() {
  304. // Define the selected conf path as soon as we have identified that
  305. // we have selected a Drupal site. Drush used to set this context
  306. // during the drush_bootstrap_drush phase.
  307. $drush_uri = _drush_bootstrap_selected_uri();
  308. drush_set_context('DRUSH_SELECTED_DRUPAL_SITE_CONF_PATH', drush_conf_path($drush_uri));
  309. $this->bootstrap_drupal_site_setup_server_global($drush_uri);
  310. return $this->bootstrap_drupal_site_validate_settings_present();
  311. }
  312. /**
  313. * Set up the $_SERVER globals so that Drupal will see the same values
  314. * that it does when serving pages via the web server.
  315. */
  316. function bootstrap_drupal_site_setup_server_global($drush_uri) {
  317. // Fake the necessary HTTP headers that Drupal needs:
  318. if ($drush_uri) {
  319. $drupal_base_url = parse_url($drush_uri);
  320. // If there's no url scheme set, add http:// and re-parse the url
  321. // so the host and path values are set accurately.
  322. if (!array_key_exists('scheme', $drupal_base_url)) {
  323. $drush_uri = 'http://' . $drush_uri;
  324. $drupal_base_url = parse_url($drush_uri);
  325. }
  326. // Fill in defaults.
  327. $drupal_base_url += array(
  328. 'path' => '',
  329. 'host' => NULL,
  330. 'port' => NULL,
  331. );
  332. $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
  333. if ($drupal_base_url['scheme'] == 'https') {
  334. $_SERVER['HTTPS'] = 'on';
  335. }
  336. if ($drupal_base_url['port']) {
  337. $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
  338. }
  339. $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
  340. $_SERVER['REQUEST_URI'] = $drupal_base_url['path'] . '/';
  341. }
  342. else {
  343. $_SERVER['HTTP_HOST'] = 'default';
  344. $_SERVER['REQUEST_URI'] = '/';
  345. }
  346. $_SERVER['PHP_SELF'] = $_SERVER['REQUEST_URI'] . 'index.php';
  347. $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
  348. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  349. $_SERVER['REQUEST_METHOD'] = NULL;
  350. $_SERVER['SERVER_SOFTWARE'] = NULL;
  351. $_SERVER['HTTP_USER_AGENT'] = NULL;
  352. $_SERVER['SCRIPT_FILENAME'] = DRUPAL_ROOT . '/index.php';
  353. }
  354. /**
  355. * Validate that the Drupal site has all of the settings that it
  356. * needs to operated.
  357. */
  358. function bootstrap_drupal_site_validate_settings_present() {
  359. $site = drush_bootstrap_value('site', $_SERVER['HTTP_HOST']);
  360. $conf_path = drush_bootstrap_value('conf_path', $this->conf_path(TRUE, TRUE));
  361. $conf_file = "$conf_path/settings.php";
  362. if (!file_exists($conf_file)) {
  363. return drush_bootstrap_error('DRUPAL_SITE_SETTINGS_NOT_FOUND', dt("Could not find a Drupal settings.php file at !file.",
  364. array('!file' => $conf_file)));
  365. }
  366. return TRUE;
  367. }
  368. /**
  369. * Called by bootstrap_drupal_site to do the main work
  370. * of the drush drupal site bootstrap.
  371. */
  372. function bootstrap_do_drupal_site() {
  373. $drush_uri = drush_get_context('DRUSH_SELECTED_URI');
  374. drush_set_context('DRUSH_URI', $drush_uri);
  375. $site = drush_set_context('DRUSH_DRUPAL_SITE', drush_bootstrap_value('site'));
  376. $conf_path = drush_set_context('DRUSH_DRUPAL_SITE_ROOT', drush_bootstrap_value('conf_path'));
  377. $this->logger->log(LogLevel::BOOTSTRAP, dt("Initialized Drupal site !site at !site_root", array('!site' => $site, '!site_root' => $conf_path)));
  378. _drush_preflight_global_options();
  379. }
  380. /**
  381. * Initialize a site on the Drupal root.
  382. *
  383. * We now set various contexts that we determined and confirmed to be valid.
  384. * Additionally we load an optional drushrc.php file in the site directory.
  385. */
  386. function bootstrap_drupal_site() {
  387. drush_load_config('site');
  388. $this->bootstrap_do_drupal_site();
  389. }
  390. /**
  391. * Initialize and load the Drupal configuration files.
  392. *
  393. * We process and store a normalized set of database credentials
  394. * from the loaded configuration file, so we can validate them
  395. * and access them easily in the future.
  396. *
  397. * Also override Drupal variables as per --variables option.
  398. */
  399. function bootstrap_drupal_configuration() {
  400. global $conf;
  401. $override = array(
  402. 'cron_safe_threshold' => 0, // Don't run poormanscron during Drush request (D7).
  403. );
  404. $current_override = drush_get_option_list('variables');
  405. foreach ($current_override as $name => $value) {
  406. if (is_numeric($name) && (strpos($value, '=') !== FALSE)) {
  407. list($name, $value) = explode('=', $value, 2);
  408. }
  409. $override[$name] = $value;
  410. }
  411. $conf = is_array($conf) ? array_merge($conf, $override) : $conf;
  412. }
  413. /**
  414. * Validate the DRUSH_BOOTSTRAP_DRUPAL_DATABASE phase
  415. *
  416. * Attempt to make a working database connection using the
  417. * database credentials that were loaded during the previous
  418. * phase.
  419. */
  420. function bootstrap_drupal_database_validate() {
  421. if (!drush_valid_db_credentials()) {
  422. return drush_bootstrap_error('DRUSH_DRUPAL_DB_ERROR');
  423. }
  424. return TRUE;
  425. }
  426. /**
  427. * Test to see if the Drupal database has a specified
  428. * table or tables.
  429. *
  430. * This is a bootstrap helper function designed to be called
  431. * from the bootstrap_drupal_database_validate() methods of
  432. * derived DrupalBoot classes. If a database exists, but is
  433. * empty, then the Drupal database bootstrap will fail. To
  434. * prevent this situation, we test for some table that is needed
  435. * in an ordinary bootstrap, and return FALSE from the validate
  436. * function if it does not exist, so that we do not attempt to
  437. * start the database bootstrap.
  438. *
  439. * Note that we must manually do our own prefix testing here,
  440. * because the existing wrappers we have for handling prefixes
  441. * depend on bootstrapping to the "database" phase, and therefore
  442. * are not available to validate this same phase.
  443. *
  444. * @param $required_tables
  445. * Array of table names, or string with one table name
  446. *
  447. * @return TRUE if all tables in input parameter exist in
  448. * the database.
  449. */
  450. function bootstrap_drupal_database_has_table($required_tables) {
  451. try {
  452. $sql = drush_sql_get_class();
  453. $spec = $sql->db_spec();
  454. $prefix = isset($spec['prefix']) ? $spec['prefix'] : NULL;
  455. if (!is_array($prefix)) {
  456. $prefix = array('default' => $prefix);
  457. }
  458. $tables = $sql->listTables();
  459. foreach ((array)$required_tables as $required_table) {
  460. $prefix_key = array_key_exists($required_table, $prefix) ? $required_table : 'default';
  461. if (!in_array($prefix[$prefix_key] . $required_table, $tables)) {
  462. return FALSE;
  463. }
  464. }
  465. }
  466. catch (Exception $e) {
  467. // Usually the checks above should return a result without
  468. // throwing an exception, but we'll catch any that are
  469. // thrown just in case.
  470. return FALSE;
  471. }
  472. return TRUE;
  473. }
  474. /**
  475. * Boostrap the Drupal database.
  476. */
  477. function bootstrap_drupal_database() {
  478. // We presume that our derived classes will connect and then
  479. // either fail, or call us via parent::
  480. $this->logger->log(LogLevel::BOOTSTRAP, dt("Successfully connected to the Drupal database."));
  481. }
  482. /**
  483. * Attempt to load the full Drupal system.
  484. */
  485. function bootstrap_drupal_full() {
  486. drush_include_engine('drupal', 'environment');
  487. $this->add_logger();
  488. // Write correct install_profile to cache as needed. Used by _drush_find_commandfiles().
  489. $cid = drush_cid_install_profile();
  490. $install_profile = $this->get_profile();
  491. if ($cached_install_profile = drush_cache_get($cid)) {
  492. // We have a cached profile. Check it for correctness and save new value if needed.
  493. if ($cached_install_profile->data != $install_profile) {
  494. drush_cache_set($cid, $install_profile);
  495. }
  496. }
  497. else {
  498. // No cached entry so write to cache.
  499. drush_cache_set($cid, $install_profile);
  500. }
  501. _drush_log_drupal_messages();
  502. }
  503. /**
  504. * Log into the bootstrapped Drupal site with a specific
  505. * username or user id.
  506. */
  507. function bootstrap_drupal_login() {
  508. $uid_or_name = drush_set_context('DRUSH_USER', drush_get_option('user', 0));
  509. $userversion = drush_user_get_class();
  510. if (!$account = $userversion->load_by_uid($uid_or_name)) {
  511. if (!$account = $userversion->load_by_name($uid_or_name)) {
  512. if (is_numeric($uid_or_name)) {
  513. $message = dt('Could not login with user ID !user.', array('!user' => $uid_or_name));
  514. if ($uid_or_name === 0) {
  515. $message .= ' ' . dt('This is typically caused by importing a MySQL database dump from a faulty tool which re-numbered the anonymous user ID in the users table. See !link for help recovering from this situation.', array('!link' => 'http://drupal.org/node/1029506'));
  516. }
  517. }
  518. else {
  519. $message = dt('Could not login with user account `!user\'.', array('!user' => $uid_or_name));
  520. }
  521. return drush_set_error('DRUPAL_USER_LOGIN_FAILED', $message);
  522. }
  523. }
  524. $userversion->setCurrentUser($account);
  525. _drush_log_drupal_messages();
  526. }
  527. }