Passed
Push — develop-3.3.x ( 819cf8...5812a0 )
by Mario
02:46
created

admin_main::set_module_info()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * PayPal Donation extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2015-2024 Skouat
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace skouat\ppde\controller\admin;
12
13
use skouat\ppde\controller\esi_controller;
14
use skouat\ppde\controller\ipn_paypal;
15
16
abstract class admin_main
17
{
18
	protected const SECONDS_IN_A_DAY = 86400;
19
20
	/** @var string */
21
	public $u_action;
22
23
	/** @var array */
24
	protected $args = [];
25
	/** @var \phpbb\config\config */
26
	protected $config;
27
	/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
28
	protected $container;
29
	/** @var string */
30
	protected $id_prefix_name;
31
	/** @var string */
32
	protected $lang_key_prefix;
33
	/** @var \phpbb\language\language */
34
	protected $language;
35
	/** @var \phpbb\log\log */
36
	protected $log;
37
	/** @var string */
38
	protected $module_name;
39
	/** @var \skouat\ppde\actions\locale_icu */
40
	protected $ppde_actions_locale;
41
	/** @var esi_controller */
42
	protected $esi_controller;
43
	/** @var bool */
44
	protected $preview;
45
	/** @var \phpbb\request\request */
46
	protected $request;
47
	/** @var bool */
48
	protected $submit;
49
	/** @var \phpbb\template\template */
50
	protected $template;
51
	/** @var \phpbb\user */
52
	protected $user;
53
54
	public function main(): void
55
	{
56
		$this->u_action_assign_template_vars();
57
		$action = $this->args['action'];
58
		switch ($action)
59
		{
60
			case 'add':
61
			case 'change':
62
			case 'edit':
63
			case 'view':
64
				$this->{$action}();
65
			break;
66
			case 'move_up':
67
			case 'move_down':
68
				$this->move();
69
			break;
70
			case 'activate':
71
			case 'deactivate':
72
				$this->enable();
73
			break;
74
			case 'approve':
75
			case 'delete':
76
				// Use a confirm box routine when approving/deleting an item
77
				if (confirm_box(true))
78
				{
79
					$this->{$action}();
80
					break;
81
				}
82
				confirm_box(false, $this->language->lang($this->lang_key_prefix . '_CONFIRM_OPERATION'), build_hidden_fields($this->get_hidden_fields()));
83
84
				// Clear $action status
85
				$this->args['action'] = $action;
86
			break;
87
			default:
88
				$this->display();
89
		}
90
		if (!empty($this->args['action']))
91
		{
92
			$this->display();
93
		}
94
	}
95
96
	/**
97
	 * Assign u_action output vars for display in the template
98
	 */
99
	protected function u_action_assign_template_vars(): void
100
	{
101
		$this->template->assign_vars(['U_ACTION' => $this->u_action]);
102
	}
103
104
	/**
105
	 * Get hidden fields arguments.
106
	 *
107
	 * @return array Hidden fields arguments.
108
	 */
109
	protected function get_hidden_fields(): array
110
	{
111
		return count($this->args) ? array_merge(
112
			['i'                           => $this->args['i'],
113
			 'mode'                        => $this->args['mode'],
114
			 'action'                      => $this->args['action'],
115
			 $this->id_prefix_name . '_id' => $this->args[$this->id_prefix_name . '_id']],
116
			$this->args['hidden_fields']) : ['id' => '', 'mode' => '', 'action' => ''];
117
	}
118
119
	/**
120
	 * Set the form action URL.
121
	 *
122
	 * @param string $u_action Form action URL.
123
	 */
124
	public function set_page_url($u_action): void
125
	{
126
		$this->u_action = $u_action;
127
	}
128
129
	/**
130
	 * Set hidden fields for the form.
131
	 *
132
	 * @param string $id     Module ID.
133
	 * @param string $mode   Module category.
134
	 * @param string $action Form action.
135
	 */
136
	public function set_hidden_fields($id, $mode, $action): void
137
	{
138
		$this->args = array_merge($this->args, [
139
			'i'             => $id,
140
			'mode'          => $mode,
141
			'action'        => $action,
142
			'hidden_fields' => [],
143
		]);
144
	}
145
146
	public function set_module_info(array $module_info, string $module_name): void
147
	{
148
		$this->id_prefix_name = $module_info['id_prefix_name'] ?? '';
149
		$this->lang_key_prefix = $module_info['lang_key_prefix'] ?? '';
150
		$this->module_name = $module_name;
151
	}
152
153
	/**
154
	 * Set the item ID.
155
	 *
156
	 * @param int $item_id Item ID.
157
	 */
158
	public function set_item_id($item_id): void
159
	{
160
		$this->args[$this->id_prefix_name . '_id'] = (int) $item_id;
161
	}
162
163
	/**
164
	 * Add item for the called controller
165
	 * This method is intended to be overridden by child classes
166
	 */
167
	protected function add(): void
168
	{
169
	}
170
171
	/**
172
	 * Approve an item.
173
	 * This method is intended to be overridden by child classes
174
	 */
175
	protected function approve(): void
176
	{
177
	}
178
179
	/**
180
	 * Change item details for the called controller
181
	 * This method is intended to be overridden by child classes
182
	 */
183
	protected function change(): void
184
	{
185
	}
186
187
	/**
188
	 * Delete item for the called controller
189
	 * This method is intended to be overridden by child classes
190
	 */
191
	protected function delete(): void
192
	{
193
	}
194
195
	/**
196
	 * Display items of the called controller
197
	 * This method is intended to be overridden by child classes
198
	 */
199
	protected function display(): void
200
	{
201
	}
202
203
	/**
204
	 * Edit item on the called controller
205
	 * This method is intended to be overridden by child classes
206
	 */
207
	protected function edit(): void
208
	{
209
	}
210
211
	/**
212
	 * Enable/disable item on the called controller
213
	 * This method is intended to be overridden by child classes
214
	 */
215
	protected function enable(): void
216
	{
217
	}
218
219
	/**
220
	 * Move up/down an item on the called controller
221
	 * This method is intended to be overridden by child classes
222
	 */
223
	protected function move(): void
224
	{
225
	}
226
227
	/**
228
	 * View a selected item on the called controller
229
	 * This method is intended to be overridden by child classes
230
	 */
231
	protected function view(): void
232
	{
233
	}
234
235
	/**
236
	 * Build remote URI select menu options.
237
	 *
238
	 * @param int    $default ID of the default selected option.
239
	 * @param string $type    Type of remote URI ('live' or 'sandbox').
240
	 */
241
	protected function build_remote_uri_select_menu($default, $type): void
242
	{
243
		$type = $this->force_type($type);
244
245
		// Grab the list of remote uri for selected type
246
		$remote_list = ipn_paypal::get_remote_uri();
247
248
		// Process each menu item for pull-down
249
		foreach ($remote_list as $id => $remote)
250
		{
251
			if ($remote['type'] !== $type)
252
			{
253
				continue;
254
			}
255
256
			// Set output block vars for display in the template
257
			$this->template->assign_block_vars('remote_options', [
258
				'REMOTE_ID'   => (int) $id,
259
				'REMOTE_NAME' => $remote['hostname'],
260
				'S_DEFAULT'   => (int) $default === (int) $id,
261
			]);
262
		}
263
		unset ($remote_list, $id);
264
	}
265
266
	/**
267
	 * Enforce the remote URI type.
268
	 *
269
	 * @param string $type Remote URI type.
270
	 * @return string Validated remote URI type.
271
	 */
272
	private function force_type($type): string
273
	{
274
		return $type === 'live' || $type === 'sandbox' ? (string) $type : 'live';
275
	}
276
277
	/**
278
	 * Submit settings.
279
	 */
280
	protected function submit_settings(): void
281
	{
282
		$this->submit = $this->is_form_submitted();
283
284
		// Test if the submitted form is valid
285
		$errors = $this->is_invalid_form('ppde_' . $this->module_name, $this->submit);
286
287
		if ($this->can_submit_data($errors))
288
		{
289
			// Set the options the user configured
290
			$this->set_settings();
291
292
			// Add option settings change action to the admin log
293
			$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_' . $this->lang_key_prefix . '_UPDATED');
294
295
			// Option settings have been updated and logged
296
			// Confirm this to the user and provide link back to previous page
297
			trigger_error($this->language->lang($this->lang_key_prefix . '_SAVED') . adm_back_link($this->u_action));
298
		}
299
	}
300
301
	/**
302
	 * Check if form is submitted.
303
	 *
304
	 * @return bool True if form is submitted, false otherwise.
305
	 */
306
	protected function is_form_submitted(): bool
307
	{
308
		return $this->request->is_set_post('submit');
309
	}
310
311
	/**
312
	 * Check for invalid form submission.
313
	 *
314
	 * @param string $form_name         Name of the form.
315
	 * @param bool   $submit_or_preview Whether the form is submitted or previewed.
316
	 * @return array Errors encountered during form validation.
317
	 */
318
	protected function is_invalid_form($form_name, $submit_or_preview = false): array
319
	{
320
		if ($submit_or_preview && !check_form_key($form_name))
321
		{
322
			return [$this->language->lang('FORM_INVALID')];
323
		}
324
325
		return [];
326
	}
327
328
	/**
329
	 * Check if data can be submitted.
330
	 *
331
	 * @param array $errors Errors encountered during form validation.
332
	 * @return bool True if data can be submitted, false otherwise.
333
	 */
334
	protected function can_submit_data(array $errors): bool
335
	{
336
		return $this->submit && empty($errors) && !$this->preview;
337
	}
338
339
	/**
340
	 * Set the options for called controller
341
	 * This method is intended to be overridden by child classes
342
	 */
343
	protected function set_settings(): void
344
	{
345
	}
346
347
	/**
348
	 * Trigger error message if data already exists
349
	 *
350
	 * @param \skouat\ppde\entity\main $entity Entity object to check for existing data.
351
	 */
352
	protected function trigger_error_data_already_exists(\skouat\ppde\entity\main $entity): void
353
	{
354
		if ($this->is_added_data_exists($entity))
355
		{
356
			// Show user warning for an already exist page and provide link back to the edit page
357
			$message = $this->language->lang($this->lang_key_prefix . '_EXISTS');
358
			$message .= '<br><br>';
359
			$message .= $this->language->lang($this->lang_key_prefix . '_GO_TO_PAGE', '<a href="' . $this->u_action . '&amp;action=edit&amp;' . $this->id_prefix_name . '_id=' . $entity->get_id() . '">&raquo; ', '</a>');
360
			trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING);
361
		}
362
	}
363
364
	/**
365
	 * Check if added data already exists.
366
	 *
367
	 * @param \skouat\ppde\entity\main $entity Entity object to check.
368
	 * @return bool True if the data exists, false otherwise.
369
	 */
370
	protected function is_added_data_exists(\skouat\ppde\entity\main $entity): bool
371
	{
372
		return $entity->data_exists($entity->build_sql_data_exists()) && $this->request->variable('action', '') === 'add';
373
	}
374
375
	/**
376
	 * Check some settings before submitting data
377
	 *
378
	 * @param \skouat\ppde\entity\main $entity            Entity object to check.
379
	 * @param string                   $field_name        Name of the field to check.
380
	 * @param string|int               $value_cmp         Value to compare against for emptiness.
381
	 * @param bool                     $submit_or_preview Whether the form has been submitted or previewed (default: false).
382
	 * @return array Errors encountered during empty data check.
383
	 */
384
	protected function is_empty_data(\skouat\ppde\entity\main $entity, $field_name, $value_cmp, $submit_or_preview = false): array
385
	{
386
		$errors = [];
387
388
		if ($submit_or_preview && $entity->{'get_' . $field_name}() == $value_cmp)
389
		{
390
			$errors[] = $this->language->lang($this->lang_key_prefix . '_EMPTY_' . strtoupper($field_name));
391
		}
392
393
		return $errors;
394
	}
395
396
	/**
397
	 * Check if the form has been submitted or previewed.
398
	 *
399
	 * @param bool $submit  Submission status (default: false).
400
	 * @param bool $preview Preview status (default: false).
401
	 * @return bool True if submitted or previewed, false otherwise.
402
	 */
403
	protected function submit_or_preview(bool $submit = false, bool $preview = false): bool
404
	{
405
		return $submit || $preview;
406
	}
407
408
	/**
409
	 * Send AJAX delete result message.
410
	 *
411
	 * @param string $message Message to send in the response.
412
	 */
413
	protected function ajax_delete_result_message($message = ''): void
414
	{
415
		if ($this->request->is_ajax())
416
		{
417
			$json_response = new \phpbb\json_response;
418
			$json_response->send([
419
				'MESSAGE_TITLE' => $this->language->lang('INFORMATION'),
420
				'MESSAGE_TEXT'  => $message,
421
				'REFRESH_DATA'  => [
422
					'time' => 3,
423
				],
424
			]);
425
		}
426
	}
427
428
	/**
429
	 * Assign add/edit action output vars for display in the template
430
	 *
431
	 * @param string  $type Action type: 'add' or 'edit'
432
	 * @param integer $id   Identifier to Edit. If action = add, then let to '0'.
433
	 */
434
	protected function add_edit_action_assign_template_vars($type, $id = 0): void
435
	{
436
		$id_action = !empty($id) ? '&amp;' . $this->id_prefix_name . '_id=' . (int) $id : '';
437
438
		$this->template->assign_vars([
439
			'S_ADD_EDIT' => true,
440
			'U_ACTION'   => $this->u_action . '&amp;action=' . $type . $id_action,
441
			'U_BACK'     => $this->u_action,
442
		]);
443
	}
444
445
	/**
446
	 * Assign error output vars for display in the template
447
	 *
448
	 * @param array $errors Array of error messages.
449
	 */
450
	protected function s_error_assign_template_vars($errors): void
451
	{
452
		$this->template->assign_vars([
453
			'S_ERROR'   => (bool) count($errors),
454
			'ERROR_MSG' => (count($errors)) ? implode('<br>', $errors) : '',
455
		]);
456
	}
457
458
	/**
459
	 * Check and return a config value with type enforcement.
460
	 *
461
	 * @param mixed  $config  The config value to check.
462
	 * @param string $type    The desired data type (e.g., 'boolean', 'integer', 'string').
463
	 * @param mixed  $default The default value to return if the config value is not set.
464
	 * @return mixed The config value or the default value if not set, with the enforced type.
465
	 */
466
	protected function check_config($config, string $type = 'boolean', $default = '')
467
	{
468
		// We're using settype to enforce data types
469
		settype($config, $type);
470
		settype($default, $type);
471
472
		return $config ?: $default;
473
	}
474
475
	/**
476
	 * Check required settings and trigger warning if missing.
477
	 *
478
	 * @param mixed $settings  The settings value to check.
479
	 * @param bool  $depend_on The condition that determines if the settings are required.
480
	 * @return mixed The settings value if the condition is met or settings are not empty; otherwise, triggers an error and terminates.
481
	 */
482
	protected function required_settings($settings, $depend_on)
483
	{
484
		if (empty($settings) && (bool) $depend_on === true)
485
		{
486
			trigger_error($this->language->lang($this->lang_key_prefix . '_MISSING') . adm_back_link($this->u_action), E_USER_WARNING);
487
		}
488
489
		return $settings;
490
	}
491
492
	/**
493
	 * Perform first-start checks and setup for the extension.
494
	 *
495
	 * @throws \ReflectionException
496
	 */
497
	protected function ppde_first_start(): void
498
	{
499
		if ($this->config['ppde_first_start'])
500
		{
501
			$this->esi_controller->set_curl_info();
502
			$this->esi_controller->set_remote_detected();
503
			$this->esi_controller->check_tls();
504
			$this->ppde_actions_locale->set_intl_info();
505
			$this->ppde_actions_locale->set_intl_detected();
506
			$this->config->set('ppde_first_start', '0');
507
		}
508
	}
509
}
510