Total Complexity | 84 |
Total Lines | 775 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like Profile often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Profile, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
37 | class Profile extends AbstractController |
||
38 | { |
||
39 | /** @var bool If the save was successful or not */ |
||
40 | private $completedSave = false; |
||
41 | |||
42 | /** @var null If this was a request to save an update */ |
||
43 | private $isSaving; |
||
44 | |||
45 | /** @var null What it says, on completion */ |
||
46 | private $_force_redirect; |
||
47 | |||
48 | /** @var array|bool Holds the output of createMenu for the profile areas */ |
||
49 | private $_profile_include_data; |
||
50 | |||
51 | /** @var string The current area chosen from the menu */ |
||
52 | private $_current_area; |
||
53 | |||
54 | /** @var string The current subsection, if any, of the area chosen */ |
||
55 | private $_current_subsection; |
||
56 | |||
57 | /** @var int Member id for the history being viewed */ |
||
58 | private $_memID = 0; |
||
59 | |||
60 | /** @var Member The \ElkArte\Member object is stored here to avoid some global */ |
||
61 | private $_profile; |
||
62 | |||
63 | /** |
||
64 | * Called before all other methods when coming from the dispatcher or |
||
65 | * action class. |
||
66 | */ |
||
67 | public function pre_dispatch() |
||
68 | { |
||
69 | require_once(SUBSDIR . '/Menu.subs.php'); |
||
70 | require_once(SUBSDIR . '/Profile.subs.php'); |
||
71 | |||
72 | $this->_memID = currentMemberID(); |
||
73 | MembersList::load($this->_memID, false, 'profile'); |
||
74 | $this->_profile = MembersList::get($this->_memID); |
||
|
|||
75 | } |
||
76 | |||
77 | /** |
||
78 | * Allow the change or view of profiles. |
||
79 | * |
||
80 | * - Fires the pre_load event |
||
81 | * |
||
82 | * @see AbstractController::action_index |
||
83 | */ |
||
84 | public function action_index() |
||
85 | { |
||
86 | global $txt, $context, $cur_profile, $profile_vars, $post_errors; |
||
87 | |||
88 | // Don't reload this as we may have processed error strings. |
||
89 | if (empty($post_errors)) |
||
90 | { |
||
91 | Txt::load('Profile'); |
||
92 | } |
||
93 | |||
94 | theme()->getTemplates()->load('Profile'); |
||
95 | |||
96 | // Trigger profile pre-load event |
||
97 | $this->_events->trigger('pre_load', ['post_errors' => $post_errors]); |
||
98 | |||
99 | // A little bit about this member |
||
100 | $context['id_member'] = $this->_memID; |
||
101 | $cur_profile = $this->_profile; |
||
102 | |||
103 | // Let's have some information about this member ready, too. |
||
104 | $context['member'] = $this->_profile; |
||
105 | $context['member']->loadContext(); |
||
106 | |||
107 | // Is this their own profile or are they looking at someone else? |
||
108 | $context['user']['is_owner'] = $this->_memID === (int) $this->user->id; |
||
109 | |||
110 | // Create the menu of profile options |
||
111 | $this->_define_profile_menu(); |
||
112 | |||
113 | // Is there an updated message to show? |
||
114 | if (isset($this->_req->query->updated)) |
||
115 | { |
||
116 | $context['push_alert'] = $_SESSION['push_enabled'] ?? null; |
||
117 | unset($_SESSION['push_enabled']); |
||
118 | $context['profile_updated'] = $txt['profile_updated_own']; |
||
119 | } |
||
120 | |||
121 | // If it said no permissions that meant it wasn't valid! |
||
122 | if (empty($this->_profile_include_data['permission'])) |
||
123 | { |
||
124 | throw new Exception('no_access', false); |
||
125 | } |
||
126 | |||
127 | // Choose the right permission set and do a pat check for good measure. |
||
128 | $this->_profile_include_data['permission'] = $this->_profile_include_data['permission'][$context['user']['is_owner'] ? 'own' : 'any']; |
||
129 | isAllowedTo($this->_profile_include_data['permission']); |
||
130 | |||
131 | // Set the selected item - now it's been validated. |
||
132 | $this->_current_area = $this->_profile_include_data['current_area']; |
||
133 | $this->_current_subsection = $this->_profile_include_data['current_subsection'] ?? ''; |
||
134 | $context['menu_item_selected'] = $this->_current_area; |
||
135 | |||
136 | // Before we go any further, let's work on the area we've said is valid. |
||
137 | // Note this is done here just in case we ever compromise the menu function in error! |
||
138 | $context['do_preview'] = isset($this->_req->post->preview_signature); |
||
139 | $this->isSaving = $this->_req->getRequest('save', 'trim'); |
||
140 | |||
141 | // Session validation and/or Token Checks |
||
142 | $this->_check_access(); |
||
143 | |||
144 | // Build the link tree. |
||
145 | $this->_build_profile_breadcrumbs(); |
||
146 | |||
147 | // Set the template for this area... if you still can :P |
||
148 | // and add the profile layer. |
||
149 | $context['sub_template'] = $this->_profile_include_data['function']; |
||
150 | theme()->getLayers()->add('profile'); |
||
151 | |||
152 | // Need JS if we made it this far |
||
153 | loadJavascriptFile('profile.js'); |
||
154 | |||
155 | // Right - are we saving - if so let's save the old data first. |
||
156 | $this->_save_updates(); |
||
157 | |||
158 | // Have some errors for some reason? |
||
159 | // @todo check that this can be safely removed. |
||
160 | if (!empty($post_errors)) |
||
161 | { |
||
162 | // Set all the errors so the template knows what went wrong. |
||
163 | foreach ($post_errors as $error_type) |
||
164 | { |
||
165 | $context['modify_error'][$error_type] = true; |
||
166 | } |
||
167 | } |
||
168 | // If it's you then we should redirect upon save. |
||
169 | elseif (!empty($profile_vars) && $context['user']['is_owner'] && !$context['do_preview']) |
||
170 | { |
||
171 | redirectexit('action=profile;area=' . $this->_current_area . (empty($this->_current_subsection) ? '' : ';sa=' . $this->_current_subsection) . ';updated'); |
||
172 | } |
||
173 | elseif (!empty($this->_force_redirect)) |
||
174 | { |
||
175 | redirectexit('action=profile' . ($context['user']['is_owner'] ? '' : ';u=' . $this->_memID) . ';area=' . $this->_current_area); |
||
176 | } |
||
177 | |||
178 | // Set the page title if it's not already set... |
||
179 | if (!isset($context['page_title'])) |
||
180 | { |
||
181 | $context['page_title'] = $txt['profile'] . (isset($txt[$this->_current_area]) ? ' - ' . $txt[$this->_current_area] : ''); |
||
182 | } |
||
183 | |||
184 | // And off we go, |
||
185 | $action = new Action(); |
||
186 | $action->initialize(['action' => $this->_profile_include_data]); |
||
187 | $action->dispatch('action'); |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Define all the sections within the profile area! |
||
192 | * |
||
193 | * We start by defining the permission required - then we take this and turn |
||
194 | * it into the relevant context ;) |
||
195 | * |
||
196 | * Possible fields: |
||
197 | * For Section: |
||
198 | * - string $title: Section title. |
||
199 | * - array $areas: Array of areas within this section. |
||
200 | * |
||
201 | * For Areas: |
||
202 | * - string $label: Text string that will be used to show the area in the menu. |
||
203 | * - string $file: Optional text string that may contain a file name that's needed for inclusion in order to display the area properly. |
||
204 | * - string $custom_url: Optional href for area. |
||
205 | * - string $function: Function to execute for this section. |
||
206 | * - bool $enabled: Should area be shown? |
||
207 | * - string $sc: Session check validation to do on save - note without this save will get unset - if set. |
||
208 | * - bool $hidden: Does this not actually appear on the menu? |
||
209 | * - bool $password: Whether to require the user's password in order to save the data in the area. |
||
210 | * - array $subsections: Array of subsections, in order of appearance. |
||
211 | * - array $permission: Array of permissions to determine who can access this area. Should contain arrays $own and $any. |
||
212 | */ |
||
213 | private function _define_profile_menu() |
||
214 | { |
||
215 | global $txt, $context, $modSettings; |
||
216 | |||
217 | $profile_areas = [ |
||
218 | 'info' => [ |
||
219 | 'title' => $txt['profileInfo'], |
||
220 | 'areas' => [ |
||
221 | 'summary' => [ |
||
222 | 'label' => $txt['summary'], |
||
223 | 'controller' => ProfileInfo::class, |
||
224 | 'function' => 'action_summary', |
||
225 | // From the summary it's possible to activate an account, so we need the token |
||
226 | 'token' => 'profile-aa%u', |
||
227 | 'token_type' => 'get', |
||
228 | 'permission' => [ |
||
229 | 'own' => 'profile_view_own', |
||
230 | 'any' => 'profile_view_any', |
||
231 | ], |
||
232 | ], |
||
233 | 'statistics' => [ |
||
234 | 'label' => $txt['statPanel'], |
||
235 | 'controller' => ProfileInfo::class, |
||
236 | 'function' => 'action_statPanel', |
||
237 | 'permission' => [ |
||
238 | 'own' => 'profile_view_own', |
||
239 | 'any' => 'profile_view_any', |
||
240 | ], |
||
241 | ], |
||
242 | 'showposts' => [ |
||
243 | 'label' => $txt['showPosts'], |
||
244 | 'controller' => ProfileInfo::class, |
||
245 | 'function' => 'action_showPosts', |
||
246 | 'subsections' => [ |
||
247 | 'messages' => [$txt['showMessages'], ['profile_view_own', 'profile_view_any']], |
||
248 | 'topics' => [$txt['showTopics'], ['profile_view_own', 'profile_view_any']], |
||
249 | 'unwatchedtopics' => [$txt['showUnwatched'], ['profile_view_own', 'profile_view_any'], 'enabled' => $modSettings['enable_unwatch'] && $context['user']['is_owner']], |
||
250 | 'attach' => [$txt['showAttachments'], ['profile_view_own', 'profile_view_any']], |
||
251 | ], |
||
252 | 'permission' => [ |
||
253 | 'own' => 'profile_view_own', |
||
254 | 'any' => 'profile_view_any', |
||
255 | ], |
||
256 | ], |
||
257 | 'showlikes' => [ |
||
258 | 'label' => $txt['likes_show'], |
||
259 | 'controller' => Likes::class, |
||
260 | 'function' => 'action_showProfileLikes', |
||
261 | 'enabled' => !empty($modSettings['likes_enabled']) && $context['user']['is_owner'], |
||
262 | 'subsections' => [ |
||
263 | 'given' => [$txt['likes_given'], ['profile_view_own']], |
||
264 | 'received' => [$txt['likes_received'], ['profile_view_own']], |
||
265 | ], |
||
266 | 'permission' => [ |
||
267 | 'own' => 'profile_view_own', |
||
268 | 'any' => [], |
||
269 | ], |
||
270 | ], |
||
271 | 'permissions' => [ |
||
272 | 'label' => $txt['showPermissions'], |
||
273 | 'controller' => ProfileInfo::class, |
||
274 | 'function' => 'action_showPermissions', |
||
275 | 'permission' => [ |
||
276 | 'own' => 'manage_permissions', |
||
277 | 'any' => 'manage_permissions', |
||
278 | ], |
||
279 | ], |
||
280 | 'history' => [ |
||
281 | 'label' => $txt['history'], |
||
282 | 'controller' => ProfileHistory::class, |
||
283 | 'function' => 'action_index', |
||
284 | 'subsections' => [ |
||
285 | 'activity' => [$txt['trackActivity'], 'moderate_forum'], |
||
286 | 'ip' => [$txt['trackIP'], 'moderate_forum'], |
||
287 | 'edits' => [$txt['trackEdits'], 'moderate_forum', 'enabled' => featureEnabled('ml') && !empty($modSettings['userlog_enabled'])], |
||
288 | 'logins' => [$txt['trackLogins'], ['profile_view_own', 'moderate_forum']], |
||
289 | ], |
||
290 | 'permission' => [ |
||
291 | 'own' => 'moderate_forum', |
||
292 | 'any' => 'moderate_forum', |
||
293 | ], |
||
294 | ], |
||
295 | 'viewwarning' => [ |
||
296 | 'label' => $txt['profile_view_warnings'], |
||
297 | 'enabled' => featureEnabled('w') && !empty($modSettings['warning_enable']) && $this->_profile['warning'] && (!empty($modSettings['warning_show']) && ($context['user']['is_owner'] || $modSettings['warning_show'] == 2)), |
||
298 | 'controller' => ProfileInfo::class, |
||
299 | 'function' => 'action_viewWarning', |
||
300 | 'permission' => [ |
||
301 | 'own' => 'profile_view_own', |
||
302 | 'any' => 'issue_warning', |
||
303 | ], |
||
304 | ], |
||
305 | ], |
||
306 | ], |
||
307 | 'edit_profile' => [ |
||
308 | 'title' => $txt['profileEdit'], |
||
309 | 'areas' => [ |
||
310 | 'account' => [ |
||
311 | 'label' => $txt['account'], |
||
312 | 'controller' => ProfileOptions::class, |
||
313 | 'function' => 'action_account', |
||
314 | 'enabled' => $context['user']['is_admin'] || ((int) $this->_profile['id_group'] !== 1 && !in_array(1, array_map('intval', explode(',', $this->_profile['additional_groups'])), true)), 'sc' => 'post', |
||
315 | 'token' => 'profile-ac%u', |
||
316 | 'password' => true, |
||
317 | 'permission' => [ |
||
318 | 'own' => ['profile_identity_any', 'profile_identity_own', 'manage_membergroups'], |
||
319 | 'any' => ['profile_identity_any', 'manage_membergroups'], |
||
320 | ], |
||
321 | ], |
||
322 | 'forumprofile' => [ |
||
323 | 'label' => $txt['forumprofile'], |
||
324 | 'controller' => ProfileOptions::class, |
||
325 | 'function' => 'action_forumProfile', |
||
326 | 'sc' => 'post', |
||
327 | 'token' => 'profile-fp%u', |
||
328 | 'permission' => [ |
||
329 | 'own' => ['profile_extra_any', 'profile_extra_own', 'profile_title_own', 'profile_title_any'], |
||
330 | 'any' => ['profile_extra_any', 'profile_title_any'], |
||
331 | ], |
||
332 | ], |
||
333 | 'theme' => [ |
||
334 | 'label' => $txt['theme'], |
||
335 | 'controller' => ProfileOptions::class, |
||
336 | 'function' => 'action_themepick', |
||
337 | 'sc' => 'post', |
||
338 | 'token' => 'profile-th%u', |
||
339 | 'permission' => [ |
||
340 | 'own' => ['profile_extra_any', 'profile_extra_own'], |
||
341 | 'any' => ['profile_extra_any'], |
||
342 | ], |
||
343 | ], |
||
344 | 'pick' => [ |
||
345 | 'label' => $txt['theme'], |
||
346 | 'controller' => ProfileOptions::class, |
||
347 | 'function' => 'action_pick', |
||
348 | 'hidden' => true, |
||
349 | 'sc' => 'post', |
||
350 | 'token' => 'profile-th%u', |
||
351 | 'permission' => [ |
||
352 | 'own' => ['profile_extra_any', 'profile_extra_own'], |
||
353 | 'any' => ['profile_extra_any'], |
||
354 | ], |
||
355 | ], |
||
356 | 'notification' => [ |
||
357 | 'label' => $txt['notifications'], |
||
358 | 'controller' => ProfileOptions::class, |
||
359 | 'function' => 'action_notification', |
||
360 | 'sc' => 'post', |
||
361 | 'token' => 'profile-nt%u', |
||
362 | 'subsections' => [ |
||
363 | 'settings' => [$txt['notify_settings']], |
||
364 | 'boards' => [$txt['notify_boards']], |
||
365 | 'topics' => [$txt['notify_topics']], |
||
366 | ], |
||
367 | 'permission' => [ |
||
368 | 'own' => ['profile_extra_any', 'profile_extra_own'], |
||
369 | 'any' => ['profile_extra_any'], |
||
370 | ], |
||
371 | ], |
||
372 | // Without profile_extra_own, settings are accessible from the PM section. |
||
373 | // @todo at some point decouple it from PMs |
||
374 | 'contactprefs' => [ |
||
375 | 'label' => $txt['contactprefs'], |
||
376 | 'controller' => ProfileOptions::class, |
||
377 | 'function' => 'action_pmprefs', |
||
378 | 'enabled' => allowedTo(['profile_extra_own', 'profile_extra_any']), |
||
379 | 'sc' => 'post', |
||
380 | 'token' => 'profile-pm%u', |
||
381 | 'permission' => [ |
||
382 | 'own' => ['pm_read'], |
||
383 | 'any' => ['profile_extra_any'], |
||
384 | ], |
||
385 | ], |
||
386 | 'ignoreboards' => [ |
||
387 | 'label' => $txt['ignoreboards'], |
||
388 | 'controller' => ProfileOptions::class, |
||
389 | 'function' => 'action_ignoreboards', |
||
390 | 'enabled' => !empty($modSettings['allow_ignore_boards']), |
||
391 | 'sc' => 'post', |
||
392 | 'token' => 'profile-ib%u', |
||
393 | 'permission' => [ |
||
394 | 'own' => ['profile_extra_any', 'profile_extra_own'], |
||
395 | 'any' => ['profile_extra_any'], |
||
396 | ], |
||
397 | ], |
||
398 | 'lists' => [ |
||
399 | 'label' => $txt['editBuddyIgnoreLists'], |
||
400 | 'controller' => ProfileOptions::class, |
||
401 | 'function' => 'action_editBuddyIgnoreLists', |
||
402 | 'enabled' => !empty($modSettings['enable_buddylist']) && $context['user']['is_owner'], |
||
403 | 'sc' => 'post', |
||
404 | 'token' => 'profile-bl%u', |
||
405 | 'subsections' => [ |
||
406 | 'buddies' => [$txt['editBuddies']], |
||
407 | 'ignore' => [$txt['editIgnoreList']], |
||
408 | ], |
||
409 | 'permission' => [ |
||
410 | 'own' => ['profile_extra_any', 'profile_extra_own'], |
||
411 | 'any' => [], |
||
412 | ], |
||
413 | ], |
||
414 | 'groupmembership' => [ |
||
415 | 'label' => $txt['groupmembership'], |
||
416 | 'controller' => ProfileOptions::class, |
||
417 | 'function' => 'action_groupMembership', |
||
418 | 'enabled' => !empty($modSettings['show_group_membership']) && $context['user']['is_owner'], |
||
419 | 'sc' => 'request', |
||
420 | 'token' => 'profile-gm%u', |
||
421 | 'token_type' => 'request', |
||
422 | 'permission' => [ |
||
423 | 'own' => ['profile_view_own'], |
||
424 | 'any' => ['manage_membergroups'], |
||
425 | ], |
||
426 | ], |
||
427 | ], |
||
428 | ], |
||
429 | 'profile_action' => [ |
||
430 | 'title' => $txt['profileAction'], |
||
431 | 'areas' => [ |
||
432 | 'sendpm' => [ |
||
433 | 'label' => $txt['profileSendIm'], |
||
434 | 'custom_url' => getUrl('action', ['action' => 'pm', 'sa' => 'send']), |
||
435 | 'permission' => [ |
||
436 | 'own' => [], |
||
437 | 'any' => ['pm_send'], |
||
438 | ], |
||
439 | ], |
||
440 | 'issuewarning' => [ |
||
441 | 'label' => $txt['profile_issue_warning'], |
||
442 | 'enabled' => featureEnabled('w') && !empty($modSettings['warning_enable']) && (!$context['user']['is_owner'] || $context['user']['is_admin']), |
||
443 | 'controller' => ProfileAccount::class, |
||
444 | 'function' => 'action_issuewarning', |
||
445 | 'token' => 'profile-iw%u', |
||
446 | 'permission' => [ |
||
447 | 'own' => [], |
||
448 | 'any' => ['issue_warning'], |
||
449 | ], |
||
450 | ], |
||
451 | 'banuser' => [ |
||
452 | 'label' => $txt['profileBanUser'], |
||
453 | 'custom_url' => getUrl('admin', ['action' => 'admin', 'area' => 'ban', 'sa' => 'add']), |
||
454 | 'enabled' => (int) $this->_profile['id_group'] !== 1 && !in_array(1, array_map('intval', explode(',', $this->_profile['additional_groups'])), true), |
||
455 | 'permission' => [ |
||
456 | 'own' => [], |
||
457 | 'any' => ['manage_bans'], |
||
458 | ], |
||
459 | ], |
||
460 | 'subscriptions' => [ |
||
461 | 'label' => $txt['subscriptions'], |
||
462 | 'controller' => ProfileSubscriptions::class, |
||
463 | 'function' => 'action_subscriptions', |
||
464 | 'enabled' => !empty($modSettings['paid_enabled']), |
||
465 | 'permission' => [ |
||
466 | 'own' => ['profile_view_own'], |
||
467 | 'any' => ['moderate_forum'], |
||
468 | ], |
||
469 | ], |
||
470 | 'deleteaccount' => [ |
||
471 | 'label' => $txt['deleteAccount'], |
||
472 | 'controller' => ProfileAccount::class, |
||
473 | 'function' => 'action_deleteaccount', |
||
474 | 'sc' => 'post', |
||
475 | 'token' => 'profile-da%u', |
||
476 | 'password' => true, |
||
477 | 'permission' => [ |
||
478 | 'own' => ['profile_remove_any', 'profile_remove_own'], |
||
479 | 'any' => ['profile_remove_any'], |
||
480 | ], |
||
481 | ], |
||
482 | 'activateaccount' => [ |
||
483 | 'controller' => ProfileAccount::class, |
||
484 | 'function' => 'action_activateaccount', |
||
485 | 'sc' => 'get', |
||
486 | 'token' => 'profile-aa%u', |
||
487 | 'token_type' => 'get', |
||
488 | 'permission' => [ |
||
489 | 'own' => [], |
||
490 | 'any' => ['moderate_forum'], |
||
491 | ], |
||
492 | ], |
||
493 | ], |
||
494 | ], |
||
495 | ]; |
||
496 | |||
497 | // Set a few options for the menu. |
||
498 | $menuOptions = [ |
||
499 | 'disable_url_session_check' => true, |
||
500 | 'hook' => 'profile', |
||
501 | 'extra_url_parameters' => [ |
||
502 | 'u' => $context['id_member'], |
||
503 | ], |
||
504 | ]; |
||
505 | |||
506 | // Actually create the menu! |
||
507 | $this->_profile_include_data = (new Menu()) |
||
508 | ->addMenuData($profile_areas) |
||
509 | ->addOptions($menuOptions) |
||
510 | ->prepareMenu() |
||
511 | ->setContext() |
||
512 | ->getIncludeData(); |
||
513 | |||
514 | unset($profile_areas); |
||
515 | |||
516 | // Make a note of the Unique ID for this menu. |
||
517 | $context['profile_menu_id'] = $context['max_menu_id']; |
||
518 | $context['profile_menu_name'] = 'menu_data_' . $context['profile_menu_id']; |
||
519 | } |
||
520 | |||
521 | /** |
||
522 | * Does session and token checks for the areas that require those |
||
523 | */ |
||
524 | private function _check_access() |
||
525 | { |
||
526 | global $context; |
||
527 | |||
528 | // Check the session, if required, and they are trying to save |
||
529 | $this->completedSave = false; |
||
530 | if (isset($this->_profile_include_data['sc']) && ($this->isSaving !== null || $context['do_preview'])) |
||
531 | { |
||
532 | checkSession($this->_profile_include_data['sc']); |
||
533 | $this->completedSave = true; |
||
534 | } |
||
535 | |||
536 | // Does this require admin/moderator session validating? |
||
537 | if ($this->isSaving !== null && !$context['user']['is_owner']) |
||
538 | { |
||
539 | validateSession(); |
||
540 | } |
||
541 | |||
542 | // Do we need to perform a token check? |
||
543 | if (!empty($this->_profile_include_data['token'])) |
||
544 | { |
||
545 | $token_name = str_replace('%u', $context['id_member'], $this->_profile_include_data['token']); |
||
546 | $token_type = $this->_profile_include_data['tokenType'] ?? 'post'; |
||
547 | |||
548 | if (!in_array($token_type, ['request', 'post', 'get'])) |
||
549 | { |
||
550 | $token_type = 'post'; |
||
551 | } |
||
552 | |||
553 | if ($this->isSaving !== null) |
||
554 | { |
||
555 | validateToken($token_name, $token_type); |
||
556 | } |
||
557 | |||
558 | createToken($token_name, $token_type); |
||
559 | $context['token_check'] = $token_name; |
||
560 | } |
||
561 | } |
||
562 | |||
563 | /** |
||
564 | * Just builds the link tree based on where were are in the profile section |
||
565 | * and whose profile is being viewed, etc. |
||
566 | */ |
||
567 | private function _build_profile_breadcrumbs() |
||
568 | { |
||
569 | global $context, $txt; |
||
570 | |||
571 | $context['breadcrumbs'][] = [ |
||
572 | 'url' => getUrl('profile', ['action' => 'profile', 'u' => $this->_memID, 'name' => $this->_profile['real_name']]), |
||
573 | 'name' => sprintf($txt['profile_of_username'], $context['member']['name']), |
||
574 | ]; |
||
575 | |||
576 | if (!empty($this->_profile_include_data['label'])) |
||
577 | { |
||
578 | $context['breadcrumbs'][] = [ |
||
579 | 'url' => getUrl('profile', ['action' => 'profile', 'area' => $this->_profile_include_data['current_area'], 'u' => $this->_memID, 'name' => $this->_profile['real_name']]), |
||
580 | 'name' => $this->_profile_include_data['label'], |
||
581 | ]; |
||
582 | } |
||
583 | |||
584 | if (empty($this->_current_subsection)) |
||
585 | { |
||
586 | return; |
||
587 | } |
||
588 | |||
589 | if (!isset($this->_profile_include_data['subsections'][$this->_current_subsection])) |
||
590 | { |
||
591 | return; |
||
592 | } |
||
593 | |||
594 | if ($this->_profile_include_data['subsections'][$this->_current_subsection]['label'] === $this->_profile_include_data['label']) |
||
595 | { |
||
596 | return; |
||
597 | } |
||
598 | |||
599 | $context['breadcrumbs'][] = [ |
||
600 | 'url' => getUrl('profile', ['action' => 'profile', 'area' => $this->_profile_include_data['current_area'], 'sa' => $this->_current_subsection, 'u' => $this->_memID, 'name' => $this->_profile['real_name']]), |
||
601 | 'name' => $this->_profile_include_data['subsections'][$this->_current_subsection]['label'], |
||
602 | ]; |
||
603 | } |
||
604 | |||
605 | /** |
||
606 | * Save profile updates |
||
607 | */ |
||
608 | private function _save_updates() |
||
771 | } |
||
772 | } |
||
773 | } |
||
774 | |||
775 | /** |
||
776 | * If a password validation before a change is needed, this is the function to do it |
||
777 | * |
||
778 | * @param bool $check_password if this profile update requires a password verification |
||
779 | * @throws Exception |
||
780 | */ |
||
781 | private function _check_password($check_password) |
||
812 | } |
||
813 | } |
||
816 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.