summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2009-01-20 03:10:00 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2009-01-20 03:10:00 +0000
commit0ec23b9b431108365bba4792e034a0f151e88ddc (patch)
tree17b2c20c59b47db102862893da78184b2a0da15e
parentcb07c9992be48479e8b53117c21407426f4dd510 (diff)
downloadbrdo-0ec23b9b431108365bba4792e034a0f151e88ddc.tar.gz
brdo-0ec23b9b431108365bba4792e034a0f151e88ddc.tar.bz2
#357403 by drewish: Make user pictures managed files.
-rw-r--r--modules/user/user.install84
-rw-r--r--modules/user/user.module162
-rw-r--r--modules/user/user.test5
3 files changed, 202 insertions, 49 deletions
diff --git a/modules/user/user.install b/modules/user/user.install
index 435bbe628..39725f299 100644
--- a/modules/user/user.install
+++ b/modules/user/user.install
@@ -170,11 +170,10 @@ function user_schema() {
'description' => "User's default language.",
),
'picture' => array(
- 'type' => 'varchar',
- 'length' => 255,
+ 'type' => 'int',
'not null' => TRUE,
- 'default' => '',
- 'description' => "Path to the user's uploaded picture.",
+ 'default' => 0,
+ 'description' => "Foreign key: {files}.fid of user's picture.",
),
'init' => array(
'type' => 'varchar',
@@ -388,6 +387,83 @@ function user_update_7003() {
}
/**
+ * Add the user's pictures to the {files} table and make them managed files.
+ */
+function user_update_7004(&$sandbox) {
+ $ret = array();
+
+ $picture_field = array(
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => 0,
+ 'description' => t("Foriegn key: {files}.fid of user's picture."),
+ );
+
+ if (!isset($sandbox['progress'])) {
+ // Check that the field hasn't been updated in an aborted run of this
+ // update.
+ if (!db_column_exists('users', 'picture_fid')) {
+ // Add a new field for the fid.
+ db_add_field($ret, 'users', 'picture_fid', $picture_field);
+ }
+
+ // Initialize batch update information.
+ $sandbox['progress'] = 0;
+ $sandbox['last_user_processed'] = -1;
+ $sandbox['max'] = db_query("SELECT COUNT(*) FROM {users} WHERE picture <> ''")->fetchField();
+ }
+
+ // As a batch operation move the photos into the {files} table and update the
+ // {user} records.
+ $limit = 500;
+ $result = db_query_range("SELECT uid, picture FROM {users} WHERE picture <> '' AND uid > :uid ORDER BY uid", array(':uid' => $sandbox['last_user_processed']), 0, $limit);
+ foreach ($result as $user) {
+ // Don't bother adding files that don't exist.
+ if (!file_exists($user->picture)) {
+ continue;
+ }
+
+ // Check if the file already exists.
+ $files = file_load_multiple(array(), array('filepath' => $user->picture));
+ if (count($files)) {
+ $file = reset($files);
+ }
+ else {
+ // Create a file object.
+ $file = new stdClass();
+ $file->filepath = $user->picture;
+ $file->filename = basename($file->filepath);
+ $file->filemime = file_get_mimetype($file->filepath);
+ $file->uid = $user->uid;
+ $file->status = FILE_STATUS_PERMANENT;
+ $file = file_save($file);
+ }
+
+ db_update('users')
+ ->fields(array('picture_fid' => $file->fid))
+ ->condition('uid', $user->uid)
+ ->execute();
+
+ // Update our progress information for the batch update.
+ $sandbox['progress']++;
+ $sandbox['last_user_processed'] = $user->uid;
+ }
+
+ // Indicate our current progress to the batch update system. If there's no
+ // max value then there's nothing to update and we're finished.
+ $ret['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
+
+ // When we're finished, drop the old picture field and rename the new one to
+ // replace it.
+ if (isset($ret['#finished']) && $ret['#finished'] == 1) {
+ db_drop_field($ret, 'users', 'picture');
+ db_change_field($ret, 'users', 'picture_fid', 'picture', $picture_field);
+ }
+
+ return $ret;
+}
+
+/**
* @} End of "defgroup user-updates-6.x-to-7.x"
* The next series of updates should start at 8000.
*/
diff --git a/modules/user/user.module b/modules/user/user.module
index 3b9403c15..506c5d28e 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -186,6 +186,14 @@ function user_load($array = array()) {
while ($role = db_fetch_object($result)) {
$user->roles[$role->rid] = $role->name;
}
+
+ if (!empty($user->picture) && ($file = file_load($user->picture))) {
+ $user->picture = $file;
+ }
+ else {
+ $user->picture = NULL;
+ }
+
user_module_invoke('load', $array, $user);
}
else {
@@ -254,6 +262,23 @@ function user_save($account, $edit = array(), $category = 'account') {
}
}
+
+ // Process picture uploads.
+ if (!empty($edit['picture']->fid)) {
+ $picture = $edit['picture'];
+ // If the picture is a temporary file move it to its final location and
+ // make it permanent.
+ if (($picture->status & FILE_STATUS_PERMANENT) == 0) {
+ $info = image_get_info($picture->filepath);
+ $destination = file_create_path(variable_get('user_picture_path', 'pictures') . '/picture-' . $account->uid . '.' . $info['extension']);
+ if ($picture = file_move($picture, $destination, FILE_EXISTS_REPLACE)) {
+ $picture->status |= FILE_STATUS_PERMANENT;
+ $edit['picture'] = file_save($picture);
+ }
+ }
+ }
+ $edit['picture'] = empty($edit['picture']->fid) ? 0 : $edit['picture']->fid;
+
$edit['data'] = $data;
$edit['uid'] = $account->uid;
// Save changes to the users table.
@@ -263,6 +288,13 @@ function user_save($account, $edit = array(), $category = 'account') {
return FALSE;
}
+ // If the picture changed or was unset, remove the old one. This step needs
+ // to occur after updating the {users} record so that user_file_references()
+ // doesn't report it in use and block the deletion.
+ if (!empty($account->picture->fid) && ($edit['picture'] != $account->picture->fid)) {
+ file_delete($account->picture);
+ }
+
// Reload user roles if provided.
if (isset($edit['roles']) && is_array($edit['roles'])) {
db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);
@@ -405,23 +437,14 @@ function user_validate_picture(&$form, &$form_state) {
'file_validate_image_resolution' => array(variable_get('user_picture_dimensions', '85x85')),
'file_validate_size' => array(variable_get('user_picture_file_size', '30') * 1024),
);
- if ($file = file_save_upload('picture_upload', $validators)) {
- // Remove the old picture.
- if (isset($form_state['values']['_account']->picture) && file_exists($form_state['values']['_account']->picture)) {
- file_unmanaged_delete($form_state['values']['_account']->picture);
- }
- // The image was saved using file_save_upload() and was added to the
- // files table as a temporary file. We'll make a copy and let the garbage
- // collector delete the original upload.
- $info = image_get_info($file->filepath);
- $destination = file_create_path(variable_get('user_picture_path', 'pictures') . '/picture-' . $form['#uid'] . '.' . $info['extension']);
- if ($filepath = file_unmanaged_copy($file->filepath, $destination, FILE_EXISTS_REPLACE)) {
- $form_state['values']['picture'] = $filepath;
- }
- else {
- form_set_error('picture_upload', t("Failed to upload the picture image; the %directory directory doesn't exist or is not writable.", array('%directory' => variable_get('user_picture_path', 'pictures'))));
- }
+ // Save the file as a temporary file.
+ $file = file_save_upload('picture_upload', $validators);
+ if ($file === FALSE) {
+ form_set_error('picture_upload', t("Failed to upload the picture image; the %directory directory doesn't exist or is not writable.", array('%directory' => variable_get('user_picture_path', 'pictures'))));
+ }
+ elseif ($file !== NULL) {
+ $form_state['values']['picture_upload'] = $file;
}
}
@@ -604,14 +627,37 @@ function user_perm() {
*
* Ensure that user pictures (avatars) are always downloadable.
*/
-function user_file_download($file) {
- if (strpos($file, variable_get('user_picture_path', 'pictures') . '/picture-') === 0) {
- $info = image_get_info(file_create_path($file));
+function user_file_download($filepath) {
+ if (strpos($filepath, variable_get('user_picture_path', 'pictures') . '/picture-') === 0) {
+ $info = image_get_info(file_create_path($filepath));
return array('Content-type: ' . $info['mime_type']);
}
}
/**
+ * Implementation of hook_file_references().
+ */
+function user_file_references($file) {
+ // Determine if the file is used by this module.
+ $count = db_query('SELECT COUNT(*) FROM {users} WHERE picture = :fid', array(':fid' => $file->fid))->fetchField();
+ if ($count) {
+ // Return the name of the module and how many references it has to the file.
+ return array('user' => $count);
+ }
+}
+
+/**
+ * Implementation of hook_file_delete().
+ */
+function user_file_delete($file) {
+ // Remove any references to the file.
+ db_update('users')
+ ->fields(array('picture' => 0))
+ ->condition('picture', $file->fid)
+ ->execute();
+}
+
+/**
* Implementation of hook_search().
*/
function user_search($op = 'search', $keys = NULL, $skip_access_check = FALSE) {
@@ -688,7 +734,7 @@ function user_user_form(&$edit, &$account, $category = NULL) {
}
/**
- * Implementation of hook_user_validate.
+ * Implementation of hook_user_validate().
*/
function user_user_validate(&$edit, &$account, $category = NULL) {
if ($category == 'account') {
@@ -714,17 +760,21 @@ function user_user_validate(&$edit, &$account, $category = NULL) {
}
/**
- * Implementation of hook_user_submit.
+ * Implementation of hook_user_submit().
*/
function user_user_submit(&$edit, &$account, $category = NULL) {
if ($category == 'account') {
+ if (!empty($edit['picture_upload'])) {
+ $edit['picture'] = $edit['picture_upload'];
+ }
// Delete picture if requested, and if no replacement picture was given.
- if (!empty($edit['picture_delete'])) {
- if ($account->picture && file_exists($account->picture)) {
- file_unmanaged_delete($account->picture);
- }
- $edit['picture'] = '';
+ elseif (!empty($edit['picture_delete'])) {
+ $edit['picture'] = NULL;
}
+ // Remove these values so they don't end up serialized in the data field.
+ $edit['picture_upload'] = NULL;
+ $edit['picture_delete'] = NULL;
+
if (isset($edit['roles'])) {
$edit['roles'] = array_filter($edit['roles']);
}
@@ -914,7 +964,8 @@ function user_block_view($delta = '') {
* Process variables for user-picture.tpl.php.
*
* The $variables array contains the following arguments:
- * - $account
+ * - $account: A user, node or comment object with 'name', 'uid' and 'picture'
+ * fields.
*
* @see user-picture.tpl.php
*/
@@ -922,16 +973,27 @@ function template_preprocess_user_picture(&$variables) {
$variables['picture'] = '';
if (variable_get('user_pictures', 0)) {
$account = $variables['account'];
- if (!empty($account->picture) && file_exists($account->picture)) {
- $picture = file_create_url($account->picture);
+ if (!empty($account->picture)) {
+ // @TODO: Ideally this function would only be passed file objects, but
+ // since there's a lot of legacy code that JOINs the {users} table to
+ // {node} or {comments} and passes the results into this function if we
+ // a numeric value in the picture field we'll assume it's a file id
+ // and load it for them. Once we've got user_load_multiple() and
+ // comment_load_multiple() functions the user module will be able to load
+ // the picture files in mass during the object's load process.
+ if (is_numeric($account->picture)) {
+ $account->picture = file_load($account->picture);
+ }
+ if (!empty($account->picture->filepath)) {
+ $filepath = $account->picture->filepath;
+ }
}
elseif (variable_get('user_picture_default', '')) {
- $picture = variable_get('user_picture_default', '');
+ $filepath = variable_get('user_picture_default', '');
}
-
- if (isset($picture)) {
+ if (isset($filepath)) {
$alt = t("@user's picture", array('@user' => $account->name ? $account->name : variable_get('anonymous', t('Anonymous'))));
- $variables['picture'] = theme('image', $picture, $alt, $alt, '', FALSE);
+ $variables['picture'] = theme('image', $filepath, $alt, $alt, '', FALSE);
if (!empty($account->uid) && user_access('access user profiles')) {
$attributes = array('attributes' => array('title' => t('View user profile.')), 'html' => TRUE);
$variables['picture'] = l($variables['picture'], "user/$account->uid", $attributes);
@@ -1616,16 +1678,30 @@ function user_edit_form(&$form_state, $uid, $edit, $register = FALSE) {
// Picture/avatar:
if (variable_get('user_pictures', 0) && !$register) {
- $form['picture'] = array('#type' => 'fieldset', '#title' => t('Picture'), '#weight' => 1);
- $picture = theme('user_picture', (object)$edit);
- if ($edit['picture']) {
- $form['picture']['current_picture'] = array('#markup' => $picture);
- $form['picture']['picture_delete'] = array('#type' => 'checkbox', '#title' => t('Delete picture'), '#description' => t('Check this box to delete your current picture.'));
- }
- else {
- $form['picture']['picture_delete'] = array('#type' => 'hidden');
- }
- $form['picture']['picture_upload'] = array('#type' => 'file', '#title' => t('Upload picture'), '#size' => 48, '#description' => 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', ''));
+ $form['picture'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Picture'),
+ '#weight' => 1,
+ );
+ $form['picture']['picture'] = array(
+ '#type' => 'value',
+ '#value' => $edit['picture'],
+ );
+ $form['picture']['picture_current'] = array(
+ '#markup' => theme('user_picture', (object)$edit),
+ );
+ $form['picture']['picture_delete'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Delete picture'),
+ '#access' => !empty($edit['picture']->fid),
+ '#description' => t('Check this box to delete your current picture.'),
+ );
+ $form['picture']['picture_upload'] = array(
+ '#type' => 'file',
+ '#title' => t('Upload picture'),
+ '#size' => 48,
+ '#description' => 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', ''),
+ );
$form['#validate'][] = 'user_validate_picture';
}
$form['#uid'] = $uid;
diff --git a/modules/user/user.test b/modules/user/user.test
index 90336a23a..22dea39b1 100644
--- a/modules/user/user.test
+++ b/modules/user/user.test
@@ -418,7 +418,7 @@ class UserCancelTestCase extends DrupalWebTestCase {
// Create a regular user.
$account = $this->drupalCreateUser(array());
-
+
// Create administrative user.
$admin_user = $this->drupalCreateUser(array('administer users'));
$this->drupalLogin($admin_user);
@@ -547,7 +547,8 @@ class UserPictureTestCase extends DrupalWebTestCase {
// user's profile page.
$text = t('The image was resized to fit within the maximum allowed dimensions of %dimensions pixels.', array('%dimensions' => $test_dim));
$this->assertRaw($text, t('Image was resized.'));
- $this->assertRaw(file_create_url($pic_path), t("Image is displayed in user's profile page"));
+ $alt = t("@user's picture", array('@user' => $this->user->name));
+ $this->assertRaw(theme('image', $pic_path, $alt, $alt, '', FALSE), t("Image is displayed in user's profile page"));
// Check if file is located in proper directory.
$this->assertTrue(is_file($pic_path), t("File is located in proper directory"));