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
![]() |
|||
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 |