Completed
Branch develop-3.3.x-refactor_modules (cfd1e1)
by Mario
03:51
created

admin_main   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 427
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 89
c 2
b 1
f 0
dl 0
loc 427
rs 5.04
wmc 57

33 Methods

Rating   Name   Duplication   Size   Complexity  
A enable() 0 2 1
A build_remote_uri_select_menu() 0 23 3
A can_submit_data() 0 3 3
A set_page_url() 0 3 1
A view() 0 2 1
A set_settings() 0 2 1
A add() 0 2 1
A submit_or_preview() 0 3 2
A submit_settings() 0 18 2
A s_error_assign_template_vars() 0 5 3
A approve() 0 2 1
A u_action_assign_template_vars() 0 4 1
A set_action() 0 3 1
A check_config() 0 7 2
A is_invalid_form() 0 8 3
A delete() 0 2 1
A is_added_data_exists() 0 3 2
A get_hidden_fields() 0 8 2
A trigger_error_data_already_exists() 0 9 2
A add_edit_action_assign_template_vars() 0 8 2
A display() 0 2 1
A ajax_delete_result_message() 0 10 2
A edit() 0 2 1
A get_action() 0 3 2
A move() 0 2 1
A is_empty_data() 0 10 3
A __construct() 0 5 1
A required_settings() 0 8 3
A change() 0 2 1
A depend_on() 0 3 2
A force_type() 0 3 3
A set_hidden_fields() 0 7 1
A set_item_id() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like admin_main 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 admin_main, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 *
4
 * PayPal Donation extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2015-2020 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\ipn_paypal;
14
use skouat\ppde\entity\main;
15
16
abstract class admin_main
17
{
18
	/** @var array */
19
	protected $args;
20
	/** @var object \phpbb\config\config */
21
	protected $config;
22
	/** @var object Symfony\Component\DependencyInjection\ContainerInterface */
23
	protected $container;
24
	/** @var string */
25
	protected $id_prefix_name;
26
	/** @var string */
27
	protected $lang_key_prefix;
28
	/** @var \phpbb\language\language */
29
	protected $language;
30
	/** @var \phpbb\log\log */
31
	protected $log;
32
	/** @var string */
33
	protected $module_name;
34
	/** @var bool */
35
	protected $preview;
36
	/** @var \phpbb\request\request */
37
	protected $request;
38
	/** @var bool */
39
	protected $submit;
40
	/** @var \phpbb\template\template */
41
	protected $template;
42
	/** @var string */
43
	protected $u_action;
44
	/** @var \phpbb\user */
45
	protected $user;
46
47
	/**
48
	 * Constructor
49
	 *
50
	 * @param string $lang_key_prefix Prefix for the messages thrown by exceptions
51
	 * @param string $id_prefix_name  Prefix name for identifier in the URL
52
	 * @param string $module_name     Name of the module currently used
53
	 *
54
	 * @access public
55
	 */
56
	public function __construct($module_name, $lang_key_prefix, $id_prefix_name)
57
	{
58
		$this->module_name = $module_name;
59
		$this->lang_key_prefix = $lang_key_prefix;
60
		$this->id_prefix_name = $id_prefix_name;
61
	}
62
63
	/**
64
	 * Set page url
65
	 *
66
	 * @param string $u_action Custom form action
67
	 *
68
	 * @return void
69
	 * @access public
70
	 */
71
	public function set_page_url($u_action)
72
	{
73
		$this->u_action = $u_action;
74
	}
75
76
	public function set_hidden_fields($id, $mode, $action)
77
	{
78
		$this->args = array_merge((array) $this->args, [
79
			'id'            => $id,
80
			'mode'          => $mode,
81
			'action'        => $action,
82
			'hidden_fields' => [],
83
		]);
84
	}
85
86
	public function get_hidden_fields()
87
	{
88
		return count($this->args) ? array_merge(
89
			['id'                          => $this->args['id'],
90
			 'mode'                        => $this->args['mode'],
91
			 'action'                      => $this->args['action'],
92
			 $this->id_prefix_name . '_id' => $this->args[$this->id_prefix_name . '_id']],
93
			$this->args['hidden_fields']) : ['id' => '', 'mode' => '', 'action' => ''];
94
	}
95
96
	public function set_action($action)
97
	{
98
		$this->args['action'] = $action;
99
	}
100
101
	public function get_action()
102
	{
103
		return (isset($this->args['action'])) ? (string) $this->args['action'] : '';
104
	}
105
106
	public function set_item_id($item_id)
107
	{
108
		$this->args[$this->id_prefix_name . '_id'] = (int) $item_id;
109
	}
110
111
	public function display()
112
	{
113
	}
114
115
	public function add()
116
	{
117
	}
118
119
	public function approve()
120
	{
121
	}
122
123
	public function change()
124
	{
125
	}
126
127
	public function delete()
128
	{
129
	}
130
131
	public function edit()
132
	{
133
	}
134
135
	public function enable()
136
	{
137
	}
138
139
	public function move()
140
	{
141
	}
142
143
	public function view()
144
	{
145
	}
146
147
	/**
148
	 * Build pull down menu options of available currency
149
	 *
150
	 * @param mixed  $default ID of the selected value.
151
	 * @param string $type    Can be 'live' or 'sandbox'
152
	 *
153
	 * @return void
154
	 * @access public
155
	 */
156
	public function build_remote_uri_select_menu($default, $type)
157
	{
158
		$type = $this->force_type($type);
159
160
		// Grab the list of remote uri for selected type
161
		$remote_list = ipn_paypal::get_remote_uri();
162
163
		// Process each menu item for pull-down
164
		foreach ($remote_list as $id => $remote)
165
		{
166
			if ($remote['type'] !== $type)
167
			{
168
				continue;
169
			}
170
171
			// Set output block vars for display in the template
172
			$this->template->assign_block_vars('remote_options', [
173
				'REMOTE_ID'   => $id,
174
				'REMOTE_NAME' => $remote['hostname'],
175
				'S_DEFAULT'   => $default == $id,
176
			]);
177
		}
178
		unset ($remote_list, $remote);
179
	}
180
181
	/**
182
	 * Enforce the type of remote provided
183
	 *
184
	 * @param string $type
185
	 *
186
	 * @return string
187
	 * @access private
188
	 */
189
	private function force_type($type)
190
	{
191
		return $type === 'live' || $type === 'sandbox' ? (string) $type : 'live';
192
	}
193
194
	/**
195
	 * The form submitting if 'submit' is true
196
	 *
197
	 * @return void
198
	 * @access protected
199
	 */
200
	protected function submit_settings()
201
	{
202
		$this->submit = $this->request->is_set_post('submit');
203
204
		// Test if the submitted form is valid
205
		$errors = $this->is_invalid_form('ppde_' . $this->module_name, $this->submit);
206
207
		if ($this->can_submit_data($errors))
208
		{
209
			// Set the options the user configured
210
			$this->set_settings();
211
212
			// Add option settings change action to the admin log
213
			$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_' . $this->lang_key_prefix . '_UPDATED');
214
215
			// Option settings have been updated and logged
216
			// Confirm this to the user and provide link back to previous page
217
			trigger_error($this->language->lang($this->lang_key_prefix . '_SAVED') . adm_back_link($this->u_action));
218
		}
219
	}
220
221
	/**
222
	 * Check if form is valid or not
223
	 *
224
	 * @param string $form_name
225
	 * @param bool   $submit_or_preview
226
	 *
227
	 * @return array
228
	 * @access protected
229
	 */
230
	protected function is_invalid_form($form_name, $submit_or_preview = false)
231
	{
232
		if (!check_form_key($form_name) && $submit_or_preview)
233
		{
234
			return [$this->language->lang('FORM_INVALID')];
235
		}
236
237
		return [];
238
	}
239
240
	/**
241
	 * @param array $errors
242
	 *
243
	 * @return bool
244
	 * @access protected
245
	 */
246
	protected function can_submit_data(array $errors)
247
	{
248
		return $this->submit && empty($errors) && !$this->preview;
249
	}
250
251
	protected function set_settings()
252
	{
253
	}
254
255
	/**
256
	 * Trigger error message if data already exists
257
	 *
258
	 * @param \skouat\ppde\entity\main $entity The entity object
259
	 *
260
	 * @access protected
261
	 */
262
	protected function trigger_error_data_already_exists(main $entity)
263
	{
264
		if ($this->is_added_data_exists($entity))
265
		{
266
			// Show user warning for an already exist page and provide link back to the edit page
267
			$message = $this->language->lang($this->lang_key_prefix . '_EXISTS');
268
			$message .= '<br><br>';
269
			$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>');
270
			trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING);
271
		}
272
	}
273
274
	/**
275
	 * @param \skouat\ppde\entity\main $entity The entity object
276
	 *
277
	 * @return bool
278
	 * @access protected
279
	 */
280
	protected function is_added_data_exists(main $entity)
281
	{
282
		return $entity->data_exists($entity->build_sql_data_exists()) && $this->request->variable('action', '') === 'add';
283
	}
284
285
	/**
286
	 * Check some settings before submitting data
287
	 *
288
	 * @param \skouat\ppde\entity\main $entity            The entity object
289
	 * @param string                   $field_name        Name of the entity function to call
290
	 * @param string|int               $value_cmp         Default value to compare with the call_user_func() return value
291
	 * @param bool                     $submit_or_preview Form submit or preview status
292
	 *
293
	 * @return array $errors
294
	 * @access protected
295
	 */
296
	protected function is_empty_data(main $entity, $field_name, $value_cmp, $submit_or_preview = false)
297
	{
298
		$errors = [];
299
300
		if (call_user_func([$entity, 'get_' . $field_name]) == $value_cmp && $submit_or_preview)
301
		{
302
			$errors[] = $this->language->lang($this->lang_key_prefix . '_EMPTY_' . strtoupper($field_name));
303
		}
304
305
		return $errors;
306
	}
307
308
	/**
309
	 * Get result of submit and preview expression
310
	 *
311
	 * @param bool $submit
312
	 * @param bool $preview
313
	 *
314
	 * @return bool
315
	 * @access protected
316
	 */
317
	protected function submit_or_preview($submit = false, $preview = false)
318
	{
319
		return (bool) $submit || (bool) $preview;
320
	}
321
322
	/**
323
	 * Show user a result message if AJAX was used
324
	 *
325
	 * @param string $message Text message to show to the user
326
	 *
327
	 * @return void
328
	 * @access protected
329
	 */
330
	protected function ajax_delete_result_message($message = '')
331
	{
332
		if ($this->request->is_ajax())
333
		{
334
			$json_response = new \phpbb\json_response;
335
			$json_response->send([
336
				'MESSAGE_TITLE' => $this->language->lang('INFORMATION'),
337
				'MESSAGE_TEXT'  => $message,
338
				'REFRESH_DATA'  => [
339
					'time' => 3,
340
				],
341
			]);
342
		}
343
	}
344
345
	/**
346
	 * Set u_action output vars for display in the template
347
	 *
348
	 * @return void
349
	 * @access protected
350
	 */
351
	protected function u_action_assign_template_vars()
352
	{
353
		$this->template->assign_vars([
354
			'U_ACTION' => $this->u_action,
355
		]);
356
	}
357
358
	/**
359
	 * Set add/edit action output vars for display in the template
360
	 *
361
	 * @param string  $type Action type: 'add' or 'edit'
362
	 * @param integer $id   Identifier to Edit. If action = add, then let to '0'.
363
	 *
364
	 * @return void
365
	 * @access protected
366
	 */
367
	protected function add_edit_action_assign_template_vars($type, $id = 0)
368
	{
369
		$id_action = !empty($id) ? '&amp;' . $this->id_prefix_name . '_id=' . (int) $id : '';
370
371
		$this->template->assign_vars([
372
			'S_ADD_EDIT' => true,
373
			'U_ACTION'   => $this->u_action . '&amp;action=' . $type . $id_action,
374
			'U_BACK'     => $this->u_action,
375
		]);
376
	}
377
378
	/**
379
	 * Set error output vars for display in the template
380
	 *
381
	 * @param array $errors
382
	 *
383
	 * @return void
384
	 * @access protected
385
	 */
386
	protected function s_error_assign_template_vars($errors)
387
	{
388
		$this->template->assign_vars([
389
			'S_ERROR'   => (count($errors)) ? true : false,
390
			'ERROR_MSG' => (count($errors)) ? implode('<br>', $errors) : '',
391
		]);
392
	}
393
394
	/**
395
	 * Check if a config value is true
396
	 *
397
	 * @param mixed  $config Config value
398
	 * @param string $type   (see settype())
399
	 * @param mixed  $default
400
	 *
401
	 * @return mixed
402
	 * @access protected
403
	 */
404
	protected function check_config($config, $type = 'boolean', $default = '')
405
	{
406
		// We're using settype to enforce data types
407
		settype($config, $type);
408
		settype($default, $type);
409
410
		return $config ? $config : $default;
411
	}
412
413
	/**
414
	 * Check if settings is required
415
	 *
416
	 * @param $settings
417
	 * @param $depend_on
418
	 *
419
	 * @return mixed
420
	 * @access protected
421
	 */
422
	protected function required_settings($settings, $depend_on)
423
	{
424
		if (empty($settings) && $depend_on == true)
425
		{
426
			trigger_error($this->language->lang($this->lang_key_prefix . '_MISSING') . adm_back_link($this->u_action), E_USER_WARNING);
427
		}
428
429
		return $settings;
430
	}
431
432
	/**
433
	 * Check if a settings depend on another.
434
	 *
435
	 * @param $config_name
436
	 *
437
	 * @return bool
438
	 * @access protected
439
	 */
440
	protected function depend_on($config_name)
441
	{
442
		return !empty($this->config[$config_name]) ? (bool) $this->config[$config_name] : false;
443
	}
444
}
445