Completed
Push — develop ( 4fb165...5f36bf )
by Mario
02:48
created

main_controller   D

Complexity

Total Complexity 125

Size/Duplication

Total Lines 951
Duplicated Lines 2.94 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 40
Bugs 10 Features 8
Metric Value
wmc 125
c 40
b 10
f 8
lcom 1
cbo 6
dl 28
loc 951
rs 4.4444

43 Methods

Rating   Name   Duplication   Size   Complexity  
A set_sort_key() 0 4 3
A set_url_delim() 0 4 2
A __construct() 0 19 1
B handle() 0 46 5
B check_params() 0 22 5
A can_use_ppde() 0 4 1
A can_view_ppde_donorlist() 0 4 1
C donorlist_handle() 0 96 7
A donorlist_is_enabled() 0 4 3
B set_return_args_url() 0 22 4
A get_donation_content_data() 0 6 1
A build_currency_select_menu() 0 20 2
A build_currency_value_select_menu() 0 18 4
A get_dropbox_status() 0 4 2
A settype_dropbox_int_value() 0 9 3
A paypal_hidden_fields() 0 16 1
A get_account_id() 0 4 2
A use_sandbox() 0 4 4
A use_ipn() 0 4 4
A generate_paypal_return_url() 0 4 1
A generate_paypal_notify_return_url() 0 4 1
A get_paypal_url() 0 4 3
A display_stats() 0 21 4
A get_default_currency_data() 0 4 1
A get_ppde_goal_langkey() 8 17 3
A currency_on_left() 0 4 2
A get_ppde_raised_langkey() 8 13 2
A get_ppde_used_langkey() 0 17 3
A generate_stats_percent() 12 16 3
A is_ppde_goal_stats() 0 4 2
A is_ppde_used_stats() 0 4 3
A percent_value() 0 4 1
A assign_vars_stats_percent() 0 7 2
C ppde_css_classname() 0 30 14
A send_data_to_template() 0 13 4
A first_start() 0 9 2
C check_curl() 0 25 7
A set_curl_info() 0 9 2
A set_remote_detected() 0 5 1
A get_ext_meta() 0 7 2
A load_metadata() 0 22 3
A retrieve_ext_name() 0 5 1
A check_fsockopen() 0 15 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like main_controller 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 main_controller, 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 Skouat
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace skouat\ppde\controller;
12
13
use Symfony\Component\DependencyInjection\ContainerInterface;
14
15
class main_controller
16
{
17
	protected $auth;
18
	protected $config;
19
	protected $container;
20
	protected $extension_manager;
21
	protected $helper;
22
	protected $ppde_entity_currency;
23
	protected $ppde_entity_donation_pages;
24
	protected $ppde_entity_transactions;
25
	protected $ppde_operator_currency;
26
	protected $ppde_operator_donation_pages;
27
	protected $ppde_operator_transactions;
28
	protected $request;
29
	protected $template;
30
	protected $user;
31
	protected $root_path;
32
	protected $php_ext;
33
	/** @var array */
34
	protected $ext_meta = array();
35
	/** @var string */
36
	protected $ext_name;
37
	/** @var string */
38
	private $donation_body;
39
	/** @var array */
40
	private $donation_content_data;
41
	/** @var string */
42
	private $return_args_url;
43
	/** @var string */
44
	private $u_action;
45
46
	/**
47
	 * Constructor
48
	 *
49
	 * @param \phpbb\auth\auth                      $auth                         Auth object
50
	 * @param \phpbb\config\config                  $config                       Config object
51
	 * @param ContainerInterface                    $container                    Service container interface
52
	 * @param \phpbb\extension\manager              $extension_manager            An instance of the phpBB extension
53
	 *                                                                            manager
54
	 * @param \phpbb\controller\helper              $helper                       Controller helper object
55
	 * @param \skouat\ppde\entity\currency          $ppde_entity_currency         Currency entity object
56
	 * @param \skouat\ppde\entity\donation_pages    $ppde_entity_donation_pages   Donation pages entity object
57
	 * @param \skouat\ppde\entity\transactions      $ppde_entity_transactions     Transactions log entity object
58
	 * @param \skouat\ppde\operators\currency       $ppde_operator_currency       Currency operator object
59
	 * @param \skouat\ppde\operators\donation_pages $ppde_operator_donation_pages Donation pages operator object
60
	 * @param \skouat\ppde\operators\transactions   $ppde_operator_transactions   Transactions log operator object
61
	 * @param \phpbb\request\request                $request                      Request object
62
	 * @param \phpbb\template\template              $template                     Template object
63
	 * @param \phpbb\user                           $user                         User object
64
	 * @param string                                $root_path                    phpBB root path
65
	 * @param string                                $php_ext                      phpEx
66
	 *
67
	 * @return \skouat\ppde\controller\main_controller
68
	 * @access public
69
	 */
70
	public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, ContainerInterface $container, \phpbb\extension\manager $extension_manager, \phpbb\controller\helper $helper, \skouat\ppde\entity\currency $ppde_entity_currency, \skouat\ppde\entity\donation_pages $ppde_entity_donation_pages, \skouat\ppde\entity\transactions $ppde_entity_transactions, \skouat\ppde\operators\currency $ppde_operator_currency, \skouat\ppde\operators\donation_pages $ppde_operator_donation_pages, \skouat\ppde\operators\transactions $ppde_operator_transactions, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user, $root_path, $php_ext)
71
	{
72
		$this->auth = $auth;
73
		$this->config = $config;
74
		$this->container = $container;
75
		$this->extension_manager = $extension_manager;
76
		$this->helper = $helper;
77
		$this->ppde_entity_currency = $ppde_entity_currency;
78
		$this->ppde_entity_donation_pages = $ppde_entity_donation_pages;
79
		$this->ppde_entity_transactions = $ppde_entity_transactions;
80
		$this->ppde_operator_currency = $ppde_operator_currency;
81
		$this->ppde_operator_donation_pages = $ppde_operator_donation_pages;
82
		$this->ppde_operator_transactions = $ppde_operator_transactions;
83
		$this->request = $request;
84
		$this->template = $template;
85
		$this->user = $user;
86
		$this->root_path = $root_path;
87
		$this->php_ext = $php_ext;
88
	}
89
90
	public function handle()
91
	{
92
		// When this extension is disabled, redirect users back to the forum index
93
		// Else if user is not allowed to use it, disallow access to the extension main page
94
		if (empty($this->config['ppde_enable']))
95
		{
96
			redirect(append_sid("{$this->root_path}index.{$this->php_ext}"));
97
		}
98
		else if (!$this->can_use_ppde())
99
		{
100
			trigger_error('NOT_AUTHORISED');
101
		}
102
103
		$entity = $this->container->get('skouat.ppde.entity.donation_pages');
104
		$this->set_return_args_url($this->request->variable('return', 'body'));
105
106
		// Prepare message for display
107
		if ($this->get_donation_content_data($this->return_args_url))
108
		{
109
			$entity->get_vars();
110
			$this->donation_body = $entity->replace_template_vars($entity->get_message_for_display(
111
				$this->donation_content_data[0]['page_content'],
112
				$this->donation_content_data[0]['page_content_bbcode_uid'],
113
				$this->donation_content_data[0]['page_content_bbcode_bitfield'],
114
				$this->donation_content_data[0]['page_content_bbcode_options']
115
			));
116
		}
117
118
		$this->template->assign_vars(array(
119
			'DEFAULT_CURRENCY'   => $this->build_currency_select_menu($this->config['ppde_default_currency']),
120
			'DONATION_BODY'      => $this->donation_body,
121
			'IMG_LOADER'         => '<img src="' . $this->root_path . '../ext/skouat/ppde/images/loader.gif' . '" />',
122
			'PPDE_DEFAULT_VALUE' => $this->config['ppde_default_value'] ? $this->config['ppde_default_value'] : 0,
123
			'PPDE_LIST_VALUE'    => $this->build_currency_value_select_menu(),
124
125
			'S_HIDDEN_FIELDS'    => $this->paypal_hidden_fields(),
126
			'S_PPDE_FORM_ACTION' => $this->get_paypal_url(),
127
			'S_RETURN_ARGS'      => $this->return_args_url,
128
			'S_SANDBOX'          => $this->use_sandbox(),
129
		));
130
131
		$this->display_stats();
132
133
		// Send all data to the template file
134
		return $this->send_data_to_template();
135
	}
136
137
	public function donorlist_handle()
138
	{
139
		// If the donorlist is not enabled, redirect users back to the forum index
140
		// Else if user is not allowed to view the donors list, disallow access to the extension page
141
		if (!$this->donorlist_is_enabled())
142
		{
143
			redirect(append_sid($this->root_path . 'index.' . $this->php_ext));
144
		}
145
		else if (!$this->can_view_ppde_donorlist())
146
		{
147
			trigger_error('NOT_AUTHORISED');
148
		}
149
150
		// Get needed container
151
		/** @type \phpbb\pagination $pagination */
152
		$pagination = $this->container->get('pagination');
153
		/** @type \phpbb\path_helper $path_helper */
154
		$path_helper = $this->container->get('path_helper');
155
156
		// Set up general vars
157
		$default_key = 'd';
158
		$sort_key = $this->request->variable('sk', $default_key);
159
		$sort_dir = $this->request->variable('sd', 'd');
160
		$start = $this->request->variable('start', 0);
161
162
		// Sorting and order
163
		$sort_key_sql = array('a' => 'amount', 'd' => 'txn.payment_date', 'u' => 'u.username_clean');
164
165
		if (!isset($sort_key_sql[$sort_key]))
166
		{
167
			$sort_key = $default_key;
168
		}
169
170
		$order_by = $sort_key_sql[$sort_key] . ' ' . (($sort_dir == 'a') ? 'ASC' : 'DESC');
171
172
		// Build a relevant pagination_url and sort_url
173
		// We do not use request_var() here directly to save some calls (not all variables are set)
174
		$check_params = array(
175
			'sk'    => array('sk', $default_key),
176
			'sd'    => array('sd', 'a'),
177
			'start' => array('start', 0),
178
		);
179
180
		$params = $this->check_params($check_params, array('start'));
181
		$sort_params = $this->check_params($check_params, array('sk', 'sd'));
182
183
		// Set '$this->u_action'
184
		$use_page = ($this->u_action) ? $this->u_action : $this->user->page['page_name'];
185
		$this->u_action = reapply_sid($path_helper->get_valid_page($use_page, $this->config['enable_mod_rewrite']));
186
187
		$pagination_url = append_sid($this->u_action, implode('&amp;', $params), true, false, true);
188
		$sort_url = $this->set_url_delim(append_sid($this->u_action, implode('&amp;', $sort_params), true, false, true), $sort_params);
189
190
		$get_donorlist_sql_ary = $this->ppde_operator_transactions->get_sql_donorlist_ary(false, $order_by);
191
		$total_donors = $this->ppde_operator_transactions->query_sql_count($get_donorlist_sql_ary, 'txn.user_id');
192
		$start = $pagination->validate_start($start, $this->config['topics_per_page'], $total_donors);
193
194
		$pagination->generate_template_pagination($pagination_url, 'pagination', 'start', $total_donors, $this->config['topics_per_page'], $start);
195
196
		// adds fields to the table schema needed by entity->import()
197
		$additional_table_schema = array(
198
			'item_username'    => array('name' => 'username', 'type' => 'string'),
199
			'item_user_colour' => array('name' => 'user_colour', 'type' => 'string'),
200
			'item_amount'      => array('name' => 'amount', 'type' => 'float'),
201
			'item_max_txn_id'  => array('name' => 'max_txn_id', 'type' => 'integer'),
202
		);
203
204
		$data_ary = $this->ppde_entity_transactions->get_data($this->ppde_operator_transactions->build_sql_donorlist_data($get_donorlist_sql_ary), $additional_table_schema, $this->config['topics_per_page'], $start);
205
206
		// Get default currency data from the database
207
		$default_currency_data = $this->get_default_currency_data($this->config['ppde_default_currency']);
208
		$this->template->assign_vars(array(
209
			'TOTAL_DONORS'    => $this->user->lang('PPDE_DONORS', $total_donors),
210
			'U_SORT_AMOUNT'   => $sort_url . 'sk=a&amp;sd=' . $this->set_sort_key($sort_key, 'a', $sort_dir),
211
			'U_SORT_DONATED'  => $sort_url . 'sk=d&amp;sd=' . $this->set_sort_key($sort_key, 'd', $sort_dir),
212
			'U_SORT_USERNAME' => $sort_url . 'sk=u&amp;sd=' . $this->set_sort_key($sort_key, 'u', $sort_dir),
213
		));
214
215
		foreach ($data_ary as $data)
216
		{
217
			$get_last_transaction_sql_ary = $this->ppde_operator_transactions->get_sql_donorlist_ary($data['max_txn_id']);
218
			$last_donation_data = $this->ppde_entity_transactions->get_data($this->ppde_operator_transactions->build_sql_donorlist_data($get_last_transaction_sql_ary));
219
			$this->template->assign_block_vars('donorrow', array(
220
				'PPDE_DONOR_USERNAME'       => get_username_string('full', $data['user_id'], $data['username'], $data['user_colour']),
221
				'PPDE_LAST_DONATED_AMOUNT'  => $this->currency_on_left(number_format($last_donation_data[0]['mc_gross'], 2), $default_currency_data[0]['currency_symbol'], (bool) $default_currency_data[0]['currency_on_left']),
222
				'PPDE_LAST_PAYMENT_DATE'    => $this->user->format_date($last_donation_data[0]['payment_date']),
223
				'PPDE_TOTAL_DONATED_AMOUNT' => $this->currency_on_left(number_format($data['amount'], 2), $default_currency_data[0]['currency_symbol'], (bool) $default_currency_data[0]['currency_on_left']),
224
			));
225
		}
226
227
		// Set "return_args_url" object before sending data to template
228
		$this->set_return_args_url('donorlist');
229
230
		// Send all data to the template file
231
		return $this->send_data_to_template();
232
	}
233
234
	/**
235
	 * Set the sort key value
236
	 *
237
	 * @param string $sk
238
	 * @param string $sk_comp
239
	 * @param string $sd
240
	 *
241
	 * @return string
242
	 * @access private
243
	 */
244
	private function set_sort_key($sk, $sk_comp, $sd)
245
	{
246
		return ($sk == $sk_comp && $sd == 'a') ? 'd' : 'a';
247
	}
248
249
	/**
250
	 * Simply adds an url or &amp; delimiter to the url when params is empty
251
	 *
252
	 * @param $url
253
	 * @param $params
254
	 *
255
	 * @return string
256
	 * @access private
257
	 */
258
	private function set_url_delim($url, $params)
259
	{
260
		return (empty($params)) ? $url . '?' : $url . '&amp;';
261
	}
262
263
	/**
264
	 * @param array    $params_ary
265
	 * @param string[] $excluded_keys
266
	 *
267
	 * @return array
268
	 * @access private
269
	 */
270
	private function check_params($params_ary, $excluded_keys)
271
	{
272
		$params = array();
273
274
		foreach ($params_ary as $key => $call)
275
		{
276
			if (!isset($_REQUEST[$key]))
277
			{
278
				continue;
279
			}
280
281
			$param = call_user_func_array('request_var', $call);
282
			$param = urlencode($key) . '=' . ((is_string($param)) ? urlencode($param) : $param);
283
284
			if (!in_array($key, $excluded_keys))
285
			{
286
				$params[] = $param;
287
			}
288
		}
289
290
		return $params;
291
	}
292
293
	/**
294
	 * @return bool
295
	 * @access public
296
	 */
297
	public function can_use_ppde()
298
	{
299
		return $this->auth->acl_get('u_ppde_use');
300
	}
301
302
	/**
303
	 * @return bool
304
	 * @access public
305
	 */
306
	public function can_view_ppde_donorlist()
307
	{
308
		return $this->auth->acl_get('u_ppde_view_donorlist');
309
	}
310
311
	/**
312
	 * @return bool
313
	 * @access private
314
	 */
315
	private function donorlist_is_enabled()
316
	{
317
		return $this->config['ppde_enable'] && $this->config['ppde_ipn_enable'] && $this->config['ppde_ipn_donorlist_enable'];
318
	}
319
320
	/**
321
	 * @param string $set_return_args_url
322
	 *
323
	 * @return null
324
	 * @access private
325
	 */
326
	private function set_return_args_url($set_return_args_url)
327
	{
328
		switch ($set_return_args_url)
329
		{
330
			case 'cancel':
331
			case 'success':
332
				$this->template->assign_vars(array(
333
					'L_PPDE_DONATION_TITLE' => $this->user->lang['PPDE_' . strtoupper($set_return_args_url) . '_TITLE'],
334
				));
335
				$this->return_args_url = $set_return_args_url;
336
				break;
337
			case 'donorlist':
338
				$this->template->assign_vars(array(
339
					'L_PPDE_DONORLIST_TITLE' => $this->user->lang['PPDE_DONORLIST_TITLE'],
340
				));
341
				$this->return_args_url = $set_return_args_url;
342
				break;
343
			default:
344
				$this->return_args_url = 'body';
345
		}
346
347
	}
348
349
	/**
350
	 * Get content of current donation pages
351
	 *
352
	 * @param string $return_args_url
353
	 *
354
	 * @return array
355
	 * @access private
356
	 */
357
	private function get_donation_content_data($return_args_url)
358
	{
359
		return $this->donation_content_data =
360
			$this->ppde_entity_donation_pages->get_data(
361
				$this->ppde_operator_donation_pages->build_sql_data($this->user->get_iso_lang_id(), $return_args_url));
362
	}
363
364
	/**
365
	 * Build pull down menu options of available currency
366
	 *
367
	 * @param int $config_value Currency identifier; default: 0
368
	 *
369
	 * @return null
370
	 * @access public
371
	 */
372
	public function build_currency_select_menu($config_value = 0)
373
	{
374
		// Grab the list of all enabled currencies; 0 is for all data
375
		$currency_items = $this->ppde_entity_currency->get_data($this->ppde_operator_currency->build_sql_data(0, true));
376
377
		// Process each rule menu item for pull-down
378
		foreach ($currency_items as $currency_item)
379
		{
380
			// Set output block vars for display in the template
381
			$this->template->assign_block_vars('options', array(
382
				'CURRENCY_ID'        => (int) $currency_item['currency_id'],
383
				'CURRENCY_ISO_CODE'  => $currency_item['currency_iso_code'],
384
				'CURRENCY_NAME'      => $currency_item['currency_name'],
385
				'CURRENCY_SYMBOL'    => $currency_item['currency_symbol'],
386
387
				'S_CURRENCY_DEFAULT' => $config_value == $currency_item['currency_id'],
388
			));
389
		}
390
		unset ($currency_items, $currency_item);
391
	}
392
393
	/**
394
	 * Build pull down menu options of available currency value
395
	 *
396
	 * @return string List of currency value set in ACP for dropdown menu
397
	 * @access private
398
	 */
399
	private function build_currency_value_select_menu()
400
	{
401
		$list_donation_value = '';
402
403
		if ($this->get_dropbox_status())
404
		{
405
			$donation_ary_value = explode(',', $this->config['ppde_dropbox_value']);
406
407
			foreach ($donation_ary_value as $value)
408
			{
409
				$int_value = $this->settype_dropbox_int_value($value);
410
				$list_donation_value .= !empty($int_value) ? '<option value="' . $int_value . '">' . $int_value . '</option>' : '';
411
			}
412
			unset($value);
413
		}
414
415
		return $list_donation_value;
416
	}
417
418
	/**
419
	 * Get dropbox config value
420
	 *
421
	 * @return bool
422
	 * @access private
423
	 */
424
	private function get_dropbox_status()
425
	{
426
		return $this->config['ppde_dropbox_enable'] && $this->config['ppde_dropbox_value'];
427
	}
428
429
	/**
430
	 * Force dropbox value to integer
431
	 *
432
	 * @param int $value
433
	 *
434
	 * @return int
435
	 * @access private
436
	 */
437
	private function settype_dropbox_int_value($value = 0)
438
	{
439
		if (settype($value, 'integer') && $value != 0)
440
		{
441
			return $value;
442
		}
443
444
		return 0;
445
	}
446
447
	/**
448
	 * Build PayPal hidden fields
449
	 *
450
	 * @return string PayPal hidden field needed to fill PayPal forms
451
	 * @access private
452
	 */
453
	private function paypal_hidden_fields()
454
	{
455
		return build_hidden_fields(array(
456
			'cmd'           => '_donations',
457
			'business'      => $this->get_account_id(),
458
			'item_name'     => $this->user->lang['PPDE_DONATION_TITLE_HEAD'] . ' ' . $this->config['sitename'],
459
			'no_shipping'   => 1,
460
			'return'        => $this->generate_paypal_return_url('success'),
461
			'notify_url'    => $this->generate_paypal_notify_return_url(),
462
			'cancel_return' => $this->generate_paypal_return_url('cancel'),
463
			'item_number'   => 'uid_' . $this->user->data['user_id'] . '_' . time(),
464
			'tax'           => 0,
465
			'bn'            => 'Board_Donate_WPS',
466
			'charset'       => 'utf-8',
467
		));
468
	}
469
470
	/**
471
	 * Get PayPal account id
472
	 *
473
	 * @return string $this Paypal account Identifier
474
	 * @access private
475
	 */
476
	private function get_account_id()
477
	{
478
		return $this->use_sandbox() ? $this->config['ppde_sandbox_address'] : $this->config['ppde_account_id'];
479
	}
480
481
	/**
482
	 * Check if Sandbox is enabled
483
	 *
484
	 * @return bool
485
	 * @access public
486
	 */
487
	public function use_sandbox()
488
	{
489
		return !empty($this->config['ppde_sandbox_enable']) && (!empty($this->config['ppde_sandbox_founder_enable']) && ($this->user->data['user_type'] == USER_FOUNDER) || empty($this->config['ppde_sandbox_founder_enable']));
490
	}
491
492
	/**
493
	 * Check if IPN is enabled
494
	 *
495
	 * @return bool
496
	 * @access public
497
	 */
498
	public function use_ipn()
499
	{
500
		return !empty($this->config['ppde_enable']) && !empty($this->config['ppde_ipn_enable']) && (!empty($this->config['ppde_curl_detected']) || !empty($this->config['ppde_fsockopen_detected']));
501
	}
502
503
	/**
504
	 * Generate PayPal return URL
505
	 *
506
	 * @param string $arg
507
	 *
508
	 * @return string
509
	 * @access private
510
	 */
511
	private function generate_paypal_return_url($arg)
512
	{
513
		return generate_board_url(true) . $this->helper->route('skouat_ppde_donate', array('return' => $arg));
514
	}
515
516
	/**
517
	 * Generate PayPal return notify URL
518
	 *
519
	 * @return string
520
	 * @access private
521
	 */
522
	private function generate_paypal_notify_return_url()
523
	{
524
		return generate_board_url(true) . $this->helper->route('skouat_ppde_ipn_listener');
525
	}
526
527
	/**
528
	 * Get PayPal URL
529
	 * Used in form and in IPN process
530
	 *
531
	 * @param bool $is_test_ipn
532
	 *
533
	 * @return string
534
	 * @access public
535
	 */
536
	public function get_paypal_url($is_test_ipn = false)
537
	{
538
		return ($is_test_ipn || $this->use_sandbox()) ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr';
539
	}
540
541
	/**
542
	 * Assign statistics vars to the template
543
	 *
544
	 * @return null
545
	 * @access public
546
	 */
547
	public function display_stats()
548
	{
549
		if ($this->config['ppde_goal_enable'] || $this->config['ppde_raised_enable'] || $this->config['ppde_used_enable'])
550
		{
551
			// Get data from the database
552
			$default_currency_data = $this->get_default_currency_data($this->config['ppde_default_currency']);
553
554
			$this->template->assign_vars(array(
555
				'PPDE_GOAL_ENABLE'   => $this->config['ppde_goal_enable'],
556
				'PPDE_RAISED_ENABLE' => $this->config['ppde_raised_enable'],
557
				'PPDE_USED_ENABLE'   => $this->config['ppde_used_enable'],
558
559
				'L_PPDE_GOAL'        => $this->get_ppde_goal_langkey($default_currency_data[0]['currency_symbol'], (bool) $default_currency_data[0]['currency_on_left']),
560
				'L_PPDE_RAISED'      => $this->get_ppde_raised_langkey($default_currency_data[0]['currency_symbol'], (bool) $default_currency_data[0]['currency_on_left']),
561
				'L_PPDE_USED'        => $this->get_ppde_used_langkey($default_currency_data[0]['currency_symbol'], (bool) $default_currency_data[0]['currency_on_left']),
562
			));
563
564
			// Generate statistics percent for display
565
			$this->generate_stats_percent();
566
		}
567
	}
568
569
	/**
570
	 * Get default currency symbol
571
	 *
572
	 * @param int $id
573
	 *
574
	 * @return array
575
	 * @access public
576
	 */
577
	public function get_default_currency_data($id = 0)
578
	{
579
		return $this->ppde_entity_currency->get_data($this->ppde_operator_currency->build_sql_data($id, true));
580
	}
581
582
	/**
583
	 * Retrieve the language key for donation goal
584
	 *
585
	 * @param string $currency_symbol Currency symbol
586
	 * @param bool   $on_left         Symbol position
587
	 *
588
	 * @return string
589
	 * @access public
590
	 */
591
	public function get_ppde_goal_langkey($currency_symbol, $on_left = true)
592
	{
593
		if ((int) $this->config['ppde_goal'] <= 0)
594
		{
595
			$l_ppde_goal = $this->user->lang['PPDE_DONATE_NO_GOAL'];
596
		}
597 View Code Duplication
		else if ((int) $this->config['ppde_goal'] < (int) $this->config['ppde_raised'])
598
		{
599
			$l_ppde_goal = $this->user->lang['PPDE_DONATE_GOAL_REACHED'];
600
		}
601
		else
602
		{
603
			$l_ppde_goal = $this->user->lang('PPDE_DONATE_GOAL_RAISE', $this->currency_on_left((int) $this->config['ppde_goal'], $currency_symbol, $on_left));
604
		}
605
606
		return $l_ppde_goal;
607
	}
608
609
	/**
610
	 * Put the currency on the left or on the right of the amount
611
	 *
612
	 * @param int    $value
613
	 * @param string $currency
614
	 * @param bool   $on_left
615
	 *
616
	 * @return string
617
	 * @access public
618
	 */
619
	public function currency_on_left($value, $currency, $on_left = true)
620
	{
621
		return $on_left ? $currency . $value : $value . $currency;
622
	}
623
624
	/**
625
	 * Retrieve the language key for donation raised
626
	 *
627
	 * @param string $currency_symbol Currency symbol
628
	 * @param bool   $on_left         Symbol position
629
	 *
630
	 * @return string
631
	 * @access public
632
	 */
633
	public function get_ppde_raised_langkey($currency_symbol, $on_left = true)
634
	{
635 View Code Duplication
		if ((int) $this->config['ppde_raised'] <= 0)
636
		{
637
			$l_ppde_raised = $this->user->lang['PPDE_DONATE_NOT_RECEIVED'];
638
		}
639
		else
640
		{
641
			$l_ppde_raised = $this->user->lang('PPDE_DONATE_RECEIVED', $this->currency_on_left((int) $this->config['ppde_raised'], $currency_symbol, $on_left));
642
		}
643
644
		return $l_ppde_raised;
645
	}
646
647
	/**
648
	 * Retrieve the language key for donation used
649
	 *
650
	 * @param string $currency_symbol Currency symbol
651
	 * @param bool   $on_left         Symbol position
652
	 *
653
	 * @return string
654
	 * @access public
655
	 */
656
	public function get_ppde_used_langkey($currency_symbol, $on_left = true)
657
	{
658
		if ((int) $this->config['ppde_used'] <= 0)
659
		{
660
			$l_ppde_used = $this->user->lang['PPDE_DONATE_NOT_USED'];
661
		}
662
		else if ((int) $this->config['ppde_used'] < (int) $this->config['ppde_raised'])
663
		{
664
			$l_ppde_used = $this->user->lang('PPDE_DONATE_USED', $this->currency_on_left((int) $this->config['ppde_used'], $currency_symbol, $on_left), $this->currency_on_left((int) $this->config['ppde_raised'], $currency_symbol, $on_left));
665
		}
666
		else
667
		{
668
			$l_ppde_used = $this->user->lang('PPDE_DONATE_USED_EXCEEDED', $this->currency_on_left((int) $this->config['ppde_used'], $currency_symbol, $on_left));
669
		}
670
671
		return $l_ppde_used;
672
	}
673
674
	/**
675
	 * Generate statistics percent for display
676
	 *
677
	 * @return null
678
	 * @access private
679
	 */
680
	private function generate_stats_percent()
681
	{
682 View Code Duplication
		if ($this->is_ppde_goal_stats())
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
683
		{
684
			$percent = $this->percent_value((int) $this->config['ppde_raised'], (int) $this->config['ppde_goal']);
685
			$this->assign_vars_stats_percent($percent, 'GOAL_NUMBER');
686
			$this->template->assign_var('PPDE_CSS_GOAL_NUMBER', $this->ppde_css_classname($percent));
687
		}
688
689 View Code Duplication
		if ($this->is_ppde_used_stats())
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
690
		{
691
			$percent = $this->percent_value((int) $this->config['ppde_used'], (int) $this->config['ppde_raised']);
692
			$this->assign_vars_stats_percent($percent, 'USED_NUMBER');
693
			$this->template->assign_var('PPDE_CSS_USED_NUMBER', $this->ppde_css_classname($percent, true));
694
		}
695
	}
696
697
	/**
698
	 * Checks if stats can be displayed
699
	 *
700
	 * @return bool
701
	 * @access private
702
	 */
703
	private function is_ppde_goal_stats()
704
	{
705
		return $this->config['ppde_goal_enable'] && (int) $this->config['ppde_goal'] > 0;
706
	}
707
708
	/**
709
	 * Checks if stats can be displayed
710
	 *
711
	 * @return bool
712
	 * @access private
713
	 */
714
	private function is_ppde_used_stats()
715
	{
716
		return $this->config['ppde_used_enable'] && (int) $this->config['ppde_raised'] > 0 && (int) $this->config['ppde_used'] > 0;
717
	}
718
719
720
	/**
721
	 * Returns percent value
722
	 *
723
	 * @param integer $multiplicand
724
	 * @param integer $dividend
725
	 *
726
	 * @return float
727
	 * @access private
728
	 */
729
	private function percent_value($multiplicand, $dividend)
730
	{
731
		return round(($multiplicand * 100) / $dividend, 2);
732
	}
733
734
	/**
735
	 * Assign statistics percent vars to template
736
	 *
737
	 * @param float  $percent
738
	 * @param string $type
739
	 *
740
	 * @return null
741
	 * @access private
742
	 */
743
	private function assign_vars_stats_percent($percent, $type)
744
	{
745
		$this->template->assign_vars(array(
746
			'PPDE_' . $type => $percent,
747
			'S_' . $type    => !empty($type) ? true : false,
748
		));
749
	}
750
751
	/**
752
	 * Returns the CSS class name based on the percent of stats
753
	 *
754
	 * @param float $value
755
	 * @param bool  $reverse
756
	 *
757
	 * @return string
758
	 * @access private
759
	 */
760
	private function ppde_css_classname($value, $reverse = false)
761
	{
762
		$value = ($reverse && $value < 100) ? 100 - $value : $value;
763
764
		switch ($value)
765
		{
766
			case ($value <= 10):
767
				return 'ten';
768
			case ($value <= 20):
769
				return 'twenty';
770
			case ($value <= 30):
771
				return 'thirty';
772
			case ($value <= 40):
773
				return 'forty';
774
			case ($value <= 50):
775
				return 'fifty';
776
			case ($value <= 60):
777
				return 'sixty';
778
			case ($value <= 70):
779
				return 'seventy';
780
			case ($value <= 80):
781
				return 'eighty';
782
			case ($value <= 90):
783
				return 'ninety';
784
			case ($value < 100):
785
				return 'hundred';
786
			default:
787
				return $reverse ? 'red' : 'green';
788
		}
789
	}
790
791
	/**
792
	 * Send data to the template file
793
	 *
794
	 * @return \Symfony\Component\HttpFoundation\Response
795
	 * @access private
796
	 */
797
	private function send_data_to_template()
798
	{
799
		switch ($this->return_args_url)
800
		{
801
			case 'cancel':
802
			case 'success':
803
				return $this->helper->render('donate_body.html', $this->user->lang('PPDE_' . strtoupper($this->return_args_url) . '_TITLE'));
804
			case 'donorlist':
805
				return $this->helper->render('donorlist_body.html', $this->user->lang('PPDE_DONORLIST_TITLE'));
806
			default:
807
				return $this->helper->render('donate_body.html', $this->user->lang('PPDE_DONATION_TITLE'));
808
		}
809
	}
810
811
	/**
812
	 * Do action if it's the first time the extension is accessed
813
	 *
814
	 * @return null
815
	 * @access public
816
	 */
817
	public function first_start()
818
	{
819
		if ($this->config['ppde_first_start'])
820
		{
821
			$this->set_curl_info();
822
			$this->set_remote_detected();
823
			$this->config['ppde_first_start'] = false;
824
		}
825
	}
826
827
	/**
828
	 * Check if cURL is available
829
	 *
830
	 * @param bool $check_version
831
	 *
832
	 * @return array|bool
833
	 * @access public
834
	 */
835
	public function check_curl($check_version = false)
836
	{
837
		if (function_exists('curl_version') && $check_version)
838
		{
839
			return curl_version();
840
		}
841
842
		if (function_exists('curl_init') && function_exists('curl_exec'))
843
		{
844
			$this->get_ext_meta();
845
846
			$ch = curl_init($this->ext_meta['extra']['version-check']['host']);
847
848
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
849
850
			$response = curl_exec($ch);
851
			$response_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
852
853
			curl_close($ch);
854
855
			return ($response !== false || $response_status !== '0') ? true : false;
856
		}
857
858
		return false;
859
	}
860
861
	/**
862
	 * Set config value for cURL version
863
	 *
864
	 * @return null
865
	 * @access public
866
	 */
867
	public function set_curl_info()
868
	{
869
		// Get cURL version informations
870
		if ($curl_info = $this->check_curl(true))
871
		{
872
			$this->config->set('ppde_curl_version', $curl_info['version']);
873
			$this->config->set('ppde_curl_ssl_version', $curl_info['ssl_version']);
874
		}
875
	}
876
877
	/**
878
	 * Set config value for cURL and fsockopen
879
	 *
880
	 * @return null
881
	 * @access public
882
	 */
883
	public function set_remote_detected()
884
	{
885
		$this->config->set('ppde_curl_detected', $this->check_curl());
886
		$this->config->set('ppde_fsock_detected', $this->check_fsockopen());
887
	}
888
889
	/**
890
	 * Get extension metadata
891
	 *
892
	 * @return null
893
	 * @access protected
894
	 */
895
	protected function get_ext_meta()
896
	{
897
		if (empty($this->ext_meta))
898
		{
899
			$this->load_metadata();
900
		}
901
	}
902
903
	/**
904
	 * Load metadata for this extension
905
	 *
906
	 * @return array
907
	 * @access public
908
	 */
909
	public function load_metadata()
910
	{
911
		// Retrieve the extension name based on the namespace of this file
912
		$this->retrieve_ext_name();
913
914
		// If they've specified an extension, let's load the metadata manager and validate it.
915
		if ($this->ext_name)
916
		{
917
			$md_manager = new \phpbb\extension\metadata_manager($this->ext_name, $this->config, $this->extension_manager, $this->template, $this->user, $this->root_path);
918
919
			try
920
			{
921
				$this->ext_meta = $md_manager->get_metadata('all');
922
			}
923
			catch (\phpbb\extension\exception $e)
924
			{
925
				trigger_error($e, E_USER_WARNING);
926
			}
927
		}
928
929
		return $this->ext_meta;
930
	}
931
932
	/**
933
	 * Retrieve the extension name
934
	 *
935
	 * @return null
936
	 * @access protected
937
	 */
938
	protected function retrieve_ext_name()
939
	{
940
		$namespace_ary = explode('\\', __NAMESPACE__);
941
		$this->ext_name = $namespace_ary[0] . '/' . $namespace_ary[1];
942
	}
943
944
	/**
945
	 * Check if fsockopen is available
946
	 *
947
	 * @return bool
948
	 * @access public
949
	 */
950
	public function check_fsockopen()
951
	{
952
		if (function_exists('fsockopen'))
953
		{
954
			$this->get_ext_meta();
955
956
			$url = parse_url($this->ext_meta['extra']['version-check']['host']);
957
958
			$fp = @fsockopen($url['path'], 80);
959
960
			return ($fp !== false) ? true : false;
961
		}
962
963
		return false;
964
	}
965
}
966