user.drush.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. <?php
  2. // $Id:
  3. /**
  4. * @file Drush User Management commands
  5. */
  6. function user_drush_help($section) {
  7. switch ($section) {
  8. case 'meta:user:title':
  9. return dt('User commands');
  10. case 'meta:user:summary':
  11. return dt('Add, modify and delete users.');
  12. }
  13. }
  14. /**
  15. * Implementation of hook_drush_command().
  16. */
  17. function user_drush_command() {
  18. $items['user-information'] = array(
  19. 'callback' => 'drush_user_information',
  20. 'description' => 'Print information about the specified user(s).',
  21. 'aliases' => array('uinf'),
  22. 'examples' => array(
  23. 'drush user-information 2,3,someguy,somegal,billgates@microsoft.com' =>
  24. 'Display information about any users with uids, names, or mail addresses matching the strings between commas.',
  25. ),
  26. 'arguments' => array(
  27. 'users' => 'A comma delimited list of uids, user names, or email addresses.',
  28. ),
  29. 'options' => array(
  30. 'full' => 'show extended information about the user',
  31. 'short' => 'show basic information about the user (this is the default)',
  32. ),
  33. );
  34. $items['user-block'] = array(
  35. 'callback' => 'drush_user_block',
  36. 'description' => 'Block the specified user(s).',
  37. 'aliases' => array('ublk'),
  38. 'arguments' => array(
  39. 'users' => 'A comma delimited list of uids, user names, or email addresses.',
  40. ),
  41. 'examples' => array(
  42. 'drush user-block 5,user3 --uid=2,3 --name=someguy,somegal --mail=billgates@microsoft.com' =>
  43. 'Block the users with name, id, or email 5 or user3, uids 2 and 3, names someguy and somegal, and email address of billgates@microsoft.com',
  44. ),
  45. 'options' => array(
  46. 'uid' => 'A comma delimited list of uids to block',
  47. 'name' => 'A comma delimited list of user names to block',
  48. 'mail' => 'A comma delimited list of user mail addresses to block',
  49. ),
  50. );
  51. $items['user-unblock'] = array(
  52. 'callback' => 'drush_user_unblock',
  53. 'description' => 'Unblock the specified user(s).',
  54. 'aliases' => array('uublk'),
  55. 'arguments' => array(
  56. 'users' => 'A comma delimited list of uids, user names, or email addresses.',
  57. ),
  58. 'examples' => array(
  59. 'drush user-unblock 5,user3 --uid=2,3 --name=someguy,somegal --mail=billgates@microsoft.com' =>
  60. 'Unblock the users with name, id, or email 5 or user3, uids 2 and 3, names someguy and somegal, and email address of billgates@microsoft.com',
  61. ),
  62. 'options' => array(
  63. 'uid' => 'A comma delimited list of uids to unblock',
  64. 'name' => 'A comma delimited list of user names to unblock',
  65. 'mail' => 'A comma delimited list of user mail addresses to unblock',
  66. ),
  67. );
  68. $items['user-add-role'] = array(
  69. 'callback' => 'drush_user_add_role',
  70. 'description' => 'Add a role to the specified user accounts.',
  71. 'aliases' => array('urol'),
  72. 'arguments' => array(
  73. 'role' => 'The name of the role to add',
  74. 'users' => '(optional) A comma delimited list of uids, user names, or email addresses.',
  75. ),
  76. 'examples' => array(
  77. 'drush user-add-role "power user" 5,user3 --uid=2,3 --name=someguy,somegal --mail=billgates@microsoft.com' =>
  78. 'Add the "power user" role to the accounts with name, id, or email 5 or user3, uids 2 and 3, names someguy and somegal, and email address of billgates@microsoft.com',
  79. ),
  80. 'options' => array(
  81. 'uid' => 'A comma delimited list of uids',
  82. 'name' => 'A comma delimited list of user names',
  83. 'mail' => 'A comma delimited list of user mail addresses',
  84. ),
  85. );
  86. $items['user-remove-role'] = array(
  87. 'callback' => 'drush_user_remove_role',
  88. 'description' => 'Remove a role from the specified user accounts.',
  89. 'aliases' => array('urrol'),
  90. 'arguments' => array(
  91. 'role' => 'The name of the role to remove',
  92. 'users' => '(optional) A comma delimited list of uids, user names, or email addresses.',
  93. ),
  94. 'examples' => array(
  95. 'drush user-remove-role "power user" 5,user3 --uid=2,3 --name=someguy,somegal --mail=billgates@microsoft.com' =>
  96. 'Remove the "power user" role from the accounts with name, id, or email 5 or user3, uids 2 and 3, names someguy and somegal, and email address of billgates@microsoft.com',
  97. ),
  98. 'options' => array(
  99. 'uid' => 'A comma delimited list of uids',
  100. 'name' => 'A comma delimited list of user names',
  101. 'mail' => 'A comma delimited list of user mail addresses',
  102. ),
  103. );
  104. $items['user-create'] = array(
  105. 'callback' => 'drush_user_create',
  106. 'description' => 'Create a user account with the specified name.',
  107. 'aliases' => array('ucrt'),
  108. 'arguments' => array(
  109. 'name' => 'The name of the account to add'
  110. ),
  111. 'examples' => array(
  112. 'drush user-create newuser --mail="person@example.com" --password="letmein"' =>
  113. 'Create a new user account with the name newuser, the email address person@example.com, and the password letmein',
  114. ),
  115. 'options' => array(
  116. 'password' => 'The password for the new account',
  117. 'mail' => 'The email address for the new account',
  118. ),
  119. );
  120. $items['user-cancel'] = array(
  121. 'callback' => 'drush_user_cancel',
  122. 'description' => 'Cancel a user account with the specified name.',
  123. 'aliases' => array('ucan'),
  124. 'arguments' => array(
  125. 'name' => 'The name of the account to cancel',
  126. ),
  127. 'examples' => array(
  128. 'drush user-cancel username' =>
  129. 'Cancel the user account with the name username and anonymize all content created by that user.',
  130. ),
  131. );
  132. $items['user-password'] = array(
  133. 'callback' => 'drush_user_password',
  134. 'description' => '(Re)Set the password for the user account with the specified name.',
  135. 'aliases' => array('upwd'),
  136. 'arguments' => array(
  137. 'name' => 'The name of the account to modify'
  138. ),
  139. 'options' => array(
  140. 'password' => '(required) The new password for the account',
  141. ),
  142. 'examples' => array(
  143. 'drush user-password someuser --password="gr3@tP@$s"' =>
  144. 'Set the password for the username someuser to gr3@tP@$s.',
  145. ),
  146. );
  147. $items['user-login'] = array(
  148. 'callback' => 'drush_user_login',
  149. 'description' => 'Display a one time login link for the given user account (defaults to uid 1).',
  150. 'aliases' => array('uli'),
  151. 'arguments' => array(
  152. 'name' => 'The name of the account to log in as. Leave it empty to log in as uid 1.'
  153. ),
  154. 'examples' => array(
  155. 'drush user-login ryan' => 'Displays a one-time login link for the user ryan.',
  156. 'open `drush user-login ryan`' => 'Open web browser and login as user ryan.',
  157. ),
  158. );
  159. // Drupal 7 only options.
  160. if (drush_drupal_major_version() >= 7) {
  161. $items['user-cancel']['options'] = array(
  162. 'delete-content' => 'Delete all content created by the user',
  163. );
  164. $items['user-cancel']['examples']['drush user-cancel --delete-content username'] =
  165. 'Cancel the user account with the name username and delete all content created by that user.';
  166. }
  167. return $items;
  168. }
  169. // Implementation of hook_drush_init().
  170. function user_drush_init() {
  171. $command_info = drush_get_command();
  172. $command = $command_info['command'];
  173. $needs_parse_args = array('user-block', 'user-unblock', 'user-add-role', 'user-remove-role');
  174. if (in_array($command, $needs_parse_args)) {
  175. // parse args and call drush_set_option for --uids
  176. $users = array();
  177. foreach (array('uid', 'name', 'mail' ) as $user_attr) {
  178. if ($arg = drush_get_option($user_attr)) {
  179. foreach(explode(',', $arg) as $search) {
  180. $uid_query = FALSE;
  181. switch ($user_attr) {
  182. case 'uid':
  183. if (drush_drupal_major_version() >= 7) {
  184. $uid_query = db_query("SELECT uid FROM {users} WHERE uid = :uid", array(':uid' => $search));
  185. }
  186. else {
  187. $uid_query = db_query("SELECT uid FROM {users} WHERE uid = %d", $search);
  188. }
  189. break;
  190. case 'name':
  191. if (drush_drupal_major_version() >= 7) {
  192. $uid_query = db_query("SELECT uid FROM {users} WHERE name = :name", array(':name' => $search));
  193. }
  194. else {
  195. $uid_query = db_query("SELECT uid FROM {users} WHERE name = '%s'", $search);
  196. }
  197. break;
  198. case 'mail':
  199. if (drush_drupal_major_version() >= 7) {
  200. $uid_query = db_query("SELECT uid FROM {users} WHERE mail = :mail", array(':mail' => $search));
  201. }
  202. else {
  203. $uid_query = db_query("SELECT uid FROM {users} WHERE mail = '%s'", $search);
  204. }
  205. break;
  206. }
  207. if ($uid_query !== FALSE) {
  208. if ($uid = drush_db_result($uid_query)) {
  209. $users[] = $uid;
  210. }
  211. else {
  212. drush_set_error("Could not find a uid for $user_attr = $search");
  213. }
  214. }
  215. }
  216. }
  217. }
  218. if (!empty($users)) {
  219. drush_set_option('uids', $users);
  220. }
  221. }
  222. }
  223. /**
  224. * Prints information about the specified user(s).
  225. */
  226. function drush_user_information($users) {
  227. $users = explode(',', $users);
  228. foreach($users as $user) {
  229. $uid = _drush_user_get_uid($user);
  230. if ($uid !== FALSE) {
  231. _drush_user_print_info($uid);
  232. }
  233. }
  234. }
  235. /**
  236. * Block the specified user(s).
  237. */
  238. function drush_user_block($users = '') {
  239. $uids = drush_get_option('uids');
  240. if ($users !== '') {
  241. $users = explode(',', $users);
  242. foreach($users as $user) {
  243. $uid = _drush_user_get_uid($user);
  244. if ($uid !== FALSE) {
  245. $uids[] = $uid;
  246. }
  247. }
  248. }
  249. if (!empty($uids)) {
  250. drush_op('user_user_operations_block', $uids);
  251. }
  252. else {
  253. return drush_set_error("Could not find any valid uids!");
  254. }
  255. }
  256. /**
  257. * Unblock the specified user(s).
  258. */
  259. function drush_user_unblock($users = '') {
  260. $uids = drush_get_option('uids');
  261. if ($users !== '') {
  262. $users = explode(',', $users);
  263. foreach($users as $user) {
  264. $uid = _drush_user_get_uid($user);
  265. if ($uid !== FALSE) {
  266. $uids[] = $uid;
  267. }
  268. }
  269. }
  270. if (!empty($uids)) {
  271. drush_op('user_user_operations_unblock', $uids);
  272. }
  273. else {
  274. return drush_set_error("Could not find any valid uids!");
  275. }
  276. }
  277. /**
  278. * Add a role to the specified user accounts.
  279. */
  280. function drush_user_add_role($role, $users = '') {
  281. $uids = drush_get_option('uids');
  282. if ($users !== '') {
  283. $users = explode(',', $users);
  284. foreach($users as $user) {
  285. $uid = _drush_user_get_uid($user);
  286. if ($uid !== FALSE) {
  287. $uids[] = $uid;
  288. }
  289. }
  290. }
  291. if (drush_drupal_major_version() >= 7) {
  292. $rid_query = db_query("SELECT rid FROM {role} WHERE name = :role", array(':role' => $role));
  293. }
  294. else {
  295. $rid_query = db_query("SELECT rid FROM {role} WHERE name = '%s'", $role);
  296. }
  297. if (!empty($uids)) {
  298. if ($rid = drush_db_result($rid_query)) {
  299. drush_op('user_multiple_role_edit', $uids, 'add_role', $rid);
  300. foreach($uids as $uid) {
  301. drush_log(dt("Added the %role role to uid %uid", array('%role' => $role, '%uid' => $uid)), 'success');
  302. }
  303. }
  304. else {
  305. return drush_set_error("There is no role named: \"$role\"!");
  306. }
  307. }
  308. else {
  309. return drush_set_error("Could not find any valid uids!");
  310. }
  311. }
  312. /**
  313. * Remove a role from the specified user accounts.
  314. */
  315. function drush_user_remove_role($role, $users = '') {
  316. $uids = drush_get_option('uids');
  317. if ($users !== '') {
  318. $users = explode(',', $users);
  319. foreach($users as $user) {
  320. $uid = _drush_user_get_uid($user);
  321. if ($uid !== FALSE) {
  322. $uids[] = $uid;
  323. }
  324. }
  325. }
  326. if (drush_drupal_major_version() >= 7) {
  327. $rid_query = db_query("SELECT rid FROM {role} WHERE name = :role", array(':role' => $role));
  328. }
  329. else {
  330. $rid_query = db_query("SELECT rid FROM {role} WHERE name = '%s'", $role);
  331. }
  332. if (!empty($uids)) {
  333. if ($rid = drush_db_result($rid_query)) {
  334. drush_op('user_multiple_role_edit', $uids, 'remove_role', $rid);
  335. foreach($uids as $uid) {
  336. drush_log(dt("Removed the %role role from uid %uid", array('%role' => $role, '%uid' => $uid)), 'success');
  337. }
  338. }
  339. else {
  340. return drush_set_error("There is no role named: \"$role\"!");
  341. }
  342. }
  343. else {
  344. return drush_set_error("Could not find any valid uids!");
  345. }
  346. }
  347. /**
  348. * Creates a new user account.
  349. */
  350. function drush_user_create($name) {
  351. $mail = drush_get_option('mail');
  352. $pass = drush_get_option('password');
  353. $new_user = array(
  354. 'name' => $name,
  355. 'pass' => $pass,
  356. 'mail' => $mail,
  357. 'access' => '0',
  358. 'status' => 1,
  359. );
  360. if (drush_drupal_major_version() >= 7) {
  361. $result = db_query("SELECT uid FROM {users} WHERE name = :name OR mail = :mail", array(':name' => $name, ':mail' => $new_user['mail']));
  362. }
  363. else {
  364. $result = db_query("SELECT uid FROM {users} WHERE name = '%s' OR mail = '%s'", $name, $new_user['mail']);
  365. }
  366. if (drush_db_result($result) === FALSE) {
  367. if (!drush_get_context('DRUSH_SIMULATE')) {
  368. $new_user_object = user_save(NULL, $new_user, NULL);
  369. if ($new_user_object !== FALSE) {
  370. _drush_user_print_info($new_user_object->uid);
  371. return $new_user_object->uid;
  372. }
  373. else {
  374. drush_set_error("Could not create a new user account with the name " . $name . "!");
  375. }
  376. }
  377. }
  378. else {
  379. drush_set_error("There is already a user account with the name " . $name . " or email address " . $new_user['mail'] . "!");
  380. }
  381. }
  382. /**
  383. * Cancels a user account.
  384. */
  385. function drush_user_cancel($name) {
  386. if (drush_drupal_major_version() >= 7) {
  387. $result = db_query("SELECT uid FROM {users} WHERE name = :name", array(':name' => $name));
  388. }
  389. else {
  390. $result = db_query("SELECT uid FROM {users} WHERE name = '%s'", $name);
  391. }
  392. $uid = drush_db_result($result);
  393. if ($uid !== FALSE) {
  394. drush_print("Cancelling the user account with the following information:");
  395. _drush_user_print_info($uid);
  396. if (drush_get_option('delete-content') && drush_drupal_major_version() >= 7) {
  397. drush_print("All content created by this user will be deleted!");
  398. }
  399. if (drush_confirm('Cancel user account?: ')) {
  400. if (drush_drupal_major_version() >= 7) {
  401. if (drush_get_option('delete-content')) {
  402. user_cancel(array(), $uid, 'user_cancel_delete');
  403. }
  404. else {
  405. user_cancel(array(), $uid, 'user_cancel_reassign');
  406. }
  407. // I got the following technique here: http://drupal.org/node/638712
  408. $batch =& batch_get();
  409. $batch['progressive'] = FALSE;
  410. batch_process();
  411. }
  412. else {
  413. user_delete(array(), $uid);
  414. }
  415. }
  416. }
  417. else {
  418. drush_set_error("Could not find a user account with the name " . $name . "!");
  419. }
  420. }
  421. /**
  422. * Sets the password for the account with the given username
  423. */
  424. function drush_user_password($name) {
  425. $pass = drush_get_option('password');
  426. if (empty($pass)) {
  427. return drush_set_error("You must specify a password!");
  428. }
  429. if (drush_drupal_major_version() >= 7) {
  430. $user = user_load_by_name($name);
  431. }
  432. else {
  433. $user = user_load(array('name' => $name));
  434. }
  435. if ($user !== FALSE) {
  436. if (!drush_get_context('DRUSH_SIMULATE')) {
  437. $user_object = user_save($user, array('pass' => $pass));
  438. if ($user_object === FALSE) {
  439. drush_set_error("Could not change the password for the user account with the name " . $name . "!");
  440. }
  441. }
  442. }
  443. else {
  444. drush_set_error("The user account with the name " . $name . " could not be loaded!");
  445. }
  446. }
  447. /**
  448. * Displays a one time login link for the given user.
  449. */
  450. function drush_user_login($name = NULL) {
  451. if (empty($name)) {
  452. $user = user_load(1);
  453. $name = '[uid 1]';
  454. }
  455. elseif (drush_drupal_major_version() >= 7) {
  456. $user = user_load_by_name($name);
  457. }
  458. else {
  459. $user = user_load(array('name' => $name));
  460. }
  461. if ($user !== FALSE) {
  462. $link = user_pass_reset_url($user);
  463. drush_print($link);
  464. return $link;
  465. }
  466. else {
  467. drush_set_error("The user account with the name " . $name . " could not be loaded!");
  468. }
  469. }
  470. /**
  471. * Print information about a given uid
  472. */
  473. function _drush_user_print_info($uid) {
  474. if (drush_drupal_major_version() >= 7) {
  475. $userinfo = user_load($uid);
  476. }
  477. else {
  478. $userinfo = user_load(array('uid' => $uid));
  479. }
  480. if (drush_get_option('full')) {
  481. $userinfo = (array)$userinfo;
  482. $userinfo_pipe = array();
  483. unset($userinfo['data']);
  484. unset($userinfo['block']);
  485. unset($userinfo['form_build_id']);
  486. foreach($userinfo as $key => $val) {
  487. if (is_array($val)) {
  488. drush_print($key . ': ');
  489. drush_print_r($val);
  490. $userinfo_pipe[] = '"' . implode(",", $val) . '"';
  491. }
  492. else {
  493. if ($key === 'created' OR $key === 'access' OR $key === 'login') {
  494. drush_print($key . ': ' . format_date($val));
  495. $userinfo_pipe[] = $val;
  496. }
  497. else {
  498. drush_print($key . ': ' . $val);
  499. $userinfo_pipe[] = $val;
  500. }
  501. }
  502. }
  503. drush_print_pipe(implode(",", $userinfo_pipe));
  504. drush_print_pipe("\n");
  505. }
  506. else {
  507. $userinfo_short = array(
  508. 'User ID' => $userinfo->uid,
  509. 'User name' => $userinfo->name,
  510. 'User mail' => $userinfo->mail,
  511. );
  512. $userinfo_short['User roles'] = implode(', ', $userinfo->roles);
  513. $userinfo->status ? $userinfo_short['User status'] = 'active' : $userinfo_short['User status'] = 'blocked';
  514. drush_print_table(drush_key_value_to_array_table($userinfo_short));
  515. drush_print_pipe("$userinfo->name, $userinfo->uid, $userinfo->mail, $userinfo->status, \"" . implode(', ', $userinfo->roles) . "\"\n");
  516. }
  517. }
  518. /**
  519. * Get uid(s) from a uid, user name, or email address.
  520. * Returns a uid, or FALSE if none found.
  521. */
  522. function _drush_user_get_uid($search) {
  523. // We use a DB query while looking for the uid to keep things speedy.
  524. $uids = array();
  525. if (is_numeric($search)) {
  526. if (drush_drupal_major_version() >= 7) {
  527. $uid_query = db_query("SELECT uid, name FROM {users} WHERE uid = :uid OR name = :name", array(':uid' => $search, ':name' => $search));
  528. }
  529. else {
  530. $uid_query = db_query("SELECT uid, name FROM {users} WHERE uid = %d OR name = '%d'", $search, $search);
  531. }
  532. }
  533. else {
  534. if (drush_drupal_major_version() >= 7) {
  535. $uid_query = db_query("SELECT uid, name FROM {users} WHERE mail = :mail OR name = :name", array(':mail' => $search, ':name' => $search));
  536. }
  537. else {
  538. $uid_query = db_query("SELECT uid, name FROM {users} WHERE mail = '%s' OR name = '%s'", $search, $search);
  539. }
  540. }
  541. while ($uid = drush_db_fetch_object($uid_query)) {
  542. $uids[$uid->uid] = $uid->name;
  543. }
  544. switch (count($uids)) {
  545. case 0:
  546. return drush_set_error("Could not find a uid for the search term '" . $search . "'!");
  547. break;
  548. case 1:
  549. return array_pop(array_keys($uids));
  550. break;
  551. default:
  552. drush_print('More than one user account was found for the search string "' . $search . '".');
  553. return(drush_choice($uids, 'Please choose a name:', '!value (uid=!key)'));
  554. }
  555. }