diff --git a/actions/profilesettings.php b/actions/profilesettings.php index 14c725ff91..10ab2cd0f6 100644 --- a/actions/profilesettings.php +++ b/actions/profilesettings.php @@ -33,11 +33,54 @@ class ProfilesettingsAction extends SettingsAction { $profile = $user->getProfile(); $this->form_header(_('Profile settings'), $msg, $success); - common_element_start('form', array('method' => 'post', + common_element('h2', NULL, _('Avatar')); + + $original = $profile->getOriginalAvatar(); + + if ($original) { + common_element('img', array('src' => $original->url, + 'class' => 'avatar original', + 'width' => $original->width, + 'height' => $original->height, + 'alt' => $user->nickname)); + } + + $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); + + if ($avatar) { + common_element('img', array('src' => $avatar->url, + 'class' => 'avatar profile', + 'width' => AVATAR_PROFILE_SIZE, + 'height' => AVATAR_PROFILE_SIZE, + 'alt' => $user->nickname)); + } + + common_element_start('form', array('enctype' => 'multipart/form-data', + 'method' => 'POST', 'id' => 'profilesettings', 'action' => common_local_url('profilesettings'))); common_hidden('token', common_session_token()); + + common_element('input', array('name' => 'MAX_FILE_SIZE', + 'type' => 'hidden', + 'id' => 'MAX_FILE_SIZE', + 'value' => MAX_AVATAR_SIZE)); + common_element('input', array('name' => 'avatarfile', + 'type' => 'file', + 'id' => 'avatarfile')); + common_submit('upload', _('Upload')); + common_element_end('form'); + + common_element_start('form', array('method' => 'POST', + 'id' => 'profilesettings', + 'action' => + common_local_url('profilesettings'))); + common_hidden('token', common_session_token()); + + common_element('h2', NULL, _('Profile Settings')); + + # too much common patterns here... abstractable? common_input('nickname', _('Nickname'), ($this->arg('nickname')) ? $this->arg('nickname') : $profile->nickname, @@ -65,22 +108,15 @@ class ProfilesettingsAction extends SettingsAction { common_checkbox('autosubscribe', _('Automatically subscribe to whoever subscribes to me (best for non-humans)'), ($this->arg('autosubscribe')) ? $this->boolean('autosubscribe') : $user->autosubscribe); - common_submit('submit', _('Save')); + + common_submit('save', _('Save')); + common_element_end('form'); common_show_footer(); } function handle_post() { - $nickname = $this->trimmed('nickname'); - $fullname = $this->trimmed('fullname'); - $homepage = $this->trimmed('homepage'); - $bio = $this->trimmed('bio'); - $location = $this->trimmed('location'); - $autosubscribe = $this->boolean('autosubscribe'); - $language = $this->trimmed('language'); - $timezone = $this->trimmed('timezone'); - # CSRF protection $token = $this->trimmed('token'); @@ -89,6 +125,23 @@ class ProfilesettingsAction extends SettingsAction { return; } + if ($this->arg('save')) { + $this->save_profile(); + } else if ($this->arg('upload')) { + $this->upload_avatar(); + } + } + + function save_profile() { + $nickname = $this->trimmed('nickname'); + $fullname = $this->trimmed('fullname'); + $homepage = $this->trimmed('homepage'); + $bio = $this->trimmed('bio'); + $location = $this->trimmed('location'); + $autosubscribe = $this->boolean('autosubscribe'); + $language = $this->trimmed('language'); + $timezone = $this->trimmed('timezone'); + # Some validation if (!Validate::string($nickname, array('min_length' => 1, @@ -201,6 +254,54 @@ class ProfilesettingsAction extends SettingsAction { $this->show_form(_('Settings saved.'), TRUE); } + + function upload_avatar() { + switch ($_FILES['avatarfile']['error']) { + case UPLOAD_ERR_OK: # success, jump out + break; + case UPLOAD_ERR_INI_SIZE: + case UPLOAD_ERR_FORM_SIZE: + $this->show_form(_('That file is too big.')); + return; + case UPLOAD_ERR_PARTIAL: + @unlink($_FILES['avatarfile']['tmp_name']); + $this->show_form(_('Partial upload.')); + return; + default: + $this->show_form(_('System error uploading file.')); + return; + } + + $info = @getimagesize($_FILES['avatarfile']['tmp_name']); + + if (!$info) { + @unlink($_FILES['avatarfile']['tmp_name']); + $this->show_form(_('Not an image or corrupt file.')); + return; + } + + switch ($info[2]) { + case IMAGETYPE_GIF: + case IMAGETYPE_JPEG: + case IMAGETYPE_PNG: + break; + default: + $this->show_form(_('Unsupported image file format.')); + return; + } + + $user = common_current_user(); + $profile = $user->getProfile(); + + if ($profile->setOriginal($_FILES['avatarfile']['tmp_name'])) { + $this->show_form(_('Avatar updated.'), true); + } else { + $this->show_form(_('Failed updating avatar.')); + } + + @unlink($_FILES['avatarfile']['tmp_name']); + } + function nickname_exists($nickname) { $user = common_current_user(); $other = User::staticGet('nickname', $nickname); diff --git a/actions/twittersettings.php b/actions/twittersettings.php index dac0ce2000..24438723f2 100644 --- a/actions/twittersettings.php +++ b/actions/twittersettings.php @@ -33,11 +33,11 @@ class TwittersettingsAction extends SettingsAction { $profile = $user->getProfile(); $fuser = NULL; $flink = Foreign_link::getForeignLink($user->id, 1); // 1 == Twitter - + if ($flink) { $fuser = Foreign_user::staticGet('user_id', $flink->user_id); } - + $this->form_header(_('Twitter settings'), $msg, $success); common_element_start('form', array('method' => 'post', 'id' => 'twittersettings', @@ -45,9 +45,11 @@ class TwittersettingsAction extends SettingsAction { common_local_url('twittersettings'))); common_hidden('token', common_session_token()); + common_element('h2', NULL, _('Twitter Account')); + if ($fuser) { common_element_start('p'); - + common_element('span', 'twitter_user', $fuser->nickname); common_element('a', array('href' => $fuser->uri), $fuser->uri); common_element('span', 'input_instructions', @@ -62,36 +64,36 @@ class TwittersettingsAction extends SettingsAction { ($this->arg('twitter_username')) ? $this->arg('twitter_username') : $profile->nickname, _('No spaces, please.')); // hey, it's what Twitter says - common_password('twitter_password', _('Twitter Password')); + common_password('twitter_password', _('Twitter Password')); } - + common_element('h2', NULL, _('Preferences')); - - if ($flink) { - common_checkbox('noticesync', _('Automatically send my notices to Twitter.'), + + if ($flink) { + common_checkbox('noticesync', _('Automatically send my notices to Twitter.'), ($flink->noticesync) ? true : false); common_checkbox('friendsync', _('Subscribe to my Twitter friends here.'), - ($flink->friendsync) ? true : false); - common_submit('save', _('Save')); + ($flink->friendsync) ? true : false); + common_submit('save', _('Save')); } else { common_checkbox('noticesync', _('Automatically send my notices to Twitter.'), true); common_checkbox('friendsync', _('Subscribe to my Twitter friends here.'), true); common_submit('add', _('Add')); } - + common_element_end('form'); common_show_footer(); } function handle_post() { - + # CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->show_form(_('There was a problem with your session token. Try again, please.')); return; } - + if ($this->arg('save')) { $this->save_preferences(); } else if ($this->arg('add')) { @@ -102,43 +104,43 @@ class TwittersettingsAction extends SettingsAction { $this->show_form(_('Unexpected form submission.')); } } - + function add_twitter_acct() { $twitter_username = $this->trimmed('twitter_username'); $twitter_password = $this->trimmed('twitter_password'); $noticesync = $this->boolean('noticesync'); $friendsync = $this->boolean('friendsync'); - + if (!Validate::string($twitter_username, array('min_length' => 1, 'max_length' => 64, 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { $this->show_form(_('Username must have only lowercase letters and numbers and no spaces.')); return; } - + // Verify this is a real Twitter user. if (!$this->verify_credentials($twitter_username, $twitter_password)) { $this->show_form(_('Could not verify your Twitter credentials!')); return; } - - // Now that we have a valid Twitter user, we have to make another api call to + + // Now that we have a valid Twitter user, we have to make another api call to // find its Twitter ID. Dumb, but true. $twitter_id = $this->get_twitter_id($twitter_username); - + if (!$twitter_id) { $this->show_form(sprintf(_('Unable to retrieve account information for "%s" from Twitter.'), $twitter_username)); return; } - + $fuser = DB_DataObject::factory('foreign_user'); $fuser->id = $twitter_id; - $fuser->service = 1; // Twitter + $fuser->service = 1; // Twitter $fuser->uri = "http://www.twitter.com/$twitter_username"; $fuser->nickname = $twitter_username; $fuser->created = common_sql_now(); $result = $fuser->insert(); - + if (!$result) { common_log_db_error($fuser, 'INSERT', __FILE__); $this->show_form(_('Unable to save your Twitter settings!')); @@ -146,7 +148,7 @@ class TwittersettingsAction extends SettingsAction { } $user = common_current_user(); - + $flink = DB_DataObject::factory('foreign_link'); $flink->user_id = $user->id; $flink->foreign_id = $fuser->id; @@ -157,19 +159,19 @@ class TwittersettingsAction extends SettingsAction { $flink->friendsync = ($friendsync) ? 2 : 0; $flink->profilesync = 0; // XXX: leave as default? $flink_id = $flink->insert(); - + if (!$flink_id) { common_log_db_error($flink, 'INSERT', __FILE__); $this->show_form(_('Unable to save your Twitter settings!')); return; } - + $this->show_form(_('Twitter settings saved.'), true); } function remove_twitter_acct() { $user = common_current_user(); - + // For now we assume one Twitter acct per Laconica acct $flink = Foreign_link::getForeignLink($user->id, 1); $fuser = Foreign_user::getForeignUser($flink->foreign_id, 1); @@ -187,13 +189,13 @@ class TwittersettingsAction extends SettingsAction { } $result = $fuser->delete(); - + if (!$result) { common_log_db_error($flink, 'DELETE', __FILE__); $this->show_form(_('Couldn\'t remove Twitter user.')); return; } - + $result = $flink->delete(); if (!$result) { @@ -204,73 +206,73 @@ class TwittersettingsAction extends SettingsAction { $this->show_form(_('Twitter account removed.'), TRUE); } - + function save_preferences() { $noticesync = $this->boolean('noticesync'); $friendsync = $this->boolean('friendsync'); $user = common_current_user(); $flink = Foreign_link::getForeignLink($user->id, 1); - + if (!$flink) { common_log_db_error($flink, 'SELECT', __FILE__); $this->show_form(_('Couldn\'t save Twitter preferences.')); return; - } - + } + $flink->noticesync = ($noticesync) ? 1 : 0; $flink->friendsync = ($friendsync) ? 2 : 0; // $flink->profilesync = 0; // XXX: leave as default? $result = $flink->update(); - + if (!$result) { common_log_db_error($flink, 'UPDATE', __FILE__); $this->show_form(_('Couldn\'t save Twitter preferences.')); return; } - + $this->show_form(_('Twitter preferences saved.')); - + return; } - function get_twitter_id($twitter_username) { - $uri = "http://twitter.com/users/show/$twitter_username.json"; + function get_twitter_id($twitter_username) { + $uri = "http://twitter.com/users/show/$twitter_username.json"; $data = $this->get_twitter_data($uri); - + if (!$data) { return NULL; } - + $user = json_decode($data); if (!$user) { return NULL; } - + return $user->id; } - function verify_credentials($user, $password) { + function verify_credentials($user, $password) { $uri = 'http://twitter.com/account/verify_credentials.json'; $data = $this->get_twitter_data($uri, $user, $password); - + if (!$data) { return false; } - - $creds = json_decode($data); - + + $creds = json_decode($data); + if (!$creds) { return false; } - - if ($creds->authorized == 1) { + + if ($creds->authorized == 1) { return true; } - - return false; + + return false; } - + // PHP's cURL the best thing to use here? -- Zach function get_twitter_data($uri, $user=NULL, $password=NULL) { $options = array( @@ -283,7 +285,7 @@ class TwittersettingsAction extends SettingsAction { CURLOPT_CONNECTTIMEOUT => 120, CURLOPT_TIMEOUT => 120 ); - + $ch = curl_init($uri); curl_setopt_array($ch, $options); $data = curl_exec($ch); @@ -294,7 +296,7 @@ class TwittersettingsAction extends SettingsAction { } curl_close($ch); - + return $data; } diff --git a/htaccess.sample b/htaccess.sample index d45b119d13..af7925b1d8 100644 --- a/htaccess.sample +++ b/htaccess.sample @@ -35,9 +35,6 @@ RewriteRule ^main/recoverpassword$ index.php?action=recoverpassword [L,QSA] RewriteRule ^main/recoverpassword/(.*)$ index.php?action=recoverpassword&code=$1 [L,QSA] RewriteRule ^main/invite$ index.php?action=invite [L,QSA] -RewriteRule ^main/favor$ index.php?action=favor [L,QSA] -RewriteRule ^main/disfavor$ index.php?action=disfavor [L,QSA] - RewriteRule ^settings/avatar$ index.php?action=avatar [L,QSA] RewriteRule ^settings/password$ index.php?action=password [L,QSA] RewriteRule ^settings/profile$ index.php?action=profilesettings [L,QSA] diff --git a/lib/settingsaction.php b/lib/settingsaction.php index 9aa5247d9d..00bec4274b 100644 --- a/lib/settingsaction.php +++ b/lib/settingsaction.php @@ -86,9 +86,6 @@ class SettingsAction extends Action { 'emailsettings' => array(_('Email'), _('Change email handling')), - 'avatar' => - array(_('Avatar'), - _('Upload a new profile image')), 'password' => array(_('Password'), _('Change your password')), diff --git a/lib/util.php b/lib/util.php index 016821c57a..96e7819870 100644 --- a/lib/util.php +++ b/lib/util.php @@ -837,7 +837,6 @@ function common_fancy_url($action, $args=NULL) { } case 'openidlogin': return common_path('main/openid'); - case 'avatar': case 'password': return common_path('settings/'.$action); case 'profilesettings':