From 56021d95721c06b618dac6272e58d22a3e87037f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 5 Jun 2008 15:37:08 -0400 Subject: [PATCH] move avatar scaling and saving to Avatar and Profile Extracted the code for setting a new original avatar to the Profile class, and moved some of it to Avatar, too. This makes it easier to have the same functionality whether an avatar is set using the profile settings (for our users), or on a remote subscription. Necessitated changing the filenaming function to just take an ID. darcs-hash:20080605193708-84dde-a441cc0474951ce7f1a1da9310b5145c0b7c3070.gz --- actions/avatar.php | 111 ++---------------------------- actions/finishremotesubscribe.php | 8 ++- actions/userauthorization.php | 44 +----------- classes/Avatar.php | 68 +++++++++++++++++- classes/Profile.php | 73 ++++++++++++++++++-- lib/util.php | 6 +- 6 files changed, 151 insertions(+), 159 deletions(-) diff --git a/actions/avatar.php b/actions/avatar.php index 9c736cd3b6..ffd003f749 100644 --- a/actions/avatar.php +++ b/actions/avatar.php @@ -104,114 +104,15 @@ class AvatarAction extends SettingsAction { } $user = common_current_user(); - - $filename = common_avatar_filename($user, image_type_to_extension($info[2]), NULL, common_timestamp()); - $filepath = common_avatar_path($filename); - - if (!move_uploaded_file($_FILES['avatarfile']['tmp_name'], $filepath)) { - @unlink($_FILES['avatarfile']['tmp_name']); - $this->show_form(_t('System error uploading file.')); - return; - } - - $avatar = DB_DataObject::factory('avatar'); - - $avatar->profile_id = $user->id; - $avatar->width = $info[0]; - $avatar->height = $info[1]; - $avatar->mediatype = image_type_to_mime_type($info[2]); - $avatar->filename = $filename; - $avatar->original = true; - $avatar->url = common_avatar_url($filename); - $avatar->created = DB_DataObject_Cast::dateTime(); # current time - - foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) { - # We don't need a scaled one if the original is already of that size! - if ($avatar->width != $size && $avatar->height != $size) { - $scaled[] = $this->scale_avatar($user, $avatar, $size); - } - } - - # XXX: start a transaction here - - if (!$this->delete_old_avatars($user)) { - @unlink($filepath); - common_server_error(_t('Error deleting old avatars.')); - return; - } - if (!$avatar->insert()) { - @unlink($filepath); - common_server_error(_t('Error inserting avatar.')); - return; - } - - foreach ($scaled as $s) { - if (!$s->insert()) { - common_server_error(_t('Error inserting scaled avatar.')); - return; - } - } - - # XXX: end transaction here - - $this->show_form(_t('Avatar updated.'), true); - } - - function scale_avatar($user, $avatar, $size) { - $image_s = imagecreatetruecolor($size, $size); - $image_a = $this->avatar_to_image($avatar); - - $square = min($avatar->width, $avatar->height); - - imagecopyresampled($image_s, $image_a, 0, 0, 0, 0, - $size, $size, $square, $square); - - $ext = ($avatar->mediattype == 'image/jpeg') ? ".jpeg" : ".png"; - - $filename = common_avatar_filename($user, $ext, $size, common_timestamp()); - - if ($avatar->mediatype == 'image/jpeg') { - imagejpeg($image_s, common_avatar_path($filename)); + $profile = $user->getProfile(); + + if ($profile->setOriginal($_FILES['avatarfile']['tmp_name'])) { + $this->show_form(_t('Avatar updated.'), true); } else { - imagepng($image_s, common_avatar_path($filename)); + $this->show_form(_t('Failed updating avatar.')); } - $scaled = DB_DataObject::factory('avatar'); - $scaled->profile_id = $avatar->profile_id; - $scaled->width = $size; - $scaled->height = $size; - $scaled->original = false; - $scaled->mediatype = ($avatar->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png'; - $scaled->filename = $filename; - $scaled->url = common_avatar_url($filename); - $scaled->created = DB_DataObject_Cast::dateTime(); # current time - - return $scaled; - } - - function avatar_to_image($avatar) { - $filepath = common_avatar_path($avatar->filename); - if ($avatar->mediatype == 'image/gif') { - return imagecreatefromgif($filepath); - } else if ($avatar->mediatype == 'image/jpeg') { - return imagecreatefromjpeg($filepath); - } else if ($avatar->mediatype == 'image/png') { - return imagecreatefrompng($filepath); - } else { - common_server_error(_t('Unsupported image type:') . $avatar->mediatype); - return NULL; - } - } - - function delete_old_avatars($user) { - $avatar = DB_DataObject::factory('avatar'); - $avatar->profile_id = $user->id; - $avatar->find(); - while ($avatar->fetch()) { - unlink(common_avatar_path($avatar->filename)); - $avatar->delete(); - } - return true; + @unlink($_FILES['avatarfile']['tmp_name']); } } diff --git a/actions/finishremotesubscribe.php b/actions/finishremotesubscribe.php index 41bc91afd8..fa9aa539fd 100644 --- a/actions/finishremotesubscribe.php +++ b/actions/finishremotesubscribe.php @@ -140,7 +140,7 @@ class FinishremotesubscribeAction extends Action { } if ($avatar_url) { - $this->add_avatar($avatar_url); + $this->add_avatar($profile, $avatar_url); } $remote->postnoticeurl = $omb[OMB_ENDPOINT_POSTNOTICE]; @@ -175,6 +175,12 @@ class FinishremotesubscribeAction extends Action { $user->nickname))); } + function add_avatar($profile, $url) { + $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); + copy($url, $temp_filename); + return $profile->setOriginal($temp_filename); + } + function access_token($omb) { $con = omb_oauth_consumer(); diff --git a/actions/userauthorization.php b/actions/userauthorization.php index 94d92ea771..87040adad0 100644 --- a/actions/userauthorization.php +++ b/actions/userauthorization.php @@ -257,7 +257,7 @@ class UserauthorizationAction extends Action { } if ($avatar_url) { - $this->add_avatar($profile->id, $avatar_url); + $this->add_avatar($profile, $avatar_url); } $user = common_current_user(); @@ -278,47 +278,9 @@ class UserauthorizationAction extends Action { } function add_avatar($profile, $url) { - $temp_filename = tempnam(sys_get_temp_dir(), 'ombavatar'); + $temp_filename = tempnam(sys_get_temp_dir(), 'listenee_avatar'); copy($url, $temp_filename); - $info = @getimagesize($temp_filename); - $filename = common_avatar_filename($profile, image_type_to_extension($info[2]), NULL, common_timestamp()); - $filepath = common_avatar_path($filename); - copy($temp_filename, $filename); - - $avatar = DB_DataObject::factory('avatar'); - - $avatar->profile_id = $profile->id; - $avatar->width = $info[0]; - $avatar->height = $info[1]; - $avatar->mediatype = image_type_to_mime_type($info[2]); - $avatar->filename = $filename; - $avatar->original = true; - $avatar->url = common_avatar_url($filename); - $avatar->created = DB_DataObject_Cast::dateTime(); # current time - - foreach (array(AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) { - $scaled[] = $this->scale_avatar($user, $avatar, $size); - } - - # XXX: start a transaction here - - if (!$this->delete_old_avatars($user)) { - @unlink($filepath); - common_server_error(_t('Error deleting old avatars.')); - return; - } - if (!$avatar->insert()) { - @unlink($filepath); - common_server_error(_t('Error inserting avatar.')); - return; - } - - foreach ($scaled as $s) { - if (!$s->insert()) { - common_server_error(_t('Error inserting scaled avatar.')); - return; - } - } + return $profile->setOriginal($temp_filename); } function show_accept_message($tok) { diff --git a/classes/Avatar.php b/classes/Avatar.php index 2e0e1f3fb5..ca2e0cbce4 100644 --- a/classes/Avatar.php +++ b/classes/Avatar.php @@ -4,18 +4,18 @@ */ require_once 'DB/DataObject.php'; -class Avatar extends DB_DataObject +class Avatar extends DB_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ public $__table = 'avatar'; // table name public $profile_id; // int(4) primary_key not_null - public $original; // tinyint(1) + public $original; // tinyint(1) public $width; // int(4) primary_key not_null public $height; // int(4) primary_key not_null public $mediatype; // varchar(32) not_null - public $filename; // varchar(255) + public $filename; // varchar(255) public $url; // varchar(255) unique_key public $created; // datetime() not_null public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP @@ -25,4 +25,66 @@ class Avatar extends DB_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE + + # We clean up the file, too + + function delete() { + $filename = $this->filename; + if (parent::delete()) { + unlink(common_avatar_path($filename)); + } + } + + # Create and save scaled version of this avatar + # XXX: maybe break into different methods + + function scale($size) { + + $image_s = imagecreatetruecolor($size, $size); + $image_a = $this->to_image(); + + $square = min($this->width, $this->height); + + imagecopyresampled($image_s, $image_a, 0, 0, 0, 0, + $size, $size, $square, $square); + + $ext = ($this->mediattype == 'image/jpeg') ? ".jpeg" : ".png"; + + $filename = common_avatar_filename($this->profile_id, $ext, $size, common_timestamp()); + + if ($this->mediatype == 'image/jpeg') { + imagejpeg($image_s, common_avatar_path($filename)); + } else { + imagepng($image_s, common_avatar_path($filename)); + } + + $scaled = DB_DataObject::factory('avatar'); + $scaled->profile_id = $this->profile_id; + $scaled->width = $size; + $scaled->height = $size; + $scaled->original = false; + $scaled->mediatype = ($this->mediattype == 'image/jpeg') ? 'image/jpeg' : 'image/png'; + $scaled->filename = $filename; + $scaled->url = common_avatar_url($filename); + $scaled->created = DB_DataObject_Cast::dateTime(); # current time + + if ($scaled->insert()) { + return $scaled; + } else { + return NULL; + } + } + + function to_image() { + $filepath = common_avatar_path($this->filename); + if ($this->mediatype == 'image/gif') { + return imagecreatefromgif($filepath); + } else if ($this->mediatype == 'image/jpeg') { + return imagecreatefromjpeg($filepath); + } else if ($this->mediatype == 'image/png') { + return imagecreatefrompng($filepath); + } else { + return NULL; + } + } } diff --git a/classes/Profile.php b/classes/Profile.php index eb29d63a27..ff63bc79e0 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -24,7 +24,7 @@ if (!defined('LACONICA')) { exit(1); } */ require_once 'DB/DataObject.php'; -class Profile extends DB_DataObject +class Profile extends DB_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -32,11 +32,11 @@ class Profile extends DB_DataObject public $__table = 'profile'; // table name public $id; // int(4) primary_key not_null public $nickname; // varchar(64) not_null - public $fullname; // varchar(255) - public $profileurl; // varchar(255) - public $homepage; // varchar(255) - public $bio; // varchar(140) - public $location; // varchar(255) + public $fullname; // varchar(255) + public $profileurl; // varchar(255) + public $homepage; // varchar(255) + public $bio; // varchar(140) + public $location; // varchar(255) public $created; // datetime() not_null public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP @@ -72,4 +72,65 @@ class Profile extends DB_DataObject return NULL; } } + + static function setOriginal($source) { + + $info = @getimagesize($source); + + if (!$info) { + return NULL; + } + + $filename = common_avatar_filename($this, + image_type_to_extension($info[2]), + NULL, common_timestamp()); + $filepath = common_avatar_path($filename); + + copy($source, $filepath); + + $avatar = new Avatar(); + + $avatar->profile_id = $this->id; + $avatar->width = $info[0]; + $avatar->height = $info[1]; + $avatar->mediatype = image_type_to_mime_type($info[2]); + $avatar->filename = $filename; + $avatar->original = true; + $avatar->url = common_avatar_url($filename); + $avatar->created = DB_DataObject_Cast::dateTime(); # current time + + # XXX: start a transaction here + + if (!$this->delete_avatars()) { + @unlink($filepath); + return NULL; + } + + if (!$avatar->insert()) { + @unlink($filepath); + return NULL; + } + + foreach (array(AVATAR_PROFILE_SIZE, AVATAR_STREAM_SIZE, AVATAR_MINI_SIZE) as $size) { + # We don't do a scaled one if original is our scaled size + if (!($avatar->width == $size && $avatar->height == $size)) { + $s = $avatar->scale($size); + if (!$s) { + return NULL; + } + } + } + + return $avatar; + } + + function delete_avatars() { + $avatar = DB_DataObject::factory('avatar'); + $avatar->profile_id = $this->id; + $avatar->find(); + while ($avatar->fetch()) { + $avatar->delete(); + } + return true; + } } diff --git a/lib/util.php b/lib/util.php index 771a4880c6..298c5c5de1 100644 --- a/lib/util.php +++ b/lib/util.php @@ -403,13 +403,13 @@ function common_at_link($sender_id, $nickname) { // where should the avatar go for this user? -function common_avatar_filename($user, $extension, $size=NULL, $extra=NULL) { +function common_avatar_filename($id, $extension, $size=NULL, $extra=NULL) { global $config; if ($size) { - return $user->id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension; + return $id . '-' . $size . (($extra) ? ('-' . $extra) : '') . $extension; } else { - return $user->id . '-original' . (($extra) ? ('-' . $extra) : '') . $extension; + return $id . '-original' . (($extra) ? ('-' . $extra) : '') . $extension; } }