Completed
Push — master ( 9b85c2...3f27cb )
by Mario
02:45
created

admin_transactions_controller::update_stats()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 5
nc 1
nop 1
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
/**
16
 * @property ContainerInterface       container         The phpBB log system
17
 * @property string                   id_prefix_name    Prefix name for identifier in the URL
18
 * @property string                   lang_key_prefix   Prefix for the messages thrown by exceptions
19
 * @property \phpbb\log\log           log               The phpBB log system.
20
 * @property string                   module_name       Name of the module currently used
21
 * @property \phpbb\request\request   request           Request object.
22
 * @property bool                     submit            State of submit $_POST variable
23
 * @property \phpbb\template\template template          Template object
24
 * @property string                   u_action          Action URL
25
 * @property \phpbb\user              user              User object.
26
 */
27
class admin_transactions_controller extends admin_main
28
{
29
	public $ppde_operator;
30
	protected $adm_relative_path;
31
	protected $auth;
32
	protected $db;
33
	protected $config;
34
	protected $entry_count;
35
	protected $last_page_offset;
36
	protected $php_ext;
37
	protected $phpbb_admin_path;
38
	protected $phpbb_root_path;
39
	protected $table_ppde_transactions;
40
	private $is_ipn_test = false;
41
	private $suffix_ipn;
42
43
	/**
44
	 * Constructor
45
	 *
46
	 * @param \phpbb\auth\auth                    $auth                       Authentication object
47
	 * @param \phpbb\db\driver\driver_interface   $db                         Database object
48
	 * @param \phpbb\config\config                $config                     Config object
49
	 * @param ContainerInterface                  $container
50
	 * @param \phpbb\log\log                      $log                        The phpBB log system
51
	 * @param \skouat\ppde\operators\transactions $ppde_operator_transactions Operator object
52
	 * @param \phpbb\request\request              $request                    Request object
53
	 * @param \phpbb\template\template            $template                   Template object
54
	 * @param \phpbb\user                         $user                       User object.
55
	 * @param string                              $adm_relative_path          phpBB admin relative path
56
	 * @param string                              $phpbb_root_path            phpBB root path
57
	 * @param string                              $php_ext                    phpEx
58
	 * @param string                              $table_ppde_transactions    Name of the table used to store data
59
	 *
60
	 * @access public
61
	 */
62
	public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, ContainerInterface $container, \phpbb\log\log $log, \skouat\ppde\operators\transactions $ppde_operator_transactions, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user, $adm_relative_path, $phpbb_root_path, $php_ext, $table_ppde_transactions)
63
	{
64
		$this->auth = $auth;
65
		$this->db = $db;
66
		$this->config = $config;
67
		$this->container = $container;
68
		$this->log = $log;
69
		$this->ppde_operator = $ppde_operator_transactions;
70
		$this->request = $request;
71
		$this->template = $template;
72
		$this->user = $user;
73
		$this->adm_relative_path = $adm_relative_path;
74
		$this->phpbb_admin_path = $phpbb_root_path . $adm_relative_path;
75
		$this->phpbb_root_path = $phpbb_root_path;
76
		$this->php_ext = $php_ext;
77
		$this->table_ppde_transactions = $table_ppde_transactions;
78
		parent::__construct(
79
			'transactions',
80
			'PPDE_DT',
81
			'transaction'
82
		);
83
	}
84
85
	/**
86
	 * Display the transactions list
87
	 *
88
	 * @param string $id     Module id
89
	 * @param string $mode   Module categorie
90
	 * @param string $action Action name
91
	 *
92
	 * @return null
93
	 * @access public
94
	 */
95
	public function display_transactions($id, $mode, $action)
96
	{
97
		// Set up general vars
98
		$start = $this->request->variable('start', 0);
99
		$deletemark = $this->request->is_set('delmarked');
100
		$deleteall = $this->request->is_set('delall');
101
		$marked = $this->request->variable('mark', array(0));
102
		// Sort keys
103
		$sort_days = $this->request->variable('st', 0);
104
		$sort_key = $this->request->variable('sk', 't');
105
		$sort_dir = $this->request->variable('sd', 'd');
106
107
		// Initiate an entity
108
		/** @type \skouat\ppde\entity\transactions $entity */
109
		$entity = $this->get_container_entity();
110
111
		// Delete entries if requested and able
112
		if (($deletemark || $deleteall) && $this->auth->acl_get('a_ppde_manage'))
113
		{
114
			if (confirm_box(true))
115
			{
116
				$where_sql = '';
117
118
				if ($deletemark && sizeof($marked))
119
				{
120
					$where_sql = $this->ppde_operator->build_marked_where_sql($marked);
121
				}
122
123
				if ($where_sql || $deleteall)
124
				{
125
					$entity->delete(0, '', $where_sql);
126
					$this->update_stats();
127
					$this->update_stats(true);
128
					$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_' . $this->lang_key_prefix . '_PURGED', time());
129
				}
130
			}
131
			else
132
			{
133
				confirm_box(false, $this->user->lang['CONFIRM_OPERATION'], build_hidden_fields(array(
134
						'start'     => $start,
135
						'delmarked' => $deletemark,
136
						'delall'    => $deleteall,
137
						'mark'      => $marked,
138
						'st'        => $sort_days,
139
						'sk'        => $sort_key,
140
						'sd'        => $sort_dir,
141
						'i'         => $id,
142
						'mode'      => $mode,
143
						'action'    => $action))
144
				);
145
			}
146
		}
147
148
		$this->do_action($action);
149
150
		if (!$action)
151
		{
152
			/** @type \phpbb\pagination $pagination */
153
			$pagination = $this->container->get('pagination');
154
155
			// Sorting
156
			$limit_days = array(0 => $this->user->lang['ALL_ENTRIES'], 1 => $this->user->lang['1_DAY'], 7 => $this->user->lang['7_DAYS'], 14 => $this->user->lang['2_WEEKS'], 30 => $this->user->lang['1_MONTH'], 90 => $this->user->lang['3_MONTHS'], 180 => $this->user->lang['6_MONTHS'], 365 => $this->user->lang['1_YEAR']);
157
			$sort_by_text = array('txn' => $this->user->lang['PPDE_DT_SORT_TXN_ID'], 'u' => $this->user->lang['PPDE_DT_SORT_DONORS'], 'ipn' => $this->user->lang['PPDE_DT_SORT_IPN_STATUS'], 'ipn_test' => $this->user->lang['PPDE_DT_SORT_IPN_TYPE'], 'ps' => $this->user->lang['PPDE_DT_SORT_PAYMENT_STATUS'], 't' => $this->user->lang['SORT_DATE']);
158
			$sort_by_sql = array('txn' => 'txn.txn_id', 'u' => 'u.username_clean', 'ipn' => 'txn.confirmed', 'ipn_test' => 'txn.test_ipn', 'ps' => 'txn.payment_status', 't' => 'txn.payment_date');
159
160
			$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
161
			gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
162
163
			// Define where and sort sql for use in displaying transactions
164
			$sql_where = ($sort_days) ? (time() - ($sort_days * 86400)) : 0;
165
			$sql_sort = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
166
167
			$keywords = utf8_normalize_nfc($this->request->variable('keywords', '', true));
168
			$keywords_param = !empty($keywords) ? '&amp;keywords=' . urlencode(htmlspecialchars_decode($keywords)) : '';
169
170
			// Grab log data
171
			$log_data = array();
172
			$log_count = 0;
173
174
			$this->view_txn_log($log_data, $log_count, $this->config['topics_per_page'], $start, $sql_where, $sql_sort, $keywords);
175
176
			$base_url = $this->u_action . '&amp;' . $u_sort_param . $keywords_param;
177
			$pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $this->config['topics_per_page'], $start);
178
179
			$this->template->assign_vars(array(
180
				'S_CLEARLOGS'  => $this->auth->acl_get('a_ppde_manage'),
181
				'S_KEYWORDS'   => $keywords,
182
				'S_LIMIT_DAYS' => $s_limit_days,
183
				'S_SORT_KEY'   => $s_sort_key,
184
				'S_SORT_DIR'   => $s_sort_dir,
185
				'S_TXN'        => $mode,
186
				'U_ACTION'     => $this->u_action . '&amp;' . $u_sort_param . $keywords_param . '&amp;start=' . $start,
187
			));
188
189
			foreach ($log_data as $row)
190
			{
191
				// Initiate vars to retrieve the 'payment_status' translation from the language key
192
				$payment_status_ary = $this->user->lang['PPDE_DT_PAYMENT_STATUS_VALUES'];
193
				$payment_status_name = strtolower($row['payment_status']);
194
195
				$this->template->assign_block_vars('log', array(
196
					'TNX_ID'           => $row['txn_id'],
197
					'USERNAME'         => $row['username_full'],
198
					'DATE'             => $this->user->format_date($row['payment_date']),
199
					'ID'               => $row['transaction_id'],
200
					'S_TEST_IPN'       => $row['test_ipn'],
201
					'CONFIRMED'        => ($row['confirmed']) ? $this->user->lang['PPDE_DT_VERIFIED'] : $this->user->lang['PPDE_DT_UNVERIFIED'],
202
					'PAYMENT_STATUS'   => $payment_status_ary[$payment_status_name],
203
					'S_CONFIRMED'      => ($row['confirmed']) ? false : true,
204
					'S_PAYMENT_STATUS' => ($payment_status_name === 'completed') ? false : true,
205
				));
206
				unset($payment_status_name);
207
			}
208
		}
209
	}
210
211
212
	/**
213
	 * @param bool $ipn_stats
214
	 */
215
	public function update_stats($ipn_stats = false)
216
	{
217
		$this->set_ipn_test_properties($ipn_stats);
218
		$this->config->set('ppde_anonymous_donors_count' . $this->suffix_ipn, $this->sql_query_update_stats('ppde_anonymous_donors_count' . $this->suffix_ipn));
219
		$this->config->set('ppde_known_donors_count' . $this->suffix_ipn, $this->sql_query_update_stats('ppde_known_donors_count' . $this->suffix_ipn), true);
220
		$this->config->set('ppde_transactions_count' . $this->suffix_ipn, $this->sql_query_update_stats('ppde_transactions_count' . $this->suffix_ipn), true);
221
	}
222
223
	/**
224
	 * Sets properties related to ipn tests
225
	 *
226
	 * @param bool $ipn_stats
227
	 *
228
	 * @return null
229
	 * @access public
230
	 */
231
	public function set_ipn_test_properties($ipn_stats)
232
	{
233
		$this->set_ipn_test($ipn_stats);
234
		$this->set_suffix_ipn();
235
	}
236
237
	/**
238
	 * Sets the property $this->is_ipn_test
239
	 *
240
	 * @param $ipn_test
241
	 *
242
	 * @return null
243
	 * @access private
244
	 */
245
	private function set_ipn_test($ipn_test)
246
	{
247
		$this->is_ipn_test = $ipn_test ? (bool) $ipn_test : false;
248
	}
249
250
	/**
251
	 * Sets the property $this->suffix_ipn
252
	 *
253
	 * @return null
254
	 * @access private
255
	 */
256
	private function set_suffix_ipn()
257
	{
258
		$this->suffix_ipn = $this->is_ipn_test ? '_ipn' : '';
259
	}
260
261
	/**
262
	 * Returns count result for updating stats
263
	 *
264
	 * @param string $config_name
265
	 *
266
	 * @return int
267
	 * @access private
268
	 */
269
	private function sql_query_update_stats($config_name)
270
	{
271
		if (!$this->config->offsetExists($config_name))
272
		{
273
			trigger_error($this->user->lang('EXCEPTION_INVALID_CONFIG_NAME', $config_name), E_USER_WARNING);
274
		}
275
276
		$this->db->sql_query($this->ppde_operator->sql_build_update_stats($config_name, $this->is_ipn_test));
277
278
		return (int) $this->db->sql_fetchfield('count_result');
279
	}
280
281
	/**
282
	 * Do action regarding the value of $action
283
	 *
284
	 * @param $action
285
	 *
286
	 * @return null
287
	 * @access private
288
	 */
289
	private function do_action($action)
290
	{
291
		// Action: view
292
		if ($action == 'view')
293
		{
294
			// Request Identifier of the transaction
295
			$transaction_id = $this->request->variable('id', 0);
296
297
			// Initiate an entity
298
			/** @type \skouat\ppde\entity\currency $entity */
299
			$entity = $this->get_container_entity();
300
301
			// add field username to the table schema needed by entity->import()
302
			$additional_table_schema = array('item_username' => array('name' => 'username', 'type' => 'string'));
303
304
			// Grab transaction data
305
			$data_ary = $entity->get_data($this->ppde_operator->build_sql_data($transaction_id), $additional_table_schema);
306
307
			foreach ($data_ary as $data)
308
			{
309
				// Initiate vars to retrieve the 'payment_status' translation from the language key
310
				$payment_status_ary = $this->user->lang['PPDE_DT_PAYMENT_STATUS_VALUES'];
311
312
				$this->template->assign_vars(array(
313
					'BOARD_USERNAME' => $data['username'],
314
					'EXCHANGE_RATE'  => '1 ' . $data['mc_currency'] . ' = ' . $data['exchange_rate'] . ' ' . $data['settle_currency'],
315
					'ITEM_NAME'      => $data['item_name'],
316
					'ITEM_NUMBER'    => $data['item_number'],
317
					'MC_CURRENCY'    => $data['net_amount'] . ' ' . $data['mc_currency'],
318
					'MC_GROSS'       => $data['mc_gross'] . ' ' . $data['mc_currency'],
319
					'MC_FEE'         => '-' . $data['mc_fee'] . ' ' . $data['mc_currency'],
320
					'MC_NET'         => $data['net_amount'] . ' ' . $data['mc_currency'],
321
					'NAME'           => $data['first_name'] . ' ' . $data['last_name'],
322
					'PAYER_EMAIL'    => $data['payer_email'],
323
					'PAYER_ID'       => $data['payer_id'],
324
					'PAYER_STATUS'   => ($data['payer_status']) ? $this->user->lang['PPDE_DT_VERIFIED'] : $this->user->lang['PPDE_DT_UNVERIFIED'],
325
					'PAYMENT_DATE'   => $this->user->format_date($data['payment_date']),
326
					'PAYMENT_STATUS' => $payment_status_ary[strtolower($data['payment_status'])],
327
					'RECEIVER_EMAIL' => $data['receiver_email'],
328
					'RECEIVER_ID'    => $data['receiver_id'],
329
					'SETTLE_AMOUNT'  => $data['settle_amount'] . ' ' . $data['settle_currency'],
330
					'TXN_ID'         => $data['txn_id'],
331
332
					'L_PPDE_DT_SETTLE_AMOUNT'         => $this->user->lang('PPDE_DT_SETTLE_AMOUNT', $data['settle_currency']),
333
					'L_PPDE_DT_EXCHANGE_RATE_EXPLAIN' => $this->user->lang('PPDE_DT_EXCHANGE_RATE_EXPLAIN', $this->user->format_date($data['payment_date'])),
334
					'S_CONVERT'                       => ($data['settle_amount'] == 0 && empty($data['exchange_rate'])) ? false : true,
335
				));
336
			}
337
338
			$this->template->assign_vars(array(
339
				'U_ACTION' => $this->u_action,
340
				'U_BACK'   => $this->u_action,
341
				'S_VIEW'   => true,
342
			));
343
		}
344
	}
345
346
	/**
347
	 * View log
348
	 *
349
	 * @param array  &$log         The result array with the logs
350
	 * @param mixed  &$log_count   If $log_count is set to false, we will skip counting all entries in the
351
	 *                             database. Otherwise an integer with the number of total matching entries is returned.
352
	 * @param int    $limit        Limit the number of entries that are returned
353
	 * @param int    $offset       Offset when fetching the log entries, f.e. when paginating
354
	 * @param int    $limit_days
355
	 * @param string $sort_by      SQL order option, e.g. 'l.log_time DESC'
356
	 * @param string $keywords     Will only return log entries that have the keywords in log_operation or log_data
357
	 *
358
	 * @return int Returns the offset of the last valid page, if the specified offset was invalid
359
	 *                               (too high)
360
	 * @access private
361
	 */
362
	private function view_txn_log(&$log, &$log_count, $limit = 0, $offset = 0, $limit_days = 0, $sort_by = 'txn.payment_date DESC', $keywords = '')
363
	{
364
		$count_logs = ($log_count !== false);
365
366
		$log = $this->get_logs($count_logs, $limit, $offset, $limit_days, $sort_by, $keywords);
367
		$log_count = $this->get_log_count();
368
369
		return $this->get_valid_offset();
370
	}
371
372
	/**
373
	 * @param bool   $count_logs
374
	 * @param int    $limit
375
	 * @param int    $offset
376
	 * @param int    $log_time
377
	 * @param string $sort_by
378
	 * @param string $keywords
379
	 *
380
	 * @return array $log
381
	 * @access private
382
	 */
383
	private function get_logs($count_logs = true, $limit = 0, $offset = 0, $log_time = 0, $sort_by = 'txn.payment_date DESC', $keywords = '')
384
	{
385
		$this->entry_count = 0;
386
		$this->last_page_offset = $offset;
387
		$url_ary = array();
388
389
		if ($this->get_container_entity()->is_in_admin() && $this->phpbb_admin_path)
390
		{
391
			$url_ary['profile_url'] = append_sid($this->phpbb_admin_path . 'index.' . $this->php_ext, 'i=users&amp;mode=overview');
392
			$url_ary['txn_url'] = append_sid($this->phpbb_admin_path . 'index.' . $this->php_ext, 'i=-skouat-ppde-acp-ppde_module&amp;mode=transactions');
393
394
		}
395
		else
396
		{
397
			$url_ary['profile_url'] = append_sid($this->phpbb_root_path . 'memberlist.' . $this->php_ext, 'mode=viewprofile');
398
			$url_ary['txn_url'] = '';
399
		}
400
401
		$get_logs_sql_ary = $this->ppde_operator->get_logs_sql_ary($keywords, $sort_by, $log_time);
402
403
		if ($count_logs)
404
		{
405
			$this->entry_count = $this->ppde_operator->query_sql_count($get_logs_sql_ary, 'txn.transaction_id');
406
407
			if ($this->entry_count == 0)
408
			{
409
				// Save the queries, because there are no logs to display
410
				$this->last_page_offset = 0;
411
412
				return array();
413
			}
414
415
			// Return the user to the last page that is valid
416
			while ($this->last_page_offset >= $this->entry_count)
417
			{
418
				$this->last_page_offset = max(0, $this->last_page_offset - $limit);
419
			}
420
		}
421
422
		return $this->ppde_operator->build_log_ary($get_logs_sql_ary, $url_ary, $limit, $this->last_page_offset);
423
	}
424
425
	/**
426
	 * @return integer
427
	 */
428
	public function get_log_count()
429
	{
430
		return ($this->entry_count) ? $this->entry_count : 0;
431
	}
432
433
	/**
434
	 * @return integer
435
	 */
436
	public function get_valid_offset()
437
	{
438
		return ($this->last_page_offset) ? $this->last_page_offset : 0;
439
	}
440
441
	/**
442
	 * @return boolean
443
	 */
444
	public function get_is_ipn_test()
445
	{
446
		return ($this->is_ipn_test) ? $this->is_ipn_test : false;
447
	}
448
449
	/**
450
	 * @return string
451
	 */
452
	public function get_suffix_ipn()
453
	{
454
		return ($this->suffix_ipn) ? $this->suffix_ipn : '';
455
	}
456
}
457