diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/blog.module | 8 | ||||
-rw-r--r-- | modules/blog/blog.module | 8 | ||||
-rw-r--r-- | modules/comment.module | 17 | ||||
-rw-r--r-- | modules/comment/comment.module | 17 | ||||
-rw-r--r-- | modules/drupal.module | 18 | ||||
-rw-r--r-- | modules/drupal/drupal.module | 18 | ||||
-rw-r--r-- | modules/locale.module | 2 | ||||
-rw-r--r-- | modules/locale/locale.module | 2 | ||||
-rw-r--r-- | modules/node.module | 2 | ||||
-rw-r--r-- | modules/node/node.module | 2 | ||||
-rw-r--r-- | modules/profile.module | 446 | ||||
-rw-r--r-- | modules/profile/profile.module | 446 | ||||
-rw-r--r-- | modules/system.module | 2 | ||||
-rw-r--r-- | modules/system/system.module | 2 | ||||
-rw-r--r-- | modules/tracker.module | 8 | ||||
-rw-r--r-- | modules/tracker/tracker.module | 8 | ||||
-rw-r--r-- | modules/user.module | 228 | ||||
-rw-r--r-- | modules/user/user.module | 228 |
18 files changed, 800 insertions, 662 deletions
diff --git a/modules/blog.module b/modules/blog.module index e95937607..9b18115d4 100644 --- a/modules/blog.module +++ b/modules/blog.module @@ -37,12 +37,8 @@ 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)) { - 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))))); - } + 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))))); } } diff --git a/modules/blog/blog.module b/modules/blog/blog.module index e95937607..9b18115d4 100644 --- a/modules/blog/blog.module +++ b/modules/blog/blog.module @@ -37,12 +37,8 @@ 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)) { - 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))))); - } + 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))))); } } diff --git a/modules/comment.module b/modules/comment.module index 69fd729fb..a0225e44b 100644 --- a/modules/comment.module +++ b/modules/comment.module @@ -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 diff --git a/modules/comment/comment.module b/modules/comment/comment.module index 69fd729fb..a0225e44b 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -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 diff --git a/modules/drupal.module b/modules/drupal.module index 77a5c8f3a..b6392a501 100644 --- a/modules/drupal.module +++ b/modules/drupal.module @@ -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"]); - } - } -} - ?> diff --git a/modules/drupal/drupal.module b/modules/drupal/drupal.module index 77a5c8f3a..b6392a501 100644 --- a/modules/drupal/drupal.module +++ b/modules/drupal/drupal.module @@ -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"]); - } - } -} - ?> diff --git a/modules/locale.module b/modules/locale.module index eedba7595..907c99834 100644 --- a/modules/locale.module +++ b/modules/locale.module @@ -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."))); } } diff --git a/modules/locale/locale.module b/modules/locale/locale.module index eedba7595..907c99834 100644 --- a/modules/locale/locale.module +++ b/modules/locale/locale.module @@ -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."))); } } diff --git a/modules/node.module b/modules/node.module index 3e1a62155..16c7015d6 100644 --- a/modules/node.module +++ b/modules/node.module @@ -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); /* diff --git a/modules/node/node.module b/modules/node/node.module index 3e1a62155..16c7015d6 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -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); /* diff --git a/modules/profile.module b/modules/profile.module index a16c47c20..d1e5e5f0c 100644 --- a/modules/profile.module +++ b/modules/profile.module @@ -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")); -} -function profile_help($section) { - $output = ""; +// TODO: add a 'date' field so we can migrate the birthday information. +function profile_help($section) { 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_settings() { - global $profile_fields; +function profile_link($type) { + if ($type == 'system') { + menu('profile', t('browse'), 'profile_browse', 0, MENU_HIDE); - if (!$profile_fields) { - _profile_init(); + 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); + } } +} - 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.')); - } +function profile_browse() { - $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++; - } + $value = arg(2) ? arg(2) : 1; - $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.")); + // 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)); - $output = theme("table", $header, $row); - $output .= form_group(t('Avatars'), $avatar); + 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; + } - return $output; -} + // 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); -function profile_user($type, $edit, &$user) { - global $profile_fields; - if (!$profile_fields) { - _profile_init(); + $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(); } +} - 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"); +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_required($title) { - // this pleads "theme, theme" ;) - return $title ." ". theme("mark"); +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_form($edit, $mode) { - global $profile_fields, $user; +function profile_view_profile($user) { - $reg_fields = _profile_active_fields($mode); - $required_fields = _profile_active_fields("required"); + profile_load_profile(&$user); - 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]); + $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>'; + } } } - 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]); - } + return $output; +} - 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="" />'); +function profile_edit_profile($edit, $user) { + + $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; + } + } + + $fields[$field->category] .= form_select($field->title, $field->name, $edit[$field->name], $options, $field->explanation); + break; } - $output .= form_file($profile_fields["avatar"][1], "profile_avatar", 64, $profile_fields["avatar"][2]); } - return array(t('Personal information') => $output); + return $fields; } -function _profile_validate($edit, $mode, $user) { +function profile_user($type, $edit, &$user) { + switch ($type) { + 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; + } +} - global $profile_fields; +function profile_validate_form($edit) { - $enabled_fields = _profile_active_fields($mode); + // Validate the title: - if (in_array("birthday", $enabled_fields) && ($birth_error = _profile_validate_birth($edit))) { - $error .= $birth_error ."<br />"; + if (!$edit['title']) { + return t('You must enter a title.'); } - if (in_array("avatar", $enabled_fields) && ($avatar_error = _profile_validate_avatar($edit, $user))) { - $error .= $avatar_error ."<br />"; - } + // Validate the 'form name': - 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; - } + 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.'); } - // 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 />"; - } - } + if (in_array($edit['name'], user_fields())) { + return t('The specified form name is reserved for use by Drupal.'); } - return $error ? $error : $edit; + // Validate the category: + + if (!$edit['category']) { + return t('You must enter a category.'); + } } -function _profile_user_view(&$user, $mode) { - global $profile_fields; +function profile_admin_add($type) { + $type = _profile_field_types($type); - foreach (_profile_active_fields($mode) as $name) { - $field = $profile_fields[$name]; - $t = "profile_". $name; - 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="" />'); - } - } + if ($_POST['op']) { + $data = $_POST['edit']; - 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")); - } - } - } + if ($error = profile_validate_form($data)) { + drupal_set_message($error, 'error'); } - } - return $output; -} + 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']); -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]); + drupal_set_message(t('the field has been created.')); + } } + else { + $data = array('name' => 'profile_'); + } + + print theme('page', _profile_field_form($type, $data), t('Add new %type', array('%type' => $type))); } -function _profile_validate_avatar(&$edit, $user) { - // check that uploaded file is an image, with a maximum file size and maximum height/width +function profile_admin_edit($fid) { - unset($edit["profile_avatar"]); + if ($_POST['op']) { + $data = $_POST['edit']; - if (!$file = file_check_upload('profile_avatar')) { - $edit["profile_avatar"] = $user->profile_avatar; - return; - } + if ($error = profile_validate_form($data)) { + drupal_set_message($error, 'error'); - $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 { + 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); + + drupal_set_message(t('the field has been updated.')); + } } else { - $error = t("Failed to upload the avatar image; the '%directory' directory doesn't exist.", array("%directory" => variable_get("profile_avatar_path", "avatars"))); + $data = db_fetch_array(db_query('SELECT * FROM {profile_fields} WHERE fid = %d', $fid)); } - return $error ? "$error<br />" : ""; + print theme('page', _profile_field_form($data['type'], $data), t('Edit %type', array('%type' => $edit['type']))); } -function _profile_active_fields($mode) { - return variable_get("profile_". $mode ."_fields", array()); +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')); } -function _profile_edit_birth($edit = "") { - global $profile_months, $profile_days; - $output = _profile_select("profile_birthday", $edit->profile_birthday, $profile_days); - $output .= " "; - $output .= _profile_select("profile_birthmonth", $edit->profile_birthmonth, $profile_months); - $output .= " "; - $output .= "<input type=\"text\" maxlength=\"4\" name=\"edit[profile_birthyear]\" size=\"5\" value=\"$edit->profile_birthyear\" />"; - return $output; -} +function _profile_field_form($type, $edit = array()) { + + $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']); -function _profile_validate_birth(&$edit) { - if (!$edit["profile_birthday"] && !$edit["profile_birthmonth"] && !$edit["profile_birthyear"]) { - // change this if you want required birth - return; + 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.")); } - if ($edit["profile_birthyear"] > 1900 && checkdate($edit["profile_birthmonth"], $edit["profile_birthday"], $edit["profile_birthyear"])) { - return; + $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")); } - else { - return t("The specified birthday is not valid.") ."<br />"; + + $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 _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>"; +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>"; + } } - return "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>"; } + + $output .= "</div>\n"; + + return $output; +} + +function _profile_field_types($type = NULL) { + $types = array('textfield', 'textarea', 'checkbox', 'selection'); + return isset($type) ? $types[$type] : $types; } ?> diff --git a/modules/profile/profile.module b/modules/profile/profile.module index a16c47c20..d1e5e5f0c 100644 --- a/modules/profile/profile.module +++ b/modules/profile/profile.module @@ -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")); -} -function profile_help($section) { - $output = ""; +// TODO: add a 'date' field so we can migrate the birthday information. +function profile_help($section) { 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_settings() { - global $profile_fields; +function profile_link($type) { + if ($type == 'system') { + menu('profile', t('browse'), 'profile_browse', 0, MENU_HIDE); - if (!$profile_fields) { - _profile_init(); + 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); + } } +} - 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.')); - } +function profile_browse() { - $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++; - } + $value = arg(2) ? arg(2) : 1; - $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.")); + // 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)); - $output = theme("table", $header, $row); - $output .= form_group(t('Avatars'), $avatar); + 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; + } - return $output; -} + // 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); -function profile_user($type, $edit, &$user) { - global $profile_fields; - if (!$profile_fields) { - _profile_init(); + $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(); } +} - 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"); +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_required($title) { - // this pleads "theme, theme" ;) - return $title ." ". theme("mark"); +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_form($edit, $mode) { - global $profile_fields, $user; +function profile_view_profile($user) { - $reg_fields = _profile_active_fields($mode); - $required_fields = _profile_active_fields("required"); + profile_load_profile(&$user); - 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]); + $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>'; + } } } - 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]); - } + return $output; +} - 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="" />'); +function profile_edit_profile($edit, $user) { + + $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; + } + } + + $fields[$field->category] .= form_select($field->title, $field->name, $edit[$field->name], $options, $field->explanation); + break; } - $output .= form_file($profile_fields["avatar"][1], "profile_avatar", 64, $profile_fields["avatar"][2]); } - return array(t('Personal information') => $output); + return $fields; } -function _profile_validate($edit, $mode, $user) { +function profile_user($type, $edit, &$user) { + switch ($type) { + 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; + } +} - global $profile_fields; +function profile_validate_form($edit) { - $enabled_fields = _profile_active_fields($mode); + // Validate the title: - if (in_array("birthday", $enabled_fields) && ($birth_error = _profile_validate_birth($edit))) { - $error .= $birth_error ."<br />"; + if (!$edit['title']) { + return t('You must enter a title.'); } - if (in_array("avatar", $enabled_fields) && ($avatar_error = _profile_validate_avatar($edit, $user))) { - $error .= $avatar_error ."<br />"; - } + // Validate the 'form name': - 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; - } + 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.'); } - // 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 />"; - } - } + if (in_array($edit['name'], user_fields())) { + return t('The specified form name is reserved for use by Drupal.'); } - return $error ? $error : $edit; + // Validate the category: + + if (!$edit['category']) { + return t('You must enter a category.'); + } } -function _profile_user_view(&$user, $mode) { - global $profile_fields; +function profile_admin_add($type) { + $type = _profile_field_types($type); - foreach (_profile_active_fields($mode) as $name) { - $field = $profile_fields[$name]; - $t = "profile_". $name; - 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="" />'); - } - } + if ($_POST['op']) { + $data = $_POST['edit']; - 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")); - } - } - } + if ($error = profile_validate_form($data)) { + drupal_set_message($error, 'error'); } - } - return $output; -} + 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']); -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]); + drupal_set_message(t('the field has been created.')); + } } + else { + $data = array('name' => 'profile_'); + } + + print theme('page', _profile_field_form($type, $data), t('Add new %type', array('%type' => $type))); } -function _profile_validate_avatar(&$edit, $user) { - // check that uploaded file is an image, with a maximum file size and maximum height/width +function profile_admin_edit($fid) { - unset($edit["profile_avatar"]); + if ($_POST['op']) { + $data = $_POST['edit']; - if (!$file = file_check_upload('profile_avatar')) { - $edit["profile_avatar"] = $user->profile_avatar; - return; - } + if ($error = profile_validate_form($data)) { + drupal_set_message($error, 'error'); - $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 { + 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); + + drupal_set_message(t('the field has been updated.')); + } } else { - $error = t("Failed to upload the avatar image; the '%directory' directory doesn't exist.", array("%directory" => variable_get("profile_avatar_path", "avatars"))); + $data = db_fetch_array(db_query('SELECT * FROM {profile_fields} WHERE fid = %d', $fid)); } - return $error ? "$error<br />" : ""; + print theme('page', _profile_field_form($data['type'], $data), t('Edit %type', array('%type' => $edit['type']))); } -function _profile_active_fields($mode) { - return variable_get("profile_". $mode ."_fields", array()); +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')); } -function _profile_edit_birth($edit = "") { - global $profile_months, $profile_days; - $output = _profile_select("profile_birthday", $edit->profile_birthday, $profile_days); - $output .= " "; - $output .= _profile_select("profile_birthmonth", $edit->profile_birthmonth, $profile_months); - $output .= " "; - $output .= "<input type=\"text\" maxlength=\"4\" name=\"edit[profile_birthyear]\" size=\"5\" value=\"$edit->profile_birthyear\" />"; - return $output; -} +function _profile_field_form($type, $edit = array()) { + + $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']); -function _profile_validate_birth(&$edit) { - if (!$edit["profile_birthday"] && !$edit["profile_birthmonth"] && !$edit["profile_birthyear"]) { - // change this if you want required birth - return; + 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.")); } - if ($edit["profile_birthyear"] > 1900 && checkdate($edit["profile_birthmonth"], $edit["profile_birthday"], $edit["profile_birthyear"])) { - return; + $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")); } - else { - return t("The specified birthday is not valid.") ."<br />"; + + $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 _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>"; +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>"; + } } - return "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>"; } + + $output .= "</div>\n"; + + return $output; +} + +function _profile_field_types($type = NULL) { + $types = array('textfield', 'textarea', 'checkbox', 'selection'); + return isset($type) ? $types[$type] : $types; } ?> diff --git a/modules/system.module b/modules/system.module index 046920158..7169250d5 100644 --- a/modules/system.module +++ b/modules/system.module @@ -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) { diff --git a/modules/system/system.module b/modules/system/system.module index 046920158..7169250d5 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -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) { diff --git a/modules/tracker.module b/modules/tracker.module index 6bbc80f43..8e5d8a11c 100644 --- a/modules/tracker.module +++ b/modules/tracker.module @@ -79,12 +79,8 @@ function tracker_posts($id = 0) { } function tracker_user($type, &$edit, &$user) { - switch ($type) { - case "view_private": - case "view_public": - if (user_access("access content")) { - return form_item(t("Recent posts"), l(t("recent posts"), "tracker/$user->uid")); - } + if ($type == 'view' && user_access("access content")) { + return form_item(t("Recent posts"), l(t("recent posts"), "tracker/$user->uid")); } } diff --git a/modules/tracker/tracker.module b/modules/tracker/tracker.module index 6bbc80f43..8e5d8a11c 100644 --- a/modules/tracker/tracker.module +++ b/modules/tracker/tracker.module @@ -79,12 +79,8 @@ function tracker_posts($id = 0) { } function tracker_user($type, &$edit, &$user) { - switch ($type) { - case "view_private": - case "view_public": - if (user_access("access content")) { - return form_item(t("Recent posts"), l(t("recent posts"), "tracker/$user->uid")); - } + if ($type == 'view' && user_access("access content")) { + return form_item(t("Recent posts"), l(t("recent posts"), "tracker/$user->uid")); } } diff --git a/modules/user.module b/modules/user.module index 68d25921a..1dbc33daf 100644 --- a/modules/user.module +++ b/modules/user.module @@ -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,37 +1075,27 @@ 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")); + if ($uid == 0) { + if ($user->uid) { + print theme('page', theme('user_profile', $user), $user->name); } + else { + $output = user_login(); + if (variable_get("user_register", 1)) { + $output .= user_register(); + } + $output .= user_pass(); - print theme('page', $output, $account->name); + print theme('page', $output, t("User login")); + } } else { - $output = user_login(); - if (variable_get("user_register", 1)) { - $output .= user_register(); + if ($account = user_load(array('uid' => $uid, "status" => 1))) { + print theme('page', theme('user_profile', $account), $account->name); + } + else { + drupal_not_found(); } - $output .= user_pass(); - - print theme('page', $output, t("User login")); } } @@ -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); @@ -1402,6 +1490,14 @@ function user_admin_edit($edit = array()) { } /* + ** 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 - return form_item(\"Favorite Ingredient\", \$user->julia_favingredient); - case t(\"view_private\"): - // when user tries to view his own user page. + case t(\"view\"): 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\"])); } } diff --git a/modules/user/user.module b/modules/user/user.module index 68d25921a..1dbc33daf 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -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,37 +1075,27 @@ 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")); + if ($uid == 0) { + if ($user->uid) { + print theme('page', theme('user_profile', $user), $user->name); } + else { + $output = user_login(); + if (variable_get("user_register", 1)) { + $output .= user_register(); + } + $output .= user_pass(); - print theme('page', $output, $account->name); + print theme('page', $output, t("User login")); + } } else { - $output = user_login(); - if (variable_get("user_register", 1)) { - $output .= user_register(); + if ($account = user_load(array('uid' => $uid, "status" => 1))) { + print theme('page', theme('user_profile', $account), $account->name); + } + else { + drupal_not_found(); } - $output .= user_pass(); - - print theme('page', $output, t("User login")); } } @@ -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); @@ -1402,6 +1490,14 @@ function user_admin_edit($edit = array()) { } /* + ** 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 - return form_item(\"Favorite Ingredient\", \$user->julia_favingredient); - case t(\"view_private\"): - // when user tries to view his own user page. + case t(\"view\"): 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\"])); } } |