Completed
Push — feature/45-drop-php-52 ( f96425 )
by Sudar
11:51
created

email-log.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Plugin Name: Email Log
4
 * Plugin URI: http://sudarmuthu.com/wordpress/email-log
5
 * Description: Logs every email sent through WordPress
6
 * Donate Link: http://sudarmuthu.com/if-you-wanna-thank-me
7
 * Author: Sudar
8
 * Version: 1.9.1
9
 * Author URI: http://sudarmuthu.com/
10
 * Text Domain: email-log
11
 * Domain Path: languages/
12
 * === RELEASE NOTES ===
13
 * Check readme file for full release notes
14
 */
15
16
/**
17
 * Copyright 2009  Sudar Muthu  (email : [email protected])
18
 * This program is free software; you can redistribute it and/or modify
19
 * it under the terms of the GNU General Public License, version 2, as
20
 * published by the Free Software Foundation.
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program; if not, write to the Free Software
27
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28
 */
29
30
/**
31
 * Plugin Root File
32
 *
33
 * @since 1.7.2
34
 */
35
if ( ! defined( 'EMAIL_LOG_PLUGIN_FILE' ) ) {
36
	define( 'EMAIL_LOG_PLUGIN_FILE', __FILE__ );
37
}
38
39
/**
40
 * Handles installation and table creation.
41
 */
42
require_once plugin_dir_path( __FILE__ ) . 'include/install.php';
43
44
/**
45
 * Helper functions.
46
 */
47
require_once plugin_dir_path( __FILE__ ) . 'include/util/helper.php';
48
49
/**
50
 * The main plugin class.
51
 *
52
 * @since Genesis
53
 */
54
class EmailLog {
55
56
	/**
57
	 * Filesystem directory path with trailing slash.
58
	 *
59
	 * @since Genesis
60
	 * @var string $include_path
61
	 */
62
	public $include_path;
63
64
	/**
65
	 * Admin screen object.
66
	 *
67
	 * @since Genesis
68
	 * @access private
69
	 * @var string $include_path
70
	 */
71
	private $admin_screen;
72
73
	/**
74
	 * Version number.
75
	 *
76
	 * @since Genesis
77
	 * @var const VERSION
78
	 */
79
	const VERSION                  = '1.9.1';
80
81
	/**
82
	 * Filter name.
83
	 *
84
	 * @since Genesis
85
	 * @var const FILTER_NAME
86
	 */
87
	const FILTER_NAME              = 'wp_mail_log';
88
89
	/**
90
	 * Page slug to be used in admin dashboard hyperlinks.
91
	 *
92
	 * @since Genesis
93
	 * @var const PAGE_SLUG
94
	 */
95
	const PAGE_SLUG                = 'email-log';
96
97
	/**
98
	 * String value to generate nonce.
99
	 *
100
	 * @since Genesis
101
	 * @var const DELETE_LOG_NONCE_FIELD
102
	 */
103
	const DELETE_LOG_NONCE_FIELD   = 'sm-delete-email-log-nonce';
104
105
	/**
106
	 * String value to generate nonce.
107
	 *
108
	 * @since Genesis
109
	 * @var const DELETE_LOG_ACTION
110
	 */
111
	const DELETE_LOG_ACTION        = 'sm-delete-email-log';
112
113
	// DB stuff
114
	const TABLE_NAME               = 'email_log';          /* Database table name */
115
	const DB_OPTION_NAME           = 'email-log-db';       /* Database option name */
116
	const DB_VERSION               = '0.1';                /* Database version */
117
118
	// JS Stuff
119
	const JS_HANDLE                = 'email-log';
120
121
	//hooks
122
	const HOOK_LOG_COLUMNS         = 'email_log_manage_log_columns';
123
	const HOOK_LOG_DISPLAY_COLUMNS = 'email_log_display_log_columns';
124
125
	/**
126
	 * Initialize the plugin by registering the hooks.
127
	 */
128
	function __construct() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
129
		$this->include_path = plugin_dir_path( __FILE__ );
130
131
		// Load localization domain.
132
		$this->translations = dirname( plugin_basename( __FILE__ ) ) . '/languages/' ;
0 ignored issues
show
The property translations does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
133
		load_plugin_textdomain( 'email-log', false, $this->translations );
134
135
		// Register hooks.
136
		add_action( 'admin_menu', array( $this, 'register_settings_page' ) );
137
138
		// Register Filter.
139
		add_filter( 'wp_mail', array( $this, 'log_email' ) );
140
		add_filter( 'set-screen-option', array( $this, 'save_screen_options' ), 10, 3 );
141
		add_filter( 'plugin_row_meta', array( $this, 'add_plugin_links' ), 10, 2 );
142
143
		$plugin = plugin_basename( __FILE__ );
144
		add_filter( "plugin_action_links_$plugin", array( $this, 'add_action_links' ) );
1 ignored issue
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $plugin instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
145
146
		// Add our ajax call.
147
		add_action( 'wp_ajax_display_content', array( $this, 'display_content_callback' ) );
148
	}
149
150
	/**
151
	 * Adds additional links in the plugin listing page.
152
	 *
153
	 * @since Genesis
154
	 *
155
	 * @see Additional links in the Plugin listing is based on
156
	 * @link http://zourbuth.com/archives/751/creating-additional-wordpress-plugin-links-row-meta/
157
	 *
158
	 * @param array $links Array with default links to display in plugins page.
159
	 * @param string $file The name of the plugin file.
160
	 * @return array Array with links to display in plugins page.
161
	 */
162
	public function add_plugin_links( $links, $file ) {
163
		$plugin = plugin_basename( __FILE__ );
164
165
		if ( $file == $plugin ) {
166
			// only for this plugin
167
			return array_merge( $links,
168
				array( '<a href="http://sudarmuthu.com/wordpress/email-log/pro-addons" target="_blank">' . __( 'Buy Addons', 'email-log' ) . '</a>' )
169
			);
170
		}
171
		return $links;
172
	}
173
174
	/**
175
	 * Registers the settings page.
176
	 *
177
	 * @since Genesis
178
	 */
179
	public function register_settings_page() {
180
		// Save the handle to your admin page - you'll need it to create a WP_Screen object
181
		$this->admin_page = add_submenu_page( 'tools.php', __( 'Email Log', 'email-log' ), __( 'Email Log', 'email-log' ), 'manage_options', self::PAGE_SLUG , array( $this, 'display_logs' ) );
182
183
		add_action( "load-{$this->admin_page}", array( $this, 'create_settings_panel' ) );
1 ignored issue
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $this instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
184
	}
185
186
	/**
187
	 * Displays the stored email log.
188
	 *
189
	 * @since Genesis
190
	 */
191
	public function display_logs() {
192
		add_thickbox();
193
194
		$this->logs_table->prepare_items( $this->get_per_page() );
195
?>
196
	<div class="wrap">
197
		<h2><?php _e( 'Email Logs', 'email-log' );?></h2>
198
		<?php
199
		if ( isset( $this->logs_deleted ) && $this->logs_deleted != '' ) {
200
			$logs_deleted = intval( $this->logs_deleted );
201
202
			if ( $logs_deleted > 0 ) {
203
				echo '<div class="updated"><p>' . sprintf( _n( '1 email log deleted.', '%s email logs deleted', $logs_deleted, 'email-log' ), $logs_deleted ) . '</p></div>';
204
			} else {
205
				echo '<div class="updated"><p>' . __( 'There was some problem in deleting the email logs' , 'email-log' ) . '</p></div>';
206
			}
207
			unset( $this->logs_deleted );
208
		}
209
?>
210
		<form id="email-logs-search" method="get">
211
			<input type="hidden" name="page" value="<?php echo self::PAGE_SLUG; ?>" >
212
<?php
213
		$this->logs_table->search_box( __( 'Search Logs', 'email-log' ), 'search_id' );
214
?>
215
		</form>
216
217
		<form id="email-logs-filter" method="get">
218
			<input type="hidden" name="page" value="<?php echo $_REQUEST['page'] ?>" />
219
<?php
220
		wp_nonce_field( self::DELETE_LOG_ACTION, self::DELETE_LOG_NONCE_FIELD );
221
		$this->logs_table->display();
222
?>
223
		</form>
224
	</div>
225
<?php
226
		/**
227
		 * Action to add additional content to email log admin footer.
228
		 *
229
		 * @since 1.8
230
		 */
231
		do_action( 'el_admin_footer' );
232
233
		// Display credits in Footer
234
		add_action( 'in_admin_footer', array( $this, 'add_footer_links' ) );
235
	}
236
237
	/**
238
	 * Adds settings panel for the plugin.
239
	 *
240
	 * @since Genesis
241
	 */
242
	public function create_settings_panel() {
243
244
		/**
245
		 * Create the WP_Screen object against your admin page handle
246
		 * This ensures we're working with the right admin page
247
		 */
248
		$this->admin_screen = WP_Screen::get( $this->admin_page );
249
250
		/**
251
		 * Content specified inline
252
		 */
253
		$this->admin_screen->add_help_tab(
254
			array(
255
				'title'    => __( 'About Plugin', 'email-log' ),
256
				'id'       => 'about_tab',
257
				'content'  => '<p>' . __( 'Email Log WordPress Plugin, allows you to log all emails that are sent through WordPress.', 'email-log' ) . '</p>',
258
				'callback' => false,
259
			)
260
		);
261
262
		// Add help sidebar
263
		$this->admin_screen->set_help_sidebar(
264
			'<p><strong>' . __( 'More information', 'email-log' ) . '</strong></p>' .
265
			'<p><a href = "http://sudarmuthu.com/wordpress/email-log">' . __( 'Plugin Homepage/support', 'email-log' ) . '</a></p>' .
266
			'<p><a href = "http://sudarmuthu.com/blog">' . __( "Plugin author's blog", 'email-log' ) . '</a></p>' .
267
			'<p><a href = "http://sudarmuthu.com/wordpress/">' . __( "Other Plugin's by Author", 'email-log' ) . '</a></p>'
268
		);
269
270
		// Add screen options
271
		$this->admin_screen->add_option(
272
			'per_page',
273
			array(
274
				'label' => __( 'Entries per page', 'email-log' ),
275
				'default' => 20,
276
				'option' => 'per_page',
277
			)
278
		);
279
280
		if ( ! class_exists( 'WP_List_Table' ) ) {
281
			require_once ABSPATH . WPINC . '/class-wp-list-table.php';
282
		}
283
284
		if ( ! class_exists( 'Email_Log_List_Table' ) ) {
285
			require_once $this->include_path . 'include/class-email-log-list-table.php';
286
		}
287
288
		//Prepare Table of elements
289
		$this->logs_table = new Email_Log_List_Table();
290
	}
291
292
	/**
293
	 * AJAX callback for displaying email content.
294
	 *
295
	 * @since 1.6
296
	 */
297
	public function display_content_callback() {
298
		global $wpdb;
299
300
		if ( current_user_can( 'manage_options' ) ) {
301
			$table_name = $wpdb->prefix . self::TABLE_NAME;
302
			$email_id   = absint( $_GET['email_id'] );
303
304
			$query   = $wpdb->prepare( 'SELECT * FROM ' . $table_name . ' WHERE id = %d', $email_id );
305
			$content = $wpdb->get_results( $query );
306
307
			echo wpautop( $content[0]->message );
308
		}
309
310
		die(); // this is required to return a proper result
311
	}
312
313
	/**
314
	 * Saves Screen options.
315
	 *
316
	 * @since Genesis
317
	 *
318
	 * @param bool|int $status Screen option value. Default false to skip.
319
	 * @param string   $option The option name.
320
	 * @param int      $value  The number of rows to use.
321
	 * @return bool|int
322
	 */
323
	function save_screen_options( $status, $option, $value ) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
324
		if ( 'per_page' == $option ) {
325
			return $value;
326
		} else {
327
			return $status;
328
		}
329
	}
330
331
	/**
332
	 * Gets the per page option.
333
	 *
334
	 * @since Genesis
335
	 *
336
	 * @return int Number of logs a user wanted to be displayed in a page.
337
	 */
338
	public static function get_per_page() {
339
		$screen = get_current_screen();
340
		$option = $screen->get_option( 'per_page', 'option' );
341
342
		$per_page = get_user_meta( get_current_user_id(), $option, true );
343
344
		if ( empty( $per_page ) || $per_page < 1 ) {
345
			$per_page = $screen->get_option( 'per_page', 'default' );
346
		}
347
348
		return $per_page;
349
	}
350
351
	/**
352
	 * Adds additional links.
353
	 *
354
	 * @since Genesis
355
	 *
356
	 * @param array $links
357
	 * @return array
358
	 */
359
	public function add_action_links( $links ) {
360
		// Add a link to this plugin's settings page
361
		$settings_link = '<a href="tools.php?page=email-log">' . __( 'Log', 'email-log' ) . '</a>';
362
		array_unshift( $links, $settings_link );
363
		return $links;
364
	}
365
366
	/**
367
	 * Adds Footer links.
368
	 *
369
	 * @since Genesis
370
	 *
371
	 * @see Function relied on
372
	 * @link http://striderweb.com/nerdaphernalia/2008/06/give-your-wordpress-plugin-credit/
373
	 */
374
	public function add_footer_links() {
375
		$plugin_data = get_plugin_data( __FILE__ );
376
		printf( '%1$s ' . __( 'plugin', 'email-log' ) . ' | ' . __( 'Version', 'email-log' ) . ' %2$s | ' . __( 'by', 'email-log' ) . ' %3$s<br />', $plugin_data['Title'], $plugin_data['Version'], $plugin_data['Author'] );
377
	}
378
379
	/**
380
	 * Logs email to database.
381
	 *
382
	 * @since Genesis
383
	 *
384
	 * @global object $wpdb
385
	 *
386
	 * @param array $mail_info Information about email.
387
	 * @return array Information about email.
388
	 */
389
	public function log_email( $mail_info ) {
390
		global $wpdb;
391
392
		$attachment_present = ( count( $mail_info['attachments'] ) > 0 ) ? 'true' : 'false';
393
394
		// return filtered array
395
		$mail_info  = apply_filters( self::FILTER_NAME, $mail_info );
396
		$table_name = $wpdb->prefix . self::TABLE_NAME;
397
398
		if ( isset( $mail_info['message'] ) ) {
399
			$message = $mail_info['message'];
400
		} else {
401
			// wpmandrill plugin is changing "message" key to "html". See https://github.com/sudar/email-log/issues/20
402
			// Ideally this should be fixed in wpmandrill, but I am including this hack here till it is fixed by them.
403
			if ( isset( $mail_info['html'] ) ) {
404
				$message = $mail_info['html'];
405
			} else {
406
				$message = '';
407
			}
408
		}
409
410
		// Log into the database
411
		$wpdb->insert( $table_name, array(
412
				'to_email'    => is_array( $mail_info['to'] ) ? implode( ',', $mail_info['to'] ) : $mail_info['to'],
413
				'subject'     => $mail_info['subject'],
414
				'message'     => $message,
415
				'headers'     => is_array( $mail_info['headers'] ) ? implode( "\n", $mail_info['headers'] ) : $mail_info['headers'],
416
				'attachments' => $attachment_present,
417
				'sent_date'   => current_time( 'mysql' ),
418
			) );
419
420
		return $mail_info;
421
	}
422
}
423
424
/**
425
 * Instantiates the plugin class
426
 *
427
 * @since Genesis
428
 *
429
 * @see Class `EmailLog`
430
 * @global EmailLog $EmailLog
431
 */
432
function email_log() {
433
	global $EmailLog;
434
	$EmailLog = new EmailLog();
435
}
436
add_action( 'init', 'email_log' );
437
?>
438