Skip to content
user.module 84.7 KiB
Newer Older
Dries Buytaert's avatar
 
Dries Buytaert committed
<?php
// $Id$

session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
session_start();

function user_system($field){
  $system["description"] = t("Enables the user registration and login system.");
Dries Buytaert's avatar
 
Dries Buytaert committed
/*** Session functions *****************************************************/

function sess_open($save_path, $session_name) {
  return 1;
}

function sess_close() {
  return 1;
}

function sess_read($key) {
  global $user;
  $user = user_load(array("sid" => $key, "status" => 1));

Dries Buytaert's avatar
 
Dries Buytaert committed
}

function sess_write($key, $value) {
  global $HTTP_SERVER_VARS;

Dries Buytaert's avatar
 
Dries Buytaert committed
  db_query("UPDATE users SET hostname = '%s', session = '%s', timestamp = '%s' WHERE sid = '$key'", $HTTP_SERVER_VARS["REMOTE_ADDR"], $value, time());
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  return '';
}

function sess_destroy($key) {
  global $HTTP_SERVER_VARS;

Dries Buytaert's avatar
 
Dries Buytaert committed
  db_query("UPDATE users SET hostname = '%s', timestamp = '%s', sid = '' WHERE sid = '$key'", $HTTP_SERVER_VARS["REMOTE_ADDR"], time());
Dries Buytaert's avatar
 
Dries Buytaert committed
}

function sess_gc($lifetime) {
  return 1;
}

/*** Common functions ******************************************************/

function user_external_load($authname) {
  $arr_uid = db_query("SELECT uid FROM authmap WHERE authname = '$authname'");

  if (db_fetch_object($arr_uid)) {
    $uid = db_result($arr_uid);
    return user_load(array("uid" => $uid));
  }
  else {
    return 0;
  }
}

function user_load($array = array()) {

  /*
  ** Dynamically compose a SQL query:
  */

Dries Buytaert's avatar
 
Dries Buytaert committed
  $query = "";

Dries Buytaert's avatar
 
Dries Buytaert committed
  foreach ($array as $key => $value) {
    if ($key == "pass") {
Kjartan Mannes's avatar
Kjartan Mannes committed
      $query .= "u.$key = '". md5($value) ."' AND ";
Dries Buytaert's avatar
 
Dries Buytaert committed
     }
    else {
      $query .= "u.$key = '". addslashes($value) ."' AND ";
    }
  }
  $result = db_query("SELECT u.*, r.name AS role FROM users u LEFT JOIN role r ON u.rid = r.rid WHERE $query u.status < 3 LIMIT 1");
Dries Buytaert's avatar
 
Dries Buytaert committed

  $user = db_fetch_object($result);
Dries Buytaert's avatar
 
Dries Buytaert committed
  if ($data = unserialize($user->data)) {
    foreach ($data as $key => $value) {
      if (!isset($user->$key)) {
        $user->$key = $value;
      }
    }
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

  return $user;
}

function user_save($account, $array = array()) {

  /*
  ** Dynamically compose a SQL query:
  */

  if ($account->uid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $data = unserialize(db_result(db_query("SELECT data FROM users WHERE uid = '$account->uid'")));
Dries Buytaert's avatar
 
Dries Buytaert committed
    foreach ($array as $key => $value) {
      if ($key == "pass") {
        $query .= "$key = '". md5($value) ."', ";
      }
      else if (substr($key, 0, 4) !== "auth") {
Dries Buytaert's avatar
 
Dries Buytaert committed
        if (in_array($key, user_fields())) {
          $query .= "$key = '". check_query($value) ."', ";
        }
        else {
          $data[$key] = $value;
        }
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
    $query .= "data = '". check_query(serialize($data)) ."', ";
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
    db_query("UPDATE users SET $query timestamp = '%s' WHERE uid = '$account->uid'", time());
Dries Buytaert's avatar
 
Dries Buytaert committed

    $user = user_load(array("uid" => $account->uid));
  }
  else {
    $array["timestamp"] = time();

    foreach ($array as $key => $value) {
      if ($key == "pass") {
        $fields[] = check_query($key);
        $values[] = "'". md5($value) ."'";
      }
      else if (substr($key, 0, 4) !== "auth") {
Dries Buytaert's avatar
 
Dries Buytaert committed
        if (in_array($key, user_fields())) {
          $fields[] = check_query($key);
          $values[] = "'". check_query($value) ."'";
        }
        else {
          $data[$key] = $value;
        }
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
    }

Dries Buytaert's avatar
 
Dries Buytaert committed
    $fields[] = "data";
    $values[] = "'". serialize($data) ."'";

Dries Buytaert's avatar
 
Dries Buytaert committed
    db_query("INSERT INTO users (". implode(", ", $fields) .") VALUES (". implode(", ", $values) .")");

    $user = user_load(array("name" => $array["name"]));
  }

  foreach ($array as $key => $value) {
    if (substr($key, 0, 4) == "auth") {
      $authmaps[$key] = $value;
    }
  }

  if ($authmaps) {
    $result = user_set_authmaps($user, $authmaps);
  }

  return $user;
}

function user_set($account, $key, $value) {
  $account->data[$key] = $value;
  return $account;
}

function user_get($account, $key) {
  return $account->data[$key];
}

function user_validate_name($name) {

  /*
  ** Verify the syntax of the given name:
  */

  if (!$name) return t("You must enter a Username.");
  if (ereg("^ ", $name)) return t("The Username cannot begin with a space.");
  if (ereg(" \$", $name)) return t("The Username cannot end with a space.");
  if (ereg("  ", $name)) return t("The Username cannot contain multiple spaces in a row.");
  // if (ereg("[^a-zA-Z0-9@-@]", $name)) return t("The Username contains an illegal character.");
  if (ereg('@', $name) && !eregi('@([0-9a-z](-?[0-9a-z])*\.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) return t("The Username is not a valid authentication ID.");
  if (!eregi('^[[:print:]]+', $name)) return t("The name contains an illegal character.");
Dries Buytaert's avatar
 
Dries Buytaert committed
  if (strlen($name) > 56) return t("The Username '$name' is too long: it must be less than 56 characters.");
}

function user_validate_mail($mail) {

  /*
  ** Verify the syntax of the given e-mail address.  Empty e-mail addresses
  ** allowed.
  */

  if ($mail && !eregi("^[_+\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3}$", $mail)) {
    return t("The e-mail address '$mail' is not valid.");
  }
}

function user_validate_authmap($account, $authname, $module) {
Dries Buytaert's avatar
 
Dries Buytaert committed
  $result = db_query("SELECT COUNT(*) from authmap WHERE uid != '$account->uid' && authname = '$authname'");
  if (db_result($result) > 0) {
    $name = module_invoke($module, "info", "name");
    return t("The %u ID %s is already taken.", array("%u" => ucfirst($name), "%s" => "<i>$authname</i>"));
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
}

function user_password($min_length = 6) {

  /*
  ** Generate a human-readable password:
  */

  mt_srand((double)microtime() * 1000000);
  $words = explode(",", variable_get("user_password", "foo,bar,guy,neo,tux,moo,sun,asm,dot,god,axe,geek,nerd,fish,hack,star,mice,warp,moon,hero,cola,girl,fish,java,perl,boss,dark,sith,jedi,drop,mojo"));
  while (strlen($password) < $min_length) $password .= trim($words[mt_rand(0, count($words))]);
  return $password;
}

function user_access($string) {

  global $user;
  static $perm;

  /*
  ** To reduce the number of SQL queries, we cache the user's permissions
  ** in a static variable.
  */
Dries Buytaert's avatar
 
Dries Buytaert committed
  if (!$perm) {
    if ($user->uid) {
      $perm = db_result(db_query("SELECT p.perm FROM role r, permission p WHERE r.rid = p.rid AND name = '$user->role'"), 0);
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
    else {
      $perm = db_result(db_query("SELECT p.perm FROM role r, permission p WHERE r.rid = p.rid AND name = 'anonymous user'"), 0);
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
  }

  if ($user->uid == 1) {
    return 1;
  }
  else {
    return strstr($perm, $string);
  }

}

function user_mail($mail, $subject, $message, $header) {
  if (variable_get("smtp_library", "") && file_exists(variable_get("smtp_library", ""))) {
    include_once variable_get("smtp_library", "");
    return user_mail_wrapper($mail, $subject, $message, $header);
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
  else {
    /*
    ** Note: if you are having problems with sending mail, or mails look wrong
    ** when they are recieved you may have to modify the str_replace to suit
    ** your systems.
    **  - \r\n will work under dos and windows.
    **  - \n will work for linux, unix and BSDs.
    **  - \r will work for macs.
    */
    return mail($mail, $subject, str_replace("\r", "", $message), $header);
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
}

function user_deny($type, $mask) {

  $allow = db_fetch_object(db_query("SELECT * FROM access WHERE status = '1' AND type = '$type' AND LOWER('$mask') LIKE LOWER(mask)"));

  $deny = db_fetch_object(db_query("SELECT * FROM access WHERE status = '0' AND type = '$type' AND LOWER('$mask') LIKE LOWER(mask)"));

  if ($deny && !$allow) {
    return 1;
  }
  else {
    return 0;
  }
}

Dries Buytaert's avatar
 
Dries Buytaert committed
function user_fields() {
  static $fields;
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  if (!$fields) {
    // is this ANSI? perhaps this should go in the database include...
    $result = db_query("SHOW FIELDS FROM users");
    while ($data = db_fetch_object($result)) {
      $fields[] = $data->Field;
    }
  }
  return $fields;
}

Dries Buytaert's avatar
 
Dries Buytaert committed
/*** Module hooks **********************************************************/

function user_perm() {
  return array("administer users");
}

function user_search($keys) {
  global $PHP_SELF;
  $result = db_query("SELECT * FROM users WHERE name LIKE '%$keys%' LIMIT 20");
  while ($account = db_fetch_object($result)) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $find[$i++] = array("title" => $account->name, "link" => (strstr($PHP_SELF, "admin.php") ? drupal_url(array("mod" => "user", "op" => "edit", "id" => $account->uid), "admin") : drupal_url(array("mod" => "user", "op" => "view", "id" => $account->uid), "module")), "user" => $account->name);
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
  return $find;
}

function user_block() {
Dries Buytaert's avatar
 
Dries Buytaert committed
  global $user, $edit;

  if ($user->uid) {
    // Display account settings:
    $block[0]["subject"] = $user->name;

Kjartan Mannes's avatar
Kjartan Mannes committed
    $output = "<div style=\"{ width: 155; }\">\n";
Dries Buytaert's avatar
 
Dries Buytaert committed
    $links = array_merge(module_invoke_all("link", "menu.create"), array(""), module_invoke_all("link", "menu.view"), array(""), module_invoke_all("link", "menu.settings"), array(""), module_invoke_all("link", "menu.misc"));
    $output .= @implode("<br />\n", $links);
    $block[1]["subject"] = t("Log in");
Kjartan Mannes's avatar
Kjartan Mannes committed
    $output = "<div align=\"center\">\n";
    $output .= "<form action=\"". drupal_url(array("mod" => "user", "op" => "login"), "module") ."\" method=\"post\">\n";
Dries Buytaert's avatar
 
Dries Buytaert committed
    // Save the referer.  We record where the user came from such that we
    // can redirect him after having completed the login form.
    if (!$edit["destination"]) $edit["destination"] = request_uri();
Kjartan Mannes's avatar
Kjartan Mannes committed
    $output .= "<input name=\"edit[destination]\" type=\"hidden\" value=\"" . $edit["destination"] . "\" />";
    $output .= "<b>". t("Username") .":</b><br /><input name=\"edit[name]\" size=\"15\" /><br />\n";
    $output .= "<b>". t("Password") .":</b><br /><input name=\"edit[pass]\" size=\"15\" type=\"password\" /><br />\n";
Kjartan Mannes's avatar
Kjartan Mannes committed
    $output .= "<input name=\"edit[remember_me]\" type=\"checkbox\" />". t("Remember me") ."<br />\n";
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= "<input name=\"edit[op]\" type=\"submit\" value=\"". t("Log in") ."\" /><br />\n";
Kjartan Mannes's avatar
Kjartan Mannes committed
    $output .= "</form></div>\n";
    if (variable_get("user_register", 1)) {
      $output .= "&raquo; ". lm(t("Register"), array("mod" => "user", "op" => "register"), "", array("title" => t("Create a new user account."))) ."<br />\n";
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= "&raquo; ". lm(t("New password"), array("mod" => "user", "op" => "password"), "", array("title" => t("Request new password via e-mail.")));
  $block[0]["info"] = t("User information");
Dries Buytaert's avatar
 
Dries Buytaert committed
  $block[0]["link"] = drupal_url(array("mod" => "user"), "module");
Dries Buytaert's avatar
 
Dries Buytaert committed
  $block[1]["link"] = drupal_url(array("mod" => "user"), "module");
Kjartan Mannes's avatar
Kjartan Mannes committed
  // Who's online block
  $time = 60 * 60; // minutes * seconds
Kjartan Mannes's avatar
Kjartan Mannes committed
  $limit = 5; // List the X most recent people
Dries Buytaert's avatar
 
Dries Buytaert committed
  $result = db_query("SELECT uid, name FROM users WHERE timestamp > unix_timestamp() - $time ORDER BY timestamp DESC LIMIT $limit");
Kjartan Mannes's avatar
Kjartan Mannes committed

  if (db_num_rows($result)) {
Kjartan Mannes's avatar
Kjartan Mannes committed
    while ($account = db_fetch_object($result)) {
      $output .= lm((strlen($account->name) > 15 ? substr($account->name, 0, 15) . '...' : $account->name), array("mod" => "user", "op" => "view", "id" => $account->uid)) ."<br />";
  $block[2]["subject"] = t("Who's online");
  $block[2]["info"] = t("Who's online");
Dries Buytaert's avatar
 
Dries Buytaert committed
  $block[3]["subject"] = t("Who's new");
  $block[3]["info"] = t("Who's new");
  $block[3]["content"] = user_new_users();
Dries Buytaert's avatar
 
Dries Buytaert committed
function user_new_users() {
  $result = db_query("SELECT uid, name FROM users WHERE status != '0' ORDER BY uid DESC LIMIT 5");
  while ($account = db_fetch_object($result)) {
    $output .= lm((strlen($account->name) > 15 ? substr($account->name, 0, 15) . '...' : $account->name), array("mod" =>user, "op" => "view", "id" => $account->uid)) ."<br />";
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
  return $output;
}

Dries Buytaert's avatar
 
Dries Buytaert committed
function user_link($type) {
  if ($type == "page") {
    $links[] = lm(t("user account"), array("mod" => "user"), "", array("title" => t("Create a user account, request a new password or edit your account settings.")));
Dries Buytaert's avatar
 
Dries Buytaert committed
  }

Dries Buytaert's avatar
 
Dries Buytaert committed
  if ($type == "menu.settings") {
    $links[] = lm(t("edit account"), array("mod" => "user", "op" => "edit"), "", array("title" => t("View and edit your account information.")));
Dries Buytaert's avatar
 
Dries Buytaert committed
  }

  if ($type == "menu.misc") {
    if (user_access("access administration pages")) {
      $links[] = la(t("administer %a", array("%a" => variable_get("site_name", "drupal"))), array(), "", array("title" => t("Access administration pages.")));
Dries Buytaert's avatar
 
Dries Buytaert committed
    }

    $links[] = lm(t("logout"), array("mod" => "user", "op" => "logout"), "", array("title" => t("Logout.")));
Dries Buytaert's avatar
 
Dries Buytaert committed
  }

  if ($type == "admin" && user_access("administer users")) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $links[] = la(t("user management"), array("mod" => "user"));
Dries Buytaert's avatar
 
Dries Buytaert committed
  }

  return $links ? $links : array();
}

function drupal_login($arguments) {
   // an XML-RPC method called by external clients (usually other Drupal instances)
  $argument = $arguments->getparam(0);
  $username = $argument->scalarval();
  $argument = $arguments->getparam(1);
  $password = $argument->scalarval();

  if ($user = user_load(array(name => "$username", "pass" => $password, "status" => 1))) {
    return new xmlrpcresp(new xmlrpcval($user->uid, "int"));
  }
  else {
    return new xmlrpcresp(new xmlrpcval(0, "int"));
  }
}


function user_xmlrpc() {
  return array("drupal.login" => array("function" => "drupal_login"));
}

/*** Authentication methods ************************************************/

function user_get_authname($account, $module) {
Dries Buytaert's avatar
 
Dries Buytaert committed

  /*
  **  Called by authentication modules in order to edit/view their authmap information.
Dries Buytaert's avatar
 
Dries Buytaert committed
  */

  $result = db_query("SELECT authname FROM authmap WHERE uid = '$account->uid' && module = '$module'");
  return db_result($result);
}

Dries Buytaert's avatar
 
Dries Buytaert committed

function user_get_authmaps($authname = NULL) {

  /*
  ** Accepts an user object, $account, or an DA name and returns an
  ** associtive array of modules and DA names. Called at external login.
  */

  $result = db_query("SELECT authname, module FROM authmap WHERE authname = '$authname'");
Dries Buytaert's avatar
 
Dries Buytaert committed
  if (db_num_rows($result) > 0) {
    while ($authmap = db_fetch_object($result)) {
      $authmaps[$authmap->module] = $authmap->authname;
    }
    return $authmaps;
  }
  else {
    return 0;
  }
}

function user_set_authmaps($account, $authmaps) {
  foreach ($authmaps as $key => $value) {
    $module = explode("_", $key, 2);
    if ($value) {
      $result = db_query("SELECT COUNT(*) from authmap WHERE uid = '$account->uid' && module = '$module[1]'");
      if (db_result($result) == 0) {
Dries Buytaert's avatar
 
Dries Buytaert committed
        $result = db_query("INSERT INTO authmap (authname, uid, module) VALUES ('%s', '%s', '%s')", $value, $account->uid, $module[1]);
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
      else {
        $result = db_query("UPDATE authmap SET authname = '$value' WHERE uid = '$account->uid' && module = '$module[1]'");
      }
    }
    else {
      $result = db_query("DELETE FROM authmap WHERE uid = '$account->uid' && module = '$module[1]'");
    }
  }
  return $result;
}

function user_auth_help_links() {
Dries Buytaert's avatar
 
Dries Buytaert committed
  foreach (module_list() as $module) {
    if (module_hook($module, "auth_help")) {
      $links[] = lm(module_invoke($module, "info", "name"), array("mod" => "user", "op" => "help"), $module);
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
  }
  return $links;
}

/*** User features *********************************************************/

Dries Buytaert's avatar
 
Dries Buytaert committed
function user_login($edit = array(), $msg = "") {
  global $user, $referer;
Dries Buytaert's avatar
 
Dries Buytaert committed

  /*
  ** If we are already logged on, go to the user page instead.
  */

  if ($user->uid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    drupal_goto(drupal_url(array("mod" => "user"), "module"));
Dries Buytaert's avatar
 
Dries Buytaert committed
  }

  if (user_deny("user", $edit["name"])) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $error = t("The name '%s' has been denied access.", array("%s" => $edit["name"]));
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
  else if ($edit["name"] && $edit["pass"]) {

    /*
Dries Buytaert's avatar
 
Dries Buytaert committed
    ** Try to log in the user locally:
Dries Buytaert's avatar
 
Dries Buytaert committed
    */

    if (!$user) {
      $name = check_input($edit["name"]);
      $pass = check_input($edit["pass"]);
      $user = user_load(array("name" => $name, "pass" => $pass, "status" => 1));
    }

    /*
    ** Strip name and server from ID:
    */

    if ($server = strrchr($edit["name"], "@")) {
      $name = check_input(substr($edit["name"], 0, strlen($edit["name"]) - strlen($server)));
      $server = check_input(substr($server, 1));
      $pass = check_input($edit["pass"]);
    }

    /*
    ** When possible, determine corrosponding external auth source. Invoke source, and login user if successful:
    */

    if (!$user && $server && $result = user_get_authmaps("$name@$server")) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      if (module_invoke(key($result), "auth", $name, $pass, $server)) {
        $user = user_external_load("$name@$server");
        watchdog("user", "external load: $name@$server, module: " . key($result));
      }
      else {
Dries Buytaert's avatar
 
Dries Buytaert committed
        $error = t("Invalid password for %s.", array("%s" => "<i>$name@$server</i>"));
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
    }

     /*
    ** Try each external authentication source in series. Register user if successful.
    */

    else if (!$user && $server) {
      foreach (module_list() as $module) {
        if (module_hook($module, "auth")) {
          if (module_invoke($module, "auth", $name, $pass, $server)) {
            if (variable_get("user_register", 1) == 1 && !user_load(array("name" => "$name@$server"))) { //register this new user
              watchdog("user", "new user: $name@$server ($module ID)");
              $user = user_save("", array("name" => "$name@$server", "pass" => user_password(), "init" => "$name@$server", "rid" => _user_authenticated_id(), "status" => 1, "authname_$module" => "$name@$server"));
Dries Buytaert's avatar
 
Dries Buytaert committed
              break;
            }
          }
        }
      }
    }

    if ($user->uid) {
      watchdog("user", "session opened for '$user->name'");

      /*
      ** Write session ID to database:
      */

      user_save($user, array("sid" => session_id()));

      /*
      ** If the user wants to be remembered, set the proper cookie such
      ** that the session won't expire.
      */

      if ($edit["remember_me"]) {
        setcookie(session_name(), session_id(), time() + 3600 * 24 * 365);
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
Dries Buytaert's avatar
 
Dries Buytaert committed
      else {
        setcookie(session_name(), session_id());
      }

      /*
Dries Buytaert's avatar
 
Dries Buytaert committed
      ** Redirect the user to the page he logged on from.
Dries Buytaert's avatar
 
Dries Buytaert committed
      */

Dries Buytaert's avatar
 
Dries Buytaert committed
      drupal_goto($edit["destination"]);
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
    else {
      if (!$error) {
        $error = t("Sorry.  Unrecognized username or password.") ." ". lm(t("Have you forgotten your password?"), array("mod" => "user", "op" => "password"));
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
      if ($server) {
        watchdog("user", "failed login for '$name@$server': $error");
      }
      else {
        watchdog("user", "failed login for '$name': $error");
      }
    }
  }

  /*
  ** Display error message (if any):
  */

  if ($error) {
Kjartan Mannes's avatar
Kjartan Mannes committed
    $output .= "<p><span style=\"color: red;\" class=\"error\">". check_output($error) ."</span></p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
  }

Dries Buytaert's avatar
 
Dries Buytaert committed
  /*
  ** Save the referer.  We record where the user came from such that we
  ** can redirect him after having completed the login form.
  */

  if (!$edit["destination"]) {
    $edit["destination"] = request_uri();
  }
  $output .= form_hidden("destination", $edit["destination"]);

Dries Buytaert's avatar
 
Dries Buytaert committed
  /*
  ** Display login form:
  */

Dries Buytaert's avatar
 
Dries Buytaert committed
  if ($msg) {
    $output .= "<p>$msg</p>";
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= form_textfield(t("Username"), "name", $edit["name"], 20, 64, t("Enter your %s username, or an ID from one of our affiliates: %a.", array("%s" => variable_get("site_name", "local"), "%a" => implode(", ", user_auth_help_links()))));
Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= form_password(t("Password"), "pass", $pass, 20, 64, t("Enter the password that accompanies your username."));
  $output .= form_checkbox(t("Remember me"), "remember_me", 1, 0, 0);
Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= form_submit(t("Log in"));
  $output .= "<p>&raquo; ". lm(t("E-mail new password"), array("mod" => "user", "op" => "password")). "<br />";
  if (variable_get("user_register", 1)) {
    $output .= "&raquo; ". lm(t("Create new account"), array("mod" => "user", "op" => "register"));
  }
  $output .= "</p>";
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  return form($output, "post", drupal_url(array ("mod" => "user"), "module"));
Dries Buytaert's avatar
 
Dries Buytaert committed
}

function _user_authenticated_id() {
  return db_result(db_query("SELECT rid FROM role WHERE name = 'authenticated user'"));
}

Dries Buytaert's avatar
 
Dries Buytaert committed
function user_logout() {
  global $user;

  if ($user->uid) {
    watchdog("user", "session closed for user '$user->name'");

    /*
    ** Destroy the current session:
    */

    session_destroy();
    unset($user);
  }

  /*
  ** Redirect the user to his personal information page:
  */

  drupal_goto("index.php");

}

function user_pass($edit = array()) {

Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($edit["name"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $account = db_fetch_object(db_query("SELECT uid, name, mail FROM users WHERE name = '%s'", $edit["name"]));
    if (!$account) $error = t("Sorry. The username <i>%s</i> is not recognized.", array("%s" => $edit["name"]));
Kjartan Mannes's avatar
Kjartan Mannes committed
  else if ($edit["mail"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $account = db_fetch_object(db_query("SELECT uid, name, mail FROM users WHERE mail = '%s'", $edit["mail"]));
    if (!$account) $error = t("Sorry. The e-mail address <i>%s</i> is not recognized.", array("%s" => $edit["mail"]));
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  if ($account) {
Dries Buytaert's avatar
 
Dries Buytaert committed

      $from = variable_get("site_mail", ini_get("sendmail_from"));
Dries Buytaert's avatar
 
Dries Buytaert committed
      $pass = user_password();

      /*
      ** Save new password:
      */

      user_save($account, array("pass" => $pass));

      /*
      ** Mail new password:
      */

      $variables = array("%username" => $account->name, "%site" => variable_get("site_name", "drupal"), "%password" => $pass, "%uri" => path_uri(), "%uri_brief" => path_uri(1), "%mailto" => $account->mail, "%date" => format_date(time()));
      $subject = strtr(variable_get("user_mail_pass_subject", t("Replacement login information for %username at %site")), $variables);
Dries Buytaert's avatar
 
Dries Buytaert committed
      $body = strtr(variable_get("user_mail_pass_body", t("%username,\n\nHere is your new password for %site.  You may now login to %uri". drupal_url(array("mod" => "user", "op" => "login"), "module") ." using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %uri". drupal_url(array("mod" => "user", "op" => "edit"), "module") .".\n\nYour new %site membership also enables you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering.  Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team")), $variables);
      $headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
      user_mail($account->mail, $subject, $body, $headers);
Dries Buytaert's avatar
 
Dries Buytaert committed

      watchdog("user", "mail password: '". $account->name ."' &lt;". $account->mail ."&gt;");
Dries Buytaert's avatar
 
Dries Buytaert committed

      return t("Your password and further instructions have been sent to your e-mail address.");
    }
    else {
Kjartan Mannes's avatar
Kjartan Mannes committed
    // Display error message if necessary.
    if ($error) {
      $output .= "<p><span style=\"color: red;\" class=\"error\">". check_output($error) ."</span></p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
    }

    /*
    ** Display form:
    */

Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= "<p>". sprintf(t("Enter your username %sor%s your e-mail address."), "<b><i>", "</i></b>") ."</p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 64);
    $output .= form_textfield(t("E-mail address"), "mail", $edit["mail"], 30, 64);
    $output .= form_submit(t("E-mail new password"));
    $output .= "<p>&raquo; ". lm(t("Log in"), array("mod" =>user, "op" => "login")) ."<br />";
    if (variable_get("user_register", 1)) {
      $output .= "&raquo; ". lm(t("Create new account"), array("mod" => "user", "op" => "register"));
    }
    $output .= "</p>";
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
    return form($output, "post", drupal_url(array ("mod" => "user"), "module"));
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
}

function user_register($edit = array()) {
  global $user;

  /*
  ** If we are already logged on, go to the user page instead.
  */

  if ($user->uid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    drupal_goto(drupal_url(array("mod" => "user", "op" => "edit"), "module"));
Dries Buytaert's avatar
 
Dries Buytaert committed

  if ($edit["name"] && $edit["mail"]) {
    if ($error = user_validate_name($edit["name"])) {
      // do nothing
    }
    else if ($error = user_validate_mail($edit["mail"])) {
      // do nothing
    }
    else if (user_deny("user", $edit["name"])) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $error = t("The name '%s' has been denied access.", array("%s" => $edit["name"]));
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
    else if (user_deny("mail", $edit["mail"])) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $error = t("The e-mail address '%s' has been denied access.", array("%s" => $edit["mail"]));
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
    else if (db_num_rows(db_query("SELECT name FROM users WHERE LOWER(name) = LOWER('%s')", $edit["name"])) > 0) {
      $error = t("The name '%s' is already taken.", array("%s" => $edit["name"]));
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
    else if (db_num_rows(db_query("SELECT mail FROM users WHERE LOWER(mail) = LOWER('%s')", $edit["mail"])) > 0) {
      $error = t("The e-mail address '%s' is already taken.", array("%s" => $edit["mail"]));
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
    else if (variable_get("user_register", 1) == 0) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $error = t("Public registrations have been disabled by the site administrator.");
    }
    else {
Dries Buytaert's avatar
 
Dries Buytaert committed
      foreach (module_list() as $module) {
        if (module_hook($module, "user")) {
          $result = module_invoke($module, "user", "register_validate", $edit, $user);
          if (is_array($result)) {
            $data = array_merge($data, $result);
          }
          elseif (is_string($result)) {
            $error = $result;
            break;
          }
        }
      }
      if (!$error) {
        $success = 1;
      }
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
  }

  if ($success) {

    watchdog("user", "new user: '". $edit["name"] ."' &lt;". $edit["mail"] ."&gt;");

    $from = variable_get("site_mail", ini_get("sendmail_from"));
Dries Buytaert's avatar
 
Dries Buytaert committed
    $pass = user_password();

    // create new user account, noting whether administrator approval is required
    $account = user_save("", array_merge(array("name" => $edit["name"], "pass" => $pass, "init" => $edit["mail"], "mail" => $edit["mail"], "rid" => _user_authenticated_id(), "status" => (variable_get("user_register", 1) == 1 ? 1 : 0)), $data));
Dries Buytaert's avatar
 
Dries Buytaert committed

    $variables = array("%username" => $edit["name"], "%site" => variable_get("site_name", "drupal"), "%password" => $pass, "%uri" => path_uri(), "%uri_brief" => path_uri(1), "%mailto" => $edit["mail"], "%date" => format_date(time()));
Dries Buytaert's avatar
 
Dries Buytaert committed
    //the first user may login immediately, and receives a customized welcome e-mail.
Kjartan Mannes's avatar
Kjartan Mannes committed
      user_mail($edit["mail"], t("drupal user account details for %s", array("%s" => $edit["name"])), strtr(t("%username,\n\nYou may now login to %uri using the following username and password:\n\n  username: %username\n  password: %password\n\nAfter logging in, you may wish to visit the following pages:\n\nAdministration: %uriadmin.php\nEdit user account: %uri". drupal_url(array("mod" => "user", "op" => "edit"), "module") ."\n\n--drupal"), $variables), "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
      // This should not be t()'ed. No point as its only shown once in the sites lifetime, and it would be bad to store the password
Dries Buytaert's avatar
 
Dries Buytaert committed
      $output .= "<p>Welcome to Drupal. You are user #1, which gives you full and immediate access.  All future registrants will receive their passwords via e-mail, so please configure your e-mail settings using the Administration pages.</p><p> Your password is <b>$pass</b>. You may change your password on the next page.</p><p>Please login below.</p>";
      $output .= form_hidden("name", $account->name);
      $output .= form_hidden("pass", $pass);
      $output .= form_submit(t("Log in"));
      return form($output);
    }
    else {
      if ($account->status) {
        /*
        ** Create new user account, no administrator approval required:
        */

        $subject = strtr(variable_get("user_mail_welcome_subject", t("User account details for %username at %site")), $variables);
Dries Buytaert's avatar
 
Dries Buytaert committed
        $body = strtr(variable_get("user_mail_welcome_body", t("%username,\n\nThank you for registering at %site. You may now login to %uri". drupal_url(array("mod" => "user", "op" => "login"), "module") ." using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %urimodule.php?mod=user&op=edit\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n--  %site team")), $variables);
        user_mail($edit["mail"], $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
        return t("Your password and further instructions have been sent to your e-mail address.");
      }
      else {
        /*
        ** Create new user account, administrator approval required:
        */
        $subject = strtr(variable_get("user_mail_welcome_subject", t("User account details for %username at %site")), $variables);
Dries Buytaert's avatar
 
Dries Buytaert committed
        $body = strtr(variable_get("user_mail_welcome_body", t("%username,\n\nThank you for registering at %site. Your account will have to be approved by the site administrator. You may now login to %uri". drupal_url(array("mod" => "user", "op" => "login"), "module") ." using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %urimodule.php?mod=user&op=edit\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n--  %site team")), $variables);
        user_mail($edit["mail"], $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
        user_mail(variable_get("site_mail", ini_get("sendmail_from")), $subject, t("%u has applied for an account.\n\n%uri", array("%u" => $account->name, "%uri" => path_uri() . drupal_url(array("mod" => "user", "op" => "edit", "id" => $account->uid), "admin"))), "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
        return t("Your password and further instructions have been sent to your e-mail address.");
      }
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
  else {
    if ($error) {
Kjartan Mannes's avatar
Kjartan Mannes committed
      $output .= "<p><span style=\"color: red;\" class=\"error\">". check_output($error) ."</span></p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Dries Buytaert's avatar
 
Dries Buytaert committed

  // display the registration form
  $affiliates = user_auth_help_links();
  if (array_count_values($affiliates) > 1) {
    $affiliates = implode(", ", $affiliates);
    $output .= "<p>" . t("Note: If you have an account with one of our affiliates (%s), you may ". lm("login now", array("mod" => "user", "op" => "login")) ." instead of registering.", array("%s" => $affiliates)) ."</p>";
  }
  $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 64, t("Your full name or your prefered username: only letters, numbers and spaces are allowed."));
  $output .= form_textfield(t("E-mail address"), "mail", $edit["mail"], 30, 64, t("A password and instructions will be sent to this e-mail address, so make sure it is accurate."));
  foreach (module_list() as $module) {
    if (module_hook($module, "user")) {
      $output .= module_invoke($module, "user", "register_form", $edit, $user);
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
  $output .= form_submit(t("Create new account"));
  $output .= "<p>&raquo; ". lm(t("E-mail new password"), array("mod" => "user", "op" => "password")). "<br />";
  $output .= "&raquo; " .lm(t("Log in"), array("mod" => "user", "op" => "login")). "</p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
}

Kjartan Mannes's avatar
Kjartan Mannes committed

function user_delete() {
  global $edit, $user;
Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($edit["confirm"]) {
    watchdog(user,"$user->name deactivated her own account.");
Kjartan Mannes's avatar
Kjartan Mannes committed
    db_query("UPDATE users SET mail = 'deleted', status='0' WHERE uid = '$user->uid'");
    $output .= t("Your account has been deactivated.");
  }
  else {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= form_item(t("Confirm Deletion"), t("You are about to deactivate your own user account. In addition, your e-mail address will be removed from the database."));
Kjartan Mannes's avatar
Kjartan Mannes committed
    $output .= form_hidden("confirm", 1);
    $output .= form_submit(t("Delete account"));
    $output = form($output);
  }
  return $output;
}

Dries Buytaert's avatar
 
Dries Buytaert committed
function user_edit($edit = array()) {
  global $user, $languages;
Dries Buytaert's avatar
 
Dries Buytaert committed

  if ($user->uid) {
    if ($edit["name"]) {
      if ($error = user_validate_name($edit["name"])) {
        // do nothing
      }
      else if ($error = user_validate_mail($edit["mail"])) {
        // do nothing
      }
Dries Buytaert's avatar
 
Dries Buytaert committed
      else if (db_num_rows(db_query("SELECT uid FROM users WHERE uid != '$user->uid' AND LOWER(name) = LOWER('%s')", $edit["name"])) > 0) {
        $error = t("The name '%s' is already taken.", array("%s" => $edit["name"]));
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
Dries Buytaert's avatar
 
Dries Buytaert committed
      else if ($edit["mail"] && db_num_rows(db_query("SELECT uid FROM users WHERE uid != '$user->uid' AND LOWER(mail) = LOWER('%s')", $edit["mail"])) > 0) {
        $error = t("The e-mail address '%s' is already taken.", array("%s" => $edit["mail"]));
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
      else if ($user->uid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
        foreach (module_list() as $module) {
          if (module_hook($module, "user")) {
            $result = module_invoke($module, "user", "edit_validate", $edit, $user);
          }
          if (is_array($result)) {
            $data = array_merge($data, $result);
          }
          elseif (is_string($result)) {
            $error = $result;
            break;
          }
        }

Dries Buytaert's avatar
 
Dries Buytaert committed
        /*
        ** If required, check that proposed passwords match.  If so,
        ** add new password to $edit.
        */

        if ($edit["pass1"]) {
          if ($edit["pass1"] == $edit["pass2"]) {
            $edit["pass"] = $edit["pass1"];
          }
          else {
            $error = t("The specified passwords do not match.");
          }
        }

        unset($edit["pass1"], $edit["pass2"]);

Dries Buytaert's avatar
 
Dries Buytaert committed
        if (!$error) {
          /*
          ** Save user information:
          */
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
          $user = user_save($user, array_merge($edit, $data));
Dries Buytaert's avatar
 
Dries Buytaert committed

          $output .= t("Your user information changes have been saved.");
Dries Buytaert's avatar
 
Dries Buytaert committed
        }
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
    }

    if ($error) {
Kjartan Mannes's avatar
Kjartan Mannes committed
      $output .= "<p><span style=\"color: red;\" class=\"error\">". check_output($error) ."</span></p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
    }

Kjartan Mannes's avatar
Kjartan Mannes committed
    if (!$edit) {
      $edit = object2array($user);
    }

    $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 55, t("Your full name or your prefered username: only letters, numbers and spaces are allowed."));
    $output .= form_textfield(t("E-mail address"), "mail", $edit["mail"], 30, 55, t("Insert a valid e-mail address.  All e-mails from the system will be sent to this address. The e-mail address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by e-mail."));
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
    foreach (module_list() as $module) {
      if (module_hook($module, "user")) {
        $output .= module_invoke($module, "user", "edit_form", $edit, $user);
      }
    }

Kjartan Mannes's avatar
Kjartan Mannes committed
    $output .= form_textfield(t("Homepage"), "homepage", $edit["homepage"], 30, 55, t("Optional") .". ". t("Make sure you enter a fully qualified URL: remember to include \"http://\"."));
    $options = "<option value=\"\"". (("" == $key) ? " selected=\"selected\"" : "") .">". t("Default theme") ."</option>\n";
    foreach (theme_list() as $key => $value) {
      $options .= "<option value=\"$key\"". (($edit["theme"] == $key) ? " selected=\"selected\"" : "") .">$key - $value->description</option>\n";
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= form_item(t("Theme"), "<select name=\"edit[theme]\">$options</select>", t("Selecting a different theme will change the look and feel of the site."));
    for ($zone = -43200; $zone <= 46800; $zone += 3600) $zones[$zone] = date("l, F dS, Y - h:i A", time() - date("Z") + $zone) ." (GMT ". $zone / 3600 .")";
Kjartan Mannes's avatar
Kjartan Mannes committed
    $output .= form_select(t("Timezone"), "timezone", $edit["timezone"], $zones, t("Select what time you currently have and your timezone settings will be set appropriate."));
    $output .= form_select(t("Language"), "language", $edit["language"], $languages, t("Selecting a different language will change the language of the site."));
    $output .= form_textarea(t("Signature"), "signature", $edit["signature"], 70, 3, t("Your signature will be publicly displayed at the end of your comments.") ."<br />". t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= form_item(t("Password"), "<input type=\"password\" name=\"edit[pass1]\" size=\"12\" maxlength=\"24\" /> <input type=\"password\" name=\"edit[pass2]\" size=\"12\" maxlength=\"24\" />", t("Enter your new password twice if you want to change your current password or leave it blank if you are happy with your current password."));
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= form_submit(t("Save user information"));
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output = form($output);
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
  else {
    $output = user_login();
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

  return $output;
}

function user_menu() {
Dries Buytaert's avatar
 
Dries Buytaert committed
  $links[] = lm(t("view user information"), array("mod" => "user", "op" => "view"));
  $links[] = lm(t("edit user information"), array("mod" => "user", "op" => "edit"));
  $links[] = lm(t("delete account"), array("mod" => "user", "op" => "delete"));
Dries Buytaert's avatar
 
Dries Buytaert committed

  return "<div align=\"center\">". implode(" &middot; ", $links) ."</div>";
}

function user_view($uid = 0) {
Dries Buytaert's avatar
 
Dries Buytaert committed

  if (!$uid) {
    $uid = $user->uid;
  }

  if ($user->uid && $user->uid == $uid) {
    $output .= form_item(t("Name"), check_output("$user->name ($user->init)"));
    $output .= form_item(t("E-mail address"), check_output($user->mail));
Dries Buytaert's avatar
 
Dries Buytaert committed

    foreach (module_list() as $module) {
      if (module_hook($module, "user")) {
        $output .= module_invoke($module, "user", "view_private", "", $user);
      }
    }

    $output .= form_item(t("Homepage"), "<a href=\"$user->homepage\">$user->homepage</a>");
Dries Buytaert's avatar
 
Dries Buytaert committed
    $output .= form_item(t("Signature"), check_output($user->signature, 1));

    $theme->header();
    $theme->box(t("User account"), user_menu());
    $theme->box(t("View user information"), $output);
    $theme->footer();
  }
  else if ($uid && $account = user_load(array("uid" => $uid, "status" => 1))) {
    $output .= form_item(t("Name"), check_output($account->name));
    $output .= form_item(t("Homepage"), "<a href=\"$account->homepage\">$account->homepage</a>");
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
    foreach (module_list() as $module) {
      if (module_hook($module, "user")) {
        $output .= module_invoke($module, "user", "view_public", "", $account);
      }
    }

Dries Buytaert's avatar
 
Dries Buytaert committed
    $theme->header();
    $theme->box(t("View user information"), $output);
    $theme->footer();
  }