Skip to content

Commit 133e42e

Browse files
committed
Begin with a well-defined sub-action interface
Signed-off-by: John Rayes <live627@gmail.com>
1 parent 01f5677 commit 133e42e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1141
-2141
lines changed

Sources/Actions/Activate.php

+64-70
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
use SMF\Lang;
2525
use SMF\Logging;
2626
use SMF\Mail;
27+
use SMF\ProvidesSubActionInterface;
28+
use SMF\ProvidesSubActionTrait;
2729
use SMF\Security;
2830
use SMF\Theme;
2931
use SMF\User;
@@ -32,34 +34,17 @@
3234
/**
3335
* Activates a user's account.
3436
*/
35-
class Activate implements ActionInterface
37+
class Activate implements ActionInterface, ProvidesSubActionInterface
3638
{
3739
use ActionTrait;
40+
use ProvidesSubActionTrait;
3841

39-
/*******************
40-
* Public properties
41-
*******************/
42+
/*********************
43+
* Internal properties
44+
*********************/
4245

43-
/**
44-
* @var string
45-
*
46-
* The sub-action to call.
47-
*/
48-
public string $subaction = '';
49-
50-
/**************************
51-
* Public static properties
52-
**************************/
53-
54-
/**
55-
* @var array
56-
*
57-
* Available sub-actions.
58-
*/
59-
public static array $subactions = [
60-
'activate' => 'activate',
61-
'resend' => 'resend',
62-
];
46+
private bool $email_change;
47+
private array $row;
6348

6449
/****************
6550
* Public methods
@@ -109,19 +94,19 @@ public function execute(): void
10994
return;
11095
}
11196

112-
$row = Db::$db->fetch_assoc($request);
113-
$row['id_member'] = (int) $row['id_member'];
114-
$row['is_activated'] = (int) $row['is_activated'];
97+
$this->row = Db::$db->fetch_assoc($request);
98+
$this->row['id_member'] = (int) $this->row['id_member'];
99+
$this->row['is_activated'] = (int) $this->row['is_activated'];
115100
Db::$db->free_result($request);
116101

117102
// Change their email address? (they probably tried a fake one first :P.)
118103
if (
119104
!empty($_POST['new_email'])
120105
&& !empty($_REQUEST['passwd'])
121-
&& Security::hashVerifyPassword($row['member_name'], $_REQUEST['passwd'], $row['passwd'])
106+
&& Security::hashVerifyPassword($this->row['member_name'], $_REQUEST['passwd'], $this->row['passwd'])
122107
&& (
123-
$row['is_activated'] == User::NOT_ACTIVATED
124-
|| $row['is_activated'] == User::UNVALIDATED
108+
$this->row['is_activated'] == 0
109+
|| $this->row['is_activated'] == 2
125110
)
126111
) {
127112
if (empty(Config::$modSettings['registration_method']) || Config::$modSettings['registration_method'] == 3) {
@@ -152,80 +137,86 @@ public function execute(): void
152137
}
153138
Db::$db->free_result($request);
154139

155-
User::updateMemberData($row['id_member'], ['email_address' => $_POST['new_email']]);
156-
$row['email_address'] = $_POST['new_email'];
140+
User::updateMemberData($this->row['id_member'], ['email_address' => $_POST['new_email']]);
141+
$this->row['email_address'] = $_POST['new_email'];
157142

158-
$email_change = true;
143+
$this->email_change = true;
159144
}
160145

161-
// Resend the password, but only if the account wasn't activated yet.
162-
if (
163-
!empty($_REQUEST['sa'])
164-
&& $_REQUEST['sa'] == 'resend'
165-
&& in_array((int) $row['is_activated'], [User::NOT_ACTIVATED, User::UNVALIDATED])
166-
&& (($_REQUEST['code'] ?? '') == '')
167-
) {
168-
$replacements = [
169-
'REALNAME' => $row['real_name'],
170-
'USERNAME' => $row['member_name'],
171-
'ACTIVATIONLINK' => Config::$scripturl . '?action=activate;u=' . $row['id_member'] . ';code=' . $row['validation_code'],
172-
'ACTIVATIONLINKWITHOUTCODE' => Config::$scripturl . '?action=activate;u=' . $row['id_member'],
173-
'ACTIVATIONCODE' => $row['validation_code'],
174-
'FORGOTPASSWORDLINK' => Config::$scripturl . '?action=reminder',
175-
];
176-
177-
$emaildata = Mail::loadEmailTemplate('resend_activate_message', $replacements, empty($row['lngfile']) || empty(Config::$modSettings['userLanguage']) ? Lang::$default : $row['lngfile']);
178-
179-
Mail::send($row['email_address'], $emaildata['subject'], $emaildata['body'], null, 'resendact', $emaildata['is_html'], 0);
180-
181-
Utils::$context['page_title'] = Lang::$txt['invalid_activation_resend'];
182-
183-
// This will ensure we don't actually get an error message if it works!
184-
Utils::$context['error_title'] = Lang::$txt['invalid_activation_resend'];
185-
186-
ErrorHandler::fatalLang(!empty($email_change) ? 'change_email_success' : 'resend_email_success', false, []);
187-
}
146+
$this->callSubAction($_REQUEST['sa'] ?? null);
147+
}
188148

149+
public function activate(): void
150+
{
189151
// Quit if this code is not right.
190-
if (empty($_REQUEST['code']) || $row['validation_code'] != $_REQUEST['code']) {
191-
if (!empty($row['is_activated'])) {
152+
if (empty($_REQUEST['code']) || $this->row['validation_code'] != $_REQUEST['code']) {
153+
if (!empty($this->row['is_activated'])) {
192154
ErrorHandler::fatalLang('already_activated', false);
193-
} elseif ($row['validation_code'] == '') {
155+
} elseif ($this->row['validation_code'] == '') {
194156
Lang::load('Profile');
195-
ErrorHandler::fatal(Lang::getTxt('registration_not_approved', ['url' => Config::$scripturl . '?action=activate;user=' . $row['member_name']]), false);
157+
ErrorHandler::fatal(Lang::getTxt('registration_not_approved', ['url' => Config::$scripturl . '?action=activate;user=' . $this->row['member_name']]), false);
196158
}
197159

198160
Utils::$context['sub_template'] = 'retry_activate';
199161
Utils::$context['page_title'] = Lang::$txt['invalid_activation_code'];
200-
Utils::$context['member_id'] = $row['id_member'];
162+
Utils::$context['member_id'] = $this->row['id_member'];
201163

202164
return;
203165
}
204166

205167
// Let the integration know that they've been activated!
206-
IntegrationHook::call('integrate_activate', [$row['member_name']]);
168+
IntegrationHook::call('integrate_activate', [$this->row['member_name']]);
207169

208170
// Validation complete - update the database!
209-
User::updateMemberData($row['id_member'], ['is_activated' => User::ACTIVATED, 'validation_code' => '']);
171+
User::updateMemberData($this->row['id_member'], ['is_activated' => 1, 'validation_code' => '']);
210172

211173
// Also do a proper member stat re-evaluation.
212174
Logging::updateStats('member', false);
213175

214176
// Notify the admin about new activations, but not re-activations.
215-
if (empty($row['is_activated'])) {
216-
Mail::adminNotify('activation', $row['id_member'], $row['member_name']);
177+
if (empty($this->row['is_activated'])) {
178+
Mail::adminNotify('activation', $this->row['id_member'], $this->row['member_name']);
217179
}
218180

219181
Utils::$context += [
220182
'page_title' => Lang::$txt['registration_successful'],
221183
'sub_template' => 'login',
222-
'default_username' => $row['member_name'],
184+
'default_username' => $this->row['member_name'],
223185
'default_password' => '',
224186
'never_expire' => false,
225187
'description' => Lang::$txt['activate_success'],
226188
];
227189
}
228190

191+
public function resend(): void
192+
{
193+
// Resend the password, but only if the account wasn't activated yet.
194+
if (
195+
in_array($this->row['is_activated'], [0, 2])
196+
&& (!isset($_REQUEST['code']) || $_REQUEST['code'] == '')
197+
) {
198+
$replacements = [
199+
'REALNAME' => $this->row['real_name'],
200+
'USERNAME' => $this->row['member_name'],
201+
'ACTIVATIONLINK' => Config::$scripturl . '?action=activate;u=' . $this->row['id_member'] . ';code=' . $this->row['validation_code'],
202+
'ACTIVATIONLINKWITHOUTCODE' => Config::$scripturl . '?action=activate;u=' . $this->row['id_member'],
203+
'ACTIVATIONCODE' => $this->row['validation_code'],
204+
'FORGOTPASSWORDLINK' => Config::$scripturl . '?action=reminder',
205+
];
206+
207+
$emaildata = Mail::loadEmailTemplate('resend_activate_message', $replacements, empty($this->row['lngfile']) || empty(Config::$modSettings['userLanguage']) ? Lang::$default : $this->row['lngfile']);
208+
209+
Mail::send($this->row['email_address'], $emaildata['subject'], $emaildata['body'], null, 'resendact', $emaildata['is_html'], 0);
210+
211+
Utils::$context['page_title'] = Lang::$txt['invalid_activation_resend'];
212+
213+
// This will ensure we don't actually get an error message if it works!
214+
Utils::$context['error_title'] = Lang::$txt['invalid_activation_resend'];
215+
216+
ErrorHandler::fatalLang($this->email_change ? 'change_email_success' : 'resend_email_success', false, []);
217+
}
218+
}
219+
229220
/******************
230221
* Internal methods
231222
******************/
@@ -235,6 +226,9 @@ public function execute(): void
235226
*/
236227
protected function __construct()
237228
{
229+
$this->addSubAction('activate', [$this, 'activate']);
230+
$this->addSubAction('resend', [$this, 'resend']);
231+
238232
// Logged in users should not bother to activate their accounts
239233
if (!empty(User::$me->id)) {
240234
Utils::redirectexit();

Sources/Actions/Admin/Attachments.php

+25-55
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
use SMF\ItemList;
3030
use SMF\Lang;
3131
use SMF\Menu;
32+
use SMF\ProvidesSubActionInterface;
33+
use SMF\ProvidesSubActionTrait;
3234
use SMF\Sapi;
3335
use SMF\SecurityToken;
3436
use SMF\Theme;
@@ -41,47 +43,12 @@
4143
/**
4244
* Maintains and manages attachments and avatars.
4345
*/
44-
class Attachments implements ActionInterface
46+
class Attachments implements ActionInterface, ProvidesSubActionInterface
4547
{
4648
use ActionTrait;
47-
49+
use ProvidesSubActionTrait;
4850
use BackwardCompatibility;
4951

50-
/*******************
51-
* Public properties
52-
*******************/
53-
54-
/**
55-
* @var string
56-
*
57-
* The requested sub-action.
58-
* This should be set by the constructor.
59-
*/
60-
public string $subaction = 'browse';
61-
62-
/**************************
63-
* Public static properties
64-
**************************/
65-
66-
/**
67-
* @var array
68-
*
69-
* Available sub-actions.
70-
*/
71-
public static array $subactions = [
72-
'attachments' => 'attachmentSettings',
73-
'avatars' => 'avatarSettings',
74-
'browse' => 'browse',
75-
'maintenance' => 'maintain',
76-
'remove' => 'remove',
77-
'byage' => 'removeByAge',
78-
'bysize' => 'removeBySize',
79-
'removeall' => 'removeAll',
80-
'repair' => 'repair',
81-
'attachpaths' => 'paths',
82-
'transfer' => 'transfer',
83-
];
84-
8552
/****************
8653
* Public methods
8754
****************/
@@ -91,11 +58,9 @@ class Attachments implements ActionInterface
9158
*/
9259
public function execute(): void
9360
{
94-
$call = method_exists($this, self::$subactions[$this->subaction]) ? [$this, self::$subactions[$this->subaction]] : Utils::getCallable(self::$subactions[$this->subaction]);
61+
IntegrationHook::call('integrate_manage_attachments', [&$this->sub_actions]);
9562

96-
if (!empty($call)) {
97-
call_user_func($call);
98-
}
63+
$this->callSubAction($_REQUEST['sa'] ?? null);
9964
}
10065

10166
/**
@@ -2575,9 +2540,9 @@ public static function manageAttachmentSettings(bool $return_config = false): ?a
25752540
return self::attachConfigVars();
25762541
}
25772542

2578-
self::load();
2579-
self::$obj->subaction = 'attachments';
2580-
self::$obj->execute();
2543+
$obj = self::load();
2544+
$obj->setDefaultSubAction('attachments');
2545+
$obj->execute();
25812546

25822547
return null;
25832548
}
@@ -2594,9 +2559,9 @@ public static function manageAvatarSettings(bool $return_config = false): ?array
25942559
return self::avatarConfigVars();
25952560
}
25962561

2597-
self::load();
2598-
self::$obj->subaction = 'avatars';
2599-
self::$obj->execute();
2562+
$obj = self::load();
2563+
$obj->setDefaultSubAction('avatars');
2564+
$obj->execute();
26002565

26012566
return null;
26022567
}
@@ -2610,6 +2575,19 @@ public static function manageAvatarSettings(bool $return_config = false): ?array
26102575
*/
26112576
protected function __construct()
26122577
{
2578+
$this->setDefaultSubAction('browse');
2579+
$this->addSubAction('attachments', [$this, 'attachmentSettings']);
2580+
$this->addSubAction('avatars', [$this, 'avatarSettings']);
2581+
$this->addSubAction('browse', [$this, 'browse']);
2582+
$this->addSubAction('maintenance', [$this, 'maintain']);
2583+
$this->addSubAction('remove', [$this, 'remove']);
2584+
$this->addSubAction('byage', [$this, 'removeByAge']);
2585+
$this->addSubAction('bysize', [$this, 'removeBySize']);
2586+
$this->addSubAction('removeall', [$this, 'removeAll']);
2587+
$this->addSubAction('repair', [$this, 'repair']);
2588+
$this->addSubAction('attachpaths', [$this, 'paths']);
2589+
$this->addSubAction('transfer', [$this, 'transfer']);
2590+
26132591
// You have to be able to moderate the forum to do this.
26142592
User::$me->isAllowedTo('manage_attachments');
26152593

@@ -2623,14 +2601,6 @@ protected function __construct()
26232601
'description' => Lang::$txt['attachments_desc'],
26242602
];
26252603

2626-
IntegrationHook::call('integrate_manage_attachments', [&self::$subactions]);
2627-
2628-
if (!empty($_REQUEST['sa']) && isset(self::$subactions[strtolower($_REQUEST['sa'])])) {
2629-
$this->subaction = strtolower($_REQUEST['sa']);
2630-
}
2631-
2632-
Utils::$context['sub_action'] = &$this->subaction;
2633-
26342604
// Default page title is good.
26352605
Utils::$context['page_title'] = Lang::$txt['attachments_avatars'];
26362606
}

0 commit comments

Comments
 (0)