/var/www/html_us/wp-content/plugins/wp-smtp/src/Mail/Admin/REST/Logs.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
<?php
/**
 * REST Controller class for handling email logs.
 *
 * @package Solid_SMTP\Controller
 */

namespace SolidWP\Mail\Admin\REST;

use 
SolidWP\Mail\Helper\Rest;
use 
SolidWP\Mail\Repository\LogsRepository;
use 
WP_REST_Request;
use 
WP_REST_Response;
use 
WP_Error;

/**
 * Class Logs
 *
 * Handles REST requests for fetching and searching email logs.
 */
class Logs extends \WP_REST_Controller {

    
/**
     * The namespace for the REST API endpoints.
     *
     * @var string
     */
    
protected $namespace 'solidwp-mail/v1';

    
/**
     * The resource name for the REST API endpoints.
     *
     * @var string
     */
    
protected $rest_base 'logs';

    
/**
     * The repository for handling email logs.
     *
     * @var LogsRepository
     */
    
protected LogsRepository $repository;

    
/**
     * Constructor.
     *
     * @param LogsRepository $repository The repository for handling email logs.
     */
    
public function __constructLogsRepository $repository ) {
        
$this->repository $repository;
    }

    
/**
     * Registers the REST routes.
     *
     * @return void
     */
    
public function register_routes() {
        
register_rest_route(
            
$this->namespace,
            
'/' $this->rest_base,
            [
                
'methods'             => \WP_REST_Server::READABLE,
                
'callback'            => [ $this'get_items' ],
                
'permission_callback' => [ $this'get_items_permissions_check' ],
                
'args'                => $this->get_collection_params(),
            ]
        );

        
register_rest_route(
            
$this->namespace,
            
'/' $this->rest_base '/delete',
            [
                
'methods'             => \WP_REST_Server::DELETABLE,
                
'callback'            => [ $this'delete_item' ],
                
'permission_callback' => [ $this'get_items_permissions_check' ],
                
'args'                => $this->get_collection_params(),
            ]
        );

        
register_rest_route(
            
$this->namespace,
            
'/' $this->rest_base '/export-csv',
            [
                
'methods'             => \WP_REST_Server::READABLE,
                
'callback'            => [ $this'export_csv' ],
                
'permission_callback' => [ $this'get_items_permissions_check' ],
                
'args'                => [
                    
'date_from' => [
                        
'required'          => true,
                        
'type'              => 'string',
                        
'format'            => 'date',
                        
'sanitize_callback' => 'sanitize_text_field',
                    ],
                    
'date_to'   => [
                        
'required'          => true,
                        
'type'              => 'string',
                        
'format'            => 'date',
                        
'sanitize_callback' => 'sanitize_text_field',
                    ],
                ],
            ]
        );
    }

    
/**
     * Handles the REST request for exporting email logs as CSV.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_REST_Response|WP_Error The response or WP_Error object on failure.
     */
    
public function export_csv$request ) {
        
$date_from $request->get_param'date_from' );
        
$date_to   $request->get_param'date_to' );

        
// Validate date format (optional)
        
if ( ! $this->is_valid_date$date_from ) || ! $this->is_valid_date$date_to ) ) {
            return new 
WP_Error'invalid_date'__'Invalid date format''wp-smtp' ), [ 'status' => 400 ] );
        }

        
// Query logs within the date range
        
$logs $this->repository->get_email_logs_by_datestrtotime$date_from ), strtotime$date_to ) );
        
// Prepare CSV content
        
$csv_content $this->generate_csv_content$logs );

        
// Set CSV filename
        
$csv_filename 'solid-mail-logs-' $date_from '-to-' $date_to '.csv';

        
// Serve CSV file
        
header'Content-Type: text/csv' );
        
header'Content-Disposition: attachment; filename="' sanitize_file_name$csv_filename ) . '"' );
        echo 
$csv_content// phpcs:ignore StellarWP.XSS.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.OutputNotEscaped

        
exit;
    }

    
/**
     * Validates the date format.
     *
     * @param string $date The date string to validate.
     *
     * @return bool True if valid, false otherwise.
     */
    
private function is_valid_date$date ) {
        
$d \DateTime::createFromFormat'Y-m-d'$date );

        return 
$d && $d->format'Y-m-d' ) === $date;
    }

    
/**
     * Generates CSV content from logs data.
     *
     * @param array $logs The logs data.
     *
     * @return string The generated CSV content.
     */
    
private function generate_csv_content$logs ) {
        
$csv_output fopen'php://output''w' );

        
// Add CSV headers
        
fputcsv$csv_output, [ 'To''Timestamp''Subject''Error' ] );

        
// Add CSV rows
        
foreach ( $logs as $log ) {
            
fputcsv$csv_output, [ $log['to'], $log['timestamp'], $log['subject'], $log['error'] ] );
        }

        
fclose$csv_output );

        
// Capture CSV output
        
return ob_get_clean();
    }

    
/**
     * Checks if a given request has access to perform the action.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_Error|bool True if the request has access, WP_Error otherwise.
     */
    
public function get_items_permissions_check$request ) {
        
// Only allow access for administrators.
        
if ( ! current_user_can'manage_options' ) ) {
            return new 
WP_Error'rest_cannot_view'__'You do not have permissions to access this endpoint''wp-smtp' ), [ 'status' => rest_authorization_required_code() ] );
        }

        return 
true;
    }

    
/**
     * Retrieves the collection parameters for the logs endpoint.
     *
     * @return array Collection parameters.
     */
    
public function get_collection_params(): array {
        return [
            
'page'        => [
                
'required'          => true,
                
'type'              => 'integer',
                
'default'           => 0,
                
'sanitize_callback' => 'absint',
            ],
            
'sortby'      => [
                
'required' => false,
                
'type'     => 'string',
                
'default'  => 'timestamp',
                
'enum'     => [ 'timestamp''subject''to' ],
            ],
            
'sort'        => [
                
'required' => false,
                
'type'     => 'string',
                
'default'  => 'desc',
                
'enum'     => [ 'asc''desc' ],
            ],
            
'search_term' => [
                
'required'          => false,
                
'type'              => 'string',
                
'default'           => '',
                
'sanitize_callback' => 'sanitize_text_field',
            ],
            
'per_page'    => [
                
'required'          => false,
                
'type'              => 'integer',
                
'default'           => 10,
                
'sanitize_callback' => 'absint',
            ],
            
'logIds'      => [
                
'required'          => true,
                
'default'           => [],
                
'type'              => 'array',
                
'sanitize_callback' => 'wp_parse_id_list',
            ],
        ];
    }

    
/**
     * Handles the REST request for deleting email logs.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_REST_Response|WP_Error The response or WP_Error object on failure.
     */
    
public function delete_item$request ) {
        
$log_ids $request['logIds'];
        
$this->repository->delete_logs$log_ids );

        return new 
WP_REST_Responsenull\WP_Http::NO_CONTENT );
    }

    
/**
     * Handles the REST request for fetching email logs.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_REST_Response|WP_Error The response or WP_Error object on failure.
     */
    
public function get_items$request ) {
        
$search_term $request->get_param'search_term' );

        
$total $this->repository->count_all_logs$search_term );
        
$data  = [
            
'logs' => $this->repository->get_email_logs$request->get_params() ),
        ];

        
$response rest_ensure_response$data );
        
Rest::paginate$request$response$total$this->namespace '/' $this->rest_base );

        return 
$response;
    }
}