- Rewrote the profile module:

+ Added a 'created' field to the users table and renamed the 'timestamp'
     fied to 'changed' (cfr. node table).  Update.php will try to determine
     a 'created' timestamp for existing users.

   + The profile module no longer uses serialized data but has its own set
     of tables.  Known existing profile data is migrated by these new tables.
       TODO: migrate the birthday field.

   + The profile fields can be grouped, and within each group, profile fields
     can be sorted using weights.

   + The profile pages can be themed.

   + The profiles can be browsed based on certain properties/settings.

   + Change the _user hook: (i) 'private_view' and 'public_view' are merged
     into 'view' as there are no private fields and (ii) 'edit_form' has
     been renamed to 'edit'.

   + Avatar handling has been refactored and is now part of the user module.
     The users table has a dedicted 'picture' field.

   + Simplified the way themes should use display/visualize pictures or
     avatars.

   + Made it possible for administrators to replace or delete avatars.

   + ...

  I hope this make for a good base to build on collectively.
4.5.x
Dries Buytaert 2004-03-11 20:33:59 +00:00
parent f10cca1182
commit 2101f6c454
28 changed files with 1061 additions and 775 deletions

View File

@ -1,3 +1,10 @@
Drupal x.x.x, xxxx-xx-xx
------------------------
- profile module:
* made it possible to administere profile fields.
* made it possible to browse the profiles by field.
Drupal 4.4.0, xxxx-xx-xx (release candidate)
--------------------------------------------

View File

@ -282,13 +282,13 @@ CREATE TABLE node (
uid int(10) NOT NULL default '0',
status int(4) NOT NULL default '1',
created int(11) NOT NULL default '0',
changed int(11) NOT NULL default '0',
comment int(2) NOT NULL default '0',
promote int(2) NOT NULL default '0',
moderate int(2) NOT NULL default '0',
users longtext NOT NULL,
teaser longtext NOT NULL,
body longtext NOT NULL,
changed int(11) NOT NULL default '0',
revisions longtext NOT NULL,
static int(2) NOT NULL default '0',
PRIMARY KEY (nid),
@ -312,6 +312,38 @@ CREATE TABLE page (
PRIMARY KEY (nid)
) TYPE=MyISAM;
--
-- Table structure for table 'profile_fields'
--
CREATE TABLE profile_fields (
fid int(10) NOT NULL auto_increment,
title varchar(255) default NULL,
name varchar(128) default NULL,
explanation TEXT default NULL,
category varchar(255) default NULL,
type varchar(128) default NULL,
weight tinyint(1) DEFAULT '0' NOT NULL,
overview tinyint(1) DEFAULT '0' NOT NULL,
options text,
KEY category (category),
UNIQUE KEY name (name),
PRIMARY KEY (fid)
);
--
-- Table structure for table 'profile_values'
--
CREATE TABLE profile_values (
fid int(11) unsigned default '0',
uid int(11) unsigned default '0',
value text,
KEY uid (uid),
KEY fid (fid)
);
--
-- Table structure for table 'url_alias'
--
@ -514,10 +546,12 @@ CREATE TABLE users (
threshold tinyint(1) default '0',
theme varchar(255) NOT NULL default '',
signature varchar(255) NOT NULL default '',
timestamp int(11) NOT NULL default '0',
created int(11) NOT NULL default '0',
changed int(11) NOT NULL default '0',
status tinyint(4) NOT NULL default '0',
timezone varchar(8) default NULL,
language char(2) NOT NULL default '',
picture varchar(255) NOT NULL DEFAULT '',
init varchar(64) default '',
data longtext,
rid int(10) unsigned NOT NULL default '0',

View File

@ -511,10 +511,12 @@ CREATE TABLE users (
threshold smallint default '0',
theme varchar(255) NOT NULL default '',
signature varchar(255) NOT NULL default '',
timestamp integer NOT NULL default '0',
created integer NOT NULL default '0',
changed integer NOT NULL default '0',
status smallint NOT NULL default '0',
timezone varchar(8) default NULL,
language char(2) NOT NULL default '',
picture varchar(255) NOT NULL DEFAULT '',
init varchar(64) default '',
data text default '',
rid integer NOT NULL default '0',

View File

@ -50,7 +50,8 @@ $sql_updates = array(
"2004-01-11" => "update_76",
"2004-01-13" => "update_77",
"2004-02-03" => "update_78",
"2004-02-21" => "update_79"
"2004-02-21" => "update_79",
"2004-03-11: first update since Drupal 4.4.0 release" => "update_80"
);
function update_32() {
@ -760,6 +761,126 @@ function update_79() {
return $ret;
}
function update_80() {
// Add a 'created' field to the users table:
update_sql('ALTER TABLE {users} ADD created INT(11) NOT NULL');
update_sql('ALTER TABLE {users} CHANGE timestamp changed INT(11) NOT NULL');
// Add some indices to speed up the update process:
update_sql('ALTER TABLE {comments} ADD index (timestamp)');
update_sql('ALTER TABLE {node} ADD index (created)');
// Assign everyone a created timestamp to begin with:
update_sql("UPDATE {users} SET created = changed WHERE created = ''");
// Print a status message:"
print '<p>Note: this might take a while ...</p>';
// Try updating the user records using the comment table:
$result = db_query('SELECT DISTINCT(u.uid) FROM {comments} c LEFT JOIN {users} u ON c.uid = u.uid WHERE c.timestamp < u.created');
while ($account = db_fetch_object($result)) {
// Retrieve the proper timestamp:
$timestamp = db_result(db_query('SELECT MIN(timestamp) FROM {comments} WHERE uid = %d', $account->uid));
// Update this user record as well as older records with an older timestamp:
db_query('UPDATE {users} SET created = %d WHERE created > %d AND uid <= %d', $timestamp, $timestamp, $account->uid);
}
// Try updating the user records using the node table:
$result = db_query('SELECT DISTINCT(u.uid) FROM {node} n LEFT JOIN {users} u ON n.uid = u.uid WHERE n.created < u.created');
while ($account = db_fetch_object($result)) {
// Retrieve the proper timestamp:
$timestamp = db_result(db_query('SELECT MIN(created) FROM {node} WHERE uid = %d', $account->uid));
// Update this user record as well as older records with an older timestamp:
db_query('UPDATE {users} SET created = %d WHERE created > %d AND uid <= %d', $timestamp, $timestamp, $account->uid);
}
// Add profile module related tables:
update_sql("CREATE TABLE {profile_fields} (
fid int(10) NOT NULL auto_increment,
title varchar(255) default NULL,
name varchar(128) default NULL,
explanation TEXT default NULL,
category varchar(255) default NULL,
type varchar(128) default NULL,
weight tinyint(1) DEFAULT '0' NOT NULL,
overview tinyint(1) DEFAULT '0' NOT NULL,
options text,
KEY category (category),
UNIQUE KEY name (name),
PRIMARY KEY (fid)
);");
update_sql("CREATE TABLE {profile_values} (
fid int(11) unsigned default '0',
uid int(11) unsigned default '0',
value text,
KEY uid (uid),
KEY fid (fid)
);");
// Migrate the old profile data to the new scheme:
$fields = array(
array("Name", "realname", "textfield", NULL, 0),
array("Address", "address", "textfield", NULL, 0),
array("City", "city", "textfield", NULL, 0),
array("State, province or region", "state", "textfield", NULL, 0),
array("Zip or postal code", "zip", "textfield", NULL, 0),
array("Country", "country", "textfield", NULL, 1),
array("Gender", "gender", "selection", "male\nfemale", 1),
array("Job title", "job", "textfield", NULL, 0),
array("ICQ messenger ID", "icq", "textfield", NULL, 0),
array("MSN messenger ID", "msn", "textfield", NULL, 0),
array("Yahoo messenger ID", "yahoo", "textfield", NULL, 0),
array("AIM messenger ID", "aim", "textfield", NULL, 0),
array("URL of homepage", "homepage", "textfield", NULL, 1),
array("Biography", "biography", "textarea", NULL, 0),
array("Interests", "interests", "textarea", NULL, 0),
array("Public key", "publickey", "textarea", NULL, 0)
);
// Remove existing data (debug mode):
db_query('DELETE FROM {profile_fields}');
db_query('DELETE FROM {profile_values}');
foreach ($fields as $field) {
db_query("INSERT INTO {profile_fields} (title, name, type, category, options, overview) VALUES ('%s', '%s', '%s', 'Personal information', '%s', %d)", $field[0], $field[1], $field[2], $field[3], $field[4]);
}
db_query("ALTER TABLE {users} ADD picture varchar(255) NOT NULL DEFAULT ''");
$result = db_query("SELECT uid FROM {users}");
while ($account = db_fetch_object($result)) {
// Load the user record:
$account = user_load(array('uid' => $account->uid));
$edit = array();
// Modify the user record:
foreach ($fields as $field) {
$old = "profile_". $field[1];
$new = $field[1];
if ($account->$old) {
$edit[$new] = $account->$old;
}
unset($account->$old);
}
// Gender specific changes:
if ($edit['gender'] == 'f') $edit['gender'] = 'female';
if ($edit['gender'] == 'm') $edit['gender'] = 'male';
// Avatar specific changes:
if ($account->profile_avatar) {
$edit['picture'] = $account->profile_avatar;
}
unset($account->profile_avatar);
// Save the update record:
user_save($account, $edit);
}
}
function update_sql($sql) {
$edit = $_POST["edit"];
$result = db_query($sql);

View File

@ -56,6 +56,7 @@ li a.active {
padding: 0.25em 1em 0.25em 0em;
}
#pager {
clear: both;
text-align: center;
}
#pager div {
@ -156,6 +157,14 @@ li a.active {
.form-submit {
margin: 0.5em 0;
}
.profile {
clear: both;
margin: 1em 0em 1em 0em;
}
.profile .picture {
float: right;
margin: 0 1em 1em 0;
}
#aggregator .feed img {
float: right;
}

View File

@ -37,13 +37,9 @@ function blog_access($op, $node) {
}
function blog_user($type, &$edit, &$user) {
switch ($type) {
case "view_public":
case "view_private":
if (user_access("maintain personal blog", $user)) {
if ($type == 'view' && user_access("maintain personal blog", $user)) {
return form_item(t("Blog"), l(t("view recent blog entries"), "blog/$user->uid", array("title" => t("Read %username's latest blog entries.", array("%username" => $user->name)))));
}
}
}
function blog_help($section) {

View File

@ -37,13 +37,9 @@ function blog_access($op, $node) {
}
function blog_user($type, &$edit, &$user) {
switch ($type) {
case "view_public":
case "view_private":
if (user_access("maintain personal blog", $user)) {
if ($type == 'view' && user_access("maintain personal blog", $user)) {
return form_item(t("Blog"), l(t("view recent blog entries"), "blog/$user->uid", array("title" => t("Read %username's latest blog entries.", array("%username" => $user->name)))));
}
}
}
function blog_help($section) {

View File

@ -138,16 +138,15 @@ function comment_settings() {
function comment_user($type, $edit, &$user) {
switch ($type) {
case "view_public":
case "view_private":
case "view":
if ($user->signature) {
return form_item(t("Signature"), check_output($user->signature));
}
break;
case "edit_form":
case "edit":
// when user tries to edit his own data
return array(t('Personal information') => form_textarea(t("Signature"), "signature", $user->signature, 70, 3, t("Your signature will be publicly displayed at the end of your comments.") ."<br />". filter_tips_short()));
case "edit_validate":
case "edit":
// validate user data editing
return array("signature" => $edit["signature"]);
}
@ -203,7 +202,7 @@ function comment_reply($pid, $nid) {
*/
if ($pid) {
$comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $pid));
$comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.picture, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $pid));
$comment = drupal_unpack($comment);
$output .= theme("comment_view", $comment);
}
@ -258,7 +257,7 @@ function comment_preview($edit) {
$output .= theme("comment_form", $edit, t("Reply"));
if ($edit["pid"]) {
$comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $edit["pid"]));
$comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.picture, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $edit["pid"]));
$comment = drupal_unpack($comment);
$output .= theme("comment_view", $comment);
}
@ -559,7 +558,7 @@ function comment_render($node, $cid = 0) {
$output .= "<form method=\"post\" action=\"". url("comment") ."\"><div>\n";
$output .= form_hidden("nid", $nid);
$result = db_query("SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0 GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users", $cid);
$result = db_query("SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.picture, u.data, c.score, c.users FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0 GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.picture, u.data, c.score, c.users", $cid);
if ($comment = db_fetch_object($result)) {
$output .= theme("comment_view", $comment, theme('links', module_invoke_all('link', 'comment', $comment, 1)));
@ -576,9 +575,9 @@ function comment_render($node, $cid = 0) {
** Multiple comments view
*/
$query .= "SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users, c.thread FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = '". check_query($nid) ."' AND c.status = 0";
$query .= "SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.picture, u.data, c.score, c.users, c.thread FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = '". check_query($nid) ."' AND c.status = 0";
$query .= " GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users, c.thread";
$query .= " GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.picture, u.data, c.score, c.users, c.thread";
/*
** We want to use the standard pager, but threads would need every

View File

@ -138,16 +138,15 @@ function comment_settings() {
function comment_user($type, $edit, &$user) {
switch ($type) {
case "view_public":
case "view_private":
case "view":
if ($user->signature) {
return form_item(t("Signature"), check_output($user->signature));
}
break;
case "edit_form":
case "edit":
// when user tries to edit his own data
return array(t('Personal information') => form_textarea(t("Signature"), "signature", $user->signature, 70, 3, t("Your signature will be publicly displayed at the end of your comments.") ."<br />". filter_tips_short()));
case "edit_validate":
case "edit":
// validate user data editing
return array("signature" => $edit["signature"]);
}
@ -203,7 +202,7 @@ function comment_reply($pid, $nid) {
*/
if ($pid) {
$comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $pid));
$comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.picture, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $pid));
$comment = drupal_unpack($comment);
$output .= theme("comment_view", $comment);
}
@ -258,7 +257,7 @@ function comment_preview($edit) {
$output .= theme("comment_form", $edit, t("Reply"));
if ($edit["pid"]) {
$comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $edit["pid"]));
$comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.picture, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $edit["pid"]));
$comment = drupal_unpack($comment);
$output .= theme("comment_view", $comment);
}
@ -559,7 +558,7 @@ function comment_render($node, $cid = 0) {
$output .= "<form method=\"post\" action=\"". url("comment") ."\"><div>\n";
$output .= form_hidden("nid", $nid);
$result = db_query("SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0 GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users", $cid);
$result = db_query("SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.picture, u.data, c.score, c.users FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0 GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.picture, u.data, c.score, c.users", $cid);
if ($comment = db_fetch_object($result)) {
$output .= theme("comment_view", $comment, theme('links', module_invoke_all('link', 'comment', $comment, 1)));
@ -576,9 +575,9 @@ function comment_render($node, $cid = 0) {
** Multiple comments view
*/
$query .= "SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users, c.thread FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = '". check_query($nid) ."' AND c.status = 0";
$query .= "SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.picture, u.data, c.score, c.users, c.thread FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = '". check_query($nid) ."' AND c.status = 0";
$query .= " GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users, c.thread";
$query .= " GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.picture, u.data, c.score, c.users, c.thread";
/*
** We want to use the standard pager, but threads would need every

View File

@ -185,22 +185,4 @@ function drupal_login($arguments) {
}
}
function drupal_user($type, $edit, $user) {
$module = "drupal";
$name = module_invoke($module, "info", "name");
switch ($type) {
case "view_private":
$result = user_get_authname($user, $module);
$title = t("%name ID", array("%name" => $name));
if ($result) {
return form_item($title, $result);
}
else {
// TODO: use a variation of $base_url instead of $HTTP_HOST below
return form_item($title, "$user->name@". $_SERVER["HTTP_HOST"]);
}
}
}
?>

View File

@ -185,22 +185,4 @@ function drupal_login($arguments) {
}
}
function drupal_user($type, $edit, $user) {
$module = "drupal";
$name = module_invoke($module, "info", "name");
switch ($type) {
case "view_private":
$result = user_get_authname($user, $module);
$title = t("%name ID", array("%name" => $name));
if ($result) {
return form_item($title, $result);
}
else {
// TODO: use a variation of $base_url instead of $HTTP_HOST below
return form_item($title, "$user->name@". $_SERVER["HTTP_HOST"]);
}
}
}
?>

View File

@ -74,7 +74,7 @@ function locale_link($type) {
function locale_user($type, &$edit, &$user) {
global $languages;
if ($type == "edit_form" && count($languages) > 1) {
if ($type == 'edit' && count($languages) > 1) {
return array(t('Locale settings') => form_radios(t("Language"), 'language', $user->language, $languages, t("Selecting a different language will change the language of the site.")));
}
}

View File

@ -74,7 +74,7 @@ function locale_link($type) {
function locale_user($type, &$edit, &$user) {
global $languages;
if ($type == "edit_form" && count($languages) > 1) {
if ($type == 'edit' && count($languages) > 1) {
return array(t('Locale settings') => form_radios(t("Language"), 'language', $user->language, $languages, t("Selecting a different language will change the language of the site.")));
}
}

View File

@ -340,7 +340,7 @@ function node_load($conditions, $revision = -1) {
** Retrieve the node:
*/
$node = db_fetch_object(db_query('SELECT n.*, u.uid, u.name, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE '. implode(' AND ', $cond)));
$node = db_fetch_object(db_query('SELECT n.*, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE '. implode(' AND ', $cond)));
$node = drupal_unpack($node);
/*

View File

@ -340,7 +340,7 @@ function node_load($conditions, $revision = -1) {
** Retrieve the node:
*/
$node = db_fetch_object(db_query('SELECT n.*, u.uid, u.name, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE '. implode(' AND ', $cond)));
$node = db_fetch_object(db_query('SELECT n.*, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE '. implode(' AND ', $cond)));
$node = drupal_unpack($node);
/*

View File

@ -1,306 +1,300 @@
<?php
// $Id$
function _profile_init() {
/*
** Add here any field you might need. Leave array[0] blank if you
** need a special tool (like birthday or avatar).
** TODO: add a clear description/explanation.
*/
$GLOBALS["profile_fields"] = array(
"realname" => array("textfield", t("Name"), "", 64, 64, ""),
"address" => array("textfield", t("Address"), "", 64, 64, ""),
"city" => array("textfield", t("City"), "", 64, 64, ""),
"state" => array("textfield", t("State, province or region"), "", 64, 64, ""),
"zip" => array("textfield", t("Zip or postal code"), "", 7, 10, ""),
"country" => array("textfield", t("Country"), "", 64, 64, ""),
"birthday" => array("", t("Birthday"), ""),
"gender" => array("select", t("Gender"), "", array(0 => "-", "m" => t("male"), "f" => t("female")), "", 0, 0),
"job" => array("textfield", t("Job title"), "", 64, 64, ""),
"icq" => array("textfield", t("ICQ messenger ID"), "", 12, 12, ""),
"msn" => array("textfield", t("MSN messenger ID"), "", 64, 64, ""),
"yahoo" => array("textfield", t("Yahoo messenger ID"), "", 64, 64, ""),
"aim" => array("textfield", t("AIM messenger ID"), "", 64, 64, ""),
"homepage" => array("textfield", t("URL of homepage"), "", 64, 64, t("Make sure you enter a fully qualified URL: remember to include \"http://\".")),
"biography" => array("textarea", t("Biography"), "", 64, 4, ""),
"interests" => array("textarea", t("Interests"), "", 64, 4, ""),
"publickey" => array("textarea", t("Public key"), "", 64, 4, ""),
"avatar" => array("", t("Avatar or picture"), t("Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.", array("%dimensions" => variable_get("profile_avatar_dimensions", "85x85"), "%size" => variable_get("profile_avatar_file_size", "30"))))
);
$GLOBALS["profile_days"] = array_merge(array(0 => t("day")), drupal_map_assoc(range(1, 31)));
$GLOBALS["profile_months"] = array(0 => t("month"), 1 => t("January"), 2 => t("February"), 3 => t("March"), 4 => t("April"), 5 => t("May"), 6 => t("June"), 7 => t("July"), 8 => t("August"), 9 => t("September"), 10 => t("October"), 11 => t("November"), 12 => t("December"));
}
// TODO: add a 'date' field so we can migrate the birthday information.
function profile_help($section) {
$output = "";
switch ($section) {
case 'admin/system/modules#description':
$output = t("Support for configurable user profiles.");
break;
case 'admin/system/modules/profile':
$output = t("When a user creates an account you can ask for some extra information, as well as letting the user have a small picture, called an avatar. <ul><li>In order for a user to enter information, you <strong>must</strong> check <em>enable</em>.</li><li>In order for other people to see the entered information, you must make it <em>public</em>.</li><li>If an item is <em>public</em>, but not enabled, the user can never give it a value and it will never be seen. <em>Public</em> does <strong>not</strong> imply <em>enable</em>.</li></ul>", array("%edit" => url("user/edit")));
break;
}
return $output;
}
function profile_link($type) {
if ($type == 'system') {
menu('profile', t('browse'), 'profile_browse', 0, MENU_HIDE);
if (user_access('administer users')) {
menu('admin/system/modules/profile', t('profile'), 'profile_admin_overview');
menu('admin/system/modules/profile/add', NULL, 'profile_admin_add', 0, MENU_HIDE);
menu('admin/system/modules/profile/edit', NULL, 'profile_admin_edit', 0, MENU_HIDE);
menu('admin/system/modules/profile/delete', NULL, 'profile_admin_delete', 0, MENU_HIDE);
}
}
}
function profile_browse() {
$value = arg(2) ? arg(2) : 1;
// Determine the field to group users by:
$field = db_fetch_object(db_query("SELECT DISTINCT(f.fid), f.type, f.title FROM {profile_fields} f INNER JOIN {profile_values} v ON f.fid = v.fid WHERE f.name = '%s' AND v.value = '%s' ORDER BY f.category, f.weight", arg(1), $value));
if ($field->fid) {
// Compile a list of fields to show:
$fields = array();
$result = db_query("SELECT name, title, type FROM {profile_fields} WHERE fid != %d AND overview = 1", $field->fid);
while ($record = db_fetch_object($result)) {
$fields[] = $record;
}
// Extract the affected users:
$result = pager_query("SELECT u.uid FROM {users} u INNER JOIN {profile_values} v ON u.uid = v.uid WHERE v.fid = $field->fid AND v.value = '". check_query($value) ."' ORDER BY u.changed DESC", 20);
$output = '';
while ($account = db_fetch_object($result)) {
$output .= theme('profile_profile', user_load(array('uid' => $account->uid)), $fields);
}
$output .= theme('pager', NULL, 20);
if ($field->type == "selection") {
$title = arg(2);
}
else {
$title = $field->title;
}
print theme('page', $output, $title);
}
else {
drupal_not_found();
}
}
function profile_load_profile(&$user) {
$result = db_query('SELECT f.name, v.value FROM {profile_fields} f INNER JOIN {profile_values} v ON f.fid = v.fid WHERE uid = %d', $user->uid);
while ($field = db_fetch_object($result)) {
if (empty($user->{$field->name})) {
$user->{$field->name} = $field->value;
}
}
}
function profile_save_profile($edit, $user) {
db_query('DELETE FROM {profile_values} WHERE uid = %d', $user->uid);
$result = db_query('SELECT fid, name FROM profile_fields');
while ($field = db_fetch_object($result)) {
if ($edit[$field->name]) {
db_query("INSERT INTO {profile_values} (fid, uid, value) VALUES (%d, %d, '%s')", $field->fid, $user->uid, $edit[$field->name]);
unset($edit[$field->name]);
}
}
}
function profile_view_profile($user) {
profile_load_profile(&$user);
$result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
while ($field = db_fetch_object($result)) {
if ($value = $user->{$field->name}) {
switch ($field->type) {
case 'textfield':
case 'textarea':
$output .= form_item($field->title, check_output($value));
break;
case 'selection':
$output .= form_item($field->title, l($value, "profile/$field->name/$value"));
break;
case 'checkbox':
$output .= '<p>'. l($field->title, "profile/$field->name/") .'</p>';
}
}
}
return $output;
}
function profile_settings() {
global $profile_fields;
function profile_edit_profile($edit, $user) {
if (!$profile_fields) {
_profile_init();
$result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
while ($field = db_fetch_object($result)) {
switch ($field->type) {
case 'textfield':
$fields[$field->category] .= form_textfield($field->title, $field->name, $edit[$field->name], 70, 255, $field->explanation);
break;
case 'textarea':
$fields[$field->category] .= form_textarea($field->title, $field->name, $edit[$field->name], 60, 4, $field->explanation);
break;
case 'checkbox':
$fields[$field->category] .= form_checkbox($field->title, $field->name, 1, $edit[$field->name], $field->explanation);
break;
case 'selection':
$options = array('--');
$lines = split("[\n\r]", $field->options);
foreach ($lines as $line) {
if ($line = trim($line)) {
$options[$line] = $line;
}
}
if (!file_check_directory(file_create_path(variable_get('profile_avatar_path', 'avatars')))) {
$error['profile_avatar_path'] = theme('error', t('Directory does not exist, or is not writable.'));
$fields[$field->category] .= form_select($field->title, $field->name, $edit[$field->name], $options, $field->explanation);
break;
}
}
$profile_public_fields = variable_get("profile_public_fields", array());
$profile_private_fields = variable_get("profile_private_fields", array());
$profile_required_fields = variable_get("profile_required_fields", array());
$header = array(t("field"), t("enable"), t("public"), t("required"));
$i = 0;
foreach ($profile_fields as $key => $field) {
$row[$i][] = $field[1];
$row[$i][] = form_checkbox("", "profile_private_fields][", $key, in_array($key, $profile_private_fields));
$row[$i][] = form_checkbox("", "profile_public_fields][", $key, in_array($key, $profile_public_fields));
$row[$i][] = form_checkbox("", "profile_required_fields][", $key, in_array($key, $profile_required_fields));
$i++;
}
$avatar = form_textfield(t("Avatar image path"), "profile_avatar_path", variable_get("profile_avatar_path", "avatars"), 30, 255, t("Subdirectory in the directory '%dir' where avatars will be stored.", array('%dir' => variable_get('file_directory_path', 'files') . FILE_SEPARATOR)) . $error['profile_avatar_path']);
$avatar .= form_textfield(t("Avatar maximum dimensions"), "profile_avatar_dimensions", variable_get("profile_avatar_dimensions", "85x85"), 10, 10, t("Maximum dimensions for avatars."));
$avatar .= form_textfield(t("Avatar maximum file size"), "profile_avatar_file_size", variable_get("profile_avatar_file_size", "30"), 10, 10, t("Maximum file size for avatars, in kB."));
$output = theme("table", $header, $row);
$output .= form_group(t('Avatars'), $avatar);
return $output;
return $fields;
}
function profile_user($type, $edit, &$user) {
global $profile_fields;
if (!$profile_fields) {
_profile_init();
}
switch ($type) {
case "edit_form":
// when user tries to edit his own data
return _profile_form(object2array($user), "private");
case "edit_validate":
// validate user data editing
return _profile_validate($edit, "private", $user);
case "view_public":
// when others look at user data
return _profile_user_view($user, "public");
case "view_private":
// when user looks at his own data
return _profile_user_view($user, "private");
case 'load':
return profile_load_profile($user);
case 'update':
return profile_save_profile($edit, $user);
case 'view':
return profile_view_profile($user);
case 'edit':
return profile_edit_profile($edit, $user);
case 'validate':
return $edit;
}
}
function profile_required($title) {
// this pleads "theme, theme" ;)
return $title ." ". theme("mark");
function profile_validate_form($edit) {
// Validate the title:
if (!$edit['title']) {
return t('You must enter a title.');
}
// Validate the 'form name':
if (eregi('[^a-z0-9_-]', $edit['name'])) {
return t('The specified form name contains one or more illegal characters. Spaces or any other special characters expect dash (-) and underscore (_) are not allowed.');
}
if (in_array($edit['name'], user_fields())) {
return t('The specified form name is reserved for use by Drupal.');
}
// Validate the category:
if (!$edit['category']) {
return t('You must enter a category.');
}
}
function _profile_form($edit, $mode) {
global $profile_fields, $user;
function profile_admin_add($type) {
$type = _profile_field_types($type);
$reg_fields = _profile_active_fields($mode);
$required_fields = _profile_active_fields("required");
foreach ($profile_fields as $name => $field) {
if ($field[0] && in_array($name, $reg_fields)) {
$f = "form_". $field[0];
$t = "profile_". $name;
$output .= $f((in_array($name, $required_fields) ? profile_required($field[1]) : $field[1]), $t, $edit[$t], $field[3], $field[4], $field[5], $field[6]);
if ($_POST['op']) {
$data = $_POST['edit'];
if ($error = profile_validate_form($data)) {
drupal_set_message($error, 'error');
}
else {
db_query("INSERT INTO {profile_fields} (title, name, explanation, category, type, weight, overview, options) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, '%s')", $data['title'], $data['name'], $data['explanation'], $data['category'], $type, $data['weight'], $data['overview'], $data['options']);
drupal_set_message(t('the field has been created.'));
}
}
if (in_array("birthday", $reg_fields)) {
$output .= form_item((in_array("birthday", $required_fields) ? profile_required($profile_fields["birthday"][1]) : $profile_fields["birthday"][1]), _profile_edit_birth(array2object($edit)), $profile_fields["birthday"][2]);
else {
$data = array('name' => 'profile_');
}
if (in_array("avatar", $reg_fields)) {
if ($edit["profile_avatar"] && file_exists($edit["profile_avatar"])) {
$output .= form_item(t("Avatar"), '<img src="'. file_create_url($edit["profile_avatar"]) .'" alt="" title="" />');
}
$output .= form_file($profile_fields["avatar"][1], "profile_avatar", 64, $profile_fields["avatar"][2]);
}
return array(t('Personal information') => $output);
print theme('page', _profile_field_form($type, $data), t('Add new %type', array('%type' => $type)));
}
function _profile_validate($edit, $mode, $user) {
function profile_admin_edit($fid) {
global $profile_fields;
if ($_POST['op']) {
$data = $_POST['edit'];
$enabled_fields = _profile_active_fields($mode);
if ($error = profile_validate_form($data)) {
drupal_set_message($error, 'error');
if (in_array("birthday", $enabled_fields) && ($birth_error = _profile_validate_birth($edit))) {
$error .= $birth_error ."<br />";
}
else {
db_query("UPDATE {profile_fields} SET title = '%s', name = '%s', explanation = '%s', category = '%s', weight = %d, overview = %d, options = '%s' WHERE fid = %d", $data['title'], $data['name'], $data['explanation'], $data['category'], $data['weight'], $data['overview'], $data['options'], $fid);
if (in_array("avatar", $enabled_fields) && ($avatar_error = _profile_validate_avatar($edit, $user))) {
$error .= $avatar_error ."<br />";
}
foreach (array_keys($profile_fields) as $field) {
// replicate any key which was saved during registration but is not in this form
if (!$edit[$field] && $user->$field) {
$edit[$field] = $user->$field;
}
}
// now check for required fields
foreach (_profile_active_fields("required") as $required) {
if ($required != "0" && in_array($required, $enabled_fields)) {
if (!$edit["profile_". $required]) {
$error .= t("This required field is missing: %a", array("%a" => $profile_fields[$required][1])) ."<br />";
drupal_set_message(t('the field has been updated.'));
}
}
else {
$data = db_fetch_array(db_query('SELECT * FROM {profile_fields} WHERE fid = %d', $fid));
}
return $error ? $error : $edit;
print theme('page', _profile_field_form($data['type'], $data), t('Edit %type', array('%type' => $edit['type'])));
}
function _profile_user_view(&$user, $mode) {
global $profile_fields;
function profile_admin_delete($fid) {
db_query('DELETE FROM {profile_fields} WHERE fid = %d', $fid);
drupal_set_message(t('the field has been deleted.'));
print theme('page', '', t('Delete field'));
}
foreach (_profile_active_fields($mode) as $name) {
$field = $profile_fields[$name];
$t = "profile_". $name;
function _profile_field_form($type, $edit = array()) {
if (!empty($user->$t)) {
switch ($field[0]) {
case "textfield":
case "textarea":
case "checkbox":
$value = ($t == "profile_homepage") ? "<a href=\"". drupal_specialchars($user->$t) ."\">". check_output($user->$t) ."</a>" : check_output($user->$t);
$output .= form_item($field[1], $value);
break;
case "select":
$output .= form_item($field[1], check_output($profile_fields[$name][3][$user->$t]));
break;
case "":
// special
if ($t == "profile_avatar") {
if (file_exists($user->$t)) {
$output .= form_item(t("Avatar"), '<img src="'. file_create_url($user->$t) .'" alt="" title="" />');
$output = form_textfield(t('Title'), 'title', $edit['title'], 70, 128, t("The title of the new field. The title will be shown to the user. An example title is 'Favorite color'."), NULL, FORM_REQUIRED);
$output .= form_textfield(t('Form name'), 'name', $edit['name'], 70, 128, t("The name of the field. The form name is not shown to the user but used internally in the HTML code and URLs.
Unless you know what you are doing, it is highly recommended that you prefix the form name with <code>profile_</code> to avoid name clashes with other fields. Because the form name's usage, spaces or any other special characters except dash (-) and underscore (_) are not allowed. An example for, name is 'profile_favorite_color' or just 'profile_color'."));
$output .= form_textarea(t('Explanation'), 'explanation', $edit['explanation'], 70, 3, t("An optional explanation to go with the new field. The explanation will be shown to the user."));
$output .= form_textfield(t('Category'), 'category', $edit['category'], 70, 128, t("The category the new field should be part of. Categories are used to group fields logically. An example category is 'Personal information'."));
$output .= form_weight(t('Weight'), 'weight', $edit['weight'], 5, t("The weights define the order in which the form fields are shown. Lighter fields \"float up\" towards the top of the category."));
$output .= form_checkbox(t('Display this field on member listsings'), 'overview', 1, $edit['overview']);
if ($type == 'selection') {
$output .= form_textarea(t('Selection options'), 'options', $edit['options'], 70, 8, t("A list op all options. Put each option on a separate line. Example options are 'red', 'blue', 'green', etc."));
}
$output .= form_submit(t('Save field'));
return form($output);
}
function profile_admin_overview() {
$result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
while ($field = db_fetch_object($result)) {
$rows[] = array($field->title, $field->name, $field->type, $field->category, l(t('edit'), "admin/system/modules/profile/edit/$field->fid"), l(t('delete'), "admin/system/modules/profile/delete/$field->fid"));
}
$header = array(t('title'), t('name'), t('type'), t('category'), array('data' => t('operations'), 'colspan' => '2'));
$output = theme('table', $header, $rows);
$output .= '<h2>'. t('Create new field') .'</h2>';
$output .= '<ul>';
foreach (_profile_field_types() as $key => $value) {
$output .= "<li>". l(t('Add new %type', array('%type' => $value)), "admin/system/modules/profile/add/$key") ."</li>";
}
$output .= '</ul>';
print theme('page', $output);
}
function theme_profile_profile($user, $fields = array()) {
$output = "<div class=\"profile\">\n";
$output .= theme('user_picture', $user);
$output .= " <div class=\"name\">". format_name($user) ."</div>\n";
foreach ($fields as $field) {
if ($user->{$field->name}) {
if ($field->type == 'checkbox') {
$output .= "<div class=\"field\">". $field->title ."</div>";
}
else {
$output .= "<div class=\"field\">". $user->{$field->name} ."</div>";
}
}
}
if ($t == "profile_birthday") {
if (isset($user->profile_birthday) && isset($user->profile_birthmonth) && isset($user->profile_birthyear)) {
// this is very european-centric, can we use format_date?
$time = mktime(0, 0, 0, $user->profile_birthmonth, $user->profile_birthday, $user->profile_birthyear);
$output .= form_item(t("Birthday"), format_date($time, "custom", "F j, Y"));
}
}
}
}
}
$output .= "</div>\n";
return $output;
}
function profile_file_download($file) {
if (strpos($file, variable_get("profile_avatar_path", "avatars") . FILE_SEPARATOR . 'avatar-') === 0) {
list($width, $height, $type, $attr) = getimagesize(file_create_path($file));
$types = array(
IMAGETYPE_GIF => 'image/gif',
IMAGETYPE_JPEG => 'image/jpeg',
IMAGETYPE_PNG => 'image/png',
IMAGETYPE_SWF => 'application/x-shockwave-flash',
IMAGETYPE_PSD => 'image/psd',
IMAGETYPE_BMP => 'image/bmp',
IMAGETYPE_TIFF_II => 'image/tiff',
IMAGETYPE_TIFF_MM => 'image/tiff',
IMAGETYPE_JPC => 'application/octet-stream',
IMAGETYPE_JP2 => 'image/jp2',
IMAGETYPE_JPX => 'application/octet-stream',
IMAGETYPE_JB2 => 'application/octet-stream',
IMAGETYPE_SWC => 'application/x-shockwave-flash',
IMAGETYPE_IFF => 'image/iff',
IMAGETYPE_WBMP => 'image/vnd.wap.wbmp',
IMAGETYPE_XBM => 'image/xbm'
);
return array('Content-type: '. $types[$type]);
}
}
function _profile_validate_avatar(&$edit, $user) {
// check that uploaded file is an image, with a maximum file size and maximum height/width
unset($edit["profile_avatar"]);
if (!$file = file_check_upload('profile_avatar')) {
$edit["profile_avatar"] = $user->profile_avatar;
return;
}
$extension = strtolower(strrchr($file->name, "."));
$size = getimagesize($file->path);
list($maxwidth, $maxheight) = explode("x", variable_get("profile_avatar_dimensions", "85x85"));
if ((!in_array($size[2], array(1, 2, 3))) || (!in_array($extension, array(".gif", ".jpg", ".png", ".jpeg")))) {
$error = t("The uploaded file was not an image.");
}
else if ($file->size > (variable_get("profile_avatar_file_size", "30") * 1000)) {
$error = t("The uploaded image is too large; the maximum file size is %a kB.", array("%a" => variable_get("profile_avatar_file_size", "30")));
}
else if ($size[0] > $maxwidth || $size[1] > $maxheight) {
$error = t("The uploaded image is too large; the maximum dimensions are %a pixels.", array("%a" => variable_get("profile_avatar_dimensions", "85x85")));
}
else if ($file = file_save_upload('profile_avatar', variable_get("profile_avatar_path", "avatars") . FILE_SEPARATOR .'avatar-'. $user->uid . $extension, 1)) {
$edit["profile_avatar"] = $file->path;
}
else {
$error = t("Failed to upload the avatar image; the '%directory' directory doesn't exist.", array("%directory" => variable_get("profile_avatar_path", "avatars")));
}
return $error ? "$error<br />" : "";
}
function _profile_active_fields($mode) {
return variable_get("profile_". $mode ."_fields", array());
}
function _profile_edit_birth($edit = "") {
global $profile_months, $profile_days;
$output = _profile_select("profile_birthday", $edit->profile_birthday, $profile_days);
$output .= "&nbsp;";
$output .= _profile_select("profile_birthmonth", $edit->profile_birthmonth, $profile_months);
$output .= "&nbsp;";
$output .= "<input type=\"text\" maxlength=\"4\" name=\"edit[profile_birthyear]\" size=\"5\" value=\"$edit->profile_birthyear\" />";
return $output;
}
function _profile_validate_birth(&$edit) {
if (!$edit["profile_birthday"] && !$edit["profile_birthmonth"] && !$edit["profile_birthyear"]) {
// change this if you want required birth
return;
}
if ($edit["profile_birthyear"] > 1900 && checkdate($edit["profile_birthmonth"], $edit["profile_birthday"], $edit["profile_birthyear"])) {
return;
}
else {
return t("The specified birthday is not valid.") ."<br />";
}
}
function _profile_select($name, $value, $options, $extra = 0, $multiple = 0) {
if (count($options) > 0) {
foreach ($options as $key=>$choice) {
$select .= "<option value=\"$key\"". (is_array($value) ? (in_array($key, $value) ? " selected=\"selected\"" : "") : ($key == $value ? " selected=\"selected\"" : "")) .">". check_form($choice) ."</option>";
}
return "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>";
}
function _profile_field_types($type = NULL) {
$types = array('textfield', 'textarea', 'checkbox', 'selection');
return isset($type) ? $types[$type] : $types;
}
?>

View File

@ -1,306 +1,300 @@
<?php
// $Id$
function _profile_init() {
/*
** Add here any field you might need. Leave array[0] blank if you
** need a special tool (like birthday or avatar).
** TODO: add a clear description/explanation.
*/
$GLOBALS["profile_fields"] = array(
"realname" => array("textfield", t("Name"), "", 64, 64, ""),
"address" => array("textfield", t("Address"), "", 64, 64, ""),
"city" => array("textfield", t("City"), "", 64, 64, ""),
"state" => array("textfield", t("State, province or region"), "", 64, 64, ""),
"zip" => array("textfield", t("Zip or postal code"), "", 7, 10, ""),
"country" => array("textfield", t("Country"), "", 64, 64, ""),
"birthday" => array("", t("Birthday"), ""),
"gender" => array("select", t("Gender"), "", array(0 => "-", "m" => t("male"), "f" => t("female")), "", 0, 0),
"job" => array("textfield", t("Job title"), "", 64, 64, ""),
"icq" => array("textfield", t("ICQ messenger ID"), "", 12, 12, ""),
"msn" => array("textfield", t("MSN messenger ID"), "", 64, 64, ""),
"yahoo" => array("textfield", t("Yahoo messenger ID"), "", 64, 64, ""),
"aim" => array("textfield", t("AIM messenger ID"), "", 64, 64, ""),
"homepage" => array("textfield", t("URL of homepage"), "", 64, 64, t("Make sure you enter a fully qualified URL: remember to include \"http://\".")),
"biography" => array("textarea", t("Biography"), "", 64, 4, ""),
"interests" => array("textarea", t("Interests"), "", 64, 4, ""),
"publickey" => array("textarea", t("Public key"), "", 64, 4, ""),
"avatar" => array("", t("Avatar or picture"), t("Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.", array("%dimensions" => variable_get("profile_avatar_dimensions", "85x85"), "%size" => variable_get("profile_avatar_file_size", "30"))))
);
$GLOBALS["profile_days"] = array_merge(array(0 => t("day")), drupal_map_assoc(range(1, 31)));
$GLOBALS["profile_months"] = array(0 => t("month"), 1 => t("January"), 2 => t("February"), 3 => t("March"), 4 => t("April"), 5 => t("May"), 6 => t("June"), 7 => t("July"), 8 => t("August"), 9 => t("September"), 10 => t("October"), 11 => t("November"), 12 => t("December"));
}
// TODO: add a 'date' field so we can migrate the birthday information.
function profile_help($section) {
$output = "";
switch ($section) {
case 'admin/system/modules#description':
$output = t("Support for configurable user profiles.");
break;
case 'admin/system/modules/profile':
$output = t("When a user creates an account you can ask for some extra information, as well as letting the user have a small picture, called an avatar. <ul><li>In order for a user to enter information, you <strong>must</strong> check <em>enable</em>.</li><li>In order for other people to see the entered information, you must make it <em>public</em>.</li><li>If an item is <em>public</em>, but not enabled, the user can never give it a value and it will never be seen. <em>Public</em> does <strong>not</strong> imply <em>enable</em>.</li></ul>", array("%edit" => url("user/edit")));
break;
}
return $output;
}
function profile_link($type) {
if ($type == 'system') {
menu('profile', t('browse'), 'profile_browse', 0, MENU_HIDE);
if (user_access('administer users')) {
menu('admin/system/modules/profile', t('profile'), 'profile_admin_overview');
menu('admin/system/modules/profile/add', NULL, 'profile_admin_add', 0, MENU_HIDE);
menu('admin/system/modules/profile/edit', NULL, 'profile_admin_edit', 0, MENU_HIDE);
menu('admin/system/modules/profile/delete', NULL, 'profile_admin_delete', 0, MENU_HIDE);
}
}
}
function profile_browse() {
$value = arg(2) ? arg(2) : 1;
// Determine the field to group users by:
$field = db_fetch_object(db_query("SELECT DISTINCT(f.fid), f.type, f.title FROM {profile_fields} f INNER JOIN {profile_values} v ON f.fid = v.fid WHERE f.name = '%s' AND v.value = '%s' ORDER BY f.category, f.weight", arg(1), $value));
if ($field->fid) {
// Compile a list of fields to show:
$fields = array();
$result = db_query("SELECT name, title, type FROM {profile_fields} WHERE fid != %d AND overview = 1", $field->fid);
while ($record = db_fetch_object($result)) {
$fields[] = $record;
}
// Extract the affected users:
$result = pager_query("SELECT u.uid FROM {users} u INNER JOIN {profile_values} v ON u.uid = v.uid WHERE v.fid = $field->fid AND v.value = '". check_query($value) ."' ORDER BY u.changed DESC", 20);
$output = '';
while ($account = db_fetch_object($result)) {
$output .= theme('profile_profile', user_load(array('uid' => $account->uid)), $fields);
}
$output .= theme('pager', NULL, 20);
if ($field->type == "selection") {
$title = arg(2);
}
else {
$title = $field->title;
}
print theme('page', $output, $title);
}
else {
drupal_not_found();
}
}
function profile_load_profile(&$user) {
$result = db_query('SELECT f.name, v.value FROM {profile_fields} f INNER JOIN {profile_values} v ON f.fid = v.fid WHERE uid = %d', $user->uid);
while ($field = db_fetch_object($result)) {
if (empty($user->{$field->name})) {
$user->{$field->name} = $field->value;
}
}
}
function profile_save_profile($edit, $user) {
db_query('DELETE FROM {profile_values} WHERE uid = %d', $user->uid);
$result = db_query('SELECT fid, name FROM profile_fields');
while ($field = db_fetch_object($result)) {
if ($edit[$field->name]) {
db_query("INSERT INTO {profile_values} (fid, uid, value) VALUES (%d, %d, '%s')", $field->fid, $user->uid, $edit[$field->name]);
unset($edit[$field->name]);
}
}
}
function profile_view_profile($user) {
profile_load_profile(&$user);
$result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
while ($field = db_fetch_object($result)) {
if ($value = $user->{$field->name}) {
switch ($field->type) {
case 'textfield':
case 'textarea':
$output .= form_item($field->title, check_output($value));
break;
case 'selection':
$output .= form_item($field->title, l($value, "profile/$field->name/$value"));
break;
case 'checkbox':
$output .= '<p>'. l($field->title, "profile/$field->name/") .'</p>';
}
}
}
return $output;
}
function profile_settings() {
global $profile_fields;
function profile_edit_profile($edit, $user) {
if (!$profile_fields) {
_profile_init();
$result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
while ($field = db_fetch_object($result)) {
switch ($field->type) {
case 'textfield':
$fields[$field->category] .= form_textfield($field->title, $field->name, $edit[$field->name], 70, 255, $field->explanation);
break;
case 'textarea':
$fields[$field->category] .= form_textarea($field->title, $field->name, $edit[$field->name], 60, 4, $field->explanation);
break;
case 'checkbox':
$fields[$field->category] .= form_checkbox($field->title, $field->name, 1, $edit[$field->name], $field->explanation);
break;
case 'selection':
$options = array('--');
$lines = split("[\n\r]", $field->options);
foreach ($lines as $line) {
if ($line = trim($line)) {
$options[$line] = $line;
}
}
if (!file_check_directory(file_create_path(variable_get('profile_avatar_path', 'avatars')))) {
$error['profile_avatar_path'] = theme('error', t('Directory does not exist, or is not writable.'));
$fields[$field->category] .= form_select($field->title, $field->name, $edit[$field->name], $options, $field->explanation);
break;
}
}
$profile_public_fields = variable_get("profile_public_fields", array());
$profile_private_fields = variable_get("profile_private_fields", array());
$profile_required_fields = variable_get("profile_required_fields", array());
$header = array(t("field"), t("enable"), t("public"), t("required"));
$i = 0;
foreach ($profile_fields as $key => $field) {
$row[$i][] = $field[1];
$row[$i][] = form_checkbox("", "profile_private_fields][", $key, in_array($key, $profile_private_fields));
$row[$i][] = form_checkbox("", "profile_public_fields][", $key, in_array($key, $profile_public_fields));
$row[$i][] = form_checkbox("", "profile_required_fields][", $key, in_array($key, $profile_required_fields));
$i++;
}
$avatar = form_textfield(t("Avatar image path"), "profile_avatar_path", variable_get("profile_avatar_path", "avatars"), 30, 255, t("Subdirectory in the directory '%dir' where avatars will be stored.", array('%dir' => variable_get('file_directory_path', 'files') . FILE_SEPARATOR)) . $error['profile_avatar_path']);
$avatar .= form_textfield(t("Avatar maximum dimensions"), "profile_avatar_dimensions", variable_get("profile_avatar_dimensions", "85x85"), 10, 10, t("Maximum dimensions for avatars."));
$avatar .= form_textfield(t("Avatar maximum file size"), "profile_avatar_file_size", variable_get("profile_avatar_file_size", "30"), 10, 10, t("Maximum file size for avatars, in kB."));
$output = theme("table", $header, $row);
$output .= form_group(t('Avatars'), $avatar);
return $output;
return $fields;
}
function profile_user($type, $edit, &$user) {
global $profile_fields;
if (!$profile_fields) {
_profile_init();
}
switch ($type) {
case "edit_form":
// when user tries to edit his own data
return _profile_form(object2array($user), "private");
case "edit_validate":
// validate user data editing
return _profile_validate($edit, "private", $user);
case "view_public":
// when others look at user data
return _profile_user_view($user, "public");
case "view_private":
// when user looks at his own data
return _profile_user_view($user, "private");
case 'load':
return profile_load_profile($user);
case 'update':
return profile_save_profile($edit, $user);
case 'view':
return profile_view_profile($user);
case 'edit':
return profile_edit_profile($edit, $user);
case 'validate':
return $edit;
}
}
function profile_required($title) {
// this pleads "theme, theme" ;)
return $title ." ". theme("mark");
function profile_validate_form($edit) {
// Validate the title:
if (!$edit['title']) {
return t('You must enter a title.');
}
// Validate the 'form name':
if (eregi('[^a-z0-9_-]', $edit['name'])) {
return t('The specified form name contains one or more illegal characters. Spaces or any other special characters expect dash (-) and underscore (_) are not allowed.');
}
if (in_array($edit['name'], user_fields())) {
return t('The specified form name is reserved for use by Drupal.');
}
// Validate the category:
if (!$edit['category']) {
return t('You must enter a category.');
}
}
function _profile_form($edit, $mode) {
global $profile_fields, $user;
function profile_admin_add($type) {
$type = _profile_field_types($type);
$reg_fields = _profile_active_fields($mode);
$required_fields = _profile_active_fields("required");
foreach ($profile_fields as $name => $field) {
if ($field[0] && in_array($name, $reg_fields)) {
$f = "form_". $field[0];
$t = "profile_". $name;
$output .= $f((in_array($name, $required_fields) ? profile_required($field[1]) : $field[1]), $t, $edit[$t], $field[3], $field[4], $field[5], $field[6]);
if ($_POST['op']) {
$data = $_POST['edit'];
if ($error = profile_validate_form($data)) {
drupal_set_message($error, 'error');
}
else {
db_query("INSERT INTO {profile_fields} (title, name, explanation, category, type, weight, overview, options) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, '%s')", $data['title'], $data['name'], $data['explanation'], $data['category'], $type, $data['weight'], $data['overview'], $data['options']);
drupal_set_message(t('the field has been created.'));
}
}
if (in_array("birthday", $reg_fields)) {
$output .= form_item((in_array("birthday", $required_fields) ? profile_required($profile_fields["birthday"][1]) : $profile_fields["birthday"][1]), _profile_edit_birth(array2object($edit)), $profile_fields["birthday"][2]);
else {
$data = array('name' => 'profile_');
}
if (in_array("avatar", $reg_fields)) {
if ($edit["profile_avatar"] && file_exists($edit["profile_avatar"])) {
$output .= form_item(t("Avatar"), '<img src="'. file_create_url($edit["profile_avatar"]) .'" alt="" title="" />');
}
$output .= form_file($profile_fields["avatar"][1], "profile_avatar", 64, $profile_fields["avatar"][2]);
}
return array(t('Personal information') => $output);
print theme('page', _profile_field_form($type, $data), t('Add new %type', array('%type' => $type)));
}
function _profile_validate($edit, $mode, $user) {
function profile_admin_edit($fid) {
global $profile_fields;
if ($_POST['op']) {
$data = $_POST['edit'];
$enabled_fields = _profile_active_fields($mode);
if ($error = profile_validate_form($data)) {
drupal_set_message($error, 'error');
if (in_array("birthday", $enabled_fields) && ($birth_error = _profile_validate_birth($edit))) {
$error .= $birth_error ."<br />";
}
else {
db_query("UPDATE {profile_fields} SET title = '%s', name = '%s', explanation = '%s', category = '%s', weight = %d, overview = %d, options = '%s' WHERE fid = %d", $data['title'], $data['name'], $data['explanation'], $data['category'], $data['weight'], $data['overview'], $data['options'], $fid);
if (in_array("avatar", $enabled_fields) && ($avatar_error = _profile_validate_avatar($edit, $user))) {
$error .= $avatar_error ."<br />";
}
foreach (array_keys($profile_fields) as $field) {
// replicate any key which was saved during registration but is not in this form
if (!$edit[$field] && $user->$field) {
$edit[$field] = $user->$field;
}
}
// now check for required fields
foreach (_profile_active_fields("required") as $required) {
if ($required != "0" && in_array($required, $enabled_fields)) {
if (!$edit["profile_". $required]) {
$error .= t("This required field is missing: %a", array("%a" => $profile_fields[$required][1])) ."<br />";
drupal_set_message(t('the field has been updated.'));
}
}
else {
$data = db_fetch_array(db_query('SELECT * FROM {profile_fields} WHERE fid = %d', $fid));
}
return $error ? $error : $edit;
print theme('page', _profile_field_form($data['type'], $data), t('Edit %type', array('%type' => $edit['type'])));
}
function _profile_user_view(&$user, $mode) {
global $profile_fields;
function profile_admin_delete($fid) {
db_query('DELETE FROM {profile_fields} WHERE fid = %d', $fid);
drupal_set_message(t('the field has been deleted.'));
print theme('page', '', t('Delete field'));
}
foreach (_profile_active_fields($mode) as $name) {
$field = $profile_fields[$name];
$t = "profile_". $name;
function _profile_field_form($type, $edit = array()) {
if (!empty($user->$t)) {
switch ($field[0]) {
case "textfield":
case "textarea":
case "checkbox":
$value = ($t == "profile_homepage") ? "<a href=\"". drupal_specialchars($user->$t) ."\">". check_output($user->$t) ."</a>" : check_output($user->$t);
$output .= form_item($field[1], $value);
break;
case "select":
$output .= form_item($field[1], check_output($profile_fields[$name][3][$user->$t]));
break;
case "":
// special
if ($t == "profile_avatar") {
if (file_exists($user->$t)) {
$output .= form_item(t("Avatar"), '<img src="'. file_create_url($user->$t) .'" alt="" title="" />');
$output = form_textfield(t('Title'), 'title', $edit['title'], 70, 128, t("The title of the new field. The title will be shown to the user. An example title is 'Favorite color'."), NULL, FORM_REQUIRED);
$output .= form_textfield(t('Form name'), 'name', $edit['name'], 70, 128, t("The name of the field. The form name is not shown to the user but used internally in the HTML code and URLs.
Unless you know what you are doing, it is highly recommended that you prefix the form name with <code>profile_</code> to avoid name clashes with other fields. Because the form name's usage, spaces or any other special characters except dash (-) and underscore (_) are not allowed. An example for, name is 'profile_favorite_color' or just 'profile_color'."));
$output .= form_textarea(t('Explanation'), 'explanation', $edit['explanation'], 70, 3, t("An optional explanation to go with the new field. The explanation will be shown to the user."));
$output .= form_textfield(t('Category'), 'category', $edit['category'], 70, 128, t("The category the new field should be part of. Categories are used to group fields logically. An example category is 'Personal information'."));
$output .= form_weight(t('Weight'), 'weight', $edit['weight'], 5, t("The weights define the order in which the form fields are shown. Lighter fields \"float up\" towards the top of the category."));
$output .= form_checkbox(t('Display this field on member listsings'), 'overview', 1, $edit['overview']);
if ($type == 'selection') {
$output .= form_textarea(t('Selection options'), 'options', $edit['options'], 70, 8, t("A list op all options. Put each option on a separate line. Example options are 'red', 'blue', 'green', etc."));
}
$output .= form_submit(t('Save field'));
return form($output);
}
function profile_admin_overview() {
$result = db_query('SELECT * FROM {profile_fields} ORDER BY category, weight');
while ($field = db_fetch_object($result)) {
$rows[] = array($field->title, $field->name, $field->type, $field->category, l(t('edit'), "admin/system/modules/profile/edit/$field->fid"), l(t('delete'), "admin/system/modules/profile/delete/$field->fid"));
}
$header = array(t('title'), t('name'), t('type'), t('category'), array('data' => t('operations'), 'colspan' => '2'));
$output = theme('table', $header, $rows);
$output .= '<h2>'. t('Create new field') .'</h2>';
$output .= '<ul>';
foreach (_profile_field_types() as $key => $value) {
$output .= "<li>". l(t('Add new %type', array('%type' => $value)), "admin/system/modules/profile/add/$key") ."</li>";
}
$output .= '</ul>';
print theme('page', $output);
}
function theme_profile_profile($user, $fields = array()) {
$output = "<div class=\"profile\">\n";
$output .= theme('user_picture', $user);
$output .= " <div class=\"name\">". format_name($user) ."</div>\n";
foreach ($fields as $field) {
if ($user->{$field->name}) {
if ($field->type == 'checkbox') {
$output .= "<div class=\"field\">". $field->title ."</div>";
}
else {
$output .= "<div class=\"field\">". $user->{$field->name} ."</div>";
}
}
}
if ($t == "profile_birthday") {
if (isset($user->profile_birthday) && isset($user->profile_birthmonth) && isset($user->profile_birthyear)) {
// this is very european-centric, can we use format_date?
$time = mktime(0, 0, 0, $user->profile_birthmonth, $user->profile_birthday, $user->profile_birthyear);
$output .= form_item(t("Birthday"), format_date($time, "custom", "F j, Y"));
}
}
}
}
}
$output .= "</div>\n";
return $output;
}
function profile_file_download($file) {
if (strpos($file, variable_get("profile_avatar_path", "avatars") . FILE_SEPARATOR . 'avatar-') === 0) {
list($width, $height, $type, $attr) = getimagesize(file_create_path($file));
$types = array(
IMAGETYPE_GIF => 'image/gif',
IMAGETYPE_JPEG => 'image/jpeg',
IMAGETYPE_PNG => 'image/png',
IMAGETYPE_SWF => 'application/x-shockwave-flash',
IMAGETYPE_PSD => 'image/psd',
IMAGETYPE_BMP => 'image/bmp',
IMAGETYPE_TIFF_II => 'image/tiff',
IMAGETYPE_TIFF_MM => 'image/tiff',
IMAGETYPE_JPC => 'application/octet-stream',
IMAGETYPE_JP2 => 'image/jp2',
IMAGETYPE_JPX => 'application/octet-stream',
IMAGETYPE_JB2 => 'application/octet-stream',
IMAGETYPE_SWC => 'application/x-shockwave-flash',
IMAGETYPE_IFF => 'image/iff',
IMAGETYPE_WBMP => 'image/vnd.wap.wbmp',
IMAGETYPE_XBM => 'image/xbm'
);
return array('Content-type: '. $types[$type]);
}
}
function _profile_validate_avatar(&$edit, $user) {
// check that uploaded file is an image, with a maximum file size and maximum height/width
unset($edit["profile_avatar"]);
if (!$file = file_check_upload('profile_avatar')) {
$edit["profile_avatar"] = $user->profile_avatar;
return;
}
$extension = strtolower(strrchr($file->name, "."));
$size = getimagesize($file->path);
list($maxwidth, $maxheight) = explode("x", variable_get("profile_avatar_dimensions", "85x85"));
if ((!in_array($size[2], array(1, 2, 3))) || (!in_array($extension, array(".gif", ".jpg", ".png", ".jpeg")))) {
$error = t("The uploaded file was not an image.");
}
else if ($file->size > (variable_get("profile_avatar_file_size", "30") * 1000)) {
$error = t("The uploaded image is too large; the maximum file size is %a kB.", array("%a" => variable_get("profile_avatar_file_size", "30")));
}
else if ($size[0] > $maxwidth || $size[1] > $maxheight) {
$error = t("The uploaded image is too large; the maximum dimensions are %a pixels.", array("%a" => variable_get("profile_avatar_dimensions", "85x85")));
}
else if ($file = file_save_upload('profile_avatar', variable_get("profile_avatar_path", "avatars") . FILE_SEPARATOR .'avatar-'. $user->uid . $extension, 1)) {
$edit["profile_avatar"] = $file->path;
}
else {
$error = t("Failed to upload the avatar image; the '%directory' directory doesn't exist.", array("%directory" => variable_get("profile_avatar_path", "avatars")));
}
return $error ? "$error<br />" : "";
}
function _profile_active_fields($mode) {
return variable_get("profile_". $mode ."_fields", array());
}
function _profile_edit_birth($edit = "") {
global $profile_months, $profile_days;
$output = _profile_select("profile_birthday", $edit->profile_birthday, $profile_days);
$output .= "&nbsp;";
$output .= _profile_select("profile_birthmonth", $edit->profile_birthmonth, $profile_months);
$output .= "&nbsp;";
$output .= "<input type=\"text\" maxlength=\"4\" name=\"edit[profile_birthyear]\" size=\"5\" value=\"$edit->profile_birthyear\" />";
return $output;
}
function _profile_validate_birth(&$edit) {
if (!$edit["profile_birthday"] && !$edit["profile_birthmonth"] && !$edit["profile_birthyear"]) {
// change this if you want required birth
return;
}
if ($edit["profile_birthyear"] > 1900 && checkdate($edit["profile_birthmonth"], $edit["profile_birthday"], $edit["profile_birthyear"])) {
return;
}
else {
return t("The specified birthday is not valid.") ."<br />";
}
}
function _profile_select($name, $value, $options, $extra = 0, $multiple = 0) {
if (count($options) > 0) {
foreach ($options as $key=>$choice) {
$select .= "<option value=\"$key\"". (is_array($value) ? (in_array($key, $value) ? " selected=\"selected\"" : "") : ($key == $value ? " selected=\"selected\"" : "")) .">". check_form($choice) ."</option>";
}
return "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>";
}
function _profile_field_types($type = NULL) {
$types = array('textfield', 'textarea', 'checkbox', 'selection');
return isset($type) ? $types[$type] : $types;
}
?>

View File

@ -77,7 +77,7 @@ function system_link($type) {
}
function system_user($type, $edit, &$user) {
if ($type == "edit_form") {
if ($type == 'edit') {
$options = "<option value=\"\">". t("Default theme") ."</option>\n";
if (count($themes = list_themes()) > 1) {
foreach ($themes as $key => $value) {

View File

@ -77,7 +77,7 @@ function system_link($type) {
}
function system_user($type, $edit, &$user) {
if ($type == "edit_form") {
if ($type == 'edit') {
$options = "<option value=\"\">". t("Default theme") ."</option>\n";
if (count($themes = list_themes()) > 1) {
foreach ($themes as $key => $value) {

View File

@ -79,13 +79,9 @@ function tracker_posts($id = 0) {
}
function tracker_user($type, &$edit, &$user) {
switch ($type) {
case "view_private":
case "view_public":
if (user_access("access content")) {
if ($type == 'view' && user_access("access content")) {
return form_item(t("Recent posts"), l(t("recent posts"), "tracker/$user->uid"));
}
}
}
function tracker_page() {

View File

@ -79,13 +79,9 @@ function tracker_posts($id = 0) {
}
function tracker_user($type, &$edit, &$user) {
switch ($type) {
case "view_private":
case "view_public":
if (user_access("access content")) {
if ($type == 'view' && user_access("access content")) {
return form_item(t("Recent posts"), l(t("recent posts"), "tracker/$user->uid"));
}
}
}
function tracker_page() {

View File

@ -78,12 +78,13 @@ function user_save($account, $array = array()) {
$query .= "data = '%s', ";
$v[] = serialize($data);
db_query("UPDATE {users} SET $query timestamp = %d WHERE uid = %d", array_merge($v, array(time(), $account->uid)));
db_query("UPDATE {users} SET $query changed = %d WHERE uid = %d", array_merge($v, array(time(), $account->uid)));
$user = user_load(array('uid' => $account->uid));
}
else {
$array['timestamp'] = time();
$array['created'] = time();
$array['changed'] = time();
$array['uid'] = db_next_id("{users}_uid");
foreach ($array as $key => $value) {
@ -112,11 +113,11 @@ function user_save($account, $array = array()) {
$user = user_load(array('name' => $array['name']));
module_invoke_all('user', "insert", $array, $user);
module_invoke_all('user', 'insert', $array, $user);
}
foreach ($array as $key => $value) {
if (substr($key, 0, 4) == "auth") {
if (substr($key, 0, 4) == 'auth') {
$authmaps[$key] = $value;
}
}
@ -136,7 +137,7 @@ function user_validate_name($name) {
if (!$name) return t("You must enter a username.");
if (substr($name, 0, 1) == ' ') return t("The username cannot begin with a space.");
if (substr($name, -1) == ' ') 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(' ', $name)) return t("The username cannot contain multiple spaces in a row.");
if (ereg('[^ [:alnum:]@_.-]', $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 (strlen($name) > 56) return t("The username '%name' is too long: it must be less than 56 characters.", array("%name" => $name));
@ -149,6 +150,35 @@ function user_validate_mail($mail) {
}
}
function user_validate_picture($file, &$edit, $user) {
// initialize the picture:
$edit['picture'] = $user->picture;
// check that uploaded file is an image, with a maximum file size and maximum height/width
$extension = strtolower(strrchr($file->name, "."));
$size = getimagesize($file->path);
list($maxwidth, $maxheight) = explode("x", variable_get('user_picture_dimensions', "85x85"));
if ((!in_array($size[2], array(1, 2, 3))) || (!in_array($extension, array(".gif", ".jpg", ".png", ".jpeg")))) {
$error = t("The uploaded file was not an image.");
}
else if ($file->size > (variable_get('user_picture_file_size', "30") * 1000)) {
$error = t("The uploaded image is too large; the maximum file size is %a kB.", array("%a" => variable_get('user_picture_file_size', "30")));
}
else if ($size[0] > $maxwidth || $size[1] > $maxheight) {
$error = t("The uploaded image is too large; the maximum dimensions are %a pixels.", array("%a" => variable_get('user_picture_dimensions', "85x85")));
}
else if ($file = file_save_upload('picture', variable_get('user_picture_path', "pictures") . FILE_SEPARATOR .'picture-'. $user->uid . $extension, 1)) {
$edit['picture'] = $file->path;
}
else {
$error = t("Failed to upload the picture image; the '%directory' directory doesn't exist.", array("%directory" => variable_get('user_picture_path', "pictures")));
}
return $error;
}
function user_validate_authmap($account, $authname, $module) {
$result = db_query("SELECT COUNT(*) from {authmap} WHERE uid != %d AND authname = '%s'", $account->uid, $authname);
if (db_result($result) > 0) {
@ -281,7 +311,7 @@ function user_fields() {
}
else {
// Make sure we return the default fields at least
$fields = array('uid', 'name', 'pass', "mail", "mode", "sort", "threshold", "theme", "signature", "timestamp", "status", "timezone", "language", "init", "data", "rid");
$fields = array('uid', 'name', 'pass', "mail", "picture", "mode", "sort", "threshold", "theme", "signature", "created", "changed", "status", "timezone", "language", "init", "data", "rid");
}
}
@ -428,6 +458,42 @@ function user_block($op = "list", $delta = 0) {
}
}
function theme_user_picture($account) {
if (variable_get('user_pictures', 0)) {
if ($account->picture && file_exists($account->picture)) {
$picture = file_create_url($account->picture);
}
else if (variable_get('user_picture_default', '')) {
$picture = variable_get('user_picture_default', '');
}
if ($picture) {
$picture = "<img src=\"$picture\" alt=\"" . t("%user's picture", array("%user" => $account->name ? $account->name : t(variable_get("anonymous", "Anonymous")))) . "\" />";
if ($account->uid) {
$picture = l($picture, "user/view/$account->uid", array("title" => t("View user profile.")));
}
return "<div class=\"picture\">$picture</div>";
}
}
}
function theme_user_profile($account) {
$output = "<div class=\"profile\">\n";
$output .= theme('user_picture', $account);
$output .= form_item(t('Name'), $account->name);
$output .= implode("\n", module_invoke_all('user', 'view', '', $account));
$output .= form_item(t('Member for'), format_interval(time() - $account->created));
if (user_access("administer users")) {
$output .= form_item(t("Administration"), l(t("edit account"), "admin/user/edit/$account->uid"));
}
$output .= "</div>\n";
return $output;
}
function theme_user_list($items, $title = NULL) {
return theme("item_list", $items, $title);
}
@ -595,7 +661,7 @@ function user_login($edit = array(), $msg = "") {
watchdog('user', "session opened for '$user->name'");
// update the user table timestamp noting user has logged in
db_query("UPDATE {users} SET timestamp = '%d' WHERE uid = '%s'", time(), $user->uid);
db_query("UPDATE {users} SET changed = '%d' WHERE uid = '%s'", time(), $user->uid);
user_module_invoke("login", $edit, $user);
@ -685,7 +751,7 @@ function user_logout() {
*/
session_destroy();
module_invoke_all('user', "logout", NULL, $user);
module_invoke_all('user', 'logout', NULL, $user);
unset($user);
}
@ -884,7 +950,15 @@ function user_edit($edit = array()) {
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']));
}
else if ($user->uid) {
else {
/*
** If required, validate the picture.
*/
if ($file = file_check_upload('picture')) {
$error = user_validate_picture($file, $edit, $user);
}
/*
** If required, check that proposed passwords match. If so,
** add new password to $edit.
@ -922,7 +996,7 @@ function user_edit($edit = array()) {
foreach (module_list() as $module) {
if (module_hook($module, 'user')) {
$result = module_invoke($module, 'user', "edit_validate", $edit, $user);
$result = module_invoke($module, 'user', 'validate', $edit, $user);
}
if (is_array($result)) {
$data = array_merge($data, $result);
@ -940,7 +1014,7 @@ function user_edit($edit = array()) {
$user = user_save($user, array_merge($edit, $data));
drupal_set_message(t("your user information changes have been saved."));
drupal_set_message(t('your user information changes have been saved.'));
}
}
}
@ -953,15 +1027,25 @@ function user_edit($edit = array()) {
$edit = object2array($user);
}
$output = form_textfield(t("Username"), 'name', $edit['name'], 30, 55, t("Your full name or your preferred 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."));
$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."));
$output = form_group(t('Account information'), $output);
$group = form_textfield(t("Username"), 'name', $edit['name'], 30, 55, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
$group .= 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."));
$group .= 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."));
$output = form_group(t('Account information'), $group);
if (variable_get('user_pictures', 0)) {
$group = '';
if (file_exists($user->picture)) {
$group .= '<img src="'. file_create_url($edit['picture']) .'" alt="" title="" />';
}
$group .= form_file(t('Upload picture or picture'), 'picture', 48, t("Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.", array("%dimensions" => variable_get('user_picture_dimensions', "85x85"), "%size" => variable_get('user_picture_file_size', "30"))) ." ". variable_get('user_picture_guidelines', ''));
$output .= form_group(t('Picture'), $group);
}
$output .= _user_profile($edit, $user);
$output .= form_submit(t("Save user information"));
$output = form($output, "post", 0, array("enctype" => "multipart/form-data"));
// the "enctype" attribute is required to upload files such as avatars
// the "enctype" attribute is required to upload files such as pictures
}
else {
$output = user_login();
@ -973,7 +1057,7 @@ function user_edit($edit = array()) {
function _user_profile($edit, $account) {
foreach (module_list() as $module) {
if ($data = module_invoke($module, 'user', 'edit_form', $edit, $account)) {
if ($data = module_invoke($module, 'user', 'edit', $edit, $account)) {
foreach ($data as $title => $form) {
$groups[$title] .= $form;
}
@ -991,28 +1075,9 @@ function _user_profile($edit, $account) {
function user_view($uid = 0) {
global $user;
if (!$uid) {
$uid = $user->uid;
}
if ($user->uid && $user->uid == $uid) {
$output = form_item(t("Name"), "$user->name ($user->init)");
$output .= form_item(t("E-mail address"), $user->mail, t("Please note that only you can see your own e-mail address - it is not publicly visible."));
$output .= implode("\n", module_invoke_all('user', "view_private", "", $user));
print theme('page', $output, $user->name);
}
else if ($uid && $account = user_load(array('uid' => $uid, "status" => 1))) {
$output = form_item(t("Name"), $account->name);
$output .= implode("\n", module_invoke_all('user', "view_public", "", $account));
if (user_access("administer users")) {
$output .= form_item(t("Administration"), l(t("edit account"), "admin/user/edit/$account->uid"));
}
print theme('page', $output, $account->name);
if ($uid == 0) {
if ($user->uid) {
print theme('page', theme('user_profile', $user), $user->name);
}
else {
$output = user_login();
@ -1023,6 +1088,15 @@ function user_view($uid = 0) {
print theme('page', $output, t("User login"));
}
}
else {
if ($account = user_load(array('uid' => $uid, "status" => 1))) {
print theme('page', theme('user_profile', $account), $account->name);
}
else {
drupal_not_found();
}
}
}
function user_page() {
@ -1124,6 +1198,20 @@ function user_settings() {
$group .= form_textarea(t("Body of password recovery e-mail"), "user_mail_pass_body", _user_mail_text("pass_body"), 70, 10, t("Customize the body of the forgotten password e-mail.") ." ". t("Available variables are:") ." %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.");
$output .= form_group(t("User email settings"), $group);
// picture settings:
if (!file_check_directory(file_create_path(variable_get('user_picture_path', 'pictures')))) {
$error = theme('error', t('The picture directory does not exist, or is not writable.'));
}
$group = form_radios(t('Picture support'), 'user_pictures', variable_get('user_pictures', 0), array(t('Disabled'), t('Enabled')), t('Enable picture support.'));
$group .= form_textfield(t("Picture image path"), 'user_picture_path', variable_get('user_picture_path', "pictures"), 45, 255, t("Subdirectory in the directory '%dir' where pictures will be stored.", array('%dir' => variable_get('file_directory_path', 'files') . FILE_SEPARATOR)) . $error);
$group .= form_textfield(t('Default picture'), 'user_picture_default', variable_get('user_picture_default', ''), 45, 255, t('URL of picture to display for users with no custom picture selected. Leave blank for none.'));
$group .= form_textfield(t("Picture maximum dimensions"), 'user_picture_dimensions', variable_get('user_picture_dimensions', "85x85"), 10, 10, t("Maximum dimensions for pictures."));
$group .= form_textfield(t("Picture maximum file size"), 'user_picture_file_size', variable_get('user_picture_file_size', "30"), 10, 10, t("Maximum file size for pictures, in kB."));
$group .= form_textarea(t("Picture guidelines"), 'user_picture_guidelines', variable_get('user_picture_guidelines', ''), 70, 4, t("This text is displayed at the picture upload form in addition to the default guidelines. It's useful for helping or instructing your users."));
$output .= form_group(t('Pictures'), $group);
// "Who's online" block settings
$period = drupal_map_assoc(array(30, 60, 120, 180, 300, 600, 900, 1800, 2700, 3600, 5400, 7200, 10800, 21600, 43200, 86400), "format_interval");
$group = form_select(t("User activity"), "user_block_seconds_online", variable_get("user_block_seconds_online", 900), $period, t("Affects \"Who's online\" block. A user is considered online for this long after they have last viewed a page."));
@ -1270,7 +1358,7 @@ function user_admin_perm($edit = array()) {
** Compile permission array:
*/
$perms = module_invoke_all("perm");
$perms = module_invoke_all('perm');
asort($perms);
/*
@ -1376,7 +1464,7 @@ function user_admin_edit($edit = array()) {
if ($op == t("Save account")) {
foreach (module_list() as $module) {
if (module_hook($module, 'user')) {
$result = module_invoke($module, 'user', "edit_validate", $edit, $account);
$result = module_invoke($module, 'user', 'validate', $edit, $account);
}
if (is_array($result)) {
$data = array_merge($data, $result);
@ -1401,6 +1489,14 @@ function user_admin_edit($edit = array()) {
$error = t("The e-mail address '%s' is already taken.", array("%s" => $edit['mail']));
}
/*
** If required, validate the picture.
*/
if ($file = file_check_upload('picture')) {
$error = user_validate_picture($file, $edit, $account);
}
/*
** If required, check that proposed passwords match. If so,
** add new password to $edit.
@ -1429,7 +1525,7 @@ function user_admin_edit($edit = array()) {
db_query("DELETE FROM {users} WHERE uid = %d", $account->uid);
db_query("DELETE FROM {authmap} WHERE uid = %d", $account->uid);
drupal_set_message(t("the account has been deleted."));
module_invoke_all('user', "delete", $account, $user);
module_invoke_all('user', 'delete', $account, $user);
}
else {
$error = t("Failed to delete account: the account has to be blocked first.");
@ -1445,14 +1541,24 @@ function user_admin_edit($edit = array()) {
** Display user form:
*/
$output .= form_item(t("User ID"), $account->uid);
$output .= form_textfield(t("Username"), 'name', $account->name, 30, 55, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
$output .= form_textfield(t("E-mail address"), "mail", $account->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."));
$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 a new password twice if you want to change the current password for this user or leave it blank if you are happy with the current password."));
$output .= form_radios(t("Status"), "status", $account->status, array(t("Blocked"), t("Active")));
$output .= form_radios(t("Role"), "rid", $account->rid, user_roles(1));
$group = form_item(t("User ID"), $account->uid);
$group .= form_textfield(t("Username"), 'name', $account->name, 30, 55, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
$group .= form_textfield(t("E-mail address"), "mail", $account->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."));
$group .= 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 a new password twice if you want to change the current password for this user or leave it blank if you are happy with the current password."));
$group .= form_radios(t("Status"), "status", $account->status, array(t("Blocked"), t("Active")));
$group .= form_radios(t("Role"), "rid", $account->rid, user_roles(1));
$output = form_group(t('Account information'), $group);
if (variable_get('user_pictures', 0)) {
$group = '';
if (file_exists($account->picture)) {
$group .= '<img src="'. file_create_url($account->picture) .'" alt="" title="" />';
}
$group .= form_file(t('Upload picture or picture'), 'picture', 48, t("Maximum dimensions are %dimensions and the maximum size is %size kB.", array("%dimensions" => variable_get('user_picture_dimensions', "85x85"), "%size" => variable_get('user_picture_file_size', "30"))));
$output .= form_group(t('Picture'), $group);
}
$output = form_group(t('Account information'), $output);
$output .= _user_profile($edit, $account);
$output .= form_submit(t("Save account"));
@ -1473,16 +1579,16 @@ function user_admin_account() {
array("data" => t("username"), "field" => "u.name"),
array("data" => t("status"), "field" => "u.status"),
array("data" => t("role"), "field" => "u.rid"),
array("data" => t("last access"), "field" => "u.timestamp", "sort" => "desc"),
array("data" => t("last access"), "field" => "u.changed", "sort" => "desc"),
t("operations")
);
$sql = "SELECT u.uid, u.name, u.status, u.timestamp, r.name AS rolename FROM {role} r INNER JOIN {users} u ON r.rid = u.rid WHERE uid != 0";
$sql = "SELECT u.uid, u.name, u.status, u.changed, r.name AS rolename FROM {role} r INNER JOIN {users} u ON r.rid = u.rid WHERE uid != 0";
$sql .= tablesort_sql($header);
$result = pager_query($sql, 50);
$status = array(t("blocked"), t("active"));
while ($account = db_fetch_object($result)) {
$rows[] = array($account->uid, format_name($account), $status[$account->status], $account->rolename, format_date($account->timestamp, "small"), l(t("edit account"), "admin/user/edit/$account->uid"));
$rows[] = array($account->uid, format_name($account), $status[$account->status], $account->rolename, format_date($account->changed, "small"), l(t("edit account"), "admin/user/edit/$account->uid"));
}
$pager = theme("pager", NULL, 50, 0, tablesort_pager());
@ -1692,18 +1798,14 @@ function user_help($section = "admin/help#user") {
function julia_user(\$type, \$edit, &\$user) {
// What type of registration action are we taking?
switch (\$type) {
case t(\"view_public\"):
// when others look at user data
case t(\"view\"):
return form_item(\"Favorite Ingredient\", \$user->julia_favingredient);
case t(\"view_private\"):
// when user tries to view his own user page.
return form_item(\"Favorite Ingredient\", \$user->julia_favingredient);
case t(\"edit_form\"):
case t(\"edit\"):
// when user tries to edit his own user page.
return form_textfield(\"Favorite Ingredient\", \"julia_favingredient\",
\$user->julia_favingredient, 50, 65,
\"Tell everyone your secret spice\");
case t(\"edit_validate\"): // Make sure the data they edited is \"valid\".
case t(\"validate\"): // Make sure the data they edited is \"valid\".
return user_save(\$user, array(\"julia_favingredient\" => \$edit[\"julia_favingredient\"]));
}
}

View File

@ -78,12 +78,13 @@ function user_save($account, $array = array()) {
$query .= "data = '%s', ";
$v[] = serialize($data);
db_query("UPDATE {users} SET $query timestamp = %d WHERE uid = %d", array_merge($v, array(time(), $account->uid)));
db_query("UPDATE {users} SET $query changed = %d WHERE uid = %d", array_merge($v, array(time(), $account->uid)));
$user = user_load(array('uid' => $account->uid));
}
else {
$array['timestamp'] = time();
$array['created'] = time();
$array['changed'] = time();
$array['uid'] = db_next_id("{users}_uid");
foreach ($array as $key => $value) {
@ -112,11 +113,11 @@ function user_save($account, $array = array()) {
$user = user_load(array('name' => $array['name']));
module_invoke_all('user', "insert", $array, $user);
module_invoke_all('user', 'insert', $array, $user);
}
foreach ($array as $key => $value) {
if (substr($key, 0, 4) == "auth") {
if (substr($key, 0, 4) == 'auth') {
$authmaps[$key] = $value;
}
}
@ -136,7 +137,7 @@ function user_validate_name($name) {
if (!$name) return t("You must enter a username.");
if (substr($name, 0, 1) == ' ') return t("The username cannot begin with a space.");
if (substr($name, -1) == ' ') 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(' ', $name)) return t("The username cannot contain multiple spaces in a row.");
if (ereg('[^ [:alnum:]@_.-]', $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 (strlen($name) > 56) return t("The username '%name' is too long: it must be less than 56 characters.", array("%name" => $name));
@ -149,6 +150,35 @@ function user_validate_mail($mail) {
}
}
function user_validate_picture($file, &$edit, $user) {
// initialize the picture:
$edit['picture'] = $user->picture;
// check that uploaded file is an image, with a maximum file size and maximum height/width
$extension = strtolower(strrchr($file->name, "."));
$size = getimagesize($file->path);
list($maxwidth, $maxheight) = explode("x", variable_get('user_picture_dimensions', "85x85"));
if ((!in_array($size[2], array(1, 2, 3))) || (!in_array($extension, array(".gif", ".jpg", ".png", ".jpeg")))) {
$error = t("The uploaded file was not an image.");
}
else if ($file->size > (variable_get('user_picture_file_size', "30") * 1000)) {
$error = t("The uploaded image is too large; the maximum file size is %a kB.", array("%a" => variable_get('user_picture_file_size', "30")));
}
else if ($size[0] > $maxwidth || $size[1] > $maxheight) {
$error = t("The uploaded image is too large; the maximum dimensions are %a pixels.", array("%a" => variable_get('user_picture_dimensions', "85x85")));
}
else if ($file = file_save_upload('picture', variable_get('user_picture_path', "pictures") . FILE_SEPARATOR .'picture-'. $user->uid . $extension, 1)) {
$edit['picture'] = $file->path;
}
else {
$error = t("Failed to upload the picture image; the '%directory' directory doesn't exist.", array("%directory" => variable_get('user_picture_path', "pictures")));
}
return $error;
}
function user_validate_authmap($account, $authname, $module) {
$result = db_query("SELECT COUNT(*) from {authmap} WHERE uid != %d AND authname = '%s'", $account->uid, $authname);
if (db_result($result) > 0) {
@ -281,7 +311,7 @@ function user_fields() {
}
else {
// Make sure we return the default fields at least
$fields = array('uid', 'name', 'pass', "mail", "mode", "sort", "threshold", "theme", "signature", "timestamp", "status", "timezone", "language", "init", "data", "rid");
$fields = array('uid', 'name', 'pass', "mail", "picture", "mode", "sort", "threshold", "theme", "signature", "created", "changed", "status", "timezone", "language", "init", "data", "rid");
}
}
@ -428,6 +458,42 @@ function user_block($op = "list", $delta = 0) {
}
}
function theme_user_picture($account) {
if (variable_get('user_pictures', 0)) {
if ($account->picture && file_exists($account->picture)) {
$picture = file_create_url($account->picture);
}
else if (variable_get('user_picture_default', '')) {
$picture = variable_get('user_picture_default', '');
}
if ($picture) {
$picture = "<img src=\"$picture\" alt=\"" . t("%user's picture", array("%user" => $account->name ? $account->name : t(variable_get("anonymous", "Anonymous")))) . "\" />";
if ($account->uid) {
$picture = l($picture, "user/view/$account->uid", array("title" => t("View user profile.")));
}
return "<div class=\"picture\">$picture</div>";
}
}
}
function theme_user_profile($account) {
$output = "<div class=\"profile\">\n";
$output .= theme('user_picture', $account);
$output .= form_item(t('Name'), $account->name);
$output .= implode("\n", module_invoke_all('user', 'view', '', $account));
$output .= form_item(t('Member for'), format_interval(time() - $account->created));
if (user_access("administer users")) {
$output .= form_item(t("Administration"), l(t("edit account"), "admin/user/edit/$account->uid"));
}
$output .= "</div>\n";
return $output;
}
function theme_user_list($items, $title = NULL) {
return theme("item_list", $items, $title);
}
@ -595,7 +661,7 @@ function user_login($edit = array(), $msg = "") {
watchdog('user', "session opened for '$user->name'");
// update the user table timestamp noting user has logged in
db_query("UPDATE {users} SET timestamp = '%d' WHERE uid = '%s'", time(), $user->uid);
db_query("UPDATE {users} SET changed = '%d' WHERE uid = '%s'", time(), $user->uid);
user_module_invoke("login", $edit, $user);
@ -685,7 +751,7 @@ function user_logout() {
*/
session_destroy();
module_invoke_all('user', "logout", NULL, $user);
module_invoke_all('user', 'logout', NULL, $user);
unset($user);
}
@ -884,7 +950,15 @@ function user_edit($edit = array()) {
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']));
}
else if ($user->uid) {
else {
/*
** If required, validate the picture.
*/
if ($file = file_check_upload('picture')) {
$error = user_validate_picture($file, $edit, $user);
}
/*
** If required, check that proposed passwords match. If so,
** add new password to $edit.
@ -922,7 +996,7 @@ function user_edit($edit = array()) {
foreach (module_list() as $module) {
if (module_hook($module, 'user')) {
$result = module_invoke($module, 'user', "edit_validate", $edit, $user);
$result = module_invoke($module, 'user', 'validate', $edit, $user);
}
if (is_array($result)) {
$data = array_merge($data, $result);
@ -940,7 +1014,7 @@ function user_edit($edit = array()) {
$user = user_save($user, array_merge($edit, $data));
drupal_set_message(t("your user information changes have been saved."));
drupal_set_message(t('your user information changes have been saved.'));
}
}
}
@ -953,15 +1027,25 @@ function user_edit($edit = array()) {
$edit = object2array($user);
}
$output = form_textfield(t("Username"), 'name', $edit['name'], 30, 55, t("Your full name or your preferred 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."));
$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."));
$output = form_group(t('Account information'), $output);
$group = form_textfield(t("Username"), 'name', $edit['name'], 30, 55, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
$group .= 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."));
$group .= 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."));
$output = form_group(t('Account information'), $group);
if (variable_get('user_pictures', 0)) {
$group = '';
if (file_exists($user->picture)) {
$group .= '<img src="'. file_create_url($edit['picture']) .'" alt="" title="" />';
}
$group .= form_file(t('Upload picture or picture'), 'picture', 48, t("Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.", array("%dimensions" => variable_get('user_picture_dimensions', "85x85"), "%size" => variable_get('user_picture_file_size', "30"))) ." ". variable_get('user_picture_guidelines', ''));
$output .= form_group(t('Picture'), $group);
}
$output .= _user_profile($edit, $user);
$output .= form_submit(t("Save user information"));
$output = form($output, "post", 0, array("enctype" => "multipart/form-data"));
// the "enctype" attribute is required to upload files such as avatars
// the "enctype" attribute is required to upload files such as pictures
}
else {
$output = user_login();
@ -973,7 +1057,7 @@ function user_edit($edit = array()) {
function _user_profile($edit, $account) {
foreach (module_list() as $module) {
if ($data = module_invoke($module, 'user', 'edit_form', $edit, $account)) {
if ($data = module_invoke($module, 'user', 'edit', $edit, $account)) {
foreach ($data as $title => $form) {
$groups[$title] .= $form;
}
@ -991,28 +1075,9 @@ function _user_profile($edit, $account) {
function user_view($uid = 0) {
global $user;
if (!$uid) {
$uid = $user->uid;
}
if ($user->uid && $user->uid == $uid) {
$output = form_item(t("Name"), "$user->name ($user->init)");
$output .= form_item(t("E-mail address"), $user->mail, t("Please note that only you can see your own e-mail address - it is not publicly visible."));
$output .= implode("\n", module_invoke_all('user', "view_private", "", $user));
print theme('page', $output, $user->name);
}
else if ($uid && $account = user_load(array('uid' => $uid, "status" => 1))) {
$output = form_item(t("Name"), $account->name);
$output .= implode("\n", module_invoke_all('user', "view_public", "", $account));
if (user_access("administer users")) {
$output .= form_item(t("Administration"), l(t("edit account"), "admin/user/edit/$account->uid"));
}
print theme('page', $output, $account->name);
if ($uid == 0) {
if ($user->uid) {
print theme('page', theme('user_profile', $user), $user->name);
}
else {
$output = user_login();
@ -1023,6 +1088,15 @@ function user_view($uid = 0) {
print theme('page', $output, t("User login"));
}
}
else {
if ($account = user_load(array('uid' => $uid, "status" => 1))) {
print theme('page', theme('user_profile', $account), $account->name);
}
else {
drupal_not_found();
}
}
}
function user_page() {
@ -1124,6 +1198,20 @@ function user_settings() {
$group .= form_textarea(t("Body of password recovery e-mail"), "user_mail_pass_body", _user_mail_text("pass_body"), 70, 10, t("Customize the body of the forgotten password e-mail.") ." ". t("Available variables are:") ." %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.");
$output .= form_group(t("User email settings"), $group);
// picture settings:
if (!file_check_directory(file_create_path(variable_get('user_picture_path', 'pictures')))) {
$error = theme('error', t('The picture directory does not exist, or is not writable.'));
}
$group = form_radios(t('Picture support'), 'user_pictures', variable_get('user_pictures', 0), array(t('Disabled'), t('Enabled')), t('Enable picture support.'));
$group .= form_textfield(t("Picture image path"), 'user_picture_path', variable_get('user_picture_path', "pictures"), 45, 255, t("Subdirectory in the directory '%dir' where pictures will be stored.", array('%dir' => variable_get('file_directory_path', 'files') . FILE_SEPARATOR)) . $error);
$group .= form_textfield(t('Default picture'), 'user_picture_default', variable_get('user_picture_default', ''), 45, 255, t('URL of picture to display for users with no custom picture selected. Leave blank for none.'));
$group .= form_textfield(t("Picture maximum dimensions"), 'user_picture_dimensions', variable_get('user_picture_dimensions', "85x85"), 10, 10, t("Maximum dimensions for pictures."));
$group .= form_textfield(t("Picture maximum file size"), 'user_picture_file_size', variable_get('user_picture_file_size', "30"), 10, 10, t("Maximum file size for pictures, in kB."));
$group .= form_textarea(t("Picture guidelines"), 'user_picture_guidelines', variable_get('user_picture_guidelines', ''), 70, 4, t("This text is displayed at the picture upload form in addition to the default guidelines. It's useful for helping or instructing your users."));
$output .= form_group(t('Pictures'), $group);
// "Who's online" block settings
$period = drupal_map_assoc(array(30, 60, 120, 180, 300, 600, 900, 1800, 2700, 3600, 5400, 7200, 10800, 21600, 43200, 86400), "format_interval");
$group = form_select(t("User activity"), "user_block_seconds_online", variable_get("user_block_seconds_online", 900), $period, t("Affects \"Who's online\" block. A user is considered online for this long after they have last viewed a page."));
@ -1270,7 +1358,7 @@ function user_admin_perm($edit = array()) {
** Compile permission array:
*/
$perms = module_invoke_all("perm");
$perms = module_invoke_all('perm');
asort($perms);
/*
@ -1376,7 +1464,7 @@ function user_admin_edit($edit = array()) {
if ($op == t("Save account")) {
foreach (module_list() as $module) {
if (module_hook($module, 'user')) {
$result = module_invoke($module, 'user', "edit_validate", $edit, $account);
$result = module_invoke($module, 'user', 'validate', $edit, $account);
}
if (is_array($result)) {
$data = array_merge($data, $result);
@ -1401,6 +1489,14 @@ function user_admin_edit($edit = array()) {
$error = t("The e-mail address '%s' is already taken.", array("%s" => $edit['mail']));
}
/*
** If required, validate the picture.
*/
if ($file = file_check_upload('picture')) {
$error = user_validate_picture($file, $edit, $account);
}
/*
** If required, check that proposed passwords match. If so,
** add new password to $edit.
@ -1429,7 +1525,7 @@ function user_admin_edit($edit = array()) {
db_query("DELETE FROM {users} WHERE uid = %d", $account->uid);
db_query("DELETE FROM {authmap} WHERE uid = %d", $account->uid);
drupal_set_message(t("the account has been deleted."));
module_invoke_all('user', "delete", $account, $user);
module_invoke_all('user', 'delete', $account, $user);
}
else {
$error = t("Failed to delete account: the account has to be blocked first.");
@ -1445,14 +1541,24 @@ function user_admin_edit($edit = array()) {
** Display user form:
*/
$output .= form_item(t("User ID"), $account->uid);
$output .= form_textfield(t("Username"), 'name', $account->name, 30, 55, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
$output .= form_textfield(t("E-mail address"), "mail", $account->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."));
$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 a new password twice if you want to change the current password for this user or leave it blank if you are happy with the current password."));
$output .= form_radios(t("Status"), "status", $account->status, array(t("Blocked"), t("Active")));
$output .= form_radios(t("Role"), "rid", $account->rid, user_roles(1));
$group = form_item(t("User ID"), $account->uid);
$group .= form_textfield(t("Username"), 'name', $account->name, 30, 55, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
$group .= form_textfield(t("E-mail address"), "mail", $account->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."));
$group .= 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 a new password twice if you want to change the current password for this user or leave it blank if you are happy with the current password."));
$group .= form_radios(t("Status"), "status", $account->status, array(t("Blocked"), t("Active")));
$group .= form_radios(t("Role"), "rid", $account->rid, user_roles(1));
$output = form_group(t('Account information'), $group);
if (variable_get('user_pictures', 0)) {
$group = '';
if (file_exists($account->picture)) {
$group .= '<img src="'. file_create_url($account->picture) .'" alt="" title="" />';
}
$group .= form_file(t('Upload picture or picture'), 'picture', 48, t("Maximum dimensions are %dimensions and the maximum size is %size kB.", array("%dimensions" => variable_get('user_picture_dimensions', "85x85"), "%size" => variable_get('user_picture_file_size', "30"))));
$output .= form_group(t('Picture'), $group);
}
$output = form_group(t('Account information'), $output);
$output .= _user_profile($edit, $account);
$output .= form_submit(t("Save account"));
@ -1473,16 +1579,16 @@ function user_admin_account() {
array("data" => t("username"), "field" => "u.name"),
array("data" => t("status"), "field" => "u.status"),
array("data" => t("role"), "field" => "u.rid"),
array("data" => t("last access"), "field" => "u.timestamp", "sort" => "desc"),
array("data" => t("last access"), "field" => "u.changed", "sort" => "desc"),
t("operations")
);
$sql = "SELECT u.uid, u.name, u.status, u.timestamp, r.name AS rolename FROM {role} r INNER JOIN {users} u ON r.rid = u.rid WHERE uid != 0";
$sql = "SELECT u.uid, u.name, u.status, u.changed, r.name AS rolename FROM {role} r INNER JOIN {users} u ON r.rid = u.rid WHERE uid != 0";
$sql .= tablesort_sql($header);
$result = pager_query($sql, 50);
$status = array(t("blocked"), t("active"));
while ($account = db_fetch_object($result)) {
$rows[] = array($account->uid, format_name($account), $status[$account->status], $account->rolename, format_date($account->timestamp, "small"), l(t("edit account"), "admin/user/edit/$account->uid"));
$rows[] = array($account->uid, format_name($account), $status[$account->status], $account->rolename, format_date($account->changed, "small"), l(t("edit account"), "admin/user/edit/$account->uid"));
}
$pager = theme("pager", NULL, 50, 0, tablesort_pager());
@ -1692,18 +1798,14 @@ function user_help($section = "admin/help#user") {
function julia_user(\$type, \$edit, &\$user) {
// What type of registration action are we taking?
switch (\$type) {
case t(\"view_public\"):
// when others look at user data
case t(\"view\"):
return form_item(\"Favorite Ingredient\", \$user->julia_favingredient);
case t(\"view_private\"):
// when user tries to view his own user page.
return form_item(\"Favorite Ingredient\", \$user->julia_favingredient);
case t(\"edit_form\"):
case t(\"edit\"):
// when user tries to edit his own user page.
return form_textfield(\"Favorite Ingredient\", \"julia_favingredient\",
\$user->julia_favingredient, 50, 65,
\"Tell everyone your secret spice\");
case t(\"edit_validate\"): // Make sure the data they edited is \"valid\".
case t(\"validate\"): // Make sure the data they edited is \"valid\".
return user_save(\$user, array(\"julia_favingredient\" => \$edit[\"julia_favingredient\"]));
}
}

View File

@ -222,7 +222,7 @@ table {
font-size: 0.8em;
padding: 1.5em;
}
.node .avatar {
.node .picture {
border: 1px solid #ddd;
float: right;
margin: 0.5em;
@ -242,7 +242,7 @@ table {
float: right;
color: red;
}
.comment .avatar {
.comment .picture {
border: 1px solid #abc;
float: right;
margin: 0.5em;

View File

@ -56,9 +56,9 @@
<!-- BEGIN: node -->
<div class="node {static}">
<!-- BEGIN: avatar -->
<div class="avatar">{avatar}</div>
<!-- END: avatar -->
<!-- BEGIN: picture -->
{picture}
<!-- END: picture -->
<!-- BEGIN: title -->
<h2 class="title"><a href="{link}">{title}</a></h2>
<!-- END: title -->
@ -75,9 +75,9 @@
<!-- BEGIN: comment -->
<div class="comment">
<!-- BEGIN: avatar -->
<div class="avatar">{avatar}</div>
<!-- END: avatar -->
<!-- BEGIN: picture -->
{picture}
<!-- END: picture -->
<h3 class="title">{title}</h3><!-- BEGIN: new --><span class="new">{new}</span><!-- END: new -->
<div class="submitted">{submitted}</div>
<div class="content">{content}</div>

View File

@ -312,7 +312,7 @@ table#footer-links {
font-size: 0.83em;
padding: 1.5em;
}
.node .avatar {
.node .picture {
border: 1px solid #fff;
float: right;
margin: 0.5em;
@ -334,7 +334,7 @@ table#footer-links {
float: right;
color: red;
}
.comment .avatar {
.comment .picture {
border: 1px solid #fff;
float: right;
margin: 0.5em;

View File

@ -59,9 +59,9 @@
<!-- BEGIN: node -->
<div class="node {static}">
<!-- BEGIN: avatar -->
<div class="avatar">{avatar}</div>
<!-- END: avatar -->
<!-- BEGIN: picture -->
{picture}
<!-- END: picture -->
<!-- BEGIN: title -->
<h1 class="title"><a href="{link}">{title}</a></h1>
<!-- END: title -->
@ -78,9 +78,9 @@
<!-- BEGIN: comment -->
<div class="comment">
<!-- BEGIN: avatar -->
<div class="avatar">{avatar}</div>
<!-- END: avatar -->
<!-- BEGIN: picture -->
<div class="picture">{picture}</div>
<!-- END: picture -->
<h3 class="title">{title}</h3><!-- BEGIN: new --><span class="new">{new}</span><!-- END: new -->
<div class="submitted">{submitted}</div>
<div class="content">{content}</div>

View File

@ -32,7 +32,8 @@ function xtemplate_settings() {
$group .= form_radios(t('Search box'), 'xtemplate_search_box', variable_get('xtemplate_search_box', 0), array(t('Disabled'), t('Enabled')), t('Show a search box in the upper right corner.'));
$output .= form_group(t('Header settings'), $group);
$group = form_checkbox(t('Display avatars with posts'), 'xtemplate_avatar_node', 1, variable_get('xtemplate_avatar_node', 0), t('Display individualized pictures identifying users with posts they start.')) . form_checkbox(t('Display avatars with comments'), 'xtemplate_avatar_comment', 1, variable_get('xtemplate_avatar_comment', 0), t('Display individualized pictures identifying users with their comments.')) . form_textfield(t('Default avatar'), 'xtemplate_avatar_default', variable_get('xtemplate_avatar_default', ''), 70, 300, t('URL of avatar to display for users with no custom avatar selected. Leave blank for none.'));
$group = form_checkbox(t('Display pictures with posts'), 'xtemplate_picture_node', 1, variable_get('xtemplate_picture_node', 0), t('Display individualized pictures identifying users with posts they start.'));
$gourp .= form_checkbox(t('Display pictures with comments'), 'xtemplate_picture_comment', 1, variable_get('xtemplate_picture_comment', 0), t('Display individualized pictures identifying users with their comments.'));
$output .= form_group(t('Avatar settings'), $group);
return $output;
@ -69,22 +70,9 @@ function xtemplate_node($node, $main = 0, $page = 0) {
$xtemplate->template->parse("node.title");
}
if (module_exist("profile") && variable_get("xtemplate_avatar_node", 0)) {
$avatar = $node->profile_avatar;
if (empty($avatar) || !file_exists($avatar)) {
$avatar = variable_get("xtemplate_avatar_default", "");
}
else {
$avatar = file_create_url($avatar);
}
if ($avatar) {
$avatar = "<img src=\"$avatar\" alt=\"" . t("%user's avatar", array("%user" => $node->name ? $node->name : t(variable_get("anonymous", "Anonymous")))) . "\" />";
if ($node->uid) {
$avatar = l($avatar, "user/view/$node->uid", array("title" => t("View user profile.")));
}
$xtemplate->template->assign("avatar", $avatar);
$xtemplate->template->parse("node.avatar");
}
if ($picture = theme('user_picture', $node)) {
$xtemplate->template->assign("picture", $picture);
$xtemplate->template->parse("node.picture");
}
if (module_exist("taxonomy") && ($taxonomy = taxonomy_link("taxonomy terms", $node))) {
@ -121,22 +109,9 @@ function xtemplate_comment($comment, $links = 0) {
$xtemplate->template->parse("comment.new");
}
if (module_exist("profile") && variable_get("xtemplate_avatar_comment", 0)) {
$avatar = $comment->profile_avatar;
if (empty($avatar) || !file_exists($avatar)) {
$avatar = variable_get("xtemplate_avatar_default", "");
}
else {
$avatar = file_create_url($avatar);
}
if ($avatar) {
$avatar = "<img src=\"$avatar\" alt=\"" . t("%user's avatar", array("%user" => $comment->name ? $comment->name : t(variable_get("anonymous", "Anonymous")))) . "\" />";
if ($comment->uid) {
$avatar = l($avatar, "user/view/$comment->uid", array("title" => t("View user profile.")));
}
$xtemplate->template->assign("avatar", $avatar);
$xtemplate->template->parse("comment.avatar");
}
if ($picture = theme('user_picture', $comment)) {
$xtemplate->template->assign("picture", $picture);
$xtemplate->template->parse("comment.picture");
}
if ($links) {