X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FAvatar.php;h=6a66228a0e417fb86ca156dd230128607f482258;hb=d6b28c64830f632bb2f4b6f3c9369b9e56ad217a;hp=bdf3739bbf86b6541853f7e2594cc4b330c7a9e5;hpb=8b32ac85d8cbfe1be03836af461d80fddd54fc6c;p=quix0rs-gnu-social.git diff --git a/classes/Avatar.php b/classes/Avatar.php index bdf3739bbf..6a66228a0e 100644 --- a/classes/Avatar.php +++ b/classes/Avatar.php @@ -4,7 +4,7 @@ */ require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; -class Avatar extends Memcached_DataObject +class Avatar extends Managed_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -15,36 +15,148 @@ class Avatar extends Memcached_DataObject 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 $url; // varchar(255) unique_key + public $filename; // varchar(191) not 255 because utf8mb4 takes more space + public $url; // varchar(191) unique_key not 255 because utf8mb4 takes more space public $created; // datetime() not_null public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP - /* Static get */ - function staticGet($k,$v=null) - { return Memcached_DataObject::staticGet('Avatar',$k,$v); } - /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - - static function pivotGet($keyCol, $keyVals, $otherCols) - { - return Memcached_DataObject::pivotGet('Avatar', $keyCol, $keyVals, $otherCols); - } - // We clean up the file, too + public static function schemaDef() + { + return array( + 'fields' => array( + 'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'), + 'original' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'uploaded by user or generated?'), + 'width' => array('type' => 'int', 'not null' => true, 'description' => 'image width'), + 'height' => array('type' => 'int', 'not null' => true, 'description' => 'image height'), + 'mediatype' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'file type'), + 'filename' => array('type' => 'varchar', 'length' => 191, 'description' => 'local filename, if local'), + 'url' => array('type' => 'text', 'description' => 'avatar location, not indexed - do not use in WHERE statement'), + 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), + 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'), + ), + 'primary key' => array('profile_id', 'width', 'height'), + 'unique keys' => array( +// 'avatar_filename_key' => array('filename'), + ), + 'foreign keys' => array( + 'avatar_profile_id_fkey' => array('profile', array('profile_id' => 'id')), + ), + 'indexes' => array( + 'avatar_profile_id_idx' => array('profile_id'), + ), + ); + } - function delete() + // We clean up the file, too + function delete($useWhere=false) { $filename = $this->filename; - if (parent::delete()) { + if (file_exists(Avatar::path($filename))) { @unlink(Avatar::path($filename)); } + + return parent::delete($useWhere); } - function pkeyGet($kv) + /* + * Deletes all avatars (but may spare the original) from a profile. + * + * @param Profile $target The profile we're deleting avatars of. + * @param boolean $original Whether original should be removed or not. + */ + public static function deleteFromProfile(Profile $target, $original=true) { + try { + $avatars = self::getProfileAvatars($target); + + foreach ($avatars as $avatar) { + assert($avatar instanceof Avatar); + + if ($avatar->original && !$original) { + continue; + } + + $avatar->delete(); + } + } catch (NoAvatarException $e) { + // There are no avatars to delete, a sort of success. + } + + return true; + } + + static protected $_avatars = array(); + + /* + * Get an avatar by profile. Currently can't call newSize with $height + */ + public static function byProfile(Profile $target, $width=null, $height=null) { - return Memcached_DataObject::pkeyGet('Avatar', $kv); + $width = intval($width); + $height = !is_null($height) ? intval($height) : null; + if (is_null($height)) { + $height = $width; + } + + $size = "{$width}x{$height}"; + + if (!isset(self::$_avatars[$target->id])) { + self::$_avatars[$target->id] = array(); + } elseif (isset(self::$_avatars[$target->id][$size])){ + return self::$_avatars[$target->id][$size]; + } + + $avatar = null; + + if (Event::handle('StartProfileGetAvatar', array($target, $width, &$avatar))) { + $avatar = self::pkeyGet( + array( + 'profile_id' => $target->id, + 'width' => $width, + 'height' => $height, + ) + ); + + Event::handle('EndProfileGetAvatar', array($target, $width, &$avatar)); + } + + if (is_null($avatar)) { + // Obviously we can't find an avatar, so let's resize the original! + $avatar = Avatar::newSize($target, $width); + } elseif (!($avatar instanceof Avatar)) { + throw new NoAvatarException($target, $avatar); + } + + self::$_avatars[$target->id]["{$avatar->width}x{$avatar->height}"] = $avatar; + return $avatar; + } + + public static function getUploaded(Profile $target) + { + $avatar = new Avatar(); + $avatar->profile_id = $target->id; + $avatar->original = true; + if (!$avatar->find(true)) { + throw new NoAvatarException($target, $avatar); + } + if (!file_exists(Avatar::path($avatar->filename))) { + // The delete call may be odd for, say, unmounted filesystems + // that cause a file to currently not exist, but actually it does... + $avatar->delete(); + throw new NoAvatarException($target, $avatar); + } + return $avatar; + } + + public static function getProfileAvatars(Profile $target) { + $avatar = new Avatar(); + $avatar->profile_id = $target->id; + if (!$avatar->find()) { + throw new NoAvatarException($target, $avatar); + } + return $avatar->fetchAll(); } /** @@ -79,7 +191,7 @@ class Avatar extends Memcached_DataObject } if ($path[0] != '/') { - $path = '/'.$path; + $path = '/' . $path; } $server = common_config('avatar', 'server'); @@ -114,11 +226,59 @@ class Avatar extends Memcached_DataObject } } + static function urlByProfile(Profile $target, $width=null, $height=null) { + try { + return self::byProfile($target, $width, $height)->displayUrl(); + } catch (Exception $e) { + common_debug(sprintf('target=>id=%s,width=%s,height=%s,message=%s', + $target->id, + $width, + $height, + $e->getMessage() + )); + return self::defaultImage($width); + } + } + static function defaultImage($size) { static $sizenames = array(AVATAR_PROFILE_SIZE => 'profile', AVATAR_STREAM_SIZE => 'stream', AVATAR_MINI_SIZE => 'mini'); - return Theme::path('default-avatar-'.$sizenames[$size].'.png'); + return Theme::path('default-avatar-' . $sizenames[$size] . '.png'); + } + + static function newSize(Profile $target, $width) { + $width = intval($width); + if ($width < 1 || $width > common_config('avatar', 'maxsize')) { + // TRANS: An error message when avatar size is unreasonable + throw new Exception(_m('Avatar size too large')); + } + // So far we only have square avatars and I don't have time to + // rewrite support for non-square ones right now ;) + $height = $width; + + $original = Avatar::getUploaded($target); + + $imagefile = new ImageFile(null, Avatar::path($original->filename)); + $filename = Avatar::filename($target->getID(), image_type_to_extension($imagefile->preferredType()), + $width, common_timestamp()); + $imagefile->resizeTo(Avatar::path($filename), array('width'=>$width, 'height'=>$height)); + + $scaled = clone($original); + $scaled->original = false; + $scaled->width = $width; + $scaled->height = $height; + $scaled->url = Avatar::url($filename); + $scaled->filename = $filename; + $scaled->created = common_sql_now(); + + 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; } }