BOINC /
boinc
| 1 | <?php |
||
| 2 | // This file is part of BOINC. |
||
| 3 | // http://boinc.berkeley.edu |
||
| 4 | // Copyright (C) 2021 University of California |
||
| 5 | // |
||
| 6 | // BOINC is free software; you can redistribute it and/or modify it |
||
| 7 | // under the terms of the GNU Lesser General Public License |
||
| 8 | // as published by the Free Software Foundation, |
||
| 9 | // either version 3 of the License, or (at your option) any later version. |
||
| 10 | // |
||
| 11 | // BOINC is distributed in the hope that it will be useful, |
||
| 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
| 14 | // See the GNU Lesser General Public License for more details. |
||
| 15 | // |
||
| 16 | // You should have received a copy of the GNU Lesser General Public License |
||
| 17 | // along with BOINC. If not, see <http://www.gnu.org/licenses/>. |
||
| 18 | |||
| 19 | // TODO: the following is organized in a funky way. Clean it up |
||
|
0 ignored issues
–
show
Coding Style
Best Practice
introduced
by
Loading history...
|
|||
| 20 | |||
| 21 | require_once("../inc/util.inc"); |
||
| 22 | require_once("../inc/profile.inc"); |
||
| 23 | require_once("../inc/akismet.inc"); |
||
| 24 | require_once("../inc/recaptchalib.inc"); |
||
| 25 | |||
| 26 | if (DISABLE_PROFILES) error_page("Profiles are disabled"); |
||
| 27 | |||
| 28 | check_get_args(array()); |
||
| 29 | |||
| 30 | // output a select form item with the given name, |
||
| 31 | // from a list of newline-delineated items from the text file. |
||
| 32 | // If $selection is provided, and if it matches one of the entries in the file, |
||
| 33 | // it will be selected by default. |
||
| 34 | // |
||
| 35 | function show_combo_box($name, $filename, $selection=null) { |
||
| 36 | echo "<select name=\"$name\" class=\"form-control\">\n"; |
||
| 37 | |||
| 38 | $file = fopen($filename, "r"); |
||
| 39 | |||
| 40 | while ($line = trim(fgets($file, 1024))) { |
||
| 41 | if ($line == $selection) { |
||
| 42 | echo "<option SELECTED value=\"$line\">$line\n"; |
||
| 43 | } else { |
||
| 44 | echo "<option value=\"$line\">$line\n"; |
||
| 45 | } |
||
| 46 | } |
||
| 47 | |||
| 48 | echo "</select>\n"; |
||
| 49 | fclose($file); |
||
| 50 | } |
||
| 51 | |||
| 52 | |||
| 53 | function show_picture_option($profile) { |
||
| 54 | row1(tra("Picture")); |
||
| 55 | |||
| 56 | $warning = ""; |
||
| 57 | if (profile_screening() && $profile && $profile->has_picture) { |
||
| 58 | $warning = offensive_profile_warning($profile->verification); |
||
| 59 | } |
||
| 60 | |||
| 61 | if ($profile && ($profile->has_picture)) { |
||
| 62 | echo " |
||
| 63 | <tr><td colspan=2> |
||
| 64 | <table border=0 cellpadding=5 |
||
| 65 | <tr> |
||
| 66 | <td valign=top><a href=\"" . IMAGE_URL . $profile->userid . '.jpg' . "\"><img src=\"" . IMAGE_URL . $profile->userid . '_sm.jpg' . "\"></a> |
||
| 67 | </td> |
||
| 68 | <td valign=top>" .tra("%1 Your profile picture is shown to the left.", $warning) ." |
||
| 69 | <p>". |
||
| 70 | tra("To replace it, click the \"Browse\" button and select a JPEG or PNG file (%1 or less).", "50KB") ."<br /> |
||
| 71 | <input name=picture type=file><br> |
||
| 72 | <p>". |
||
| 73 | tra("To remove it from your profile, check this box:") . " |
||
| 74 | <input type=checkbox name=delete_pic> |
||
| 75 | <p> |
||
| 76 | </td></tr>"; |
||
| 77 | rowify("<br>"); |
||
| 78 | end_table(); |
||
| 79 | echo "</td></tr>"; |
||
| 80 | } else { |
||
| 81 | rowify(tra("If you would like include a picture with your profile, click the \"Browse\" button and select a JPEG or PNG file. Please select images of %1 or less.", "50KB") . " |
||
| 82 | <p> |
||
| 83 | <input name=picture type=file> |
||
| 84 | "); |
||
| 85 | rowify("<br>"); |
||
| 86 | } |
||
| 87 | } |
||
| 88 | |||
| 89 | function show_language_selection($profile) { |
||
| 90 | if (!file_exists(LANGUAGE_FILE)) { |
||
| 91 | return; |
||
| 92 | } |
||
| 93 | row1(tra("Language")); |
||
| 94 | echo "<tr><td> |
||
| 95 | <p>" . |
||
| 96 | tra("Select the language in which your profile is written:") . " |
||
| 97 | <p> |
||
| 98 | "; |
||
| 99 | if (isset($profile->language)) { |
||
| 100 | show_combo_box("language", LANGUAGE_FILE, $profile->language); |
||
| 101 | } else { |
||
| 102 | show_combo_box("language", LANGUAGE_FILE, "English"); |
||
| 103 | } |
||
| 104 | echo "</td></tr>\n"; |
||
| 105 | } |
||
| 106 | |||
| 107 | function show_submit() { |
||
| 108 | row1(tra("Submit profile")); |
||
| 109 | if (recaptcha_public_key()) { |
||
| 110 | table_row(boinc_recaptcha_get_html(recaptcha_public_key())); |
||
| 111 | } |
||
| 112 | table_row("<p><input class=\"btn btn-success\" type=\"submit\" value=\"".tra("Create/edit profile") ."\" name=\"submit\">"); |
||
| 113 | } |
||
| 114 | |||
| 115 | // Returns an array containing: |
||
| 116 | // [0]: The original image refered to by $fileName if its dimensions are |
||
| 117 | // less than MAX_IMG_WIDTH x MAX_IMG_HEIGHT, or a version scaled to |
||
| 118 | // those dimensions if it was too large. |
||
| 119 | // [1]: A scaled version of the above. |
||
| 120 | |||
| 121 | function getImages($fileName) { |
||
| 122 | $size = getImageSize($fileName); |
||
|
0 ignored issues
–
show
|
|||
| 123 | |||
| 124 | // Determine if the filetype uploaded is supported. |
||
| 125 | // TODO: Change these to constants. |
||
|
0 ignored issues
–
show
|
|||
| 126 | switch($size[2]) { |
||
| 127 | case '2': // JPEG |
||
| 128 | $image = imageCreateFromJPEG($fileName); |
||
|
0 ignored issues
–
show
|
|||
| 129 | break; |
||
| 130 | case '3': // PNG |
||
| 131 | $image = imageCreateFromPNG($fileName); |
||
|
0 ignored issues
–
show
|
|||
| 132 | break; |
||
| 133 | default: |
||
|
0 ignored issues
–
show
|
|||
| 134 | error_page(tra("The format of your uploaded image is not supported.")); |
||
| 135 | } |
||
| 136 | |||
| 137 | $width = $size[0]; |
||
| 138 | $height = $size[1]; |
||
| 139 | |||
| 140 | $smallImage = scale_image($image, $width, $height, SMALL_IMG_WIDTH, SMALL_IMG_HEIGHT); |
||
|
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
| 141 | |||
| 142 | if ($width > MAX_IMG_WIDTH || $height > MAX_IMG_HEIGHT) { |
||
| 143 | $image = scale_image($image, $width, $height, MAX_IMG_WIDTH, MAX_IMG_HEIGHT); |
||
| 144 | } |
||
| 145 | |||
| 146 | /* |
||
| 147 | echo "<br><br>Image type: $size[2]"; |
||
| 148 | echo "<br>Original width: $width"; |
||
| 149 | echo "<br>Original height: $height"; |
||
| 150 | echo "<br>Scalar: $scalar"; |
||
| 151 | echo "<br>Dest width: " . ($width / $scalar); |
||
| 152 | echo "<br>Dest height: " . ($height / $scalar); |
||
| 153 | echo "<br>Horizontal offset: $horiz_offset"; |
||
| 154 | echo "<br>Vertical offset: $vert_offset"; |
||
| 155 | echo "<br><br><a href=\"images/user_profile/test.jpg\">View result</a>"; |
||
| 156 | */ |
||
| 157 | |||
| 158 | return array($image, $smallImage); |
||
| 159 | } |
||
| 160 | |||
| 161 | function show_description() { |
||
| 162 | echo " |
||
| 163 | <p>" .tra("Your %1 profile %2 lets you share your opinions and background with the %3 community.", "<b>", "</b>", PROJECT) . " |
||
| 164 | <p> |
||
| 165 | "; |
||
| 166 | } |
||
| 167 | |||
| 168 | function show_questions($profile) { |
||
| 169 | $response1 = ""; |
||
| 170 | $response2 = ""; |
||
| 171 | if (isset($profile->response1)) { |
||
| 172 | $response1 = $profile->response1; |
||
| 173 | } |
||
| 174 | if (isset($profile->response2)) { |
||
| 175 | $response2 = $profile->response2; |
||
| 176 | } |
||
| 177 | |||
| 178 | row1(show_profile_heading1()); |
||
| 179 | rowify(show_profile_question1().bbcode_info()); |
||
| 180 | show_textarea("response1", $response1); |
||
| 181 | row1( show_profile_heading2()); |
||
| 182 | rowify( show_profile_question2().bbcode_info()); |
||
| 183 | show_textarea("response2", $response2); |
||
| 184 | show_language_selection($profile); |
||
| 185 | } |
||
| 186 | |||
| 187 | function show_textarea($name, $text) { |
||
| 188 | rowify("<textarea name=\"$name\" class=\"form-control\" rows=\"10\">" . $text . "</textarea>"); |
||
| 189 | } |
||
| 190 | |||
| 191 | // $profile is null if user doesn't already have a profile. |
||
| 192 | // Don't assign to $profile->x if this is the case. |
||
| 193 | // |
||
| 194 | function process_create_profile($user, $profile) { |
||
| 195 | $response1 = post_str('response1', true); |
||
| 196 | $response2 = post_str('response2', true); |
||
| 197 | $language = post_str('language', true); |
||
| 198 | |||
| 199 | if (recaptcha_private_key()) { |
||
| 200 | if (!boinc_recaptcha_isValidated(recaptcha_private_key())) { |
||
| 201 | $profile->response1 = $response1; |
||
| 202 | $profile->response2 = $response2; |
||
| 203 | show_profile_form($profile, |
||
| 204 | tra("Your ReCaptcha response was not correct. Please try again.") |
||
| 205 | ); |
||
| 206 | return; |
||
| 207 | } |
||
| 208 | } |
||
| 209 | if (!akismet_check($user, $response1)) { |
||
| 210 | $profile->response1 = $response1; |
||
| 211 | $profile->response2 = $response2; |
||
| 212 | show_profile_form($profile, |
||
| 213 | tra("Your first response was flagged as spam by the Akismet anti-spam system. Please modify your text and try again.") |
||
| 214 | ); |
||
| 215 | return; |
||
| 216 | } |
||
| 217 | if (!akismet_check($user, $response2)) { |
||
| 218 | $profile->response1 = $response1; |
||
| 219 | $profile->response2 = $response2; |
||
| 220 | show_profile_form($profile, |
||
| 221 | tra("Your second response was flagged as spam by the Akismet anti-spam system. Please modify your text and try again.") |
||
| 222 | ); |
||
| 223 | return; |
||
| 224 | } |
||
| 225 | |||
| 226 | if (isset($_POST['delete_pic'])) { |
||
| 227 | $delete_pic = $_POST['delete_pic']; |
||
| 228 | } else { |
||
| 229 | $delete_pic = "off"; |
||
| 230 | } |
||
| 231 | |||
| 232 | if (strlen($response1)==0 && |
||
| 233 | strlen($response2)==0 && |
||
| 234 | $delete_pic != "on" && |
||
| 235 | !is_uploaded_file($_FILES['picture']['tmp_name']) |
||
| 236 | ) { |
||
| 237 | error_page(tra("Your profile submission was empty.")); |
||
| 238 | exit(); |
||
|
0 ignored issues
–
show
|
|||
| 239 | } |
||
| 240 | |||
| 241 | if ($delete_pic == "on") { |
||
| 242 | delete_user_pictures($profile->userid); |
||
| 243 | $profile->has_picture = false; |
||
| 244 | $profile->verification = 0; |
||
| 245 | } |
||
| 246 | |||
| 247 | $profile ? $has_picture = $profile->has_picture: $has_picture = false; |
||
| 248 | |||
| 249 | if (is_uploaded_file($_FILES['picture']['tmp_name'])) { |
||
| 250 | $has_picture = true; |
||
| 251 | if ($profile) $profile->verification = 0; |
||
| 252 | |||
| 253 | // echo "<br>Name: " . $_FILES['picture']['name']; |
||
| 254 | // echo "<br>Type: " . $_FILES['picture']['type']; |
||
| 255 | // echo "<br>Size: " . $_FILES['picture']['size']; |
||
| 256 | // echo "<br>Temp name: " . $_FILES['picture']['tmp_name']; |
||
| 257 | |||
| 258 | $images = getImages($_FILES['picture']['tmp_name']); |
||
| 259 | |||
| 260 | // Write the original image file to disk. |
||
| 261 | // TODO: define a constant for image quality. |
||
|
0 ignored issues
–
show
|
|||
| 262 | ImageJPEG($images[0], IMAGE_PATH . $user->id . '.jpg'); |
||
|
0 ignored issues
–
show
|
|||
| 263 | ImageJPEG($images[1], IMAGE_PATH . $user->id . '_sm.jpg'); |
||
|
0 ignored issues
–
show
|
|||
| 264 | } |
||
| 265 | $response1 = sanitize_html($response1); |
||
| 266 | $response2 = sanitize_html($response2); |
||
| 267 | |||
| 268 | $has_picture = $has_picture?1:0; |
||
| 269 | if ($profile) { |
||
| 270 | $query = " response1 = '".BoincDb::escape_string($response1)."'," |
||
| 271 | ." response2 = '".BoincDb::escape_string($response2)."'," |
||
| 272 | ." language = '".BoincDb::escape_string($language)."'," |
||
| 273 | ." has_picture = $has_picture," |
||
| 274 | ." verification = $profile->verification" |
||
| 275 | ." WHERE userid = $user->id"; |
||
| 276 | $result = BoincProfile::update_aux($query); |
||
| 277 | if (!$result) { |
||
| 278 | error_page(tra("Could not update the profile: database error")); |
||
| 279 | } |
||
| 280 | } else { |
||
| 281 | $query = 'SET ' |
||
| 282 | ." userid=$user->id," |
||
| 283 | ." language = '".BoincDb::escape_string($language)."'," |
||
| 284 | ." response1 = '".BoincDb::escape_string($response1)."'," |
||
| 285 | ." response2 = '".BoincDb::escape_string($response2)."'," |
||
| 286 | ." has_picture = $has_picture," |
||
| 287 | ." recommend=0, " |
||
| 288 | ." reject=0, " |
||
| 289 | ." posts=0, " |
||
| 290 | ." uotd_time=0, " |
||
| 291 | ." verification=0"; |
||
| 292 | $result = BoincProfile::insert($query); |
||
| 293 | if (!$result) { |
||
| 294 | error_page(tra("Could not create the profile: database error")); |
||
| 295 | } |
||
| 296 | } |
||
| 297 | $user->update("has_profile=1"); |
||
| 298 | |||
| 299 | page_head(tra("Profile saved")); |
||
| 300 | |||
| 301 | echo tra("Congratulations! Your profile was successfully entered into our database.") |
||
| 302 | ."<br><br>" |
||
| 303 | ."<a href=\"view_profile.php?userid=".$user->id."\">" |
||
| 304 | .tra("View your profile") |
||
| 305 | ."</a><br>" |
||
| 306 | ; |
||
|
0 ignored issues
–
show
|
|||
| 307 | page_tail(); |
||
| 308 | } |
||
| 309 | |||
| 310 | function show_profile_form($profile, $warning=null) { |
||
| 311 | if ($profile) { |
||
| 312 | page_head(tra("Edit your profile"), null, null, null, boinc_recaptcha_get_head_extra()); |
||
| 313 | } else { |
||
| 314 | page_head(tra("Create a profile"), null, null, null, boinc_recaptcha_get_head_extra()); |
||
| 315 | } |
||
| 316 | |||
| 317 | if ($warning) { |
||
| 318 | echo "<p class=\"text-danger\">$warning</p> |
||
| 319 | "; |
||
| 320 | } |
||
| 321 | |||
| 322 | echo " |
||
| 323 | <form action=", $_SERVER['PHP_SELF'], " method=\"POST\", ENCTYPE=\"multipart/form-data\"> |
||
| 324 | "; |
||
| 325 | start_table(); |
||
| 326 | show_description(); |
||
| 327 | show_questions($profile); |
||
| 328 | show_picture_option($profile); |
||
| 329 | show_submit(); |
||
| 330 | end_table(); |
||
| 331 | echo "</form>"; |
||
| 332 | page_tail(); |
||
| 333 | |||
| 334 | } |
||
| 335 | |||
| 336 | $user = get_logged_in_user(true); |
||
| 337 | if (VALIDATE_EMAIL_TO_POST) { |
||
| 338 | check_validated_email($user); |
||
| 339 | } |
||
| 340 | |||
| 341 | $profile = get_profile($user->id); |
||
| 342 | $config = get_config(); |
||
| 343 | $min_credit = parse_config($config, "<profile_min_credit>"); |
||
| 344 | if ($min_credit && $user->expavg_credit < $min_credit) { |
||
| 345 | error_page( |
||
| 346 | tra("To prevent spam, an average credit of %1 or greater is required to create or edit a profile. We apologize for this inconvenience.", $min_credit) |
||
| 347 | ); |
||
| 348 | } |
||
| 349 | |||
| 350 | if (post_str("submit", true)) { |
||
| 351 | process_create_profile($user, $profile); |
||
| 352 | clear_cache_entry("view_profile.php", "userid=$user->id"); |
||
| 353 | exit; |
||
| 354 | } |
||
| 355 | |||
| 356 | show_profile_form($profile); |
||
| 357 | |||
| 358 | ?> |
||
| 359 |