diff --git a/actions/avatarsettings.php b/actions/avatarsettings.php index 663a14ae3a..77c6681c3c 100644 --- a/actions/avatarsettings.php +++ b/actions/avatarsettings.php @@ -109,8 +109,6 @@ class AvatarsettingsAction extends SettingsAction return; } - $original = $profile->getOriginalAvatar(); - $this->elementStart('form', array('enctype' => 'multipart/form-data', 'method' => 'post', 'id' => 'form_settings_avatar', @@ -124,7 +122,9 @@ class AvatarsettingsAction extends SettingsAction if (Event::handle('StartAvatarFormData', array($this))) { $this->elementStart('ul', 'form_data'); - if ($original) { + try { + $original = Avatar::getOriginal($profile); + $this->elementStart('li', array('id' => 'avatar_original', 'class' => 'avatar_view')); // TRANS: Header on avatar upload page for thumbnail of originally uploaded avatar (h2). @@ -136,6 +136,8 @@ class AvatarsettingsAction extends SettingsAction 'alt' => $user->nickname)); $this->elementEnd('div'); $this->elementEnd('li'); + } catch (NoResultException $e) { + // No original avatar found! } $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); @@ -195,8 +197,6 @@ class AvatarsettingsAction extends SettingsAction return; } - $original = $profile->getOriginalAvatar(); - $this->elementStart('form', array('method' => 'post', 'id' => 'form_settings_avatar', 'class' => 'form_settings', @@ -402,14 +402,7 @@ class AvatarsettingsAction extends SettingsAction $user = common_current_user(); $profile = $user->getProfile(); - $avatar = $profile->getOriginalAvatar(); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); - if($avatar) $avatar->delete(); + Avatar::deleteFromProfile($profile); // TRANS: Success message for deleting a user avatar. $this->showForm(_('Avatar deleted.'), true); diff --git a/actions/foaf.php b/actions/foaf.php index 77e27796db..7f76c222cb 100644 --- a/actions/foaf.php +++ b/actions/foaf.php @@ -141,7 +141,7 @@ class FoafAction extends Action $this->elementEnd('based_near'); } - $avatar = $this->profile->getOriginalAvatar(); + $avatar = Avatar::getOriginal($this->profile); if ($avatar) { $this->elementStart('img'); $this->elementStart('Image', array('rdf:about' => $avatar->url)); diff --git a/classes/Avatar.php b/classes/Avatar.php index aed6ea0dd2..40f9bc6bc9 100644 --- a/classes/Avatar.php +++ b/classes/Avatar.php @@ -59,6 +59,30 @@ class Avatar extends Managed_DataObject } } + public static function deleteFromProfile(Profile $target) { + $avatars = Avatar::getProfileAvatars($target->id); + foreach ($avatars as $avatar) { + $avatar->delete(); + } + } + + public static function getOriginal(Profile $target) + { + $avatar = new Avatar(); + $avatar->profile_id = $target->id; + $avatar->original = true; + if (!$avatar->find(true)) { + throw new NoResultException($avatar); + } + return $avatar; + } + + public static function getProfileAvatars(Profile $target) { + $avatar = new Avatar(); + $avatar->profile_id = $target->id; + return $avatar->fetchAll(); + } + /** * Where should the avatar go for this user? */ @@ -133,4 +157,32 @@ class Avatar extends Managed_DataObject AVATAR_MINI_SIZE => 'mini'); return Theme::path('default-avatar-'.$sizenames[$size].'.png'); } + + static function newSize(Profile $target, $size) { + $size = floor($size); + if ($size <1 || $size > 999) { + // TRANS: An error message when avatar size is unreasonable + throw new Exception(_m('Unreasonable avatar size')); + } + + $original = Avatar::getOriginal($target); + + $imagefile = new ImageFile($target->id, Avatar::path($original->filename)); + $filename = $imagefile->resize($size); + + $scaled = clone($original); + $scaled->original = false; + $scaled->width = $size; + $scaled->height = $size; + $scaled->url = Avatar::url($filename); + $scaled->created = DB_DataObject_Cast::dateTime(); + + if (!$scaled->insert()) { + // TRANS: An error message when unable to insert avatar data into the db + throw new Exception(_m('Could not insert new avatar data to database')); + } + + // Return the new avatar object + return $scaled; + } } diff --git a/classes/Profile.php b/classes/Profile.php index 79eb00d22a..5d8e46a741 100644 --- a/classes/Profile.php +++ b/classes/Profile.php @@ -118,7 +118,7 @@ class Profile extends Managed_DataObject protected $_avatars; - function getAvatar($width, $height=null) + public function getAvatar($width, $height=null) { if (is_null($height)) { $height = $width; @@ -127,7 +127,6 @@ class Profile extends Managed_DataObject $avatar = $this->_getAvatar($width); if (empty($avatar)) { - if (Event::handle('StartProfileGetAvatar', array($this, $width, &$avatar))) { $avatar = Avatar::pkeyGet( array( @@ -139,6 +138,17 @@ class Profile extends Managed_DataObject Event::handle('EndProfileGetAvatar', array($this, $width, &$avatar)); } + // if-empty within an if-empty? Let's find a prettier solution... + if (empty($avatar)) { + // Obviously we can't find an avatar, so let's resize the original! + try { + $avatar = Avatar::newSize($this, $width); + } catch (Exception $e) { + // Could not generate a resized avatar. How do we handle it? + } + } + + // cache the avatar for future use $this->_fillAvatar($width, $avatar); } @@ -164,21 +174,18 @@ class Profile extends Managed_DataObject return null; } - function _fillAvatar($width, $avatar) + protected function _fillAvatar($width, Avatar $avatar) { - //common_debug("Storing avatar of width: {$avatar->width} and profile_id {$avatar->profile_id} in profile {$this->id}."); - $this->_avatars[$width] = $avatar; - + // This avoids storing null values, a problem report in issue #3478 + $this->_avatars[$width] = $avatar; } - function getOriginalAvatar() + // For backwards compatibility only! + public function getOriginalAvatar() { - $pkey = array('profile_id' => $this->id, - 'original' => true); - $avatar = Avatar::pkeyGet($pkey); - if (!empty($avatar)) { - return $avatar; - } else { + try { + return Avatar::getOriginal($this); + } catch (Exception $e) { return null; } } @@ -207,21 +214,10 @@ class Profile extends Managed_DataObject 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)) { - $scaled_filename = $imagefile->resize($size); - - //$scaled = DB_DataObject::factory('avatar'); - $scaled = new Avatar(); - $scaled->profile_id = $this->id; - $scaled->width = $size; - $scaled->height = $size; - $scaled->original = false; - $scaled->mediatype = image_type_to_mime_type($imagefile->type); - $scaled->filename = $scaled_filename; - $scaled->url = Avatar::url($scaled_filename); - $scaled->created = DB_DataObject_Cast::dateTime(); # current time - - if (!$scaled->insert()) { - return null; + try { + Avatar::newSize($this, $size); + } catch (Exception $e) { + // should we abort the generation and live without smaller avatars? } } } diff --git a/lib/activityobject.php b/lib/activityobject.php index ad7e636696..0b29888083 100644 --- a/lib/activityobject.php +++ b/lib/activityobject.php @@ -459,10 +459,11 @@ class ActivityObject $object->title = $profile->getBestName(); $object->link = $profile->profileurl; - $orig = $profile->getOriginalAvatar(); - - if (!empty($orig)) { + try { + $orig = Avatar::getOriginal($profile); $object->avatarLinks[] = AvatarLink::fromAvatar($orig); + } catch (Exception $e) { + // Could not find an original avatar to link } $sizes = array( diff --git a/plugins/OMB/lib/omboauthdatastore.php b/plugins/OMB/lib/omboauthdatastore.php index 857748bf4a..9603986ba7 100644 --- a/plugins/OMB/lib/omboauthdatastore.php +++ b/plugins/OMB/lib/omboauthdatastore.php @@ -289,14 +289,7 @@ class OMBOAuthDataStore extends OAuthDataStore throw new Exception(_('Error inserting avatar.')); } } else { - $avatar = $profile->getOriginalAvatar(); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); - if($avatar) $avatar->delete(); - $avatar = $profile->getAvatar(AVATAR_MINI_SIZE); - if($avatar) $avatar->delete(); + Avatar::deleteFromProfile($profile); } if ($exists) {