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
This commit is contained in:
Evan Prodromou 2008-06-05 15:37:08 -04:00
parent dcc915bd93
commit 56021d9572
6 changed files with 151 additions and 159 deletions

View File

@ -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']);
}
}

View File

@ -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();

View File

@ -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) {

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}