function delete() { $filename = $this->filename; if (parent::delete()) { @unlink(Avatar::path($filename)); } }
function setOriginal($filename) { $imagefile = new ImageFile($this->id, Avatar::path($filename)); $orig = clone $this; $this->original_logo = Avatar::url($filename); $this->homepage_logo = Avatar::url($imagefile->resize(AVATAR_PROFILE_SIZE)); $this->stream_logo = Avatar::url($imagefile->resize(AVATAR_STREAM_SIZE)); $this->mini_logo = Avatar::url($imagefile->resize(AVATAR_MINI_SIZE)); common_debug(common_log_objstring($this)); return $this->update($orig); }
function setOriginal($filename) { $imagefile = new ImageFile($this->id, Avatar::path($filename)); $avatar = new Avatar(); $avatar->profile_id = $this->id; $avatar->width = $imagefile->width; $avatar->height = $imagefile->height; $avatar->mediatype = image_type_to_mime_type($imagefile->type); $avatar->filename = $filename; $avatar->original = true; $avatar->url = Avatar::url($filename); $avatar->created = DB_DataObject_Cast::dateTime(); # current time # XXX: start a transaction here if (!$this->delete_avatars() || !$avatar->insert()) { @unlink(Avatar::path($filename)); 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)) { $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; } } } return $avatar; }
/** * Handle the request * * Check whether the credentials are valid and output the result * * @return void */ protected function handle() { parent::handle(); // Workaround for PHP returning empty $_POST and $_FILES when POST // length > post_max_size in php.ini if (empty($_FILES) && empty($_POST) && $_SERVER['CONTENT_LENGTH'] > 0) { // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. // TRANS: %s is the number of bytes of the CONTENT_LENGTH. $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', intval($_SERVER['CONTENT_LENGTH'])); $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); } if (empty($this->user)) { // TRANS: Client error displayed updating profile image without having a user object. $this->clientError(_('No such user.'), 404); } try { $imagefile = ImageFile::fromUpload('image'); } catch (Exception $e) { $this->clientError($e->getMessage()); } $type = $imagefile->preferredType(); $filename = Avatar::filename($user->id, image_type_to_extension($type), null, 'tmp' . common_timestamp()); $filepath = Avatar::path($filename); $imagefile->copyTo($filepath); $profile = $this->user->getProfile(); $profile->setOriginal($filename); $twitter_user = $this->twitterUserArray($profile, true); if ($this->format == 'xml') { $this->initDocument('xml'); $this->showTwitterXmlUser($twitter_user, 'user', true); $this->endDocument('xml'); } elseif ($this->format == 'json') { $this->initDocument('json'); $this->showJsonObjects($twitter_user); $this->endDocument('json'); } }
function setOriginal($filename) { // This should be handled by the Profile->setOriginal function so user and group avatars are handled the same $imagefile = new ImageFile(null, Avatar::path($filename)); $sizes = array('homepage_logo' => AVATAR_PROFILE_SIZE, 'stream_logo' => AVATAR_STREAM_SIZE, 'mini_logo' => AVATAR_MINI_SIZE); $orig = clone $this; $this->original_logo = Avatar::url($filename); foreach ($sizes as $name => $size) { $filename = Avatar::filename($this->profile_id, image_type_to_extension($imagefile->preferredType()), $size, common_timestamp()); $imagefile->resizeTo(Avatar::path($filename), array('width' => $size, 'height' => $size)); $this->{$name} = Avatar::url($filename); } common_debug(common_log_objstring($this)); return $this->update($orig); }
/** * Handle an image upload * * Does all the magic for handling an image upload, and crops the * image by default. * * @return void */ function uploadLogo() { try { $imagefile = ImageFile::fromUpload('avatarfile'); } catch (Exception $e) { $this->showForm($e->getMessage()); return; } $type = $imagefile->preferredType(); $filename = Avatar::filename($this->group->id, image_type_to_extension($type), null, 'group-temp-' . common_timestamp()); $filepath = Avatar::path($filename); $imagefile->copyTo($filepath); $filedata = array('filename' => $filename, 'filepath' => $filepath, 'width' => $imagefile->width, 'height' => $imagefile->height, 'type' => $type); $_SESSION['FILEDATA'] = $filedata; $this->filedata = $filedata; $this->mode = 'crop'; // TRANS: Form instructions on the group logo page. $this->showForm(_('Pick a square area of the image to be the logo.'), true); }
function resize($size, $x = 0, $y = 0, $w = null, $h = null) { $w = $w === null ? $this->width : $w; $h = $h === null ? $this->height : $h; if (!file_exists($this->filepath)) { throw new Exception(_('Lost our file.')); return; } // Don't crop/scale if it isn't necessary if ($size === $this->width && $size === $this->height && $x === 0 && $y === 0 && $w === $this->width && $h === $this->height) { $outname = Avatar::filename($this->id, image_type_to_extension($this->type), $size, common_timestamp()); $outpath = Avatar::path($outname); @copy($this->filepath, $outpath); return $outname; } switch ($this->type) { case IMAGETYPE_GIF: $image_src = imagecreatefromgif($this->filepath); break; case IMAGETYPE_JPEG: $image_src = imagecreatefromjpeg($this->filepath); break; case IMAGETYPE_PNG: $image_src = imagecreatefrompng($this->filepath); break; case IMAGETYPE_BMP: $image_src = imagecreatefrombmp($this->filepath); break; case IMAGETYPE_WBMP: $image_src = imagecreatefromwbmp($this->filepath); break; case IMAGETYPE_XBM: $image_src = imagecreatefromxbm($this->filepath); break; default: throw new Exception(_('Unknown file type')); return; } $image_dest = imagecreatetruecolor($size, $size); if ($this->type == IMAGETYPE_GIF || $this->type == IMAGETYPE_PNG || $this->type == IMAGETYPE_BMP) { $transparent_idx = imagecolortransparent($image_src); if ($transparent_idx >= 0) { $transparent_color = imagecolorsforindex($image_src, $transparent_idx); $transparent_idx = imagecolorallocate($image_dest, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']); imagefill($image_dest, 0, 0, $transparent_idx); imagecolortransparent($image_dest, $transparent_idx); } elseif ($this->type == IMAGETYPE_PNG) { imagealphablending($image_dest, false); $transparent = imagecolorallocatealpha($image_dest, 0, 0, 0, 127); imagefill($image_dest, 0, 0, $transparent); imagesavealpha($image_dest, true); } } imagecopyresampled($image_dest, $image_src, 0, 0, $x, $y, $size, $size, $w, $h); if ($this->type == IMAGETYPE_BMP) { //we don't want to save BMP... it's an inefficient, rare, antiquated format //save png instead $this->type = IMAGETYPE_PNG; } else { if ($this->type == IMAGETYPE_WBMP) { //we don't want to save WBMP... it's a rare format that we can't guarantee clients will support //save png instead $this->type = IMAGETYPE_PNG; } else { if ($this->type == IMAGETYPE_XBM) { //we don't want to save XBM... it's a rare format that we can't guarantee clients will support //save png instead $this->type = IMAGETYPE_PNG; } } } $outname = Avatar::filename($this->id, image_type_to_extension($this->type), $size, common_timestamp()); $outpath = Avatar::path($outname); switch ($this->type) { case IMAGETYPE_GIF: imagegif($image_dest, $outpath); break; case IMAGETYPE_JPEG: imagejpeg($image_dest, $outpath, 100); break; case IMAGETYPE_PNG: imagepng($image_dest, $outpath); break; default: throw new Exception(_('Unknown file type')); return; } imagedestroy($image_src); imagedestroy($image_dest); return $outname; }
/** * Fetch a remote avatar image and save to local storage. * * @param string $url avatar source URL * @param string $filename bare local filename for download * @return bool true on success, false on failure */ function fetchAvatar($url, $filename) { common_debug($this->name() . " - Fetching Twitter avatar: {$url}"); $request = HTTPClient::start(); $response = $request->get($url); if ($response->isOk()) { $avatarfile = Avatar::path($filename); $ok = file_put_contents($avatarfile, $response->getBody()); if (!$ok) { common_log(LOG_WARNING, $this->name() . " - Couldn't open file {$filename}"); return false; } } else { return false; } return true; }
/** * Download and update given avatar image * * @param string $url * @throws Exception in various failure cases */ protected function updateAvatar($url) { if ($url == $this->avatar) { // We've already got this one. return; } if (!common_valid_http_url($url)) { // TRANS: Server exception. %s is a URL. throw new ServerException(sprintf(_m('Invalid avatar URL %s.'), $url)); } if ($this->isGroup()) { $self = $this->localGroup(); } else { $self = $this->localProfile(); } if (!$self) { throw new ServerException(sprintf(_m('Tried to update avatar for unsaved remote profile %s.'), $this->uri)); } // @todo FIXME: This should be better encapsulated // ripped from oauthstore.php (for old OMB client) $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); try { if (!copy($url, $temp_filename)) { // TRANS: Server exception. %s is a URL. throw new ServerException(sprintf(_m('Unable to fetch avatar from %s.'), $url)); } if ($this->isGroup()) { $id = $this->group_id; } else { $id = $this->profile_id; } // @todo FIXME: Should we be using different ids? $imagefile = new ImageFile($id, $temp_filename); $filename = Avatar::filename($id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); } catch (Exception $e) { unlink($temp_filename); throw $e; } // @todo FIXME: Hardcoded chmod is lame, but seems to be necessary to // keep from accidentally saving images from command-line (queues) // that can't be read from web server, which causes hard-to-notice // problems later on: // // http://status.net/open-source/issues/2663 chmod(Avatar::path($filename), 0644); $profile = $this->localProfile(); if (!empty($profile)) { $profile->setOriginal($filename); } $orig = clone $this; $this->avatar = $url; $this->update($orig); }
/** * Handle the results of jcrop. * * @return void */ public function cropAvatar() { $filedata = $_SESSION['FILEDATA']; if (!$filedata) { // TRANS: Server error displayed if an avatar upload went wrong somehow server side. $this->serverError(_('Lost our file data.')); } $file_d = $filedata['width'] > $filedata['height'] ? $filedata['height'] : $filedata['width']; $dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x') : 0; $dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y') : 0; $dest_w = $this->arg('avatar_crop_w') ? $this->arg('avatar_crop_w') : $file_d; $dest_h = $this->arg('avatar_crop_h') ? $this->arg('avatar_crop_h') : $file_d; $size = intval(min($dest_w, $dest_h, common_config('avatar', 'maxsize'))); $box = array('width' => $size, 'height' => $size, 'x' => $dest_x, 'y' => $dest_y, 'w' => $dest_w, 'h' => $dest_h); $user = common_current_user(); $profile = $user->getProfile(); $imagefile = new ImageFile(null, $filedata['filepath']); $filename = Avatar::filename($profile->getID(), image_type_to_extension($imagefile->preferredType()), $size, common_timestamp()); try { $imagefile->resizeTo(Avatar::path($filename), $box); } catch (UseFileAsThumbnailException $e) { common_debug('Using uploaded avatar directly without resizing, copying it to: ' . $filename); if (!copy($filedata['filepath'], Avatar::path($filename))) { common_debug('Tried to copy image file ' . $filedata['filepath'] . ' to destination ' . Avatar::path($filename)); throw new ServerException('Could not copy file to destination.'); } } if ($profile->setOriginal($filename)) { @unlink($filedata['filepath']); unset($_SESSION['FILEDATA']); $this->mode = 'upload'; // TRANS: Success message for having updated a user avatar. $this->showForm(_('Avatar updated.'), true); } else { // TRANS: Error displayed on the avatar upload page if the avatar could not be updated for an unknown reason. $this->showForm(_('Failed updating avatar.')); } }
/** * Compat interface for old code generating avatar thumbnails... * Saves the scaled file directly into the avatar area. * * @param int $size target width & height -- must be square * @param int $x (default 0) upper-left corner to crop from * @param int $y (default 0) upper-left corner to crop from * @param int $w (default full) width of image area to crop * @param int $h (default full) height of image area to crop * @return string filename */ function resize($size, $x = 0, $y = 0, $w = null, $h = null) { $targetType = $this->preferredType(); $outname = Avatar::filename($this->id, image_type_to_extension($targetType), $size, common_timestamp()); $outpath = Avatar::path($outname); $this->resizeTo($outpath, $size, $size, $x, $y, $w, $h); return $outname; }
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->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; }
/** * Actually save the avatar we found locally. * * @param User $user * @param string $url to avatar URL * @todo merge wrapper funcs for this into common place for 1.0 core */ private function saveAvatar($user, $url) { if (!common_valid_http_url($url)) { // TRANS: Server exception thrown when an avatar URL is invalid. // TRANS: %s is the invalid avatar URL. throw new ServerException(sprintf(_m('Invalid avatar URL %s.'), $url)); } // @todo FIXME: This should be better encapsulated // ripped from OStatus via oauthstore.php (for old OMB client) $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); try { if (!copy($url, $temp_filename)) { // TRANS: Exception thrown when fetching an avatar from a URL fails. // TRANS: %s is a URL. throw new ServerException(sprintf(_m('Unable to fetch avatar from %s.'), $url)); } $profile = $user->getProfile(); $id = $profile->id; $imagefile = new ImageFile(null, $temp_filename); $filename = Avatar::filename($id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); } catch (Exception $e) { unlink($temp_filename); throw $e; } $profile->setOriginal($filename); }
function update_profile($req, $consumer, $token) { $version = $req->get_parameter('omb_version'); if ($version != OMB_VERSION_01) { $this->clientError(_('Unsupported OMB version'), 400); return false; } # First, check to see if listenee exists $listenee = $req->get_parameter('omb_listenee'); $remote = Remote_profile::staticGet('uri', $listenee); if (!$remote) { $this->clientError(_('Profile unknown'), 404); return false; } # Second, check to see if they should be able to post updates! # We see if there are any subscriptions to that remote user with # the given token. $sub = new Subscription(); $sub->subscribed = $remote->id; $sub->token = $token->key; if (!$sub->find(true)) { $this->clientError(_('You did not send us that profile'), 403); return false; } $profile = Profile::staticGet('id', $remote->id); if (!$profile) { # This one is our fault $this->serverError(_('Remote profile with no matching profile'), 500); return false; } $nickname = $req->get_parameter('omb_listenee_nickname'); if ($nickname && !Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { $this->clientError(_('Nickname must have only lowercase letters and numbers and no spaces.')); return false; } $license = $req->get_parameter('omb_listenee_license'); if ($license && !common_valid_http_url($license)) { $this->clientError(sprintf(_("Invalid license URL '%s'"), $license)); return false; } $profile_url = $req->get_parameter('omb_listenee_profile'); if ($profile_url && !common_valid_http_url($profile_url)) { $this->clientError(sprintf(_("Invalid profile URL '%s'."), $profile_url)); return false; } # optional stuff $fullname = $req->get_parameter('omb_listenee_fullname'); if ($fullname && mb_strlen($fullname) > 255) { $this->clientError(_("Full name is too long (max 255 chars).")); return false; } $homepage = $req->get_parameter('omb_listenee_homepage'); if ($homepage && (!common_valid_http_url($homepage) || mb_strlen($homepage) > 255)) { $this->clientError(sprintf(_("Invalid homepage '%s'"), $homepage)); return false; } $bio = $req->get_parameter('omb_listenee_bio'); if ($bio && mb_strlen($bio) > 140) { $this->clientError(_("Bio is too long (max 140 chars).")); return false; } $location = $req->get_parameter('omb_listenee_location'); if ($location && mb_strlen($location) > 255) { $this->clientError(_("Location is too long (max 255 chars).")); return false; } $avatar = $req->get_parameter('omb_listenee_avatar'); if ($avatar) { if (!common_valid_http_url($avatar) || strlen($avatar) > 255) { $this->clientError(sprintf(_("Invalid avatar URL '%s'"), $avatar)); return false; } $size = @getimagesize($avatar); if (!$size) { $this->clientError(sprintf(_("Can't read avatar URL '%s'"), $avatar)); return false; } if ($size[0] != AVATAR_PROFILE_SIZE || $size[1] != AVATAR_PROFILE_SIZE) { $this->clientError(sprintf(_("Wrong size image at '%s'"), $avatar)); return false; } if (!in_array($size[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { $this->clientError(sprintf(_("Wrong image type for '%s'"), $avatar)); return false; } } $orig_profile = clone $profile; /* Use values even if they are an empty string. Parsing an empty string in updateProfile is the specified way of clearing a parameter in OMB. */ if (!is_null($nickname)) { $profile->nickname = $nickname; } if (!is_null($profile_url)) { $profile->profileurl = $profile_url; } if (!is_null($fullname)) { $profile->fullname = $fullname; } if (!is_null($homepage)) { $profile->homepage = $homepage; } if (!is_null($bio)) { $profile->bio = $bio; } if (!is_null($location)) { $profile->location = $location; } if (!$profile->update($orig_profile)) { $this->serverError(_('Could not save new profile info'), 500); return false; } else { if ($avatar) { $temp_filename = tempnam(sys_get_temp_dir(), 'listenee_avatar'); copy($avatar, $temp_filename); $imagefile = new ImageFile($profile->id, $temp_filename); $filename = Avatar::filename($profile->id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); if (!$profile->setOriginal($filename)) { $this->serverError(_('Could not save avatar info'), 500); return false; } } return true; } }
/** * Handle the request * * Check whether the credentials are valid and output the result * * @param array $args $_REQUEST data (unused) * * @return void */ function handle($args) { parent::handle($args); if ($_SERVER['REQUEST_METHOD'] != 'POST') { $this->clientError(_('This method requires a POST.'), 400, $this->format); return; } // Workaround for PHP returning empty $_POST and $_FILES when POST // length > post_max_size in php.ini if (empty($_FILES) && empty($_POST) && $_SERVER['CONTENT_LENGTH'] > 0) { // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. // TRANS: %s is the number of bytes of the CONTENT_LENGTH. $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', intval($_SERVER['CONTENT_LENGTH'])); $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); return; } if (empty($this->user)) { $this->clientError(_('No such user.'), 404, $this->format); return; } try { $imagefile = ImageFile::fromUpload('image'); } catch (Exception $e) { $this->clientError($e->getMessage(), 400, $this->format); return; } $filename = Avatar::filename($user->id, image_type_to_extension($imagefile->type), null, 'tmp' . common_timestamp()); $filepath = Avatar::path($filename); move_uploaded_file($imagefile->filepath, $filepath); $profile = $this->user->getProfile(); if (empty($profile)) { $this->clientError(_('User has no profile.')); return; } $profile->setOriginal($filename); common_broadcast_profile($profile); $twitter_user = $this->twitterUserArray($profile, true); if ($this->format == 'xml') { $this->initDocument('xml'); $this->showTwitterXmlUser($twitter_user); $this->endDocument('xml'); } elseif ($this->format == 'json') { $this->initDocument('json'); $this->showJsonObjects($twitter_user); $this->endDocument('json'); } }
/** * Handle an image upload * * Does all the magic for handling an image upload, and crops the * image by default. * * @return void */ function uploadAvatar() { try { $imagefile = ImageFile::fromUpload('avatarfile'); } catch (Exception $e) { $this->showForm($e->getMessage()); return; } if ($imagefile === null) { // TRANS: Validation error on avatar upload form when no file was uploaded. $this->showForm(_('No file uploaded.')); return; } $cur = common_current_user(); $type = $imagefile->preferredType(); $filename = Avatar::filename($cur->id, image_type_to_extension($type), null, 'tmp' . common_timestamp()); $filepath = Avatar::path($filename); $imagefile->copyTo($filepath); $filedata = array('filename' => $filename, 'filepath' => $filepath, 'width' => $imagefile->width, 'height' => $imagefile->height, 'type' => $type); $_SESSION['FILEDATA'] = $filedata; $this->filedata = $filedata; $this->mode = 'crop'; // TRANS: Avatar upload form instruction after uploading a file. $this->showForm(_('Pick a square area of the image to be your avatar.'), true); }
/** * Download and update given avatar image * * @param string $url * @param mixed $dest either a Profile or User_group object * @throws Exception in various failure cases */ private function saveAvatar($url, $dest) { // Yammer API data mostly gives us the small variant. // Try hitting the source image if we can! // @fixme no guarantee of this URL scheme I think. $url = preg_replace('/_small(\\..*?)$/', '$1', $url); if (!common_valid_http_url($url)) { throw new ServerException(sprintf(_m("Invalid avatar URL %s."), $url)); } // @fixme this should be better encapsulated // ripped from oauthstore.php (for old OMB client) $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); try { if (!copy($url, $temp_filename)) { throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url)); } $id = $dest->id; // @fixme should we be using different ids? $imagefile = new ImageFile($id, $temp_filename); $filename = Avatar::filename($id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); } catch (Exception $e) { unlink($temp_filename); throw $e; } // @fixme hardcoded chmod is lame, but seems to be necessary to // keep from accidentally saving images from command-line (queues) // that can't be read from web server, which causes hard-to-notice // problems later on: // // http://status.net/open-source/issues/2663 chmod(Avatar::path($filename), 0644); $dest->setOriginal($filename); }
protected function newAvatar(Profile $profile, $url, $filename, $mediatype) { // Clear out old avatars, won't do anything if there are none Avatar::deleteFromProfile($profile); // throws exception if unable to fetch $this->fetchRemoteUrl($url, Avatar::path($filename)); $avatar = new Avatar(); $avatar->profile_id = $profile->id; $avatar->original = 1; // this is an original/"uploaded" avatar $avatar->mediatype = $mediatype; $avatar->filename = $filename; $avatar->width = $this->avatarsize; $avatar->height = $this->avatarsize; $avatar->created = common_sql_now(); $id = $avatar->insert(); if (empty($id)) { common_log(LOG_WARNING, __METHOD__ . " Couldn't insert avatar - " . $e->getMessage()); common_log_db_error($avatar, 'INSERT', __FILE__); throw new ServerException('Could not insert avatar'); } common_debug(__METHOD__ . " - Saved new avatar for {$profile->id}."); return $avatar; }
/** * Handle the request * * @return void */ protected function handle() { parent::handle(); $profile = $this->user->getProfile(); $base64img = $this->img; if (stristr($base64img, 'image/jpeg')) { $base64img_mime = 'image/jpeg'; } elseif (stristr($base64img, 'image/png')) { // should convert to jpg here!! $base64img_mime = 'image/png'; } $base64img = str_replace('data:image/jpeg;base64,', '', $base64img); $base64img = str_replace('data:image/png;base64,', '', $base64img); $base64img = str_replace(' ', '+', $base64img); $base64img_hash = md5($base64img); $base64img = base64_decode($base64img); $base64img_basename = basename('avatar'); $base64img_filename = File::filename($profile, $base64img_basename, $base64img_mime); $base64img_path = File::path($base64img_filename); $base64img_success = file_put_contents($base64img_path, $base64img); $base64img_mimetype = MediaFile::getUploadedMimeType($base64img_path, $base64img_filename); $mediafile = new MediaFile($profile, $base64img_filename, $base64img_mimetype); $imagefile = new ImageFile($mediafile->fileRecord->id, File::path($mediafile->filename)); $imagefile->resizeTo(File::path($mediafile->filename), array('width' => $this->cropW, 'height' => $this->cropH, 'x' => $this->cropX, 'y' => $this->cropY, 'w' => $this->cropW, 'h' => $this->cropH)); $type = $imagefile->preferredType(); $filename = Avatar::filename($profile->id, image_type_to_extension($type), null, common_timestamp()); $filepath = Avatar::path($filename); $imagefile->copyTo($filepath); $profile = $this->user->getProfile(); $profile->setOriginal($filename); $mediafile->delete(); $twitter_user = $this->twitterUserArray($profile, true); $this->initDocument('json'); $this->showJsonObjects($twitter_user); $this->endDocument('json'); }
/** * Handle the results of jcrop. * * @return void */ function cropLogo() { $filedata = $_SESSION['FILEDATA']; if (!$filedata) { // TRANS: Server error displayed trying to crop an uploaded group logo that is no longer present. $this->serverError(_('Lost our file data.')); } // If image is not being cropped assume pos & dimentions of original $dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x') : 0; $dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y') : 0; $dest_w = $this->arg('avatar_crop_w') ? $this->arg('avatar_crop_w') : $filedata['width']; $dest_h = $this->arg('avatar_crop_h') ? $this->arg('avatar_crop_h') : $filedata['height']; $size = min($dest_w, $dest_h, common_config('avatar', 'maxsize')); $box = array('width' => $size, 'height' => $size, 'x' => $dest_x, 'y' => $dest_y, 'w' => $dest_w, 'h' => $dest_h); $profile = $this->group->getProfile(); $imagefile = new ImageFile(null, $filedata['filepath']); $filename = Avatar::filename($profile->getID(), image_type_to_extension($imagefile->preferredType()), $size, common_timestamp()); $imagefile->resizeTo(Avatar::path($filename), $box); if ($profile->setOriginal($filename)) { @unlink($filedata['filepath']); unset($_SESSION['FILEDATA']); $this->mode = 'upload'; // TRANS: Form success message after updating a group logo. $this->showForm(_('Logo updated.'), true); } else { // TRANS: Form failure message after failing to update a group logo. $this->showForm(_('Failed updating logo.')); } }
/** * Handle an image upload * * Does all the magic for handling an image upload, and crops the * image by default. * * @return void */ function uploadAvatar() { try { $imagefile = ImageFile::fromUpload('avatarfile'); } catch (Exception $e) { $this->showForm($e->getMessage()); return; } if ($imagefile === null) { $this->showForm(_('No file uploaded.')); return; } $cur = common_current_user(); $filename = Avatar::filename($cur->id, image_type_to_extension($imagefile->type), null, 'tmp' . common_timestamp()); $filepath = Avatar::path($filename); move_uploaded_file($imagefile->filepath, $filepath); $filedata = array('filename' => $filename, 'filepath' => $filepath, 'width' => $imagefile->width, 'height' => $imagefile->height, 'type' => $imagefile->type); $_SESSION['FILEDATA'] = $filedata; $this->filedata = $filedata; $this->mode = 'crop'; $this->showForm(_('Pick a square area of the image to be your avatar'), true); }
public function setOriginal($filename) { if ($this->isGroup()) { // Until Group avatars are handled just like profile avatars. return $this->getGroup()->setOriginal($filename); } $imagefile = new ImageFile(null, Avatar::path($filename)); $avatar = new Avatar(); $avatar->profile_id = $this->id; $avatar->width = $imagefile->width; $avatar->height = $imagefile->height; $avatar->mediatype = image_type_to_mime_type($imagefile->type); $avatar->filename = $filename; $avatar->original = true; $avatar->url = Avatar::url($filename); $avatar->created = common_sql_now(); // XXX: start a transaction here if (!Avatar::deleteFromProfile($this, true) || !$avatar->insert()) { // If we can't delete the old avatars, let's abort right here. @unlink(Avatar::path($filename)); return null; } return $avatar; }
/** * Handle an image upload * * Does all the magic for handling an image upload, and crops the * image by default. * * @return void */ function uploadLogo() { if ($_FILES['app_icon']['error'] == UPLOAD_ERR_OK) { try { $imagefile = ImageFile::fromUpload('app_icon'); } catch (Exception $e) { common_debug("damn that sucks"); $this->showForm($e->getMessage()); return; } $filename = Avatar::filename($this->id, image_type_to_extension($imagefile->type), null, 'oauth-app-icon-' . common_timestamp()); $filepath = Avatar::path($filename); move_uploaded_file($imagefile->filepath, $filepath); $this->setOriginal($filename); } }
function setAvatar($user) { try { $picUrl = sprintf('http://graph.facebook.com/%d/picture?type=large', $this->fbuser->id); // fetch the picture from Facebook $client = new HTTPClient(); // fetch the actual picture $response = $client->get($picUrl); if ($response->isOk()) { // seems to always be jpeg, but not sure $tmpname = "facebook-avatar-tmp-" . common_random_hexstr(4); $ok = file_put_contents(Avatar::path($tmpname), $response->getBody()); if (!$ok) { common_log(LOG_WARNING, 'Couldn\'t save tmp Facebook avatar: ' . $tmpname, __FILE__); } else { // save it as an avatar $imagefile = new ImageFile(null, Avatar::path($tmpname)); $filename = Avatar::filename($user->id, image_type_to_extension($imagefile->preferredType()), 180, common_timestamp()); // Previous docs said 180 is the "biggest img we get from Facebook" $imagefile->resizeTo(Avatar::path($filename, array('width' => 180, 'height' => 180))); // No need to keep the temporary file around... @unlink(Avatar::path($tmpname)); $profile = $user->getProfile(); if ($profile->setOriginal($filename)) { common_log(LOG_INFO, sprintf('Saved avatar for %s (%d) from Facebook picture for ' . '%s (fbuid %d), filename = %s', $user->nickname, $user->id, $this->fbuser->name, $this->fbuid, $filename), __FILE__); // clean up tmp file } } } } catch (Exception $e) { common_log(LOG_WARNING, 'Couldn\'t save Facebook avatar: ' . $e->getMessage(), __FILE__); // error isn't fatal, continue } }
function setAvatar($user) { try { $picUrl = sprintf('http://graph.facebook.com/%d/picture?type=large', $this->fbuser->id); // fetch the picture from Facebook $client = new HTTPClient(); // fetch the actual picture $response = $client->get($picUrl); if ($response->isOk()) { // seems to always be jpeg, but not sure $tmpname = "facebook-avatar-tmp-" . common_good_rand(4); $ok = file_put_contents(Avatar::path($tmpname), $response->getBody()); if (!$ok) { common_log(LOG_WARNING, 'Couldn\'t save tmp Facebook avatar: ' . $tmpname, __FILE__); } else { // save it as an avatar $file = new ImageFile($user->id, Avatar::path($tmpname)); $filename = $file->resize(180); // size of the biggest img we get from Facebook $profile = $user->getProfile(); if ($profile->setOriginal($filename)) { common_log(LOG_INFO, sprintf('Saved avatar for %s (%d) from Facebook picture for ' . '%s (fbuid %d), filename = %s', $user->nickname, $user->id, $this->fbuser->name, $this->fbuid, $filename), __FILE__); // clean up tmp file @unlink(Avatar::path($tmpname)); } } } } catch (Exception $e) { common_log(LOG_WARNING, 'Couldn\'t save Facebook avatar: ' . $e->getMessage(), __FILE__); // error isn't fatal, continue } }
/** * Actually save the avatar we found locally. * * @param User $user * @param string $url to avatar URL * @todo merge wrapper funcs for this into common place for 1.0 core */ private function saveAvatar($user, $url) { if (!common_valid_http_url($url)) { throw new ServerException(sprintf(_m("Invalid avatar URL %s."), $url)); } // @fixme this should be better encapsulated // ripped from OStatus via oauthstore.php (for old OMB client) $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); try { if (!copy($url, $temp_filename)) { throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url)); } $profile = $user->getProfile(); $id = $profile->id; // @fixme should we be using different ids? $imagefile = new ImageFile($id, $temp_filename); $filename = Avatar::filename($id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); } catch (Exception $e) { unlink($temp_filename); throw $e; } $profile->setOriginal($filename); }
function add_avatar($profile, $url) { $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); try { copy($url, $temp_filename); $imagefile = new ImageFile($profile->id, $temp_filename); $filename = Avatar::filename($profile->id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); } catch (Exception $e) { unlink($temp_filename); throw $e; } return $profile->setOriginal($filename); }
/** * Download and update given avatar image * * @param string $url * @throws Exception in various failure cases */ protected function updateAvatar($url) { if ($url == $this->avatar) { // We've already got this one. return; } if (!common_valid_http_url($url)) { throw new ServerException(sprintf(_m("Invalid avatar URL %s"), $url)); } if ($this->isGroup()) { $self = $this->localGroup(); } else { $self = $this->localProfile(); } if (!$self) { throw new ServerException(sprintf(_m("Tried to update avatar for unsaved remote profile %s"), $this->uri)); } // @fixme this should be better encapsulated // ripped from oauthstore.php (for old OMB client) $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); if (!copy($url, $temp_filename)) { throw new ServerException(sprintf(_m("Unable to fetch avatar from %s"), $url)); } if ($this->isGroup()) { $id = $this->group_id; } else { $id = $this->profile_id; } // @fixme should we be using different ids? $imagefile = new ImageFile($id, $temp_filename); $filename = Avatar::filename($id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); $self->setOriginal($filename); $orig = clone $this; $this->avatar = $url; $this->update($orig); }
/** * Download and update given avatar image * * @param string $url * @return Avatar The Avatar we have on disk. (seldom used) * @throws Exception in various failure cases */ public function updateAvatar($url, $force = false) { try { // If avatar URL differs: update. If URLs were identical but we're forced: update. if ($url == $this->avatar && !$force) { // If there's no locally stored avatar, throw an exception and continue fetching below. $avatar = Avatar::getUploaded($this->localProfile()) instanceof Avatar; return $avatar; } } catch (NoAvatarException $e) { // No avatar available, let's fetch it. } if (!common_valid_http_url($url)) { // TRANS: Server exception. %s is a URL. throw new ServerException(sprintf(_m('Invalid avatar URL %s.'), $url)); } $self = $this->localProfile(); // @todo FIXME: This should be better encapsulated // ripped from oauthstore.php (for old OMB client) $temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar'); try { $imgData = HTTPClient::quickGet($url); // Make sure it's at least an image file. ImageFile can do the rest. if (false === getimagesizefromstring($imgData)) { throw new UnsupportedMediaException(_('Downloaded group avatar was not an image.')); } file_put_contents($temp_filename, $imgData); unset($imgData); // No need to carry this in memory. if ($this->isGroup()) { $id = $this->group_id; } else { $id = $this->profile_id; } $imagefile = new ImageFile(null, $temp_filename); $filename = Avatar::filename($id, image_type_to_extension($imagefile->type), null, common_timestamp()); rename($temp_filename, Avatar::path($filename)); } catch (Exception $e) { unlink($temp_filename); throw $e; } // @todo FIXME: Hardcoded chmod is lame, but seems to be necessary to // keep from accidentally saving images from command-line (queues) // that can't be read from web server, which causes hard-to-notice // problems later on: // // http://status.net/open-source/issues/2663 chmod(Avatar::path($filename), 0644); $self->setOriginal($filename); $orig = clone $this; $this->avatar = $url; $this->update($orig); return Avatar::getUploaded($self); }
function setAvatar($user) { $picUrl = sprintf('http://graph.facebook.com/%s/picture?type=large', $this->fbuid); // fetch the picture from Facebook $client = new HTTPClient(); // fetch the actual picture $response = $client->get($picUrl); if ($response->isOk()) { $finalUrl = $client->getUrl(); // Make sure the filename is unique becuase it's possible for a user // to deauthorize our app, and then come back in as a new user but // have the same Facebook picture (avatar URLs have a unique index // and their URLs are based on the filenames). $filename = 'facebook-' . common_good_rand(4) . '-' . substr(strrchr($finalUrl, '/'), 1); $ok = file_put_contents(Avatar::path($filename), $response->getBody()); if (!$ok) { common_log(LOG_WARNING, sprintf('Couldn\'t save Facebook avatar %s', $tmp), __FILE__); } else { // save it as an avatar $profile = $user->getProfile(); if ($profile->setOriginal($filename)) { common_log(LOG_INFO, sprintf('Saved avatar for %s (%d) from Facebook picture for ' . '%s (fbuid %d), filename = %s', $user->nickname, $user->id, $this->fbuser['name'], $this->fbuid, $filename), __FILE__); } } } }