diff -r 3343a05e7e5b -r 6a59951b70e4 plugins/SpecialUserPrefs.php --- a/plugins/SpecialUserPrefs.php Fri Aug 21 11:47:26 2009 -0400 +++ b/plugins/SpecialUserPrefs.php Fri Aug 21 11:54:26 2009 -0400 @@ -184,6 +184,10 @@ switch ( $section ) { + case 'Avatar': + $template->preload_js('jquery'); + $template->preload_js('jquery-ui'); + break; case 'EmailPassword': // Require elevated privileges (well sortof) if ( $session->auth_level < USER_LEVEL_CHPREF ) @@ -793,197 +797,18 @@ break; } - // Determine current avatar - $q = $db->sql_query('SELECT user_has_avatar, avatar_type FROM ' . table_prefix . 'users WHERE user_id = ' . $session->user_id . ';'); - if ( !$q ) - $db->_die('Avatar CP selecting user\'s avatar data'); - - list($has_avi, $avi_type) = $db->fetchrow_num(); - if ( isset($_POST['submit']) ) { - $action = ( isset($_POST['avatar_action']) ) ? $_POST['avatar_action'] : 'keep'; - $avi_path = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $session->user_id . '.' . $avi_type; - switch($action) - { - case 'keep': - default: - break; - case 'remove': - if ( $has_avi ) - { - // First switch the avatar off - $q = $db->sql_query('UPDATE ' . table_prefix . 'users SET user_has_avatar = 0 WHERE user_id = ' . $session->user_id . ';'); - if ( !$q ) - $db->_die('Avatar CP switching user avatar off'); - - if ( @unlink($avi_path) ) - { - echo '
' . $lang->get('usercp_avatar_delete_success') . '
'; - } - $has_avi = 0; - } - break; - case 'set_http': - case 'set_file': - // Hackish way to preserve the UNIX philosophy of reusing as much code as possible - if ( $action == 'set_http' ) - { - // Check if this action is enabled - if ( getConfig('avatar_upload_http', 1) !== 1 ) - { - // non-localized, only appears on hack attempt - echo '
Uploads over HTTP are disabled.
'; - break; - } - // Download the file - require_once( ENANO_ROOT . '/includes/http.php' ); - - if ( !preg_match('/^http:\/\/([a-z0-9-\.]+)(:([0-9]+))?\/(.+)$/', $_POST['avatar_http_url'], $match) ) - { - echo '
' . $lang->get('usercp_avatar_invalid_url') . '
'; - break; - } - - $hostname = $match[1]; - $uri = '/' . $match[4]; - $port = ( $match[3] ) ? intval($match[3]) : 80; - $max_size = intval(getConfig('avatar_max_size')); - - // Get temporary file - $tempfile = tempnam(false, "enanoavatar_{$session->user_id}"); - if ( !$tempfile ) - echo '
Error getting temp file.
'; - - @unlink($tempfile); - $request = new Request_HTTP($hostname, $uri, 'GET', $port); - $result = $request->write_response_to_file($tempfile, 50, $max_size); - if ( !$result || $request->response_code != HTTP_OK ) - { - @unlink($tempfile); - echo '
' . $lang->get('usercp_avatar_bad_write') . '
'; - break; - } - - // Response written. Proceed to validation... - } - else - { - // Check if this action is enabled - if ( getConfig('avatar_upload_file', 1) !== 1 ) - { - // non-localized, only appears on hack attempt - echo '
Uploads from the browser are disabled.
'; - break; - } - - $max_size = intval(getConfig('avatar_max_size')); - - $file =& $_FILES['avatar_file']; - $tempfile =& $file['tmp_name']; - if ( filesize($tempfile) > $max_size ) - { - @unlink($tempfile); - echo '
' . $lang->get('usercp_avatar_file_too_large') . '
'; - break; - } - } - $file_type = get_image_filetype($tempfile); - if ( !$file_type ) - { - unlink($tempfile); - echo '
' . $lang->get('usercp_avatar_bad_filetype') . '
'; - break; - } - - $avi_path_new = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $session->user_id . '.' . $file_type; - - // The file type is good - validate dimensions and animation - switch($file_type) - { - case 'png': - $is_animated = is_png_animated($tempfile); - $dimensions = png_get_dimensions($tempfile); - break; - case 'gif': - $is_animated = is_gif_animated($tempfile); - $dimensions = gif_get_dimensions($tempfile); - break; - case 'jpg': - $is_animated = false; - $dimensions = jpg_get_dimensions($tempfile); - break; - default: - echo '
API mismatch
'; - break 2; - } - // Did we get invalid size data? If so the image is probably corrupt. - if ( !$dimensions ) - { - @unlink($tempfile); - echo '
' . $lang->get('usercp_avatar_corrupt_image') . '
'; - break; - } - // Is the image animated? - if ( $is_animated && getConfig('avatar_enable_anim') !== '1' ) - { - @unlink($tempfile); - echo '
' . $lang->get('usercp_avatar_disallowed_animation') . '
'; - break; - } - // Check image dimensions - list($image_x, $image_y) = $dimensions; - $max_x = intval(getConfig('avatar_max_width')); - $max_y = intval(getConfig('avatar_max_height')); - if ( $image_x > $max_x || $image_y > $max_y ) - { - @unlink($tempfile); - echo '
' . $lang->get('usercp_avatar_too_large') . '
'; - break; - } - // All good! - @unlink($avi_path); - if ( rename($tempfile, $avi_path_new) ) - { - $q = $db->sql_query('UPDATE ' . table_prefix . "users SET user_has_avatar = 1, avatar_type = '$file_type' WHERE user_id = {$session->user_id};"); - if ( !$q ) - $db->_die('Avatar CP updating users table after successful avatar upload'); - $has_avi = 1; - $avi_type = $file_type; - echo '
' . $lang->get('usercp_avatar_upload_success') . '
'; - } - else - { - echo '
' . $lang->get('usercp_avatar_move_failed') . '
'; - } - break; - case 'set_gravatar': - // set avatar to use Gravatar - // make sure we're allowed to do this - if ( getConfig('avatar_upload_gravatar') != '1' ) - { - // access denied - break; - } - // first, remove old image - if ( $has_avi ) - { - // First switch the avatar off - $q = $db->sql_query('UPDATE ' . table_prefix . 'users SET user_has_avatar = 0 WHERE user_id = ' . $session->user_id . ';'); - if ( !$q ) - $db->_die('Avatar CP switching user avatar off'); - - @unlink($avi_path); - } - // set to gravatar mode - $q = $db->sql_query('UPDATE ' . table_prefix . 'users SET user_has_avatar = 1, avatar_type = \'grv\' WHERE user_id = ' . $session->user_id . ';'); - if ( !$q ) - $db->_die('Avatar CP switching user avatar off'); - - $has_avi = 1; - echo '
' . $lang->get('usercp_avatar_gravatar_success') . '
'; - break; - } + list($has_avi, $avi_type) = avatar_post($session->user_id); + } + else + { + // Determine current avatar + $q = $db->sql_query('SELECT user_has_avatar, avatar_type FROM ' . table_prefix . 'users WHERE user_id = ' . $session->user_id . ';'); + if ( !$q ) + $db->_die('Avatar CP selecting user\'s avatar data'); + + list($has_avi, $avi_type) = $db->fetchrow_num(); } ?> @@ -991,28 +816,17 @@ function avatar_select_field(elParent) { + $('td#avatar_upload_btns > div:visible').hide('blind'); switch(elParent.value) { - case 'keep': - case 'remove': - $('avatar_upload_http').object.style.display = 'none'; - $('avatar_upload_file').object.style.display = 'none'; - $('avatar_upload_gravatar').object.style.display = 'none'; - break; case 'set_http': - $('avatar_upload_http').object.style.display = 'block'; - $('avatar_upload_file').object.style.display = 'none'; - $('avatar_upload_gravatar').object.style.display = 'none'; + $('#avatar_upload_http').show('blind'); break; case 'set_file': - $('avatar_upload_http').object.style.display = 'none'; - $('avatar_upload_file').object.style.display = 'block'; - $('avatar_upload_gravatar').object.style.display = 'none'; + $('#avatar_upload_file').show('blind'); break; case 'set_gravatar': - $('avatar_upload_gravatar').object.style.display = 'block'; - $('avatar_upload_http').object.style.display = 'none'; - $('avatar_upload_file').object.style.display = 'none'; + $('#avatar_upload_gravatar').show('blind'); break; } } @@ -1030,7 +844,7 @@ '; echo ' - + ' . $lang->get('usercp_avatar_label_current') . ' '; @@ -1051,7 +865,7 @@ ' . $lang->get('usercp_avatar_lbl_change') . ' - +

'; if ( getConfig('avatar_upload_http') == '1' ) @@ -1062,10 +876,6 @@ ' . $lang->get('usercp_avatar_lbl_url_desc') . ' ' . $lang->get('usercp_avatar_limits') . ' '; } - else - { - echo ' '; - } if ( getConfig('avatar_upload_file') == '1' ) { echo '
@@ -1074,10 +884,6 @@ ' . $lang->get('usercp_avatar_lbl_file_desc') . ' ' . $lang->get('usercp_avatar_limits') . ' '; } - else - { - echo ' '; - } if ( getConfig('avatar_upload_gravatar') == '1' ) { $rating_images = array('g' => '0', 'pg' => '1', 'r' => '2', 'x' => '3'); @@ -1092,10 +898,6 @@ ' . $lang->get("usercp_avatar_gravatar_rating_$max_rating") . ' '; } - else - { - echo ' '; - } echo ' '; @@ -1128,4 +930,237 @@ $template->footer(); } +// Avatar POST processor +function avatar_post($user_id, $quiet = false) +{ + global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + + $had_a_boo_boo = true; + + // Determine current avatar + $q = $db->sql_query('SELECT user_has_avatar, avatar_type FROM ' . table_prefix . 'users WHERE user_id = ' . $session->user_id . ';'); + if ( !$q ) + $db->_die('Avatar CP selecting user\'s avatar data'); + + list($has_avi, $avi_type) = $db->fetchrow_num(); + + $action = ( isset($_POST['avatar_action']) ) ? $_POST['avatar_action'] : 'keep'; + $avi_path = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $user_id . '.' . $avi_type; + switch($action) + { + case 'keep': + default: + $had_a_boo_boo = false; + break; + case 'remove': + if ( $has_avi ) + { + // First switch the avatar off + $q = $db->sql_query('UPDATE ' . table_prefix . 'users SET user_has_avatar = 0 WHERE user_id = ' . $user_id . ';'); + if ( !$q ) + $db->_die('Avatar CP switching user avatar off'); + + if ( @unlink($avi_path) ) + { + $quiet || print '
' . $lang->get('usercp_avatar_delete_success') . '
'; + } + $has_avi = 0; + } + $had_a_boo_boo = false; + break; + case 'set_http': + case 'set_file': + // Hackish way to preserve the UNIX philosophy of reusing as much code as possible + if ( $action == 'set_http' ) + { + // Check if this action is enabled + if ( getConfig('avatar_upload_http', 1) !== 1 ) + { + // non-localized, only appears on hack attempt + echo '
Uploads over HTTP are disabled.
'; + break; + } + // Download the file + require_once( ENANO_ROOT . '/includes/http.php' ); + + if ( !preg_match('/^http:\/\/((?:[a-z0-9-\.]+|\[[a-f0-9:]+\]))(:([0-9]+))?\/(.+)$/', $_POST['avatar_http_url'], $match) ) + { + echo '
' . $lang->get('usercp_avatar_invalid_url') . '
'; + break; + } + + $hostname = $match[1]; + $uri = '/' . $match[4]; + $port = ( $match[3] ) ? intval($match[3]) : 80; + $max_size = intval(getConfig('avatar_max_size')); + + // Get temporary file + $tempfile = tempnam(false, "enanoavatar_{$user_id}"); + if ( !$tempfile ) + echo '
Error getting temp file.
'; + + @unlink($tempfile); + $request = new Request_HTTP($hostname, $uri, 'GET', $port); + // max download size: 2MB, keeps things reasonable + // note: we'll try to scale the image down before checking filesize + $result = $request->write_response_to_file($tempfile, 1160, 2097152); + if ( !$result || $request->response_code != HTTP_OK ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_bad_write') . '
'; + break; + } + + // Response written. Proceed to validation... + } + else + { + // Check if this action is enabled + if ( getConfig('avatar_upload_file', 1) !== 1 ) + { + // non-localized, only appears on hack attempt + echo '
Uploads from the browser are disabled.
'; + break; + } + + $max_size = intval(getConfig('avatar_max_size')); + + $file =& $_FILES['avatar_file']; + $tempfile =& $file['tmp_name']; + } + $file_type = get_image_filetype($tempfile); + if ( !$file_type ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_bad_filetype') . '
'; + break; + } + + $avi_path_new = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $user_id . '.' . $file_type; + + // The file type is good - validate dimensions and animation + switch($file_type) + { + case 'png': + $is_animated = is_png_animated($tempfile); + $dimensions = png_get_dimensions($tempfile); + break; + case 'gif': + $is_animated = is_gif_animated($tempfile); + $dimensions = gif_get_dimensions($tempfile); + break; + case 'jpg': + $is_animated = false; + $dimensions = jpg_get_dimensions($tempfile); + break; + default: + echo '
API mismatch
'; + break 2; + } + // Did we get invalid size data? If so the image is probably corrupt. + if ( !$dimensions ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_corrupt_image') . '
'; + break; + } + // Is the image animated? + if ( $is_animated && getConfig('avatar_enable_anim') !== '1' ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_disallowed_animation') . '
'; + break; + } + // Check image dimensions + list($image_x, $image_y) = $dimensions; + $max_x = intval(getConfig('avatar_max_width')); + $max_y = intval(getConfig('avatar_max_height')); + if ( $image_x > $max_x || $image_y > $max_y ) + { + // try to scale the image + try + { + @rename($tempfile, "$tempfile-unscaled.$file_type"); + $scale_result = scale_image("$tempfile-unscaled.$file_type", "$tempfile.$file_type", $max_x, $max_y, true); + if ( $scale_result ) + { + if ( !(@unlink("$tempfile-unscaled.$file_type") && @rename("$tempfile.$file_type", $tempfile)) ) + { + // scale failed + @unlink("$tempfile-scale.$file_type"); + echo '
Rename failure: ' . $lang->get('usercp_avatar_too_large') . '
'; + break; + } + } + else + { + @unlink($tempfile); + @unlink("$tempfile-unscaled.$file_type"); + echo '
Scale failure: ' . $lang->get('usercp_avatar_too_large') . '
'; + break; + } + } + catch ( Exception $e ) + { + // If we get here, the scaling process most definitely failed. + echo '
EXCEPTION: ' . $lang->get('usercp_avatar_too_large') . '
'; + break; + } + } + // Check file size last, so that the scale operation is considered + if ( filesize($tempfile) > $max_size ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_file_too_large') . '
'; + break; + } + // All good! + @unlink($avi_path); + if ( rename($tempfile, $avi_path_new) ) + { + $q = $db->sql_query('UPDATE ' . table_prefix . "users SET user_has_avatar = 1, avatar_type = '$file_type' WHERE user_id = {$user_id};"); + if ( !$q ) + $db->_die('Avatar CP updating users table after successful avatar upload'); + $has_avi = 1; + $avi_type = $file_type; + $quiet || print '
' . $lang->get('usercp_avatar_upload_success') . '
'; + } + else + { + echo '
' . $lang->get('usercp_avatar_move_failed') . '
'; + } + $had_a_boo_boo = false; + break; + case 'set_gravatar': + // set avatar to use Gravatar + // make sure we're allowed to do this + if ( getConfig('avatar_upload_gravatar') != '1' ) + { + // access denied + break; + } + // first, remove old image + if ( $has_avi ) + { + // First switch the avatar off + $q = $db->sql_query('UPDATE ' . table_prefix . 'users SET user_has_avatar = 0 WHERE user_id = ' . $user_id . ';'); + if ( !$q ) + $db->_die('Avatar CP switching user avatar off'); + + @unlink($avi_path); + } + // set to gravatar mode + $q = $db->sql_query('UPDATE ' . table_prefix . 'users SET user_has_avatar = 1, avatar_type = \'grv\' WHERE user_id = ' . $user_id . ';'); + if ( !$q ) + $db->_die('Avatar CP switching user avatar off'); + + $has_avi = 1; + $quiet || print '
' . $lang->get('usercp_avatar_gravatar_success') . '
'; + $had_a_boo_boo = false; + break; + } + return array($has_avi, $avi_type, $had_a_boo_boo); +} + ?>