Passed
Push — develop-3.3.x ( 7c1a2d...eebe3b )
by Mario
02:39
created

ipn_log::prepare_message()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 12
rs 10
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
 * Special Thanks to the following individuals for their inspiration:
10
 *    David Lewis (Highway of Life) http://startrekguide.com
11
 *    Micah Carrick ([email protected]) http://www.micahcarrick.com
12
 */
13
14
namespace skouat\ppde\controller;
15
16
use phpbb\config\config;
17
use phpbb\filesystem\filesystem_interface;
18
use phpbb\path_helper;
19
20
class ipn_log
21
{
22
	protected $config;
23
	protected $filesystem;
24
	protected $path_helper;
25
	protected $ppde_controller_main;
26
27
	private $log_path_filename;
28
29
	/**
30
	 * The output handler. A null handler is configured by default.
31
	 *
32
	 * @var \skouat\ppde\output_handler\log_wrapper_output_handler
33
	 */
34
	private $output_handler;
35
36
	/**
37
	 * If true, errors are logged into /store/ppde_transactions.log.
38
	 * If false, errors aren't logged. Default is false.
39
	 *
40
	 * @var boolean
41
	 */
42
	private $use_log_error = false;
43
	private $report_data = ['remote_uri'             => '',
44
							'remote_type'            => '',
45
							'remote_report_response' => '',
46
							'remote_response_status' => '',
47
							'remote_data'            => [],
48
	];
49
50
	/**
51
	 * Constructor
52
	 *
53
	 * @param config               $config               Config object
54
	 * @param filesystem_interface $filesystem           phpBB's filesystem service
55
	 * @param path_helper          $path_helper          Path helper object
56
	 * @param main_controller      $ppde_controller_main Main controller
57
	 */
58
	public function __construct(
59
		config $config,
60
		filesystem_interface $filesystem,
61
		path_helper $path_helper,
62
		main_controller $ppde_controller_main
63
	)
64
	{
65
		$this->config = $config;
66
		$this->filesystem = $filesystem;
67
		$this->path_helper = $path_helper;
68
		$this->ppde_controller_main = $ppde_controller_main;
69
70
		$this->log_path_filename = $this->generate_log_filename();
71
	}
72
73
	/**
74
	 * Generate a unique log filename
75
	 *
76
	 * @return string The generated log filename
77
	 */
78
	private function generate_log_filename(): string
79
	{
80
		$date = new \DateTime();
81
		return $this->path_helper->get_phpbb_root_path() . 'store/ext/ppde/ppde_tx_' . $date->format('Y-m-d_His_') . unique_id() . '.log';
82
	}
83
84
	/**
85
	 * Check if error logging is enabled
86
	 *
87
	 * @return bool True if error logging is enabled, false otherwise
88
	 */
89
	public function is_use_log_error(): bool
90
	{
91
		return $this->use_log_error;
92
	}
93
94
	/**
95
	 * Set whether to use error logging
96
	 *
97
	 * @param bool $use_log_error True to enable error logging, false to disable
98
	 */
99
	public function set_use_log_error(bool $use_log_error): void
100
	{
101
		$this->use_log_error = $use_log_error;
102
	}
103
104
	/**
105
	 * Set the report data for logging
106
	 *
107
	 * @param string $remote_uri             The remote URI
108
	 * @param string $remote_type            The remote type
109
	 * @param string $remote_report_response The remote report response
110
	 * @param string $remote_response_status The remote response status
111
	 * @param array  $remote_data            The remote data
112
	 */
113
	public function set_report_data(string $remote_uri, string $remote_type, string $remote_report_response, string $remote_response_status, array $remote_data): void
114
	{
115
		$this->report_data = [
116
			'remote_uri'             => $remote_uri,
117
			'remote_type'            => $remote_type,
118
			'remote_report_response' => $remote_report_response,
119
			'remote_response_status' => $remote_response_status,
120
			'remote_data'            => $remote_data,
121
		];
122
	}
123
124
	/**
125
	 * Log error messages
126
	 *
127
	 * @param string $message     The error message to log
128
	 * @param bool   $log_in_file Whether to log the error in a file
129
	 * @param bool   $exit        Whether to exit after logging the error
130
	 * @param int    $error_type  The type of error (E_USER_NOTICE, E_USER_WARNING, etc.)
131
	 * @param array  $args        Additional arguments to include in the log
132
	 */
133
	public function log_error(string $message, bool $log_in_file = false, bool $exit = false, int $error_type = E_USER_NOTICE, array $args = []): void
134
	{
135
		$error_timestamp = date('d-M-Y H:i:s Z');
136
137
		$backtrace = '';
138
		if (!empty($this->config['ppde_sandbox_enable']) && $this->ppde_controller_main->use_ipn())
139
		{
140
			$backtrace = get_backtrace();
141
		}
142
143
		$message = $this->prepare_message($message, $args);
144
145
		if ($log_in_file)
146
		{
147
			$this->write_to_file($error_timestamp, $message, $backtrace);
148
		}
149
150
		if ($exit)
151
		{
152
			trigger_error($message, $error_type);
153
		}
154
	}
155
156
	/**
157
	 * Prepare the error message
158
	 *
159
	 * @param string $message The base error message
160
	 * @param array  $args    Additional arguments to include in the message
161
	 * @return string The prepared error message
162
	 */
163
	private function prepare_message(string $message, array $args): string
164
	{
165
		if (!empty($args))
166
		{
167
			$message .= '<br>[args]<br>';
168
			foreach ($args as $key => $value)
169
			{
170
				$value = urlencode($value);
171
				$message .= $key . ' = ' . $value . ';<br>';
172
			}
173
		}
174
		return $message;
175
	}
176
177
	/**
178
	 * Write error message to file
179
	 *
180
	 * @param string $timestamp The timestamp of the error
181
	 * @param string $message   The error message
182
	 * @param string $backtrace The backtrace of the error
183
	 */
184
	private function write_to_file(string $timestamp, string $message, string $backtrace): void
185
	{
186
		$message_in_file = str_replace('<br>', "\n", $message);
187
		$backtrace = html_entity_decode(strip_tags(str_replace(['<br />', '<br>', "\n\n"], "\n", $backtrace)));
188
189
		try
190
		{
191
			$this->set_output_handler(new \skouat\ppde\output_handler\log_wrapper_output_handler($this->filesystem, $this->log_path_filename));
192
			$this->output_handler->write(sprintf('[%s] %s %s', $timestamp, $message_in_file, $backtrace));
193
		}
194
		catch (\Exception $e)
195
		{
196
			// If we can't write to our log file, fall back to error_log
197
			$this->log_error('PPDE Log Error: ' . $e->getMessage() . '<br>Original message: ' . $message_in_file);
198
		}
199
	}
200
201
	/**
202
	 * Set the output handler
203
	 *
204
	 * @param \skouat\ppde\output_handler\log_wrapper_output_handler $handler The output handler
205
	 */
206
	public function set_output_handler(\skouat\ppde\output_handler\log_wrapper_output_handler $handler): void
207
	{
208
		$this->output_handler = $handler;
209
	}
210
211
	/**
212
	 * Get Text Report
213
	 *
214
	 * Returns a report of the IPN transaction in plain text format. This is
215
	 * useful in emails to order processors and system administrators. Override
216
	 * this method in your own class to customize the report.
217
	 *
218
	 * @return string The generated text report
219
	 */
220
	public function get_text_report(): string
221
	{
222
		$r = '';
223
224
		// Date and POST url
225
		$this->text_report_insert_line($r);
226
		$r .= "\n[" . date('m/d/Y g:i A') . '] - ' . $this->report_data['remote_uri'] . ' ( ' . $this->report_data['remote_type'] . " )\n";
227
228
		// HTTP Response
229
		$this->text_report_insert_line($r);
230
		$r .= "\n" . $this->report_data['remote_report_response'] . "\n";
231
		$r .= "\n" . $this->report_data['remote_response_status'] . "\n";
232
		$this->text_report_insert_line($r);
233
234
		// POST vars
235
		$r .= "\n";
236
		$this->text_report_insert_args($r);
237
		$r .= "\n\n";
238
239
		return $r;
240
	}
241
242
	/**
243
	 * Insert hyphens line in the text report
244
	 *
245
	 * @param string $r The report string to append to
246
	 */
247
	private function text_report_insert_line(string &$r = ''): void
248
	{
249
		$r .= str_repeat('-', 80);
250
	}
251
252
	/**
253
	 * Insert remote data args into the text report
254
	 *
255
	 * @param string $r The report string to append to
256
	 */
257
	private function text_report_insert_args(string &$r = ''): void
258
	{
259
		foreach ($this->report_data['remote_data'] as $key => $value)
260
		{
261
			$r .= str_pad($key, 25) . $value . "\n";
262
		}
263
	}
264
}
265