Email Log - Version 2.0.0

Version Description

Ability to search logs by date. Dropped support to PHP 5.2

Download this release

Release Info

Developer sudar
Plugin Icon 128x128 Email Log
Version 2.0.0
Comparing to
See all releases

Code changes from version 1.9.1 to 2.0.0

Files changed (43) hide show
  1. assets/css/admin/addon-list.css +101 -0
  2. assets/css/admin/view-logs.css +44 -0
  3. assets/js/admin/addon-list.js +22 -0
  4. assets/js/admin/view-logs.js +27 -0
  5. email-log.php +32 -392
  6. include/Addon/API/EDDAPI.php +126 -0
  7. include/Addon/API/EDDUpdater.php +67 -0
  8. include/Addon/Addon.php +314 -0
  9. include/Addon/AddonList.php +190 -0
  10. include/Addon/AddonUpdater.php +67 -0
  11. include/Addon/DependencyEnforcer.php +100 -0
  12. include/Addon/EmailLogAddon.php +54 -0
  13. include/Addon/License/AddonLicense.php +42 -0
  14. include/Addon/License/BaseLicense.php +227 -0
  15. include/Addon/License/BundleLicense.php +73 -0
  16. include/Addon/License/Licenser.php +286 -0
  17. include/Addon/addon-helper.php +31 -0
  18. include/Core/DB/TableManager.php +267 -0
  19. include/Core/EmailLog.php +206 -0
  20. include/Core/EmailLogger.php +73 -0
  21. include/Core/Loadie.php +20 -0
  22. include/Core/Request/LogListAction.php +166 -0
  23. include/Core/Request/NonceChecker.php +79 -0
  24. include/Core/Request/OverridePluginAPI.php +48 -0
  25. include/Core/UI/Component/AdminUIEnhancer.php +113 -0
  26. include/Core/UI/ListTable/LogListTable.php +297 -0
  27. include/Core/UI/Page/AddonListPage.php +74 -0
  28. include/Core/UI/Page/BasePage.php +106 -0
  29. include/Core/UI/Page/LogListPage.php +229 -0
  30. include/Core/UI/Page/SettingsPage.php +127 -0
  31. include/Core/UI/Setting/Setting.php +89 -0
  32. include/Core/UI/Setting/SettingField.php +16 -0
  33. include/Core/UI/Setting/SettingSection.php +48 -0
  34. include/Core/UI/UILoader.php +70 -0
  35. include/EmailLogAutoloader.php +216 -0
  36. include/compatibility/EmailLog.php +18 -0
  37. include/libraries/EDD_SL_Plugin_Updater.php +477 -0
  38. include/util/EmailHeaderParser.php +131 -0
  39. include/util/helper.php +28 -9
  40. languages/email-log.pot +672 -149
  41. load-email-log.php +73 -0
  42. readme.txt +44 -47
  43. uninstall.php +28 -31
assets/css/admin/addon-list.css ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .el-container {
2
+ width: 100%;
3
+ }
4
+
5
+ .el-addon {
6
+ background: #FFF;
7
+ border: 1px solid #ccc;
8
+ box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
9
+ padding: 1%;
10
+ margin-bottom: 2%;
11
+ }
12
+
13
+ .el-container .disabled {
14
+ cursor: not-allowed !important;
15
+ }
16
+
17
+ @media screen and (max-width:989px) {
18
+ .el-addon {
19
+ float: none;
20
+ width: 95%;
21
+ }
22
+
23
+ .el-addon img {
24
+ height: auto;
25
+ width: 100%;
26
+ }
27
+ }
28
+
29
+ @media screen and (min-width:990px) and (max-width:1199px) {
30
+ .el-addon {
31
+ float: left;
32
+ width: 45%;
33
+ }
34
+
35
+ .el-addon img {
36
+ height: auto;
37
+ width: 100%;
38
+ }
39
+
40
+ .el-addon:nth-child(even) {
41
+ margin-left: 1%;
42
+ }
43
+ }
44
+
45
+ @media screen and (min-width:1200px) {
46
+ .el-addon {
47
+ float: left;
48
+ width: 30%;
49
+ }
50
+
51
+ .el-addon img {
52
+ height: auto;
53
+ width: 100%;
54
+ }
55
+
56
+ .el-addon:nth-child(3n-1) {
57
+ margin-left: 1.5%;
58
+ margin-right: 1.5%;
59
+ }
60
+
61
+ .el-addon:nth-child(3n+1) {
62
+ clear: both;
63
+ }
64
+ }
65
+
66
+ .bundle-license {
67
+ margin-bottom: 3%;
68
+ }
69
+
70
+ .bundle-license .notice-warning {
71
+ padding-top: 10px;
72
+ padding-bottom: 10px;
73
+ }
74
+
75
+ .bundle-license .el-license {
76
+ font-size: 1.7em;
77
+ }
78
+
79
+ .bundle-license .button {
80
+ margin-top: 2px;
81
+ }
82
+
83
+ .bundle-license .expires {
84
+ margin-left: 5px;
85
+ margin-top: 5px;
86
+ }
87
+
88
+ .individual-license {
89
+ padding-top: 10px;
90
+ }
91
+
92
+ .individual-license .button {
93
+ margin-top: -2px;
94
+ }
95
+
96
+ .el-expander {
97
+ float: right;
98
+ font-size: 40px;
99
+ margin-top: -5px;
100
+ margin-right: 10px;
101
+ }
assets/css/admin/view-logs.css ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #search_id-search-date-input {
2
+ float: left;
3
+ height: 28px;
4
+ margin: 0 4px 0 0;
5
+ }
6
+
7
+ #tabs {
8
+ margin-top: 10px;
9
+ }
10
+
11
+ .tabs-text-textarea {
12
+ height: 100%;
13
+ width: 100%;
14
+ }
15
+
16
+ #tabs-1,
17
+ #tabs-2 {
18
+ height: 335px;
19
+ overflow: auto;
20
+ }
21
+
22
+ #view-message-footer {
23
+ padding: 10px 0 0 0;
24
+ }
25
+
26
+ #thickbox-footer-close {
27
+ display: block;
28
+ height: 20px;
29
+ text-align: center;
30
+ text-decoration: none;
31
+ background: #f1f1f1;
32
+ padding: 5px 0;
33
+ color: #c4c4c4;
34
+ }
35
+
36
+ #thickbox-footer-close:hover {
37
+ background: #eee;
38
+ color: #666;
39
+ }
40
+
41
+ #TB_ajaxContent {
42
+ padding-bottom: 10px !important; /* Override the default Thickbox css values. */
43
+ overflow: hidden !important; /* Override the default Thickbox css values. */
44
+ }
assets/js/admin/addon-list.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Show/Hide individual add-on license key input.
3
+ */
4
+ ( function( $ ) {
5
+ $( document ).ready( function() {
6
+ $( '.el-addon .el-expander' ).on( 'click', function() {
7
+ var $this = $( this );
8
+
9
+ $this.parent().find( '.individual-license' ).toggle();
10
+
11
+ if ( $this.hasClass( 'dashicons-arrow-down' ) ) {
12
+ $this
13
+ .removeClass( 'dashicons-arrow-down' )
14
+ .addClass( 'dashicons-arrow-up' );
15
+ } else {
16
+ $this
17
+ .removeClass( 'dashicons-arrow-up' )
18
+ .addClass( 'dashicons-arrow-down' );
19
+ }
20
+ } );
21
+ } );
22
+ } )(jQuery);
assets/js/admin/view-logs.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $ ) {
2
+
3
+ $( document ).ready(function() {
4
+ $( '#search_id-search-date-input' ).datepicker({
5
+ changeMonth: true,
6
+ changeYear: true,
7
+ dateFormat: 'yy-mm-dd'
8
+ });
9
+
10
+ $( document ).on('click', '#thickbox-footer-close', function( event ) {
11
+ event.preventDefault();
12
+ tb_remove();
13
+ });
14
+ });
15
+
16
+ var tabsInsertedEvent = 'tabs_elem_inserted';
17
+
18
+ insertionQ( '#tabs' ).every(function ( element ) {
19
+ $( element ).trigger( tabsInsertedEvent )
20
+ });
21
+
22
+ $( document ).on( tabsInsertedEvent, function() {
23
+ $( '#tabs' ).tabs();
24
+ });
25
+
26
+
27
+ })( jQuery );
email-log.php CHANGED
@@ -1,11 +1,11 @@
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/
@@ -27,411 +27,51 @@
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() {
129
- $this->include_path = plugin_dir_path( __FILE__ );
130
-
131
- // Load localization domain.
132
- $this->translations = dirname( plugin_basename( __FILE__ ) ) . '/languages/' ;
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' ) );
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' ) );
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 ) {
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
- ?>
1
  <?php
2
  /**
3
  * Plugin Name: Email Log
4
+ * Plugin URI: https://wpemaillog.com
5
  * Description: Logs every email sent through WordPress
6
  * Donate Link: http://sudarmuthu.com/if-you-wanna-thank-me
7
  * Author: Sudar
8
+ * Version: 2.0.0
9
  * Author URI: http://sudarmuthu.com/
10
  * Text Domain: email-log
11
  * Domain Path: languages/
27
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
  */
29
 
30
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ // Include the stub of the old `EmailLog` class, so that old add-ons don't generate a fatal error.
33
+ include_once plugin_dir_path( __FILE__ ) . 'include/compatibility/EmailLog.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
+ if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
36
  /**
37
+ * Version 2.0 of the Email Log plugin dropped support for PHP 5.2.
38
+ * If you are still struck with PHP 5.2 and can't update, then use v1.9.1 of the plugin.
39
+ * But note that some add-ons may not work.
40
  *
41
+ * @see http://sudarmuthu.com/blog/why-i-am-dropping-support-for-php-5-2-in-my-wordpress-plugins/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  *
43
+ * @since 2.0
44
  */
45
+ function email_log_compatibility_notice() {
46
+ ?>
47
+ <div class="error">
48
+ <p>
49
+ <?php printf(
50
+ __( 'Email Log requires at least PHP 5.3 to function properly. Please upgrade PHP or use <a href="%s">v1.9.1 of Email Log</a>.', 'email-log' ), // @codingStandardsIgnoreLine
51
+ 'https://downloads.wordpress.org/plugin/email-log.1.9.1.zip'
52
+ );
53
+ ?>
54
+ </p>
55
+ </div>
56
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
58
 
59
+ add_action( 'admin_notices', 'email_log_compatibility_notice' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
  /**
62
+ * Deactivate Email Log.
63
  *
64
+ * @since 2.0
65
  */
66
+ function email_log_deactivate() {
67
+ deactivate_plugins( plugin_basename( __FILE__ ) );
 
 
 
 
 
 
 
 
 
 
 
 
68
  }
69
 
70
+ add_action( 'admin_init', 'email_log_deactivate' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
 
75
+ // PHP is at least 5.3, so we can safely include namespace code.
76
+ require_once 'load-email-log.php';
77
+ load_email_log( __FILE__ );
 
 
 
 
 
 
 
 
 
 
 
include/Addon/API/EDDAPI.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon\API;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * Wrapper for EDD API
7
+ *
8
+ * @since 2.0.0
9
+ */
10
+ class EDDAPI {
11
+
12
+ /**
13
+ * Store URL.
14
+ * EDD and EDD SL plugins should be installed there.
15
+ *
16
+ * @var string
17
+ */
18
+ protected $store_url;
19
+
20
+ /**
21
+ * EDDAPI constructor.
22
+ * If store url is not passed it is read from config.
23
+ *
24
+ * @param string|null $store_url Store URL.
25
+ */
26
+ public function __construct( $store_url = null ) {
27
+ if ( null === $store_url ) {
28
+ $email_log = email_log();
29
+ $store_url = $email_log->get_store_url();
30
+ }
31
+
32
+ $this->store_url = $store_url;
33
+ }
34
+
35
+ /**
36
+ * Activate License.
37
+ *
38
+ * @param string $license_key License Key.
39
+ * @param string $addon_name Add-on Name.
40
+ *
41
+ * @return object API Response JSON Object.
42
+ */
43
+ public function activate_license( $license_key, $addon_name ) {
44
+ $params = array(
45
+ 'edd_action' => 'activate_license',
46
+ 'license' => $license_key,
47
+ 'item_name' => urlencode( $addon_name ),
48
+ 'url' => home_url(),
49
+ );
50
+
51
+ return $this->call_edd_api( $params );
52
+ }
53
+
54
+ /**
55
+ * Deactivate License.
56
+ *
57
+ * @param string $license_key License Key.
58
+ * @param string $addon_name Add-on Name.
59
+ *
60
+ * @return object API Response JSON Object.
61
+ */
62
+ public function deactivate_license( $license_key, $addon_name ) {
63
+ $params = array(
64
+ 'edd_action' => 'deactivate_license',
65
+ 'license' => $license_key,
66
+ 'item_name' => urlencode( $addon_name ),
67
+ 'url' => home_url(),
68
+ );
69
+
70
+ return $this->call_edd_api( $params );
71
+ }
72
+
73
+ /**
74
+ * Get version information.
75
+ *
76
+ * @param string $license_key License Key.
77
+ * @param string $addon_name Add-on Name.
78
+ *
79
+ * @return object API Response JSON Object.
80
+ */
81
+ public function get_version( $license_key, $addon_name ) {
82
+ $params = array(
83
+ 'edd_action' => 'get_version',
84
+ 'license' => $license_key,
85
+ 'item_name' => $addon_name,
86
+ 'url' => home_url(),
87
+ );
88
+
89
+ return $this->call_edd_api( $params );
90
+ }
91
+
92
+ /**
93
+ * Call the EDD API.
94
+ *
95
+ * @param array $params Parameters for request.
96
+ *
97
+ * @return object API Response in JSON.
98
+ * @throws \Exception If there is any error while making the request.
99
+ *
100
+ * TODO: Make the errors more user friendly and provide links to support.
101
+ */
102
+ protected function call_edd_api( $params ) {
103
+ $response = wp_remote_post( $this->store_url, array(
104
+ 'timeout' => 15,
105
+ 'body' => $params,
106
+ ) );
107
+
108
+ if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
109
+
110
+ if ( is_wp_error( $response ) ) {
111
+ throw new \Exception( $response->get_error_message() );
112
+ }
113
+
114
+ throw new \Exception( __( 'Unknown error occurred while trying to contact Email Log store. Please try again after sometime. If the problem persists contact support.', 'email-log' ) );
115
+ }
116
+
117
+ $body = wp_remote_retrieve_body( $response );
118
+ $data = json_decode( $body );
119
+
120
+ if ( empty( $data ) ) {
121
+ throw new \Exception( __( 'Unable to parse the response Email Log store response. Please try again after sometime. If the problem persists contact support.', 'email-log' ) );
122
+ }
123
+
124
+ return $data;
125
+ }
126
+ }
include/Addon/API/EDDUpdater.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon\API;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
6
+ $email_log = email_log();
7
+ require_once $email_log->get_plugin_path() . 'include/libraries/EDD_SL_Plugin_Updater.php';
8
+ }
9
+
10
+ /**
11
+ * Update add-on using EDD API.
12
+ *
13
+ * @since 2.0.0
14
+ */
15
+ class EDDUpdater extends \EDD_SL_Plugin_Updater {
16
+
17
+ /**
18
+ * Add-on slug.
19
+ * The base class already has a slug property but it is private.
20
+ * So we have to create a duplicate to handle that.
21
+ *
22
+ * @var string
23
+ */
24
+ protected $addon_slug;
25
+
26
+ /**
27
+ * Extract add-on slug alone and then pass everything to parent.
28
+ *
29
+ * @param string $_api_url The URL pointing to the custom API endpoint.
30
+ * @param string $_plugin_file Path to the plugin file.
31
+ * @param array|null $_api_data Optional data to send with API calls.
32
+ */
33
+ public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
34
+ $this->addon_slug = basename( $_plugin_file, '.php' );
35
+
36
+ parent::__construct( $_api_url, $_plugin_file, $_api_data );
37
+ }
38
+
39
+ /**
40
+ * Get add-on slug.
41
+ *
42
+ * @return string Add-on slug.
43
+ */
44
+ public function get_slug() {
45
+ return $this->addon_slug;
46
+ }
47
+
48
+ /**
49
+ * Get Download URL.
50
+ * We can't call `api_request` method directly since it is declared as private in parent class.
51
+ * So we call the `plugins_api_filter` method instead.
52
+ *
53
+ * @return string Download url.
54
+ */
55
+ public function get_download_url() {
56
+ $args = new \stdClass();
57
+ $args->slug = $this->addon_slug;
58
+
59
+ $response = $this->plugins_api_filter( null, 'plugin_information', $args );
60
+
61
+ if ( ! $response instanceof \stdClass || ! property_exists( $response, 'package' ) ) {
62
+ return '';
63
+ }
64
+
65
+ return $response->package;
66
+ }
67
+ }
include/Addon/Addon.php ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon;
2
+
3
+ use EmailLog\Addon\License\AddonLicense;
4
+
5
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
6
+
7
+ /**
8
+ * Encapsulate Add-on Data.
9
+ *
10
+ * @since 2.0.0
11
+ *
12
+ * @property-read string $name
13
+ * @property-read string $version
14
+ * @property-read string $thumbnail
15
+ * @property-read string $description
16
+ * @property-read string $link
17
+ * @property-read string $slug
18
+ * @property-read string $file
19
+ * @property-read string $author
20
+ */
21
+ class Addon {
22
+
23
+ private $name;
24
+ private $version;
25
+ private $thumbnail;
26
+ private $description;
27
+ private $link;
28
+ private $slug;
29
+ private $file;
30
+ private $author;
31
+
32
+ protected $email_log;
33
+ protected $license;
34
+
35
+ /**
36
+ * Construct Addon object from data array.
37
+ *
38
+ * @param array $data Data array.
39
+ * @param \EmailLog\Addon\License\AddonLicense|null $license Add-on License.
40
+ * @param \EmailLog\Core\EmailLog|null $email_log Email Log instance.
41
+ */
42
+ public function __construct( $data, $license = null, $email_log = null ) {
43
+ $this->parse_data( $data );
44
+
45
+ if ( null === $license ) {
46
+ $license = new AddonLicense();
47
+ $license->set_addon_name( $this->name );
48
+ $license->load();
49
+ }
50
+ $this->license = $license;
51
+
52
+ if ( null === $email_log ) {
53
+ $email_log = email_log();
54
+ }
55
+ $this->email_log = $email_log;
56
+ }
57
+
58
+ /**
59
+ * Render the add-on in Addon list page.
60
+ */
61
+ public function render() {
62
+ ?>
63
+ <div class="el-addon">
64
+ <h3 class="el-addon-title"> <?php echo esc_html( $this->name ); ?> </h3>
65
+
66
+ <a href="<?php echo esc_url( $this->link ); ?>?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=addon-grid&utm_content=<?php echo $this->name; ?>"
67
+ title="<?php echo esc_attr( $this->name ); ?>">
68
+ <img src="<?php echo esc_url( $this->thumbnail ); ?>" class="attachment-showcase wp-post-image"
69
+ alt="<?php echo esc_attr( $this->name ); ?>" title="<?php echo esc_attr( $this->name ); ?>">
70
+ </a>
71
+
72
+ <p> <?php echo esc_html( $this->description ); ?> </p>
73
+
74
+ <?php $this->print_actions(); ?>
75
+ </div> <!-- .el-addon -->
76
+
77
+ <?php
78
+ }
79
+
80
+ /**
81
+ * Have a magic getter instead of having individual getters.
82
+ *
83
+ * @param string $property Property.
84
+ *
85
+ * @return string Value for the property.
86
+ */
87
+ public function __get( $property ) {
88
+ if ( isset( $this->{$property} ) ) {
89
+ return $this->{$property};
90
+ }
91
+
92
+ return false;
93
+ }
94
+
95
+ /**
96
+ * Get Add-on License object.
97
+ *
98
+ * @return \EmailLog\Addon\License\AddonLicense License object.
99
+ */
100
+ public function get_license() {
101
+ return $this->license;
102
+ }
103
+
104
+ /**
105
+ * Get action links for add-ons.
106
+ */
107
+ protected function print_actions() {
108
+ if ( $this->has_valid_bundle_license() ) {
109
+ $this->print_valid_actions();
110
+ return;
111
+ }
112
+
113
+ if ( ! $this->has_valid_addon_license() ) {
114
+ $this->print_invalid_actions();
115
+ } else {
116
+ $this->print_valid_actions();
117
+ }
118
+
119
+ $this->render_individual_license();
120
+ }
121
+
122
+ /**
123
+ * Print actions that are available when the license is valid.
124
+ */
125
+ protected function print_valid_actions() {
126
+ if ( $this->is_installed() ) {
127
+ $actions = '<a disabled class="button button-secondary">' . _x( 'Installed', 'Installed on website but not activated', 'email-log' );
128
+
129
+ if ( $this->is_active() ) {
130
+ $actions .= ' &amp; ' . _x( 'Activated', 'Installed and activated on website', 'email-log' ) . '</a>';
131
+ } else {
132
+ $actions .= sprintf( '</a> <a class="button button-primary" href="%s">%s</a>', $this->get_activate_url(), _x( 'Activate', 'Enable addon so it may be used', 'email-log' ) );
133
+ }
134
+ } else {
135
+ $actions = sprintf( '<a class="button button-primary" href="%s">%s</a>', $this->get_install_url(), _x( 'Install', 'Download and activate addon', 'email-log' ) );
136
+ }
137
+
138
+ $actions .= sprintf( ' <a class="button button-secondary" target="_blank" href="%s">%s</a>', $this->get_download_url(), _x( 'Download', 'Download to your computer', 'email-log' ) );
139
+
140
+ echo $actions;
141
+ }
142
+
143
+ /**
144
+ * Print actions that are available when the license is not valid.
145
+ */
146
+ protected function print_invalid_actions() {
147
+ $label = _x( 'Activate License to Install', 'Download and activate addon', 'email-log' );
148
+
149
+ if ( $this->is_installed() ) {
150
+ $label = _x( 'Activate License to Use', 'Download and activate addon', 'email-log' );
151
+ }
152
+
153
+ printf(
154
+ '<a disabled class="button-secondary disabled" title="%s" href="#">%s</a>',
155
+ __( 'You need an active license to install the add-on', 'email-log' ),
156
+ $label
157
+ );
158
+ }
159
+
160
+ /**
161
+ * Render Individual license form.
162
+ */
163
+ protected function render_individual_license() {
164
+ $action = 'el_license_activate';
165
+ $action_text = __( 'Activate', 'email-log' );
166
+ $button_class = 'button-primary';
167
+ $dashicon = 'down';
168
+ $license_wrap = 'hidden';
169
+ $expires = '';
170
+
171
+ if ( $this->has_valid_addon_license() ) {
172
+ $action = 'el_license_deactivate';
173
+ $action_text = __( 'Deactivate', 'email-log' );
174
+ $button_class = '';
175
+ $dashicon = 'up';
176
+ $license_wrap = '';
177
+
178
+ $expiry_date = date( 'F d, Y', strtotime( $this->get_license()->get_expiry_date() ) );
179
+ $expires = sprintf( __( 'Your license expires on %s', 'email-log' ), $expiry_date );
180
+ }
181
+ ?>
182
+
183
+ <span class="el-expander dashicons dashicons-arrow-<?php echo sanitize_html_class( $dashicon ); ?>"
184
+ title="<?php _e( 'Individual add-on license', 'email-log' ); ?>"></span>
185
+
186
+ <div class="individual-license <?php echo sanitize_html_class( $license_wrap ); ?>">
187
+ <form method="post">
188
+ <input type="text" name="el-license" class="el-license" size="36"
189
+ title="<?php _e( 'Email Log License Key', 'email-log' ); ?>"
190
+ placeholder="<?php echo esc_attr( sprintf( __( '%s Add-on License Key', 'email-log' ), $this->name ) ); ?>"
191
+ value="<?php echo esc_attr( $this->get_addon_license_key() ); ?>">
192
+
193
+ <input type="submit" class="button button-large <?php echo sanitize_html_class( $button_class ); ?>"
194
+ value="<?php echo esc_attr( $action_text ); ?>">
195
+
196
+ <p class="expires"><?php echo esc_html( $expires ); ?></p>
197
+
198
+ <input type="hidden" name="el-addon" value="<?php echo esc_attr( $this->name ); ?>">
199
+ <input type="hidden" name="el-action" value="<?php echo esc_attr( $action ); ?>">
200
+
201
+ <?php wp_nonce_field( $action, $action . '_nonce' ); ?>
202
+ </form>
203
+ </div>
204
+ <?php
205
+
206
+ }
207
+
208
+ /**
209
+ * Is the add-on installed?
210
+ *
211
+ * @return bool True, if installed. False otherwise.
212
+ */
213
+ public function is_installed() {
214
+ $installed_plugins = array_keys( get_plugins() );
215
+
216
+ return in_array( $this->file, $installed_plugins, true );
217
+ }
218
+
219
+ /**
220
+ * Get the version of the add-on.
221
+ * If the add-on is installed then it returns the installed version,
222
+ * otherwise returns the latest add-on version from server.
223
+ *
224
+ * @return string Add-on version.
225
+ */
226
+ public function get_version() {
227
+ if ( ! $this->is_installed() ) {
228
+ return $this->version;
229
+ }
230
+
231
+ $plugins_data = get_plugins();
232
+
233
+ return $plugins_data[ $this->file ]['Version'];
234
+ }
235
+
236
+ /**
237
+ * Is the add-on active?
238
+ *
239
+ * @return bool True if the add-on is active, False otherwise.
240
+ */
241
+ public function is_active() {
242
+ return is_plugin_active( $this->file );
243
+ }
244
+
245
+ /**
246
+ * Get the activate url for the add-on.
247
+ *
248
+ * @return string Activate url with nonce.
249
+ */
250
+ protected function get_activate_url() {
251
+ return wp_nonce_url( network_admin_url( 'plugins.php?action=activate&amp;plugin=' . $this->file ), 'activate-plugin_' . $this->file );
252
+ }
253
+
254
+ /**
255
+ * Get the install url for the add-on.
256
+ *
257
+ * @return string Install url with nonce.
258
+ */
259
+ protected function get_install_url() {
260
+ return wp_nonce_url( network_admin_url( 'update.php?action=install-plugin&plugin=' . $this->slug ), 'install-plugin_' . $this->slug );
261
+ }
262
+
263
+ /**
264
+ * Get the download url for add-on.
265
+ *
266
+ * @return string Download url for add-on.
267
+ */
268
+ public function get_download_url() {
269
+ return $this->email_log->get_licenser()->get_addon_download_url( $this->slug );
270
+ }
271
+
272
+ /**
273
+ * Is there a valid bundle license?
274
+ *
275
+ * @return bool True if valid, False otherwise.
276
+ */
277
+ protected function has_valid_bundle_license() {
278
+ return $this->email_log->get_licenser()->is_bundle_license_valid();
279
+ }
280
+
281
+ /**
282
+ * Is the license of this add-on valid?
283
+ *
284
+ * @return bool True if valid, False otherwise.
285
+ */
286
+ protected function has_valid_addon_license() {
287
+ return $this->get_license()->is_valid();
288
+ }
289
+
290
+ /**
291
+ * Get license key if the add-on has a valid license.
292
+ *
293
+ * @return string|null License key if found, null otherwise.
294
+ */
295
+ public function get_addon_license_key() {
296
+ return $this->get_license()->get_license_key();
297
+ }
298
+
299
+ /**
300
+ * Parse and store add-on data from data array.
301
+ *
302
+ * @param array $data Data array.
303
+ */
304
+ protected function parse_data( $data ) {
305
+ $this->name = $data['info']['title'];
306
+ $this->version = $data['info']['version'];
307
+ $this->thumbnail = $data['info']['thumbnail'];
308
+ $this->description = $data['info']['excerpt'];
309
+ $this->link = $data['info']['permalink'];
310
+ $this->slug = 'email-log-' . $data['info']['slug'];
311
+ $this->file = sprintf( '%1$s/%1$s.php', $this->slug );
312
+ $this->author = 'Sudar Muthu';
313
+ }
314
+ }
include/Addon/AddonList.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * Retrieve the list of add-ons and render them.
7
+ *
8
+ * @since 2.0.0
9
+ */
10
+ class AddonList {
11
+
12
+ const CACHE_EXPIRY_IN_HRS = 12;
13
+ const CACHE_KEY = 'el_addon_data';
14
+
15
+ /**
16
+ * Add-on list.
17
+ *
18
+ * @var Addon[]
19
+ */
20
+ protected $addons;
21
+
22
+ /**
23
+ * Store URL.
24
+ *
25
+ * @var string
26
+ */
27
+ protected $store_url;
28
+
29
+ /**
30
+ * Create a list of add-ons.
31
+ *
32
+ * @param Addon[]|null $addons List of Add-ons. If not passed, they will be automatically loaded.
33
+ * @param string|null $store_url Store url.
34
+ */
35
+ public function __construct( $addons = null, $store_url = null ) {
36
+ if ( null === $store_url ) {
37
+ $email_log = email_log();
38
+ $store_url = $email_log->get_store_url();
39
+ }
40
+ $this->store_url = $store_url;
41
+
42
+ if ( null === $addons ) {
43
+ $addons = $this->get_addons();
44
+ }
45
+
46
+ $this->addons = $addons;
47
+ }
48
+
49
+ /**
50
+ * Get an add-on by name.
51
+ *
52
+ * @param string $name Add-on name.
53
+ *
54
+ * @return \EmailLog\Addon\Addon|false Add-on if found, False otherwise.
55
+ */
56
+ public function get_addon_by_name( $name ) {
57
+ if ( array_key_exists( $name, $this->addons ) ) {
58
+ return $this->addons[ $name ];
59
+ }
60
+
61
+ return false;
62
+ }
63
+
64
+ /**
65
+ * Get all add-ons that are not active (either not installed or not activated).
66
+ *
67
+ * @return \EmailLog\Addon\Addon[] List of inactive add-ons.
68
+ */
69
+ public function get_inactive_addons() {
70
+ $inactive_addons = array();
71
+
72
+ foreach ( $this->addons as $addon ) {
73
+ if ( ! $addon->is_active() ) {
74
+ $inactive_addons[] = $addon;
75
+ }
76
+ }
77
+
78
+ return $inactive_addons;
79
+ }
80
+
81
+ /**
82
+ * Setup page to render the list of add-ons.
83
+ */
84
+ public function render() {
85
+ ?>
86
+
87
+ <div class="el-container">
88
+ <?php $this->render_addons(); ?>
89
+ <div class="clear"></div>
90
+ </div> <!-- .el-container -->
91
+ <?php
92
+ }
93
+
94
+ /**
95
+ * Retrieve the list of add-ons by calling the store API.
96
+ *
97
+ * @return Addon[] List of add-ons, empty array if API call fails.
98
+ */
99
+ protected function get_addons() {
100
+ if ( false === ( $json = get_transient( self::CACHE_KEY ) ) ) {
101
+ $response = wp_remote_get( $this->get_api_url() );
102
+
103
+ if ( is_wp_error( $response ) || ! is_array( $response ) ) {
104
+ // TODO: Don't keep trying if the server is down.
105
+ return array();
106
+ }
107
+
108
+ $json = json_decode( wp_remote_retrieve_body( $response ), true );
109
+
110
+ if ( ! is_array( $json ) ) {
111
+ return array();
112
+ }
113
+
114
+ set_transient( self::CACHE_KEY, $json, self::CACHE_EXPIRY_IN_HRS * HOUR_IN_SECONDS );
115
+ }
116
+
117
+ return $this->parse_response( $json );
118
+ }
119
+
120
+ /**
121
+ * Parse the response and get the list of add-on.
122
+ *
123
+ * @param array $data JSON Data array.
124
+ *
125
+ * @return array List of Add-ons.
126
+ */
127
+ protected function parse_response( $data ) {
128
+ if ( ! array_key_exists( 'products', $data ) ) {
129
+ return array();
130
+ }
131
+
132
+ return $this->build_addon_list( $data['products'] );
133
+ }
134
+
135
+ /**
136
+ * Build a list of Addon objects from products data array.
137
+ *
138
+ * @param array $products Products data array.
139
+ *
140
+ * @return Addon[] List of Addons.
141
+ */
142
+ protected function build_addon_list( $products ) {
143
+ $addons = array();
144
+
145
+ foreach ( $products as $product ) {
146
+ $addon = new Addon( $product );
147
+ $addons[ $addon->name ] = $addon;
148
+ }
149
+
150
+ return $addons;
151
+ }
152
+
153
+ /**
154
+ * Render the add-on list or display an error if the list can't be retrieved.
155
+ */
156
+ protected function render_addons() {
157
+ if ( empty( $this->addons ) ) {
158
+ $this->render_empty_list();
159
+ }
160
+
161
+ foreach ( $this->addons as $addon ) {
162
+ $addon->render();
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Display a notice if the list of add-on can't be retrieved.
168
+ */
169
+ protected function render_empty_list() {
170
+ ?>
171
+ <span class="el-addon-empty">
172
+ <?php
173
+ printf(
174
+ __( 'We are not able to retrieve the add-on list now. Please visit the <a href="%s">add-on page</a> to view the add-ons.', 'email-log' ), // @codingStandardsIgnoreLine
175
+ 'https://wpemaillog.com/store/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=addon-grid-failed'
176
+ );
177
+ ?>
178
+ </span>
179
+ <?php
180
+ }
181
+
182
+ /**
183
+ * Get API URL.
184
+ *
185
+ * @return string API URL.
186
+ */
187
+ protected function get_api_url() {
188
+ return $this->store_url . '/edd-api/products/?category=addon';
189
+ }
190
+ }
include/Addon/AddonUpdater.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon;
2
+
3
+ use EmailLog\Addon\API\EDDUpdater;
4
+
5
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
6
+
7
+ /**
8
+ * Add-on Updater.
9
+ * Auto updates add-on based on EDD SL API.
10
+ *
11
+ * @since 2.0.0
12
+ */
13
+ class AddonUpdater {
14
+
15
+ private $addon_file;
16
+ private $addon_name;
17
+ private $addon_version;
18
+ private $addon_author;
19
+
20
+ /**
21
+ * Create a new instance of AddonUpdater.
22
+ *
23
+ * @param string $addon_file Add-on main file.
24
+ */
25
+ public function __construct( $addon_file ) {
26
+ $this->addon_file = $addon_file;
27
+ }
28
+
29
+ /**
30
+ * Set Add-on data.
31
+ *
32
+ * @param string $addon_name Add-on Name.
33
+ * @param string $addon_version Add-on Version.
34
+ * @param string $addon_author Add-on Author.
35
+ */
36
+ public function set_addon_data( $addon_name, $addon_version, $addon_author ) {
37
+ $this->addon_name = $addon_name;
38
+ $this->addon_version = $addon_version;
39
+ $this->addon_author = $addon_author;
40
+ }
41
+
42
+ /**
43
+ * Set up hooks and load the license handler.
44
+ * This method is called on `wp-loaded` hook.
45
+ */
46
+ public function load() {
47
+ add_action( 'admin_init', array( $this, 'setup_updater' ) );
48
+ }
49
+
50
+ /**
51
+ * Setup up Add-on auto-updater using EDD library.
52
+ */
53
+ public function setup_updater() {
54
+ $email_log = email_log();
55
+ $license_key = $email_log->get_licenser()->get_addon_license_key( $this->addon_name );
56
+
57
+ $updater = new EDDUpdater( $email_log->get_store_url(), $this->addon_file, array(
58
+ 'version' => $this->addon_version,
59
+ 'license' => $license_key,
60
+ 'item_name' => $this->addon_name,
61
+ 'author' => $this->addon_author,
62
+ )
63
+ );
64
+
65
+ $email_log->get_licenser()->add_updater( $updater );
66
+ }
67
+ }
include/Addon/DependencyEnforcer.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon;
2
+
3
+ use EmailLog\Core\Loadie;
4
+
5
+ /**
6
+ * Enforce Addon Dependency by deactivating add-ons that don't satisfy dependency.
7
+ *
8
+ * @since 2.0
9
+ */
10
+ class DependencyEnforcer implements Loadie {
11
+
12
+ /**
13
+ * Addon Dependency Map.
14
+ * TODO: This map should be dynamically pulled from website based on base plugin version.
15
+ *
16
+ * @var array
17
+ */
18
+ private $addon_dependency_map = array(
19
+ 'email-log-forward-email/email-log-forward-email.php' => '2.0',
20
+ 'email-log-more-fields/email-log-more-fields.php' => '2.0',
21
+ 'email-log-resend-email/email-log-resend-email.php' => '2.0',
22
+ );
23
+
24
+ /**
25
+ * Setup action and hooks.
26
+ */
27
+ public function load() {
28
+ // TODO: Ideally, this should not be called on all admin pages.
29
+ add_action( 'admin_notices', array( $this, 'render_compatibility_notice' ) );
30
+ }
31
+
32
+ /**
33
+ * Render compatibility notice, if needed.
34
+ * TODO: Include link to the add-on store in the admin notice.
35
+ */
36
+ public function render_compatibility_notice() {
37
+ $deactivated_addons = $this->deactivate_outdated_active_addons();
38
+
39
+ if ( empty( $deactivated_addons ) ) {
40
+ return;
41
+ }
42
+
43
+ ?>
44
+ <div class="error">
45
+ <p>
46
+ <?php _e( 'The following add-ons are not compatible with the installed version of Email Log and have been deactivated.', 'email-log' ); ?>
47
+ <ul>
48
+ <?php
49
+ array_walk( $deactivated_addons, function( $addon ) {
50
+ echo '<li>' . esc_html( $addon ) . '</li>';
51
+ } );
52
+ ?>
53
+ </ul>
54
+ <?php _e( 'Please get the latest version of these add-ons from add-on store.', 'email-log' ); ?>
55
+ </p>
56
+ </div>
57
+ <?php
58
+ }
59
+
60
+ /**
61
+ * Deactivate outdated active add-ons.
62
+ *
63
+ * @access private
64
+ * @return array List of add-ons (name and version) that got deactivated.
65
+ */
66
+ private function deactivate_outdated_active_addons() {
67
+ $deactivated_active_addons = array();
68
+
69
+ $outdated_active_addons = $this->get_outdated_active_addons();
70
+ foreach ( $outdated_active_addons as $addon_file_name => $outdated_active_addon ) {
71
+ deactivate_plugins( plugin_basename( $addon_file_name ) );
72
+ $deactivated_active_addons[] = $outdated_active_addon['Name'] . ' ' . $outdated_active_addon['Version'];
73
+ }
74
+
75
+ return $deactivated_active_addons;
76
+ }
77
+
78
+ /**
79
+ * Get the list of add-ons that are outdated and are active.
80
+ *
81
+ * @access private
82
+ * @return array List of outdated and active add-ons.
83
+ */
84
+ private function get_outdated_active_addons() {
85
+ $outdated_active_addons = array();
86
+ $plugins = get_plugins();
87
+
88
+ foreach ( $this->addon_dependency_map as $addon => $required_version ) {
89
+ if ( is_plugin_active( $addon ) ) {
90
+ $active_addon = $plugins[ $addon ];
91
+
92
+ if ( version_compare( $active_addon['Version'], $required_version, '<' ) ) {
93
+ $outdated_active_addons[ $addon ] = $active_addon;
94
+ }
95
+ }
96
+ }
97
+
98
+ return $outdated_active_addons;
99
+ }
100
+ }
include/Addon/EmailLogAddon.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * Base Email Log Addon.
7
+ *
8
+ * @since 2.0.0
9
+ */
10
+ abstract class EmailLogAddon {
11
+
12
+ protected $addon_file;
13
+ protected $addon_name = '';
14
+ protected $addon_version = '';
15
+ protected $addon_author = 'Sudar Muthu';
16
+
17
+ /**
18
+ * Addon Updater.
19
+ *
20
+ * @var \EmailLog\Addon\AddonUpdater
21
+ */
22
+ private $updater;
23
+
24
+ /**
25
+ * Initialize add-on data.
26
+ *
27
+ * @access protected
28
+ * @return void
29
+ */
30
+ abstract protected function initialize();
31
+
32
+ /**
33
+ * Construct a new EmailLogAddon instance.
34
+ *
35
+ * @param string $addon_file Addon main file.
36
+ * @param \EmailLog\Addon\AddonUpdater $updater Addon Updater.
37
+ */
38
+ public function __construct( $addon_file, $updater ) {
39
+ $this->addon_file = $addon_file;
40
+ $this->updater = $updater;
41
+
42
+ $this->initialize();
43
+ }
44
+
45
+ /**
46
+ * Load the add-on and setup hooks.
47
+ *
48
+ * @inheritdoc
49
+ */
50
+ public function load() {
51
+ $this->updater->set_addon_data( $this->addon_name, $this->addon_version, $this->addon_author );
52
+ $this->updater->load();
53
+ }
54
+ }
include/Addon/License/AddonLicense.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon\License;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * EmailLog License.
7
+ *
8
+ * @since 2.0.0
9
+ */
10
+ class AddonLicense extends BaseLicense {
11
+
12
+ public function is_valid() {
13
+ if ( ! $this->license_data instanceof \stdClass || ! isset( $this->license_data->license ) ) {
14
+ return false;
15
+ }
16
+
17
+ return ( 'valid' === $this->license_data->license );
18
+ }
19
+
20
+ /**
21
+ * Get License key.
22
+ *
23
+ * @return string|null License key.
24
+ */
25
+ public function get_license_key() {
26
+ if ( empty( $this->license_data ) ) {
27
+ return parent::get_license_key();
28
+ }
29
+
30
+ return $this->license_data->license_key;
31
+ }
32
+
33
+ /**
34
+ * Option name in which individual license data is stored.
35
+ * This method should be called only after setting the add-on name.
36
+ *
37
+ * @return string Option name.
38
+ */
39
+ protected function get_option_name() {
40
+ return 'el_license_' . md5( $this->get_addon_name() );
41
+ }
42
+ }
include/Addon/License/BaseLicense.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon\License;
2
+
3
+ use EmailLog\Addon\API\EDDAPI;
4
+
5
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
6
+
7
+ /**
8
+ * Base class for for Bundle License and Add-on License.
9
+ *
10
+ * @since 2.0.0
11
+ */
12
+ abstract class BaseLicense {
13
+
14
+ protected $addon_name;
15
+ protected $license_key;
16
+ protected $license_data;
17
+
18
+ /**
19
+ * EDD API Wrapper.
20
+ *
21
+ * @var \EmailLog\Addon\API\EDDAPI
22
+ */
23
+ protected $edd_api;
24
+
25
+ /**
26
+ * Is the license activated and valid?
27
+ *
28
+ * @return bool True if license is active, False otherwise.
29
+ */
30
+ abstract public function is_valid();
31
+
32
+ /**
33
+ * Get the option name in which license data will be stored.
34
+ *
35
+ * @return string Option name.
36
+ */
37
+ abstract protected function get_option_name();
38
+
39
+ /**
40
+ * Construct a new License object.
41
+ * If the API Wrapper is not provided, then a new one is initialized.
42
+ *
43
+ * @param \EmailLog\Addon\API\EDDAPI|null $edd_api (Optional) EDD API Wrapper instance. Default is null.
44
+ */
45
+ public function __construct( $edd_api = null ) {
46
+ if ( is_null( $edd_api ) ) {
47
+ $edd_api = new EDDAPI();
48
+ }
49
+
50
+ $this->edd_api = $edd_api;
51
+ }
52
+
53
+ /**
54
+ * Set the license Key.
55
+ *
56
+ * @param string $license_key License Key.
57
+ */
58
+ public function set_license_key( $license_key ) {
59
+ $this->license_key = $license_key;
60
+ }
61
+
62
+ /**
63
+ * Get the license key.
64
+ *
65
+ * @return string|null License Key.
66
+ */
67
+ public function get_license_key() {
68
+ return $this->license_key;
69
+ }
70
+
71
+ /**
72
+ * Set add-on name.
73
+ *
74
+ * @param string $addon_name Add-on Name.
75
+ */
76
+ public function set_addon_name( $addon_name ) {
77
+ $this->addon_name = $addon_name;
78
+ }
79
+
80
+ /**
81
+ * Get the add-on name.
82
+ *
83
+ * @return string Add-on name.
84
+ */
85
+ public function get_addon_name() {
86
+ return $this->addon_name;
87
+ }
88
+
89
+ /**
90
+ * Get the expiry date of the license.
91
+ *
92
+ * @return string|false Expiry date in `yyyy-mm-dd hh:mm:ss` format if license is valid, False otherwise.
93
+ */
94
+ public function get_expiry_date() {
95
+ if ( ! empty( $this->license_data ) && isset( $this->license_data->expires ) ) {
96
+ return $this->license_data->expires;
97
+ }
98
+
99
+ return false;
100
+ }
101
+
102
+ /**
103
+ * Activate License by calling EDD API.
104
+ * The license data returned by API is stored in an option.
105
+ *
106
+ * @return object API Response JSON Object.
107
+ * @throws \Exception In case of communication errors or License Issues.
108
+ */
109
+ public function activate() {
110
+ $response = $this->edd_api->activate_license( $this->get_license_key(), $this->get_addon_name() );
111
+
112
+ if ( $response->success && 'valid' === $response->license ) {
113
+ $response->license_key = $this->get_license_key();
114
+
115
+ $this->store( $response );
116
+ return $response;
117
+ }
118
+
119
+ switch ( $response->error ) {
120
+ case 'expired':
121
+ $message = sprintf(
122
+ __( 'Your license key expired on %s.' , 'email-log'),
123
+ date_i18n( get_option( 'date_format' ), strtotime( $response->expires, current_time( 'timestamp' ) ) )
124
+ );
125
+ break;
126
+
127
+ case 'revoked':
128
+ $message = __( 'Your license key has been disabled.' , 'email-log');
129
+ break;
130
+
131
+ case 'missing':
132
+ $message = __( 'Your license key is invalid.' , 'email-log');
133
+ break;
134
+
135
+ case 'invalid':
136
+ case 'site_inactive':
137
+ $message = __( 'Your license is not active for this URL.' , 'email-log');
138
+ break;
139
+
140
+ case 'item_name_mismatch':
141
+ $message = sprintf( __( 'Your license key is not valid for %s.' , 'email-log'), $this->get_addon_name() );
142
+ break;
143
+
144
+ case 'no_activations_left':
145
+ $message = __( 'Your license key has reached its activation limit.' , 'email-log');
146
+ break;
147
+
148
+ default:
149
+ $message = __( 'An error occurred, please try again.' , 'email-log');
150
+ break;
151
+ }
152
+
153
+ throw new \Exception( $message );
154
+ }
155
+
156
+ /**
157
+ * Deactivate the license by calling EDD API.
158
+ * The stored license data will be cleared.
159
+ *
160
+ * @return object API Response JSON object.
161
+ * @throws \Exception In case of communication errors.
162
+ */
163
+ public function deactivate() {
164
+ $response = $this->edd_api->deactivate_license( $this->get_license_key(), $this->get_addon_name() );
165
+
166
+ if ( $response->success && 'deactivated' === $response->license ) {
167
+ $this->clear();
168
+ return $response;
169
+ }
170
+
171
+ $message = __( 'An error occurred, please try again.', 'email-log' );
172
+
173
+ if ( isset( $response->error ) ) {
174
+ $message .= ' ' . $response->error;
175
+ }
176
+
177
+ throw new \Exception( $message );
178
+ }
179
+
180
+ /**
181
+ * Get version information by calling EDD API.
182
+ * // TODO: Currently not used. Will be removed eventually.
183
+ *
184
+ * @return object API Response JSON Object.
185
+ * @throws \Exception In case of communication errors.
186
+ */
187
+ public function get_version() {
188
+ $response = $this->edd_api->get_version( $this->get_license_key(), $this->get_addon_name() );
189
+
190
+ if ( isset( $response->new_version ) && ! isset( $response->msg ) ) {
191
+ return $response;
192
+ }
193
+
194
+ $message = __( 'An error occurred, please try again', 'email-log' ) . $response->error;
195
+ throw new \Exception( $message );
196
+ }
197
+
198
+ /**
199
+ * Load the license data from DB option.
200
+ */
201
+ public function load() {
202
+ $this->license_data = get_option( $this->get_option_name(), null );
203
+ }
204
+
205
+ /**
206
+ * Store License data in DB option.
207
+ *
208
+ * @access protected
209
+ *
210
+ * @param object $license_data License data.
211
+ */
212
+ protected function store( $license_data ) {
213
+ $this->license_data = $license_data;
214
+ update_option( $this->get_option_name(), $license_data );
215
+ }
216
+
217
+ /**
218
+ * Clear stored license data.
219
+ *
220
+ * @access protected
221
+ */
222
+ protected function clear() {
223
+ $this->license_data = null;
224
+ $this->license_key = null;
225
+ delete_option( $this->get_option_name() );
226
+ }
227
+ }
include/Addon/License/BundleLicense.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon\License;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * BundleLicense Object.
7
+ * There can be only one BundleLicence for all the add-ons.
8
+ *
9
+ * @since 2.0.0
10
+ */
11
+ class BundleLicense extends BaseLicense {
12
+
13
+ /**
14
+ * For Bundle the add-on name is hardcoded.
15
+ *
16
+ * @var string Add-on name.
17
+ */
18
+ protected $addon_name = 'Email Log Bundle';
19
+
20
+ /**
21
+ * Is the license valid?
22
+ *
23
+ * @return bool True if valid, False otherwise.
24
+ */
25
+ public function is_valid() {
26
+ if ( empty( $this->license_data ) ) {
27
+ return false;
28
+ }
29
+
30
+ return ( 'valid' === $this->license_data->license );
31
+ }
32
+
33
+ /**
34
+ * Return bundle license key.
35
+ *
36
+ * @return string Bundle License key, if found.
37
+ */
38
+ public function get_license_key() {
39
+ if ( empty( $this->license_data ) ) {
40
+ return parent::get_license_key();
41
+ }
42
+
43
+ return $this->license_data->bundle_license_key;
44
+ }
45
+
46
+ /**
47
+ * The option name in which the bundle license data will be stored.
48
+ *
49
+ * @return string Option name.
50
+ */
51
+ protected function get_option_name() {
52
+ return 'el_bundle_license';
53
+ }
54
+
55
+ /**
56
+ * Get the license key of an add-on from Bundle.
57
+ *
58
+ * @param string $addon_name Add-on name.
59
+ *
60
+ * @return bool|string False if no license key is found, otherwise license key.
61
+ */
62
+ public function get_addon_license_key( $addon_name ) {
63
+ if ( empty( $this->license_data ) ) {
64
+ return false;
65
+ }
66
+
67
+ if ( ! isset( $this->license_data->bundled_licenses->{$addon_name} ) ) {
68
+ return false;
69
+ }
70
+
71
+ return $this->license_data->bundled_licenses->{$addon_name}->license_key;
72
+ }
73
+ }
include/Addon/License/Licenser.php ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Addon\License;
2
+
3
+ use EmailLog\Addon\AddonList;
4
+ use EmailLog\Addon\API\EDDUpdater;
5
+ use EmailLog\Core\Loadie;
6
+
7
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
8
+
9
+ /**
10
+ * Handles the add-on licensing for Email Log.
11
+ *
12
+ * There can be one normal license for each add-on or one bundle license for all add-ons.
13
+ * This class is final because we don't want other plugins to interfere with Email Log licensing.
14
+ *
15
+ * @since 2.0.0
16
+ */
17
+ final class Licenser implements Loadie {
18
+
19
+ /**
20
+ * Bundle License object.
21
+ *
22
+ * @var \EmailLog\Addon\License\BundleLicense
23
+ */
24
+ private $bundle_license;
25
+
26
+ /**
27
+ * List of Add-on updaters.
28
+ *
29
+ * @var \EmailLog\Addon\API\EDDUpdater[]
30
+ */
31
+ private $updaters = array();
32
+
33
+ /**
34
+ * List of add-ons.
35
+ *
36
+ * @var \EmailLog\Addon\AddonList
37
+ */
38
+ private $addon_list;
39
+
40
+ /**
41
+ * Licenser constructor.
42
+ * If the bundle_license object is not passed a new object is created.
43
+ * If the addon_list object is not passed a new object is created.
44
+ *
45
+ * @param null|\EmailLog\Addon\License\BundleLicense $bundle_license Optional. Bundle License.
46
+ * @param null|\EmailLog\Addon\AddonList $addon_list Optional. Add-on List.
47
+ */
48
+ public function __construct( $bundle_license = null, $addon_list = null ) {
49
+ if ( ! $bundle_license instanceof BundleLicense ) {
50
+ $bundle_license = new BundleLicense();
51
+ }
52
+
53
+ if ( ! $addon_list instanceof AddonList ) {
54
+ $addon_list = new AddonList();
55
+ }
56
+
57
+ $this->bundle_license = $bundle_license;
58
+ $this->addon_list = $addon_list;
59
+ }
60
+
61
+ /**
62
+ * Load all Licenser related hooks.
63
+ *
64
+ * @inheritdoc
65
+ */
66
+ public function load() {
67
+ $this->bundle_license->load();
68
+
69
+ add_action( 'el_before_addon_list', array( $this, 'render_bundle_license_form' ) );
70
+
71
+ add_action( 'el_bundle_license_activate', array( $this, 'activate_bundle_license' ) );
72
+ add_action( 'el_bundle_license_deactivate', array( $this, 'deactivate_bundle_license' ) );
73
+
74
+ add_action( 'el_license_activate', array( $this, 'activate_addon_license' ) );
75
+ add_action( 'el_license_deactivate', array( $this, 'deactivate_addon_license' ) );
76
+ }
77
+
78
+ /**
79
+ * Add an Add-on Updater.
80
+ *
81
+ * @param \EmailLog\Addon\API\EDDUpdater $updater Add-on Updater.
82
+ */
83
+ public function add_updater( $updater ) {
84
+ if ( $updater instanceof EDDUpdater ) {
85
+ $this->updaters[ $updater->get_slug() ] = $updater;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Get list of add-ons.
91
+ *
92
+ * @return \EmailLog\Addon\AddonList Add-on List.
93
+ */
94
+ public function get_addon_list() {
95
+ return $this->addon_list;
96
+ }
97
+
98
+ /**
99
+ * Render the Bundle License Form.
100
+ */
101
+ public function render_bundle_license_form() {
102
+ $action = 'el_bundle_license_activate';
103
+ $action_text = __( 'Activate', 'email-log' );
104
+ $button_class = 'button-primary';
105
+ $expires = '';
106
+
107
+ if ( $this->is_bundle_license_valid() ) {
108
+ $action = 'el_bundle_license_deactivate';
109
+ $action_text = __( 'Deactivate', 'email-log' );
110
+ $button_class = '';
111
+ $expiry_date = date( 'F d, Y', strtotime( $this->get_bundle_license_expiry_date() ) );
112
+ $expires = sprintf( __( 'Your license expires on %s', 'email-log' ), $expiry_date );
113
+ }
114
+ ?>
115
+
116
+ <div class="bundle-license">
117
+ <?php if ( ! $this->is_bundle_license_valid() ) : ?>
118
+ <p class="notice notice-warning">
119
+ <?php
120
+ printf(
121
+ __( "Enter your license key to activate add-ons. If you don't have a license, then you can <a href='%s' target='_blank'>buy it</a>", 'email-log' ),
122
+ 'https://wpemaillog.com/store/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=notice&utm_content=buy-it'
123
+ );
124
+ ?>
125
+ </p>
126
+ <?php endif; ?>
127
+
128
+ <form method="post">
129
+ <input type="text" name="el-license" class="el-license" size="40"
130
+ title="<?php _e( 'Email Log Bundle License Key', 'email-log' ); ?>"
131
+ placeholder="<?php _e( 'Email Log Bundle License Key', 'email-log' ); ?>"
132
+ value="<?php echo esc_attr( $this->bundle_license->get_license_key() ); ?>">
133
+
134
+ <input type="submit" class="button button-large <?php echo sanitize_html_class( $button_class ); ?>"
135
+ value="<?php echo esc_attr( $action_text ); ?>">
136
+
137
+ <p class="expires"><?php echo esc_html( $expires ); ?></p>
138
+
139
+ <input type="hidden" name="el-action" value="<?php echo esc_attr( $action ); ?>">
140
+
141
+ <?php wp_nonce_field( $action, $action . '_nonce' ); ?>
142
+ </form>
143
+ </div>
144
+ <?php
145
+ }
146
+
147
+ /**
148
+ * Activate Bundle License.
149
+ *
150
+ * @param array $request Request Object.
151
+ */
152
+ public function activate_bundle_license( $request ) {
153
+ $license_key = sanitize_text_field( $request['el-license'] );
154
+
155
+ $this->bundle_license->set_license_key( $license_key );
156
+
157
+ try {
158
+ $this->bundle_license->activate();
159
+ $message = __( 'Your license has been activated. You can now install add-ons, will receive automatic updates and access to email support.', 'email-log' );
160
+ $type = 'updated';
161
+ } catch ( \Exception $e ) {
162
+ $message = $e->getMessage();
163
+ $type = 'error';
164
+ }
165
+
166
+ add_settings_error( 'bundle-license', 'bundle-license', $message, $type );
167
+ }
168
+
169
+ /**
170
+ * Deactivate Bundle License.
171
+ */
172
+ public function deactivate_bundle_license() {
173
+ try {
174
+ $this->bundle_license->deactivate();
175
+ $message = __( 'Your license has been deactivated. You will not receive automatic updates.', 'email-log' );
176
+ $type = 'updated';
177
+ } catch ( \Exception $e ) {
178
+ $message = $e->getMessage();
179
+ $type = 'error';
180
+ }
181
+
182
+ add_settings_error( 'bundle-license', 'bundle-license', $message, $type );
183
+ }
184
+
185
+ /**
186
+ * Is the bundle license valid?
187
+ *
188
+ * @return bool True, if Bundle License is active, False otherwise.
189
+ */
190
+ public function is_bundle_license_valid() {
191
+ return $this->bundle_license->is_valid();
192
+ }
193
+
194
+ /**
195
+ * Get the expiry date of the Bundle License.
196
+ *
197
+ * @return string|false Expiry date, False if license is not valid.
198
+ */
199
+ protected function get_bundle_license_expiry_date() {
200
+ return $this->bundle_license->get_expiry_date();
201
+ }
202
+
203
+ /**
204
+ * Activate individual add-on License.
205
+ *
206
+ * @param array $request Request Array.
207
+ */
208
+ public function activate_addon_license( $request ) {
209
+ $license_key = sanitize_text_field( $request['el-license'] );
210
+ $addon_name = sanitize_text_field( $request['el-addon'] );
211
+
212
+ $license = $this->addon_list->get_addon_by_name( $addon_name )->get_license();
213
+ $license->set_license_key( $license_key );
214
+
215
+ try {
216
+ $license->activate();
217
+ $message = sprintf(
218
+ __( 'Your license for %s has been activated. You will receive automatic updates and access to email support.', 'email-log' ),
219
+ $addon_name
220
+ );
221
+ $type = 'updated';
222
+ } catch ( \Exception $e ) {
223
+ $message = $e->getMessage();
224
+ $type = 'error';
225
+ }
226
+
227
+ add_settings_error( 'addon-license', 'addon-license', $message, $type );
228
+ }
229
+
230
+ /**
231
+ * Deactivate individual add-on License.
232
+ *
233
+ * @param array $request Request Array.
234
+ */
235
+ public function deactivate_addon_license( $request ) {
236
+ $license_key = sanitize_text_field( $request['el-license'] );
237
+ $addon_name = sanitize_text_field( $request['el-addon'] );
238
+
239
+ $license = $this->addon_list->get_addon_by_name( $addon_name )->get_license();
240
+ $license->set_license_key( $license_key );
241
+
242
+ try {
243
+ $license->deactivate();
244
+ $message = sprintf(
245
+ __( 'Your license for %s has been deactivated. You will not receive automatic updates.', 'email-log' ),
246
+ $addon_name
247
+ );
248
+ $type = 'updated';
249
+ } catch ( \Exception $e ) {
250
+ $message = $e->getMessage();
251
+ $type = 'error';
252
+ }
253
+
254
+ add_settings_error( 'addon-license', 'addon-license', $message, $type );
255
+ }
256
+
257
+ /**
258
+ * Get the license key of an add-on.
259
+ *
260
+ * @param string $addon_name Addon.
261
+ *
262
+ * @return bool|string License key if found, False otherwise.
263
+ */
264
+ public function get_addon_license_key( $addon_name ) {
265
+ if ( $this->is_bundle_license_valid() ) {
266
+ return $this->bundle_license->get_addon_license_key( $addon_name );
267
+ }
268
+
269
+ return $this->addon_list->get_addon_by_name( $addon_name )->get_addon_license_key();
270
+ }
271
+
272
+ /**
273
+ * Get the Download URL of an add-on.
274
+ *
275
+ * @param string $addon_slug Add-on slug.
276
+ *
277
+ * @return string Download URL.
278
+ */
279
+ public function get_addon_download_url( $addon_slug ) {
280
+ if ( isset( $this->updaters[ $addon_slug ] ) ) {
281
+ return $this->updaters[ $addon_slug ]->get_download_url();
282
+ }
283
+
284
+ return '';
285
+ }
286
+ }
include/Addon/addon-helper.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add-on helper functions.
4
+ * These functions are not using namespace since they may be used from a PHP 5.2 file.
5
+ *
6
+ * @since 2.0
7
+ */
8
+
9
+ /**
10
+ * Load an Email Log add-on.
11
+ *
12
+ * @since 2.0.0
13
+ *
14
+ * @param string $addon_class Add-on class name.
15
+ * @param string $addon_file Add-on File.
16
+ *
17
+ * @return \EmailLog\Addon\EmailLogAddon Instance of the add-on.
18
+ */
19
+ function load_email_log_addon( $addon_class, $addon_file ) {
20
+ $email_log = email_log();
21
+
22
+ $addon_dir = plugin_dir_path( $addon_file );
23
+ $email_log->loader->add_namespace( 'EmailLog', $addon_dir . 'include' );
24
+
25
+ $addon_updater = new \EmailLog\Addon\AddonUpdater( $addon_file );
26
+ $addon = new $addon_class( $addon_file, $addon_updater );
27
+
28
+ add_action( 'el_loaded', array( $addon, 'load' ) );
29
+
30
+ return $addon;
31
+ }
include/Core/DB/TableManager.php ADDED
@@ -0,0 +1,267 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\DB;
2
+ /**
3
+ * Handle installation and db table creation
4
+ */
5
+
6
+ use EmailLog\Core\Loadie;
7
+
8
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
9
+
10
+ /**
11
+ * Helper class to create table.
12
+ *
13
+ * @since 2.0.0
14
+ */
15
+ class TableManager implements Loadie {
16
+
17
+ /* Database table name */
18
+ const LOG_TABLE_NAME = 'email_log';
19
+
20
+ /* Database option name */
21
+ const DB_OPTION_NAME = 'email-log-db';
22
+
23
+ /* Database version */
24
+ const DB_VERSION = '0.1';
25
+
26
+ /**
27
+ * Setup hooks.
28
+ */
29
+ public function load() {
30
+ add_action( 'wpmu_new_blog', array( $this, 'create_table_for_new_blog' ) );
31
+
32
+ add_filter( 'wpmu_drop_tables', array( $this, 'delete_table_from_deleted_blog' ) );
33
+ }
34
+
35
+ /**
36
+ * On plugin activation, create table if needed.
37
+ *
38
+ * @param bool $network_wide True if the plugin was network activated.
39
+ */
40
+ public function on_activate( $network_wide ) {
41
+ if ( is_multisite() && $network_wide ) {
42
+ // Note: if there are more than 10,000 blogs or
43
+ // if `wp_is_large_network` filter is set, then this may fail.
44
+ // TODO: Take care of the deprecated function.
45
+ $sites = wp_get_sites();
46
+
47
+ foreach ( $sites as $site ) {
48
+ switch_to_blog( $site['blog_id'] );
49
+ $this->create_table();
50
+ restore_current_blog();
51
+ }
52
+ } else {
53
+ $this->create_table();
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Create email log table when a new blog is created.
59
+ *
60
+ * @param int $blog_id Blog Id.
61
+ */
62
+ public function create_table_for_new_blog( $blog_id ) {
63
+ if ( is_plugin_active_for_network( 'email-log/email-log.php' ) ) {
64
+ switch_to_blog( $blog_id );
65
+ $this->create_table();
66
+ restore_current_blog();
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Add email log table to the list of tables deleted when a blog is deleted.
72
+ *
73
+ * @param array $tables List of tables to be deleted.
74
+ *
75
+ * @return string[] $tables Modified list of tables to be deleted.
76
+ */
77
+ public function delete_table_from_deleted_blog( $tables ) {
78
+ $tables[] = $this->get_log_table_name();
79
+
80
+ return $tables;
81
+ }
82
+
83
+ /**
84
+ * Get email log table name.
85
+ *
86
+ * @return string Email Log Table name.
87
+ */
88
+ public function get_log_table_name() {
89
+ global $wpdb;
90
+
91
+ return $wpdb->prefix . self::LOG_TABLE_NAME;
92
+ }
93
+
94
+ /**
95
+ * Insert log data into DB.
96
+ *
97
+ * @param array $data Data to be inserted.
98
+ */
99
+ public function insert_log( $data ) {
100
+ global $wpdb;
101
+
102
+ $table_name = $this->get_log_table_name();
103
+ $wpdb->insert( $table_name, $data );
104
+ }
105
+
106
+ /**
107
+ * Delete log entries by ids.
108
+ *
109
+ * @param string $ids Comma separated list of log ids.
110
+ *
111
+ * @return false|int Number of log entries that got deleted. False on failure.
112
+ */
113
+ public function delete_logs( $ids ) {
114
+ global $wpdb;
115
+
116
+ $table_name = $this->get_log_table_name();
117
+
118
+ // Can't use wpdb->prepare for the below query. If used it results in this bug // https://github.com/sudar/email-log/issues/13.
119
+ $ids = esc_sql( $ids );
120
+
121
+ return $wpdb->query( "DELETE FROM {$table_name} where id IN ( {$ids} )" ); //@codingStandardsIgnoreLine
122
+ }
123
+
124
+ /**
125
+ * Delete all log entries.
126
+ *
127
+ * @return false|int Number of log entries that got deleted. False on failure.
128
+ */
129
+ public function delete_all_logs() {
130
+ global $wpdb;
131
+
132
+ $table_name = $this->get_log_table_name();
133
+
134
+ return $wpdb->query( "DELETE FROM {$table_name}" ); //@codingStandardsIgnoreLine
135
+ }
136
+
137
+ /**
138
+ * Deletes Email Logs older than the specified interval.
139
+ *
140
+ * @param int $interval_in_days No. of days beyond which logs are to be deleted.
141
+ *
142
+ * @return int $deleted_rows_count Count of rows deleted.
143
+ */
144
+ public function delete_logs_older_than( $interval_in_days ) {
145
+ global $wpdb;
146
+ $table_name = $this->get_log_table_name();
147
+
148
+ $query = $wpdb->prepare( "DELETE FROM {$table_name} WHERE sent_date < DATE_SUB( CURDATE(), INTERVAL %d DAY )", $interval_in_days );
149
+ $deleted_rows_count = $wpdb->query( $query );
150
+
151
+ return $deleted_rows_count;
152
+ }
153
+
154
+ /**
155
+ * Fetch log item by ID.
156
+ *
157
+ * @param array $ids Optional. Array of IDs of the log items to be retrieved.
158
+ *
159
+ * @return array Log item(s).
160
+ */
161
+ public function fetch_log_items_by_id( $ids = array() ) {
162
+ global $wpdb;
163
+ $table_name = $this->get_log_table_name();
164
+
165
+ $query = "SELECT * FROM {$table_name}";
166
+
167
+ if ( ! empty( $ids ) ) {
168
+ $ids = array_map( 'absint', $ids );
169
+
170
+ // Can't use wpdb->prepare for the below query. If used it results in this bug https://github.com/sudar/email-log/issues/13.
171
+ $ids_list = esc_sql( implode( ',', $ids ) );
172
+
173
+ $query .= " where id IN ( {$ids_list} )";
174
+ }
175
+
176
+ return $wpdb->get_results( $query, 'ARRAY_A' ); //@codingStandardsIgnoreLine
177
+ }
178
+
179
+ /**
180
+ * Fetch log items.
181
+ *
182
+ * @param array $request Request object.
183
+ * @param int $per_page Entries per page.
184
+ * @param int $current_page_no Current page no.
185
+ *
186
+ * @return array Log entries and total items count.
187
+ */
188
+ public function fetch_log_items( $request, $per_page, $current_page_no ) {
189
+ global $wpdb;
190
+ $table_name = $this->get_log_table_name();
191
+
192
+ $query = 'SELECT * FROM ' . $table_name;
193
+ $count_query = 'SELECT count(*) FROM ' . $table_name;
194
+ $query_cond = '';
195
+
196
+ if ( isset( $request['s'] ) && $request['s'] !== '' ) {
197
+ $search_term = trim( esc_sql( $request['s'] ) );
198
+ $query_cond .= " WHERE ( to_email LIKE '%$search_term%' OR subject LIKE '%$search_term%' ) ";
199
+ }
200
+
201
+ if ( isset( $request['d'] ) && $request['d'] !== '' ) {
202
+ $search_date = trim( esc_sql( $request['d'] ) );
203
+ if ( '' === $query_cond ) {
204
+ $query_cond .= " WHERE sent_date BETWEEN '$search_date 00:00:00' AND '$search_date 23:59:59' ";
205
+ } else {
206
+ $query_cond .= " AND sent_date BETWEEN '$search_date 00:00:00' AND '$search_date 23:59:59' ";
207
+ }
208
+ }
209
+
210
+ // Ordering parameters.
211
+ $orderby = ! empty( $request['orderby'] ) ? esc_sql( $request['orderby'] ) : 'sent_date';
212
+ $order = ! empty( $request['order'] ) ? esc_sql( $request['order'] ) : 'DESC';
213
+
214
+ if ( ! empty( $orderby ) & ! empty( $order ) ) {
215
+ $query_cond .= ' ORDER BY ' . $orderby . ' ' . $order;
216
+ }
217
+
218
+ // Find total number of items.
219
+ $count_query = $count_query . $query_cond;
220
+ $total_items = $wpdb->get_var( $count_query );
221
+
222
+ // Adjust the query to take pagination into account.
223
+ if ( ! empty( $current_page_no ) && ! empty( $per_page ) ) {
224
+ $offset = ( $current_page_no - 1 ) * $per_page;
225
+ $query_cond .= ' LIMIT ' . (int) $offset . ',' . (int) $per_page;
226
+ }
227
+
228
+ // Fetch the items.
229
+ $query = $query . $query_cond;
230
+ $items = $wpdb->get_results( $query );
231
+
232
+ return array( $items, $total_items );
233
+ }
234
+
235
+ /**
236
+ * Create email log table.
237
+ *
238
+ * @access private
239
+ *
240
+ * @global object $wpdb
241
+ */
242
+ private function create_table() {
243
+ global $wpdb;
244
+
245
+ $table_name = $this->get_log_table_name();
246
+ $charset_collate = $wpdb->get_charset_collate();
247
+
248
+ if ( $wpdb->get_var( "show tables like '{$table_name}'" ) != $table_name ) {
249
+
250
+ $sql = 'CREATE TABLE ' . $table_name . ' (
251
+ id mediumint(9) NOT NULL AUTO_INCREMENT,
252
+ to_email VARCHAR(100) NOT NULL,
253
+ subject VARCHAR(250) NOT NULL,
254
+ message TEXT NOT NULL,
255
+ headers TEXT NOT NULL,
256
+ attachments TEXT NOT NULL,
257
+ sent_date timestamp NOT NULL,
258
+ PRIMARY KEY (id)
259
+ ) ' . $charset_collate . ' ;';
260
+
261
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
262
+ dbDelta( $sql );
263
+
264
+ add_option( self::DB_OPTION_NAME, self::DB_VERSION );
265
+ }
266
+ }
267
+ }
include/Core/EmailLog.php ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core;
2
+
3
+ use EmailLog\Core\DB\TableManager;
4
+ use EmailLog\EmailLogAutoloader;
5
+
6
+ /**
7
+ * The main plugin class.
8
+ *
9
+ * @since Genesis
10
+ */
11
+ class EmailLog {
12
+
13
+ /**
14
+ * Plugin Version number.
15
+ *
16
+ * @since Genesis
17
+ * @var string
18
+ */
19
+ const VERSION = '2.0.0';
20
+
21
+ /**
22
+ * Email Log Store URL.
23
+ */
24
+ const STORE_URL = 'https://wpemaillog.com';
25
+
26
+ /**
27
+ * Flag to track if the plugin is loaded.
28
+ *
29
+ * @since 2.0
30
+ * @access private
31
+ * @var bool
32
+ */
33
+ private $loaded = false;
34
+
35
+ /**
36
+ * Plugin file path.
37
+ *
38
+ * @since 2.0
39
+ * @access private
40
+ * @var string
41
+ */
42
+ private $plugin_file;
43
+
44
+ /**
45
+ * Filesystem directory path where translations are stored.
46
+ *
47
+ * @since 2.0
48
+ * @var string
49
+ */
50
+ public $translations_path;
51
+
52
+ /**
53
+ * Auto loader.
54
+ *
55
+ * @var \EmailLog\EmailLogAutoloader
56
+ */
57
+ public $loader;
58
+
59
+ /**
60
+ * Database Table Manager.
61
+ *
62
+ * @since 2.0
63
+ * @var \EmailLog\Core\DB\TableManager
64
+ */
65
+ public $table_manager;
66
+
67
+ /**
68
+ * Add-on Licenser.
69
+ *
70
+ * @since 2.0
71
+ * @var \EmailLog\Addon\License\Licenser
72
+ */
73
+ private $licenser;
74
+
75
+ /**
76
+ * List of loadies.
77
+ *
78
+ * @var Loadie[]
79
+ */
80
+ private $loadies = array();
81
+
82
+ /**
83
+ * Initialize the plugin.
84
+ *
85
+ * @param string $file Plugin file.
86
+ * @param EmailLogAutoloader $loader EmailLog Autoloader.
87
+ * @param TableManager $table_manager Table Manager.
88
+ */
89
+ public function __construct( $file, $loader, $table_manager ) {
90
+ $this->plugin_file = $file;
91
+ $this->loader = $loader;
92
+ $this->table_manager = $table_manager;
93
+
94
+ $this->add_loadie( $table_manager );
95
+
96
+ $this->translations_path = dirname( plugin_basename( $this->plugin_file ) ) . '/languages/' ;
97
+ }
98
+
99
+ /**
100
+ * Set Licenser.
101
+ *
102
+ * @param \EmailLog\Addon\License\Licenser $licenser Add-on Licenser.
103
+ */
104
+ public function set_licenser( $licenser ) {
105
+ if ( $this->add_loadie( $licenser ) ) {
106
+ $this->licenser = $licenser;
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Get Licenser.
112
+ *
113
+ * @return \EmailLog\Addon\License\Licenser
114
+ */
115
+ public function get_licenser() {
116
+ return $this->licenser;
117
+ }
118
+
119
+ /**
120
+ * Add an Email Log Loadie.
121
+ * The `load()` method of the Loadies will be called when Email Log is loaded.
122
+ *
123
+ * @param \EmailLog\Core\Loadie $loadie Loadie to be loaded.
124
+ *
125
+ * @return bool False if Email Log is already loaded or if $loadie is not of `Loadie` type. True otherwise.
126
+ */
127
+ public function add_loadie( $loadie ) {
128
+ if ( $this->loaded ) {
129
+ return false;
130
+ }
131
+
132
+ if ( ! $loadie instanceof Loadie ) {
133
+ return false;
134
+ }
135
+
136
+ $this->loadies[] = $loadie;
137
+
138
+ return true;
139
+ }
140
+
141
+ /**
142
+ * Load the plugin.
143
+ */
144
+ public function load() {
145
+ if ( $this->loaded ) {
146
+ return;
147
+ }
148
+
149
+ load_plugin_textdomain( 'email-log', false, $this->translations_path );
150
+
151
+ $this->table_manager->load();
152
+
153
+ foreach ( $this->loadies as $loadie ) {
154
+ $loadie->load();
155
+ }
156
+
157
+ $this->loaded = true;
158
+
159
+ /**
160
+ * Email Log plugin loaded.
161
+ *
162
+ * @since 2.0
163
+ */
164
+ do_action( 'el_loaded' );
165
+ }
166
+
167
+ /**
168
+ * Return Email Log version.
169
+ *
170
+ * @return string Email Log Version.
171
+ */
172
+ public function get_version() {
173
+ return self::VERSION;
174
+ }
175
+
176
+ /**
177
+ * Return the Email Log plugin directory path.
178
+ *
179
+ * @return string Plugin directory path.
180
+ */
181
+ public function get_plugin_path() {
182
+ return plugin_dir_path( $this->plugin_file );
183
+ }
184
+
185
+ /**
186
+ * Return the Email Log plugin file.
187
+ *
188
+ * @since 2.0.0
189
+ *
190
+ * @return string Plugin directory path.
191
+ */
192
+ public function get_plugin_file() {
193
+ return $this->plugin_file;
194
+ }
195
+
196
+ /**
197
+ * Get Email Log Store URL.
198
+ *
199
+ * @since 2.0.0
200
+ *
201
+ * @return string Store URL
202
+ */
203
+ public function get_store_url() {
204
+ return self::STORE_URL;
205
+ }
206
+ }
include/Core/EmailLogger.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core;
2
+
3
+ /**
4
+ * Log's emails sent through `wp_mail`.
5
+ *
6
+ * @package EmailLog\Core
7
+ * @since 2.0
8
+ */
9
+ class EmailLogger implements Loadie {
10
+
11
+ /**
12
+ * Load the logger.
13
+ */
14
+ public function load() {
15
+ add_filter( 'wp_mail', array( $this, 'log_email' ) );
16
+ }
17
+
18
+ /**
19
+ * Logs email to database.
20
+ *
21
+ * @param array $mail_info Information about email.
22
+ *
23
+ * @return array Information about email.
24
+ */
25
+ public function log_email( $mail_info ) {
26
+ $email_log = email_log();
27
+ /**
28
+ * Hook to modify wp_mail contents before Email Log plugin logs.
29
+ *
30
+ * @since Genesis
31
+ *
32
+ * @param array $mail_info {
33
+ * @type string $to
34
+ * @type string $subject
35
+ * @type string $message
36
+ * @type string $headers
37
+ * @type string $attachment
38
+ * }
39
+ */
40
+ $mail_info = apply_filters( 'el_wp_mail_log', $mail_info );
41
+
42
+ $headers = '';
43
+ if ( isset( $mail_info['headers'] ) ) {
44
+ $headers = is_array( $mail_info['headers'] ) ? implode( "\n", $mail_info['headers'] ) : $mail_info['headers'];
45
+ }
46
+
47
+ $data = array(
48
+ 'attachments' => ( count( $mail_info['attachments'] ) > 0 ) ? 'true' : 'false',
49
+ 'to_email' => is_array( $mail_info['to'] ) ? implode( ',', $mail_info['to'] ) : $mail_info['to'],
50
+ 'subject' => $mail_info['subject'],
51
+ 'headers' => $headers,
52
+ 'sent_date' => current_time( 'mysql' ),
53
+ );
54
+
55
+ $message = '';
56
+
57
+ if ( isset( $mail_info['message'] ) ) {
58
+ $message = $mail_info['message'];
59
+ } else {
60
+ // wpmandrill plugin is changing "message" key to "html". See https://github.com/sudar/email-log/issues/20
61
+ // Ideally this should be fixed in wpmandrill, but I am including this hack here till it is fixed by them.
62
+ if ( isset( $mail_info['html'] ) ) {
63
+ $message = $mail_info['html'];
64
+ }
65
+ }
66
+
67
+ $data['message'] = $message;
68
+
69
+ $email_log->table_manager->insert_log( $data );
70
+
71
+ return $mail_info;
72
+ }
73
+ }
include/Core/Loadie.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * EmailLog Loadie interface.
7
+ * The `load()` method of this interface will be called by Email Log.
8
+ * Even though Loadie is not an actual word it sound more logical than subscriber.
9
+ *
10
+ * @since 2.0.0
11
+ */
12
+ interface Loadie {
13
+
14
+ /**
15
+ * This method will be called by Email Log after `wp-loaded` event.
16
+ *
17
+ * @return void
18
+ */
19
+ public function load();
20
+ }
include/Core/Request/LogListAction.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\Request;
2
+
3
+ use EmailLog\Core\Loadie;
4
+
5
+ /**
6
+ * Actions performed in Log List.
7
+ *
8
+ * @since 2.0.0
9
+ */
10
+ class LogListAction implements Loadie {
11
+
12
+ /**
13
+ * Setup actions.
14
+ *
15
+ * @inheritdoc
16
+ */
17
+ public function load() {
18
+ add_action( 'wp_ajax_el-log-list-view-message', array( $this, 'view_log_message' ) );
19
+
20
+ add_action( 'el-log-list-delete', array( $this, 'delete_logs' ) );
21
+ add_action( 'el-log-list-delete-all', array( $this, 'delete_all_logs' ) );
22
+ }
23
+
24
+ /**
25
+ * AJAX callback for displaying email content.
26
+ *
27
+ * @since 1.6
28
+ */
29
+ public function view_log_message() {
30
+ /**
31
+ * Filters the User capability to View Email Log content.
32
+ *
33
+ * Refer User Capabilities at
34
+ * @link https://codex.wordpress.org/Roles_and_Capabilities#Capabilities
35
+ *
36
+ * @since 2.0.0
37
+ *
38
+ * @param string $user_capability User capability to view Log content.
39
+ */
40
+ $view_email_log_capability = apply_filters( 'el_view_email_log_capability', 'manage_options' );
41
+
42
+ if ( current_user_can( $view_email_log_capability ) ) {
43
+ $id = absint( $_GET['log_id'] );
44
+
45
+ if ( $id > 0 ) {
46
+ $log_items = $this->get_table_manager()->fetch_log_items_by_id( array( $id ) );
47
+ if ( count( $log_items ) > 0 ) {
48
+ $log_item = $log_items[0];
49
+
50
+ ob_start();
51
+ ?>
52
+ <table style="width: 100%;">
53
+ <tr style="background: #eee;">
54
+ <td style="padding: 5px;"><?php _e( 'Sent at', 'email-log' ); ?>:</td>
55
+ <td style="padding: 5px;"><?php echo $log_item['sent_date'] ?></td>
56
+ </tr>
57
+ <tr style="background: #eee;">
58
+ <td style="padding: 5px;"><?php _e( 'To', 'email-log' ); ?>:</td>
59
+ <td style="padding: 5px;"><?php echo $log_item['to_email'] ?></td>
60
+ </tr>
61
+ <tr style="background: #eee;">
62
+ <td style="padding: 5px;"><?php _e( 'Subject', 'email-log' ); ?>:</td>
63
+ <td style="padding: 5px;"><?php echo $log_item['subject'] ?></td>
64
+ </tr>
65
+
66
+ <?php
67
+ /**
68
+ * After the headers are displayed in the View Message thickbox.
69
+ * This action can be used to add additional headers.
70
+ *
71
+ * @since 2.0.0
72
+ *
73
+ * @param array $log_item Log item that is getting rendered.
74
+ */
75
+ do_action( 'el_view_log_after_headers', $log_item );
76
+ ?>
77
+
78
+ </table>
79
+
80
+ <div id="tabs">
81
+ <ul>
82
+ <li><a href="#tabs-1"><?php _e( 'HTML', 'email-log' ); ?></a></li>
83
+ <li><a href="#tabs-2"><?php _e( 'Text', 'email-log' ); ?></a></li>
84
+ </ul>
85
+ <div id="tabs-1">
86
+ <?php echo $log_item['message']; ?>
87
+ </div>
88
+ <div id="tabs-2">
89
+ <textarea class="tabs-text-textarea"><?php echo esc_textarea( $log_item['message'] ); ?></textarea>
90
+ </div>
91
+ </div>
92
+
93
+ <div id="view-message-footer">
94
+ <a href="#" id="thickbox-footer-close"><?php _e( 'Close', 'email-log' ); ?></a>
95
+ </div>
96
+
97
+ <?php
98
+ $output = ob_get_clean();
99
+ echo $output;
100
+ }
101
+ }
102
+ }
103
+
104
+ die(); // this is required to return a proper result.
105
+ }
106
+
107
+ /**
108
+ * Delete log entries by id.
109
+ *
110
+ * @param array $data Request data.
111
+ */
112
+ public function delete_logs( $data ) {
113
+ $ids = $data['email-log'];
114
+
115
+ if ( ! is_array( $ids ) ) {
116
+ $ids = array( $ids );
117
+ }
118
+
119
+ $ids = array_map( 'absint', $ids );
120
+ $id_list = implode( ',', $ids );
121
+
122
+ $logs_deleted = $this->get_table_manager()->delete_logs( $id_list );
123
+ $this->render_log_deleted_notice( $logs_deleted );
124
+ }
125
+
126
+ /**
127
+ * Delete all log entries.
128
+ */
129
+ public function delete_all_logs() {
130
+ $logs_deleted = $this->get_table_manager()->delete_all_logs();
131
+ $this->render_log_deleted_notice( $logs_deleted );
132
+ }
133
+
134
+ /**
135
+ * Render Logs deleted notice.
136
+ *
137
+ * @param int|False $logs_deleted Number of entries deleted, False otherwise.
138
+ */
139
+ protected function render_log_deleted_notice( $logs_deleted ) {
140
+ $message = __( 'There was some problem in deleting the email logs', 'email-log' );
141
+ $type = 'error';
142
+
143
+ if ( absint( $logs_deleted ) > 0 ) {
144
+ $message = sprintf( _n( '1 email log deleted.', '%s email logs deleted', $logs_deleted, 'email-log' ), $logs_deleted );
145
+ $type = 'updated';
146
+ }
147
+
148
+ add_settings_error(
149
+ 'log-list',
150
+ 'deleted-email-logs',
151
+ $message,
152
+ $type
153
+ );
154
+ }
155
+
156
+ /**
157
+ * Get TableManager instance.
158
+ *
159
+ * @return \EmailLog\Core\DB\TableManager TableManager instance.
160
+ */
161
+ protected function get_table_manager() {
162
+ $email_log = email_log();
163
+
164
+ return $email_log->table_manager;
165
+ }
166
+ }
include/Core/Request/NonceChecker.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\Request;
2
+
3
+ use EmailLog\Core\Loadie;
4
+ use EmailLog\Core\UI\Page\LogListPage;
5
+
6
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
7
+
8
+ /**
9
+ * Check nonce for all Email Log requests.
10
+ *
11
+ * @since 2.0.0
12
+ */
13
+ class NonceChecker implements Loadie {
14
+
15
+ /**
16
+ * Setup hooks.
17
+ *
18
+ * @inheritdoc
19
+ */
20
+ public function load() {
21
+ add_action( 'admin_init', array( $this, 'check_nonce' ) );
22
+ }
23
+
24
+ /**
25
+ * Check nonce for all Email Log Requests.
26
+ * All Email Log Requests will have the `el_` prefix and
27
+ * nonce would be available at `el_{action_name}_nonce`.
28
+ */
29
+ public function check_nonce() {
30
+ if ( ! isset( $_POST['el-action'] ) && ! isset( $_REQUEST['action'] ) ) {
31
+ return;
32
+ }
33
+
34
+ if ( isset( $_POST['el-action'] ) ) {
35
+ $action = sanitize_text_field( $_POST['el-action'] );
36
+
37
+ if ( ! isset( $_POST[ $action . '_nonce' ] ) ) {
38
+ return;
39
+ }
40
+
41
+ if ( ! wp_verify_nonce( $_POST[ $action . '_nonce' ], $action ) ) {
42
+ return;
43
+ }
44
+ }
45
+
46
+ if ( isset( $_REQUEST['action'] ) ) {
47
+ $action = sanitize_text_field( $_REQUEST['action'] );
48
+
49
+ if ( 'el-log-list-' !== substr( $action, 0, 12 ) ) {
50
+ return;
51
+ }
52
+
53
+ if ( ! wp_verify_nonce( $_REQUEST[ LogListPage::DELETE_LOG_NONCE_FIELD ], LogListPage::DELETE_LOG_ACTION ) ) {
54
+ return;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Perform `el` action.
60
+ * Nonce check has already happened at this point.
61
+ *
62
+ * @since 2.0.0
63
+ *
64
+ * @param string $action Action name.
65
+ * @param array $_REQUEST Request data.
66
+ */
67
+ do_action( 'el_action', $action, $_REQUEST );
68
+
69
+ /**
70
+ * Perform `el` action.
71
+ * Nonce check has already happened at this point.
72
+ *
73
+ * @since 2.0.0
74
+ *
75
+ * @param array $_REQUEST Request data.
76
+ */
77
+ do_action( $action, $_REQUEST );
78
+ }
79
+ }
include/Core/Request/OverridePluginAPI.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\Request;
2
+
3
+ use EmailLog\Addon\AddonList;
4
+ use EmailLog\Addon\API\EDDUpdater;
5
+ use EmailLog\Core\Loadie;
6
+
7
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
8
+
9
+ /**
10
+ * Override WordPress Plugin API.
11
+ * This is already done by EDD_SL_Plugin_Updater for Active add-on
12
+ * and this class does it for all in active or yet to be installed add-ons.
13
+ *
14
+ * @since 2.0.0
15
+ */
16
+ class OverridePluginAPI implements Loadie {
17
+
18
+ /**
19
+ * Setup actions.
20
+ *
21
+ * @inheritdoc
22
+ */
23
+ public function load() {
24
+ add_action( 'admin_init', array( $this, 'setup_updaters_for_inactive_addons' ) );
25
+ }
26
+
27
+ /**
28
+ * Setup updaters for all in-active addons.
29
+ */
30
+ public function setup_updaters_for_inactive_addons() {
31
+ $email_log = email_log();
32
+ $inactive_addons = $email_log->get_licenser()->get_addon_list()->get_inactive_addons();
33
+
34
+ foreach ( $inactive_addons as $inactive_addon ) {
35
+ $license_key = $email_log->get_licenser()->get_addon_license_key( $inactive_addon->name );
36
+
37
+ $updater = new EDDUpdater( $email_log->get_store_url(), $inactive_addon->file, array(
38
+ 'version' => $inactive_addon->get_version(),
39
+ 'license' => $license_key,
40
+ 'item_name' => $inactive_addon->name,
41
+ 'author' => $inactive_addon->author,
42
+ )
43
+ );
44
+
45
+ $email_log->get_licenser()->add_updater( $updater );
46
+ }
47
+ }
48
+ }
include/Core/UI/Component/AdminUIEnhancer.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\Component;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * Enhance Admin UI and add links about EmailLog in the following places.
7
+ * - Plugin List page.
8
+ * - Footer for all EmailLog pages.
9
+ *
10
+ * @since 2.0.0
11
+ */
12
+ class AdminUIEnhancer {
13
+
14
+ /**
15
+ * Plugin file name.
16
+ *
17
+ * @var string
18
+ */
19
+ protected $plugin_file;
20
+
21
+ /**
22
+ * Plugin basename.
23
+ *
24
+ * @var string
25
+ */
26
+ protected $plugin_basename;
27
+
28
+ /**
29
+ * Initialize the component and store the plugin basename.
30
+ *
31
+ * @param string|null $file Plugin file.
32
+ */
33
+ public function __construct( $file = null ) {
34
+ if ( null === $file ) {
35
+ $email_log = email_log();
36
+ $file = $email_log->get_plugin_file();
37
+ }
38
+
39
+ $this->plugin_file = $file;
40
+ $this->plugin_basename = plugin_basename( $file );
41
+ }
42
+
43
+ /**
44
+ * Setup hooks.
45
+ *
46
+ * @inheritdoc
47
+ */
48
+ public function load() {
49
+ add_filter( 'plugin_row_meta', array( $this, 'insert_addon_store_link' ), 10, 2 );
50
+ add_filter( 'plugin_action_links_' . $this->plugin_basename, array( $this, 'insert_view_logs_link' ) );
51
+
52
+ add_action( 'el_admin_footer', array( $this, 'hook_footer_links' ) );
53
+ }
54
+
55
+ /**
56
+ * Add link to Add-ons store.
57
+ *
58
+ * @see Additional links in the Plugin listing is based on
59
+ * @link http://zourbuth.com/archives/751/creating-additional-wordpress-plugin-links-row-meta/
60
+ *
61
+ * @param array $links Array with default links to display in plugins page.
62
+ * @param string $file The name of the plugin file.
63
+ *
64
+ * @return array Modified list of links to display in plugins page.
65
+ */
66
+ public function insert_addon_store_link( $links, $file ) {
67
+ if ( $file === $this->plugin_basename ) {
68
+ $links[] = '<a href="https://wpemaillog.com/store/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=plugin-page" target="_blank">' .
69
+ __( 'Buy Addons', 'email-log' ) . '</a>';
70
+ }
71
+
72
+ return $links;
73
+ }
74
+
75
+ /**
76
+ * Add link to 'View logs' page in plugin listing page.
77
+ *
78
+ * @param array $links List of links.
79
+ *
80
+ * @return array Modified list of links.
81
+ */
82
+ public function insert_view_logs_link( $links ) {
83
+ $settings_link = '<a href="admin.php?page=email-log">' . __( 'View Logs', 'email-log' ) . '</a>';
84
+ array_unshift( $links, $settings_link );
85
+
86
+ return $links;
87
+ }
88
+
89
+ /**
90
+ * Hook Footer links.
91
+ */
92
+ public function hook_footer_links() {
93
+ add_action( 'in_admin_footer', array( $this, 'add_credit_links' ) );
94
+ }
95
+
96
+ /**
97
+ * Adds Footer links.
98
+ *
99
+ * @since Genesis
100
+ *
101
+ * @see Function relied on
102
+ * @link http://striderweb.com/nerdaphernalia/2008/06/give-your-wordpress-plugin-credit/
103
+ */
104
+ public function add_credit_links() {
105
+ $plugin_data = get_plugin_data( $this->plugin_file );
106
+ printf(
107
+ '%1$s ' . __( 'plugin', 'email-log' ) . ' | ' . __( 'Version', 'email-log' ) . ' %2$s | ' . __( 'by', 'email-log' ) . ' %3$s<br />',
108
+ $plugin_data['Title'],
109
+ $plugin_data['Version'],
110
+ $plugin_data['Author']
111
+ );
112
+ }
113
+ }
include/Core/UI/ListTable/LogListTable.php ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\ListTable;
2
+
3
+ if ( ! class_exists( 'WP_List_Table' ) ) {
4
+ require_once ABSPATH . WPINC . '/class-wp-list-table.php';
5
+ }
6
+
7
+ /**
8
+ * Table to display Email Logs.
9
+ *
10
+ * Based on Custom List Table Example by Matt Van Andel.
11
+ */
12
+ class LogListTable extends \WP_List_Table {
13
+ /**
14
+ * @var object The page where this table is rendered.
15
+ *
16
+ * @since 2.0
17
+ */
18
+ protected $page;
19
+
20
+ /**
21
+ * Set up a constructor that references the parent constructor.
22
+ *
23
+ * We use the parent reference to set some default configs.
24
+ */
25
+ public function __construct( $page, $args = array() ) {
26
+ $this->page = $page;
27
+
28
+ $args = wp_parse_args( $args, array(
29
+ 'singular' => 'email-log', // singular name of the listed records
30
+ 'plural' => 'email-logs', // plural name of the listed records
31
+ 'ajax' => false, // does this table support ajax?
32
+ 'screen' => $this->page->get_screen(),
33
+ ) );
34
+
35
+ parent::__construct( $args );
36
+ }
37
+
38
+ /**
39
+ * Adds extra markup in the toolbars before or after the list.
40
+ *
41
+ * @access protected
42
+ *
43
+ * @param string $which Add the markup after (bottom) or before (top) the list.
44
+ */
45
+ protected function extra_tablenav( $which ) {
46
+ if ( 'top' == $which ) {
47
+ // The code that goes before the table is here.
48
+ echo '<span id = "el-pro-msg">';
49
+ _e( 'Additional fields are available in Pro add-on. ', 'email-log' );
50
+ echo '<a href="https://wpemaillog.com/addons/more-fields/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=inline&utm_content=mf" style="color:red">';
51
+ _e( 'Buy Now', 'email-log' );
52
+ echo '</a>';
53
+ echo '</span>';
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Returns the list of column and title names.
59
+ *
60
+ * @see WP_List_Table::single_row_columns()
61
+ *
62
+ * @return array An associative array containing column information: 'slugs'=>'Visible Titles'.
63
+ */
64
+ public function get_columns() {
65
+ $columns = array(
66
+ 'cb' => '<input type="checkbox" />', // Render a checkbox instead of text.
67
+ 'sent_date' => __( 'Sent at', 'email-log' ),
68
+ 'to' => __( 'To', 'email-log' ),
69
+ 'subject' => __( 'Subject', 'email-log' ),
70
+ );
71
+
72
+ /**
73
+ * Filter the email log list table columns.
74
+ *
75
+ * @since 2.0
76
+ * @param array $columns Columns of email log list table.
77
+ */
78
+ return apply_filters( 'el_manage_log_columns', $columns );
79
+ }
80
+
81
+ /**
82
+ * Returns the list of columns.
83
+ *
84
+ * @access protected
85
+ *
86
+ * @return array<string,array<string|boolean>> An associative array containing all the columns
87
+ * that should be sortable: 'slugs'=>array('data_values',bool).
88
+ */
89
+ protected function get_sortable_columns() {
90
+ $sortable_columns = array(
91
+ 'sent_date' => array( 'sent_date', true ), // true means it's already sorted.
92
+ 'to' => array( 'to_email', false ),
93
+ 'subject' => array( 'subject', false ),
94
+ );
95
+ return $sortable_columns;
96
+ }
97
+
98
+ /**
99
+ * Returns value for default columns.
100
+ *
101
+ * @access protected
102
+ *
103
+ * @param object $item Data object.
104
+ * @param string $column_name Column Name.
105
+ */
106
+ protected function column_default( $item, $column_name ) {
107
+ /**
108
+ * Display Email Log list table columns.
109
+ *
110
+ * @since 2.0
111
+ *
112
+ * @param string $column_name Column Name.
113
+ * @param object $item Data object.
114
+ */
115
+ do_action( 'el_display_log_columns', $column_name, $item );
116
+ }
117
+
118
+ /**
119
+ * Display sent date column.
120
+ *
121
+ * @access protected
122
+ *
123
+ * @param object $item Current item object.
124
+ * @return string Markup to be displayed for the column.
125
+ */
126
+ protected function column_sent_date( $item ) {
127
+ $email_date = mysql2date(
128
+ sprintf( __( '%s @ %s', 'email-log' ), get_option( 'date_format', 'F j, Y' ), get_option( 'time_format', 'g:i A' ) ),
129
+ $item->sent_date
130
+ );
131
+
132
+ $actions = array();
133
+
134
+ $content_ajax_url = add_query_arg(
135
+ array(
136
+ 'action' => 'el-log-list-view-message',
137
+ 'log_id' => $item->id,
138
+ 'width' => '800',
139
+ 'height' => '550',
140
+ ),
141
+ 'admin-ajax.php'
142
+ );
143
+
144
+ $actions['view-content'] = sprintf( '<a href="%1$s" class="thickbox" title="%2$s">%3$s</a>',
145
+ esc_url( $content_ajax_url ),
146
+ __( 'Email Content', 'email-log' ),
147
+ __( 'View Content', 'email-log' )
148
+ );
149
+
150
+ $delete_url = add_query_arg(
151
+ array(
152
+ 'page' => $_REQUEST['page'],
153
+ 'action' => 'el-log-list-delete',
154
+ $this->_args['singular'] => $item->id,
155
+ )
156
+ );
157
+ $delete_url = add_query_arg( $this->page->get_nonce_args(), $delete_url );
158
+
159
+ $actions['delete'] = sprintf( '<a href="%s">%s</a>',
160
+ esc_url( $delete_url ),
161
+ __( 'Delete', 'email-log' )
162
+ );
163
+
164
+ /**
165
+ * This filter can be used to modify the list of row actions that are displayed.
166
+ *
167
+ * @since 1.8
168
+ *
169
+ * @param array $actions List of actions.
170
+ * @param object $item The current log item.
171
+ */
172
+ $actions = apply_filters( 'el_row_actions', $actions, $item );
173
+
174
+ return sprintf( '%1$s <span style="color:silver">(id:%2$s)</span>%3$s',
175
+ /*$1%s*/ $email_date,
176
+ /*$2%s*/ $item->id,
177
+ /*$3%s*/ $this->row_actions( $actions )
178
+ );
179
+ }
180
+
181
+ /**
182
+ * To field.
183
+ *
184
+ * @access protected
185
+ *
186
+ * @param object $item
187
+ * @return string
188
+ */
189
+ protected function column_to( $item ) {
190
+ return esc_html( $item->to_email );
191
+ }
192
+
193
+ /**
194
+ * Subject field.
195
+ *
196
+ * @access protected
197
+ *
198
+ * @param object $item
199
+ * @return string
200
+ */
201
+ protected function column_subject( $item ) {
202
+ return esc_html( $item->subject );
203
+ }
204
+
205
+ /**
206
+ * Markup for action column.
207
+ *
208
+ * @access protected
209
+ *
210
+ * @param object $item
211
+ * @return string
212
+ */
213
+ protected function column_cb( $item ) {
214
+ return sprintf(
215
+ '<input type="checkbox" name="%1$s[]" value="%2$s" />',
216
+ /*$1%s*/ $this->_args['singular'],
217
+ /*$2%s*/ $item->id
218
+ );
219
+ }
220
+
221
+ /**
222
+ * Specify the list of bulk actions.
223
+ *
224
+ * @access protected
225
+ *
226
+ * @return array An associative array containing all the bulk actions: 'slugs'=>'Visible Titles'.
227
+ */
228
+ protected function get_bulk_actions() {
229
+ $actions = array(
230
+ 'el-log-list-delete' => __( 'Delete', 'email-log' ),
231
+ 'el-log-list-delete-all' => __( 'Delete All Logs', 'email-log' ),
232
+ );
233
+ $actions = apply_filters( 'el_bulk_actions', $actions );
234
+ return $actions;
235
+ }
236
+
237
+ /**
238
+ * Prepare data for display.
239
+ */
240
+ public function prepare_items() {
241
+ $this->_column_headers = $this->get_column_info();
242
+
243
+ // Get current page number.
244
+ $current_page_no = $this->get_pagenum();
245
+ $per_page = $this->page->get_per_page();
246
+
247
+ list( $items, $total_items ) = $this->page->get_table_manager()->fetch_log_items( $_GET, $per_page, $current_page_no );
248
+
249
+ $this->items = $items;
250
+
251
+ // Register pagination options & calculations.
252
+ $this->set_pagination_args( array(
253
+ 'total_items' => $total_items,
254
+ 'per_page' => $per_page,
255
+ 'total_pages' => ceil( $total_items / $per_page ),
256
+ ) );
257
+ }
258
+
259
+ /**
260
+ * Displays default message when no items are found.
261
+ */
262
+ public function no_items() {
263
+ _e( 'Your email log is empty', 'email-log' );
264
+ }
265
+
266
+ /**
267
+ * Displays the search box.
268
+ *
269
+ * @since 2.0
270
+ *
271
+ * @param string $text The 'submit' button label.
272
+ * @param string $input_id ID attribute value for the search input field.
273
+ */
274
+ public function search_box( $text, $input_id ) {
275
+ $input_text_id = $input_id . '-search-input';
276
+ $input_date_id = $input_id . '-search-date-input';
277
+ $input_date_val = ( ! empty( $_REQUEST['d'] ) ) ? sanitize_text_field( $_REQUEST['d'] ) : '';
278
+
279
+
280
+ if ( ! empty( $_REQUEST['orderby'] ) )
281
+ echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
282
+ if ( ! empty( $_REQUEST['order'] ) )
283
+ echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
284
+ if ( ! empty( $_REQUEST['post_mime_type'] ) )
285
+ echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
286
+ if ( ! empty( $_REQUEST['detached'] ) )
287
+ echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
288
+ ?>
289
+ <p class="search-box">
290
+ <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo $text; ?>:</label>
291
+ <input type="search" id="<?php echo esc_attr( $input_date_id ); ?>" name="d" value="<?php echo $input_date_val; ?>" placeholder="<?php _e( 'Search by date', 'email-log' ); ?>" />
292
+ <input type="search" id="<?php echo esc_attr( $input_text_id ); ?>" name="s" value="<?php _admin_search_query(); ?>" placeholder="<?php _e( 'Search by term', 'email-log' ); ?>" />
293
+ <?php submit_button( $text, '', '', false, array( 'id' => 'search-submit' ) ); ?>
294
+ </p>
295
+ <?php
296
+ }
297
+ }
include/Core/UI/Page/AddonListPage.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\Page;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * Addon List Page
7
+ *
8
+ * @since 2.0
9
+ */
10
+ class AddonListPage extends BasePage {
11
+
12
+ /**
13
+ * Page slug.
14
+ */
15
+ const PAGE_SLUG = 'email-log-addons';
16
+
17
+ /**
18
+ * Register page.
19
+ */
20
+ public function register_page() {
21
+ $this->page = add_submenu_page(
22
+ LogListPage::PAGE_SLUG,
23
+ __( 'Add-ons', 'email-log' ),
24
+ __( 'Add-ons', 'email-log' ),
25
+ 'manage_options',
26
+ self::PAGE_SLUG,
27
+ array( $this, 'render_page' )
28
+ );
29
+
30
+ add_action( "load-{$this->page}", array( $this, 'render_help_tab' ) );
31
+ add_action( "load-{$this->page}", array( $this, 'enqueue_assets' ) );
32
+ }
33
+
34
+ /**
35
+ * Render the list of add-on in the page.
36
+ */
37
+ public function render_page() {
38
+ ?>
39
+ <div class="wrap">
40
+ <h1><?php _e( 'Email Log Add-ons', 'email-log' ); ?></h1>
41
+ <?php settings_errors(); ?>
42
+
43
+ <p>
44
+ <?php _e( 'These add-ons provide additional functionality to Email Log plugin and are available for purchase.', 'email-log' ); ?>
45
+ <?php _e( 'If your license includes the add-ons below, you will be able to install them from here with one-click.', 'email-log' ); ?>
46
+ </p>
47
+
48
+ <?php
49
+ /**
50
+ * Before add-ons are listed in the add-on list page.
51
+ *
52
+ * @since 2.0.0
53
+ */
54
+ do_action( 'el_before_addon_list' );
55
+
56
+ $email_log = email_log();
57
+ $email_log->get_licenser()->get_addon_list()->render();
58
+ ?>
59
+ </div>
60
+ <?php
61
+
62
+ $this->render_page_footer();
63
+ }
64
+
65
+ /**
66
+ * Enqueue static assets needed for this page.
67
+ */
68
+ public function enqueue_assets() {
69
+ $email_log = email_log();
70
+
71
+ wp_enqueue_style( 'el_addon_list', plugins_url( 'assets/css/admin/addon-list.css', $email_log->get_plugin_file() ), array(), $email_log->get_version() );
72
+ wp_enqueue_script( 'el_addon_list', plugins_url( 'assets/js/admin/addon-list.js', $email_log->get_plugin_file() ), array( 'jquery' ), $email_log->get_version(), true );
73
+ }
74
+ }
include/Core/UI/Page/BasePage.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\Page;
2
+
3
+ use EmailLog\Core\Loadie;
4
+
5
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
6
+
7
+ /**
8
+ * Base class for all Email Log admin pages.
9
+ *
10
+ * @since 2.0.0
11
+ */
12
+ abstract class BasePage implements Loadie {
13
+
14
+ /**
15
+ * Current page.
16
+ *
17
+ * @var string
18
+ */
19
+ protected $page;
20
+
21
+ /**
22
+ * Current screen.
23
+ *
24
+ * @var \WP_Screen
25
+ */
26
+ protected $screen;
27
+
28
+ /**
29
+ * Register page.
30
+ *
31
+ * @return void
32
+ */
33
+ abstract public function register_page();
34
+
35
+ /**
36
+ * Setup hooks related to pages.
37
+ *
38
+ * @inheritdoc
39
+ */
40
+ public function load() {
41
+ add_action( 'admin_menu', array( $this, 'register_page' ) );
42
+ }
43
+
44
+ /**
45
+ * Render help tab.
46
+ */
47
+ public function render_help_tab() {
48
+ $content = '<p>' .
49
+ __( 'Email Log is a WordPress plugin that allows you to easily log and view all emails sent from WordPress.', 'email-log' ) .
50
+ '</p>' .
51
+ '<p>' .
52
+ __( 'You can view the logged emails from the View Logs screen. ', 'email-log' ) .
53
+ sprintf(
54
+ __( 'Check the <a href="%s">documentation about the View Logs screen</a> for more details.', 'email-log' ),
55
+ 'https://wpemaillog.com/docs/view-logged-email/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=help&utm_content=docs-content'
56
+ ) .
57
+ '</p>' .
58
+ '<p>' .
59
+ sprintf(
60
+ __( 'You can perform advanced actions like re-sending email, automatically forwarding emails or export logs with our <a href="%s">premium plugins</a>.', 'email-log' ),
61
+ 'https://wpemaillog.com/store/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=help&utm_content=store-content'
62
+ ) .
63
+ '</p>';
64
+
65
+ $this->get_screen()->add_help_tab(
66
+ array(
67
+ 'title' => __( 'About Plugin', 'email-log' ),
68
+ 'id' => 'about_tab',
69
+ 'content' => $content,
70
+ 'callback' => false,
71
+ )
72
+ );
73
+
74
+ $this->get_screen()->set_help_sidebar(
75
+ '<p><strong>' . __( 'More information', 'email-log' ) . '</strong></p>' .
76
+ '<p><a href = "https://wpemaillog.com/docs/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=help&utm_content=docs">' . __( 'Documentation', 'email-log' ) . '</a></p>' .
77
+ '<p><a href = "https://wpemaillog.com/support/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=help&utm_content=support">' . __( 'Support', 'email-log' ) . '</a></p>' .
78
+ '<p><a href = "https://wpemaillog.com/store/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=help&utm_content=store">' . __( 'Add-ons', 'email-log' ) . '</a></p>'
79
+ );
80
+ }
81
+
82
+ /**
83
+ * Render admin page footer.
84
+ */
85
+ protected function render_page_footer() {
86
+ /**
87
+ * Action to add additional content to email log admin footer.
88
+ *
89
+ * @since 1.8
90
+ */
91
+ do_action( 'el_admin_footer' );
92
+ }
93
+
94
+ /**
95
+ * Return the WP_Screen object for the current page's handle.
96
+ *
97
+ * @return \WP_Screen Screen object.
98
+ */
99
+ public function get_screen() {
100
+ if ( ! isset( $this->screen ) ) {
101
+ $this->screen = \WP_Screen::get( $this->page );
102
+ }
103
+
104
+ return $this->screen;
105
+ }
106
+ }
include/Core/UI/Page/LogListPage.php ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\Page;
2
+
3
+ use EmailLog\Core\DB\TableManager;
4
+ use EmailLog\Core\UI\ListTable\LogListTable;
5
+
6
+ /**
7
+ * Log List Page.
8
+ *
9
+ * @since 2.0
10
+ */
11
+ class LogListPage extends BasePage {
12
+ /**
13
+ * @var LogListTable
14
+ */
15
+ protected $log_list_table;
16
+
17
+ /**
18
+ * Page slug.
19
+ */
20
+ const PAGE_SLUG = 'email-log';
21
+
22
+ /**
23
+ * Delete Log Nonce Field.
24
+ */
25
+ const DELETE_LOG_NONCE_FIELD = 'el-delete-email-log-nonce';
26
+
27
+ /**
28
+ * Delete Log Action.
29
+ */
30
+ const DELETE_LOG_ACTION = 'el-delete-email-log';
31
+
32
+ /**
33
+ * Setup hooks.
34
+ */
35
+ public function load() {
36
+ parent::load();
37
+
38
+ add_filter( 'set-screen-option', array( $this, 'save_screen_options' ), 10, 3 );
39
+
40
+ add_action( 'admin_enqueue_scripts', array( $this, 'load_view_logs_assets' ) );
41
+ }
42
+
43
+ /**
44
+ * Register page.
45
+ *
46
+ * @inheritdoc
47
+ */
48
+ public function register_page() {
49
+ add_menu_page(
50
+ __( 'Email Log', 'email-log' ),
51
+ __( 'Email Log', 'email-log' ),
52
+ 'manage_options',
53
+ self::PAGE_SLUG,
54
+ array( $this, 'render_page' ),
55
+ 'dashicons-email-alt',
56
+ 26
57
+ );
58
+
59
+ $this->page = add_submenu_page(
60
+ self::PAGE_SLUG,
61
+ __( 'View Logs', 'email-log'),
62
+ __( 'View Logs', 'email-log'),
63
+ 'manage_options',
64
+ self::PAGE_SLUG,
65
+ array( $this, 'render_page' )
66
+ );
67
+
68
+ add_action( "load-{$this->page}", array( $this, 'load_page' ) );
69
+
70
+ /**
71
+ * Fires before loading log list page.
72
+ *
73
+ * @since 2.0
74
+ *
75
+ * @param string $page Page slug.
76
+ */
77
+ do_action( 'el_load_log_list_page', $this->page );
78
+ }
79
+
80
+ /**
81
+ * Render page.
82
+ */
83
+ public function render_page() {
84
+ add_thickbox();
85
+
86
+ $this->log_list_table->prepare_items();
87
+ ?>
88
+ <div class="wrap">
89
+ <h2><?php _e( 'Email Logs', 'email-log' ); ?></h2>
90
+ <?php settings_errors(); ?>
91
+
92
+ <form id="email-logs-search" method="get">
93
+ <input type="hidden" name="page" value="<?php echo esc_attr( self::PAGE_SLUG ); ?>">
94
+ <?php $this->log_list_table->search_box( __( 'Search Logs', 'email-log' ), 'search_id' ); ?>
95
+ </form>
96
+
97
+ <form id="email-logs-filter" method="get">
98
+ <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>"/>
99
+ <?php
100
+ wp_nonce_field( self::DELETE_LOG_ACTION, self::DELETE_LOG_NONCE_FIELD );
101
+ $this->log_list_table->display();
102
+ ?>
103
+ </form>
104
+ </div>
105
+ <?php
106
+ $this->render_page_footer();
107
+ }
108
+
109
+ /**
110
+ * Load page.
111
+ */
112
+ public function load_page() {
113
+ $this->render_help_tab();
114
+
115
+ // Add screen options
116
+ $this->get_screen()->add_option(
117
+ 'per_page',
118
+ array(
119
+ 'label' => __( 'Entries per page', 'email-log' ),
120
+ 'default' => 20,
121
+ 'option' => 'per_page',
122
+ )
123
+ );
124
+
125
+ $this->log_list_table = new LogListTable( $this );
126
+ }
127
+
128
+ /**
129
+ * Gets the per page option.
130
+ *
131
+ * @return int Number of logs a user wanted to be displayed in a page.
132
+ */
133
+ public function get_per_page() {
134
+ $screen = get_current_screen();
135
+ $option = $screen->get_option( 'per_page', 'option' );
136
+
137
+ $per_page = get_user_meta( get_current_user_id(), $option, true );
138
+
139
+ if ( empty( $per_page ) || $per_page < 1 ) {
140
+ $per_page = $screen->get_option( 'per_page', 'default' );
141
+ }
142
+
143
+ return $per_page;
144
+ }
145
+
146
+ /**
147
+ * Verify nonce for all bulk actions.
148
+ */
149
+ public function check_nonce() {
150
+ if ( ! isset( $_REQUEST[ self::DELETE_LOG_NONCE_FIELD ] ) ) {
151
+ return false;
152
+ }
153
+
154
+ $nonce = $_REQUEST[ self::DELETE_LOG_NONCE_FIELD ];
155
+
156
+ if ( ! wp_verify_nonce( $nonce, self::DELETE_LOG_ACTION ) ) {
157
+ wp_die( 'Cheating, Huh? ' );
158
+ }
159
+
160
+ return true;
161
+ }
162
+
163
+ /**
164
+ * Get nonce args.
165
+ *
166
+ * @return array Nonce args.
167
+ */
168
+ public function get_nonce_args() {
169
+ return array(
170
+ self::DELETE_LOG_NONCE_FIELD => wp_create_nonce( self::DELETE_LOG_ACTION ),
171
+ );
172
+ }
173
+
174
+ /**
175
+ * Get TableManager instance.
176
+ *
177
+ * @return TableManager TableManager instance.
178
+ */
179
+ public function get_table_manager() {
180
+ $email_log = email_log();
181
+
182
+ return $email_log->table_manager;
183
+ }
184
+
185
+ /**
186
+ * Saves Screen options.
187
+ *
188
+ * @since Genesis
189
+ *
190
+ * @param bool|int $status Screen option value. Default false to skip.
191
+ * @param string $option The option name.
192
+ * @param int $value The number of rows to use.
193
+ *
194
+ * @return bool|int
195
+ */
196
+ public function save_screen_options( $status, $option, $value ) {
197
+ if ( 'per_page' == $option ) {
198
+ return $value;
199
+ } else {
200
+ return $status;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Loads assets on the Log List page.
206
+ *
207
+ * @since 2.0.0
208
+ *
209
+ * @param string $hook The current admin page.
210
+ */
211
+ public function load_view_logs_assets( $hook ) {
212
+ // Don't load assets if not View Logs page.
213
+ if ( 'toplevel_page_email-log' !== $hook ) {
214
+ return;
215
+ }
216
+
217
+ $email_log = email_log();
218
+ $plugin_dir_url = plugin_dir_url( $email_log->get_plugin_file() );
219
+
220
+ wp_enqueue_style( 'jquery-ui-css', $plugin_dir_url . 'assets/vendor/jquery-ui/themes/base/jquery-ui.min.css', array(), '1.12.1' );
221
+ wp_enqueue_style( 'el-view-logs-css', $plugin_dir_url . 'assets/css/admin/view-logs.css', array( 'jquery-ui-css' ), $email_log->get_version() );
222
+
223
+ wp_enqueue_script( 'jquery-ui-datepicker' );
224
+ wp_enqueue_script( 'el-view-logs', $plugin_dir_url . 'assets/js/admin/view-logs.js', array( 'jquery-ui-datepicker' ), $email_log->get_version(), true );
225
+
226
+ wp_enqueue_script( 'jquery-ui', $plugin_dir_url . 'assets/vendor/jquery-ui/jquery-ui.min.js', array( 'jquery' ), '1.12.1' );
227
+ wp_enqueue_script( 'insertionQ', $plugin_dir_url . 'assets/vendor/insertionQuery/insQ.min.js', array( 'jquery' ), '1.0.4' );
228
+ }
229
+ }
include/Core/UI/Page/SettingsPage.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\Page;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * Settings Page.
7
+ * This page is displayed only if any add-on has a setting enabled.
8
+ *
9
+ * @since 2.0.0
10
+ */
11
+ class SettingsPage extends BasePage {
12
+
13
+ /**
14
+ * Page slug.
15
+ */
16
+ const PAGE_SLUG = 'email-log-settings';
17
+
18
+ /**
19
+ * Specify additional hooks.
20
+ *
21
+ * @inheritdoc
22
+ */
23
+ public function load() {
24
+ parent::load();
25
+
26
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
27
+ }
28
+
29
+ /**
30
+ * Register settings and add setting sections and fields.
31
+ */
32
+ public function register_settings() {
33
+ $sections = $this->get_setting_sections();
34
+
35
+ foreach ( $sections as $section ) {
36
+ register_setting(
37
+ self::PAGE_SLUG,
38
+ $section->option_name,
39
+ array( 'sanitize_callback' => $section->sanitize_callback )
40
+ );
41
+
42
+ add_settings_section(
43
+ $section->id,
44
+ $section->title,
45
+ $section->callback,
46
+ self::PAGE_SLUG
47
+ );
48
+
49
+ foreach ( $section->fields as $field ) {
50
+ add_settings_field(
51
+ $section->id . '[' . $field->id . ']',
52
+ $field->title,
53
+ $field->callback,
54
+ self::PAGE_SLUG,
55
+ $section->id,
56
+ $field->args
57
+ );
58
+ }
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Get a list of setting sections defined.
64
+ * An add-on can define a setting section.
65
+ *
66
+ * @return \EmailLog\Core\UI\Setting\SettingSection[] List of defined setting sections.
67
+ */
68
+ protected function get_setting_sections() {
69
+ /**
70
+ * Specify the list of setting sections in the settings page.
71
+ * An add-on can add its own setting section by adding an instance of
72
+ * SectionSection to the array.
73
+ *
74
+ * @since 2.0.0
75
+ * @param \EmailLog\Core\UI\Setting\SettingSection[] List of SettingSections.
76
+ */
77
+ return apply_filters( 'el_setting_sections', array() );
78
+ }
79
+
80
+ /**
81
+ * Register page.
82
+ */
83
+ public function register_page() {
84
+
85
+ $sections = $this->get_setting_sections();
86
+
87
+ if ( empty( $sections ) ) {
88
+ return;
89
+ }
90
+
91
+ $this->page = add_submenu_page(
92
+ LogListPage::PAGE_SLUG,
93
+ __( 'Settings', 'email-log' ),
94
+ __( 'Settings', 'email-log' ),
95
+ 'manage_options',
96
+ self::PAGE_SLUG,
97
+ array( $this, 'render_page' )
98
+ );
99
+
100
+ add_action( "load-{$this->page}", array( $this, 'render_help_tab' ) );
101
+ }
102
+
103
+ /**
104
+ * Render the page.
105
+ * //TODO: Convert these sections into tabs.
106
+ */
107
+ public function render_page() {
108
+ ?>
109
+ <div class="wrap">
110
+ <h1><?php _e( 'Email Log Settings', 'email-log' ); ?></h1>
111
+
112
+ <form method="post" action="options.php">
113
+ <?php
114
+ settings_errors();
115
+ settings_fields( self::PAGE_SLUG );
116
+ do_settings_sections( self::PAGE_SLUG );
117
+
118
+ submit_button( __( 'Save', 'email-log' ) );
119
+ ?>
120
+ </form>
121
+
122
+ </div>
123
+ <?php
124
+
125
+ $this->render_page_footer();
126
+ }
127
+ }
include/Core/UI/Setting/Setting.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\Setting;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * Email Log Setting.
7
+ * Contains a setting section and a number of fields.
8
+ *
9
+ * @since 2.0.0
10
+ */
11
+ abstract class Setting {
12
+
13
+ /**
14
+ * @var \EmailLog\Core\UI\Setting\SettingSection
15
+ */
16
+ protected $section;
17
+
18
+ /**
19
+ * Set default values for SettingSection.
20
+ * Further customization can be done by the add-on in the `initialize` method.
21
+ */
22
+ public function __construct() {
23
+ $this->section = new SettingSection();
24
+ $this->section->fields = $this->get_fields();
25
+ $this->section->callback = array( $this, 'render' );
26
+ $this->section->sanitize_callback = array( $this, 'sanitize' );
27
+
28
+ $this->initialize();
29
+ }
30
+
31
+ /**
32
+ * Setup hooks and filters.
33
+ */
34
+ public function load() {
35
+ add_filter( 'el_setting_sections', array( $this, 'register' ) );
36
+ }
37
+
38
+ /**
39
+ * Register the setting using the filter.
40
+ *
41
+ * @param SettingSection[] $sections List of existing SettingSections.
42
+ *
43
+ * @return SettingSection[] Modified list of SettingSections.
44
+ */
45
+ public function register( $sections ) {
46
+ $sections[] = $this->section;
47
+
48
+ return $sections;
49
+ }
50
+
51
+ /**
52
+ * Get the value stored in the option.
53
+ *
54
+ * @return mixed Stored value.
55
+ */
56
+ public function get_value() {
57
+ return get_option( $this->section->option_name );
58
+ }
59
+
60
+ /**
61
+ * Customize the SettingSection.
62
+ *
63
+ * @return void
64
+ */
65
+ abstract protected function initialize();
66
+
67
+ /**
68
+ * Get the list of SettingFields.
69
+ *
70
+ * @return SettingField[] List of fields for the Setting.
71
+ */
72
+ abstract protected function get_fields();
73
+
74
+ /**
75
+ * Render the Settings.
76
+ *
77
+ * @return void
78
+ */
79
+ abstract public function render();
80
+
81
+ /**
82
+ * Sanitize the option values.
83
+ *
84
+ * @param mixed $values User entered values.
85
+ *
86
+ * @return mixed Sanitized values.
87
+ */
88
+ abstract public function sanitize( $values );
89
+ }
include/Core/UI/Setting/SettingField.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\Setting;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * A setting field used in Email Log Settings page.
7
+ *
8
+ * @see add_settings_field()
9
+ */
10
+ class SettingField {
11
+
12
+ public $id;
13
+ public $title;
14
+ public $callback;
15
+ public $args = array();
16
+ }
include/Core/UI/Setting/SettingSection.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI\Setting;
2
+
3
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
+
5
+ /**
6
+ * A Section used in Email Log Settings page.
7
+ * Ideally each add-on may have a different setting section.
8
+ *
9
+ * @see add_settings_section()
10
+ */
11
+ class SettingSection {
12
+
13
+ public $id;
14
+ public $title;
15
+ public $callback;
16
+
17
+ /**
18
+ * Each section will have a single option name and the value will be array.
19
+ * All individual fields will be stored as an element in the value array.
20
+ *
21
+ * @var string
22
+ */
23
+ public $option_name;
24
+
25
+ /**
26
+ * Sanitize callback for the setting.
27
+ * An array will be passed to this callback.
28
+ *
29
+ * @var callable
30
+ */
31
+ public $sanitize_callback;
32
+
33
+ /**
34
+ * List of fields for this section.
35
+ *
36
+ * @var SettingField[]
37
+ */
38
+ public $fields = array();
39
+
40
+ /**
41
+ * Add a field to the section.
42
+ *
43
+ * @param \EmailLog\Core\UI\Setting\SettingField $field Field to add.
44
+ */
45
+ public function add_field( SettingField $field ) {
46
+ $this->fields[] = $field;
47
+ }
48
+ }
include/Core/UI/UILoader.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Core\UI;
2
+
3
+ use EmailLog\Core\Loadie;
4
+
5
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
6
+
7
+ /**
8
+ * Admin UI Loader.
9
+ * Loads and initializes all admin pages and components.
10
+ *
11
+ * @since 2.0
12
+ */
13
+ class UILoader implements Loadie {
14
+
15
+ /**
16
+ * UI Component List.
17
+ *
18
+ * @var array
19
+ */
20
+ protected $components = array();
21
+
22
+ /**
23
+ * List of Admin pages.
24
+ *
25
+ * @var \EmailLog\Core\UI\Page\BasePage[]
26
+ */
27
+ protected $pages = array();
28
+
29
+ /**
30
+ * Load all components and setup hooks.
31
+ *
32
+ * @inheritdoc
33
+ */
34
+ public function load() {
35
+ $this->initialize_components();
36
+ $this->initialize_pages();
37
+
38
+ foreach ( $this->components as $component ) {
39
+ $component->load();
40
+ }
41
+
42
+ foreach ( $this->pages as $page ) {
43
+ $page->load();
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Initialize UI component Objects.
49
+ *
50
+ * This method may be overwritten in tests.
51
+ *
52
+ * @access protected
53
+ */
54
+ protected function initialize_components() {
55
+ $this->components['admin_ui_enhancer'] = new Component\AdminUIEnhancer();
56
+ }
57
+
58
+ /**
59
+ * Initialize Admin page Objects.
60
+ *
61
+ * This method may be overwritten in tests.
62
+ *
63
+ * @access protected
64
+ */
65
+ protected function initialize_pages() {
66
+ $this->pages['log_list_page'] = new Page\LogListPage();
67
+ $this->pages['addon_list_page'] = new Page\AddonListPage();
68
+ $this->pages['settings_page'] = new Page\SettingsPage();
69
+ }
70
+ }
include/EmailLogAutoloader.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog;
2
+
3
+ /**
4
+ * Autoloader for EmailLog, based on the PSR-4 general purpose implemetation.
5
+ *
6
+ * @see http://www.php-fig.org/psr/psr-4/
7
+ *
8
+ * This differs from WordPress coding standard in the following ways.
9
+ *
10
+ * - Class name and directory names use Snake case.
11
+ * - Use of namespaces.
12
+ *
13
+ * Given a foo-bar package of classes in the file system at the following
14
+ * paths ...
15
+ *
16
+ * /path/to/packages/foo-bar/
17
+ * src/
18
+ * Baz.php # Foo\Bar\Baz
19
+ * Qux/
20
+ * Quux.php # Foo\Bar\Qux\Quux
21
+ * tests/
22
+ * BazTest.php # Foo\Bar\BazTest
23
+ * Qux/
24
+ * QuuxTest.php # Foo\Bar\Qux\QuuxTest
25
+ *
26
+ * ... add the path to the class files for the \Foo\Bar\ namespace prefix
27
+ * as follows:
28
+ *
29
+ * <?php
30
+ * // instantiate the loader
31
+ * $loader = new \EmailLog\EmailLogAutoloader;
32
+ *
33
+ * // register the autoloader
34
+ * $loader->register();
35
+ *
36
+ * // register the base directories for the namespace prefix
37
+ * $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
38
+ * $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
39
+ *
40
+ * The following line would cause the autoloader to attempt to load the
41
+ * \Foo\Bar\Qux\Quux class from /path/to/packages/foo-bar/src/Qux/Quux.php:
42
+ *
43
+ * <?php
44
+ * new \Foo\Bar\Qux\Quux;
45
+ *
46
+ * The following line would cause the autoloader to attempt to load the
47
+ * \Foo\Bar\Qux\QuuxTest class from /path/to/packages/foo-bar/tests/Qux/QuuxTest.php:
48
+ *
49
+ * <?php
50
+ * new \Foo\Bar\Qux\QuuxTest;
51
+ *
52
+ * @since 2.0
53
+ */
54
+ class EmailLogAutoloader {
55
+ /**
56
+ * An associative array where the key is a namespace prefix and the value
57
+ * is an array of base directories for classes in that namespace.
58
+ *
59
+ * @var array
60
+ */
61
+ protected $prefixes = array();
62
+
63
+ /**
64
+ * An associative array containing the list files that needs to be autoloaded.
65
+ *
66
+ * @var array
67
+ */
68
+ protected $files = array();
69
+
70
+ /**
71
+ * Register loader with SPL autoloader stack.
72
+ *
73
+ * @return void
74
+ */
75
+ public function register() {
76
+ spl_autoload_register( array( $this, 'load_class' ) );
77
+
78
+ // file exists check is already done in `add_file`.
79
+ foreach ( $this->files as $file ) {
80
+ $this->require_file( $file );
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Adds a base directory for a namespace prefix.
86
+ *
87
+ * @param string $prefix The namespace prefix.
88
+ * @param string $base_dir A base directory for class files in the
89
+ * namespace.
90
+ * @param bool $prepend If true, prepend the base directory to the stack
91
+ * instead of appending it; this causes it to be searched first rather
92
+ * than last.
93
+ *
94
+ * @return void
95
+ */
96
+ public function add_namespace( $prefix, $base_dir, $prepend = false ) {
97
+ // normalize namespace prefix
98
+ $prefix = trim( $prefix, '\\' ) . '\\';
99
+
100
+ // normalize the base directory with a trailing separator
101
+ $base_dir = rtrim( $base_dir, DIRECTORY_SEPARATOR ) . '/';
102
+
103
+ // initialize the namespace prefix array
104
+ if ( false === isset( $this->prefixes[ $prefix ] ) ) {
105
+ $this->prefixes[ $prefix ] = array();
106
+ }
107
+
108
+ // retain the base directory for the namespace prefix
109
+ if ( $prepend ) {
110
+ array_unshift( $this->prefixes[ $prefix ], $base_dir );
111
+ } else {
112
+ array_push( $this->prefixes[ $prefix ], $base_dir );
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Add a file to be autoloaded.
118
+ *
119
+ * @param string $filename File to be autoloaded.
120
+ */
121
+ public function add_file( $filename ) {
122
+ if ( ! in_array( $filename, $this->files, true ) ) {
123
+ $this->files[] = $filename;
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Loads the class file for a given class name.
129
+ *
130
+ * @param string $class The fully-qualified class name.
131
+ *
132
+ * @return string|false The mapped file name on success, or boolean false on
133
+ * failure.
134
+ */
135
+ public function load_class( $class ) {
136
+ // the current namespace prefix
137
+ $prefix = $class;
138
+
139
+ // work backwards through the namespace names of the fully-qualified
140
+ // class name to find a mapped file name
141
+ while ( false !== $pos = strrpos( $prefix, '\\' ) ) {
142
+
143
+ // retain the trailing namespace separator in the prefix
144
+ $prefix = substr( $class, 0, $pos + 1 );
145
+
146
+ // the rest is the relative class name
147
+ $relative_class = substr( $class, $pos + 1 );
148
+
149
+ // try to load a mapped file for the prefix and relative class
150
+ $mapped_file = $this->load_mapped_file( $prefix, $relative_class );
151
+ if ( $mapped_file !== false ) {
152
+ return $mapped_file;
153
+ }
154
+
155
+ // remove the trailing namespace separator for the next iteration
156
+ // of strrpos()
157
+ $prefix = rtrim( $prefix, '\\' );
158
+ }
159
+
160
+ // never found a mapped file
161
+ return false;
162
+ }
163
+
164
+ /**
165
+ * Load the mapped file for a namespace prefix and relative class.
166
+ *
167
+ * @param string $prefix The namespace prefix.
168
+ * @param string $relative_class The relative class name.
169
+ *
170
+ * @return false|string Boolean false if no mapped file can be loaded, or the
171
+ * name of the mapped file that was loaded.
172
+ */
173
+ protected function load_mapped_file( $prefix, $relative_class ) {
174
+ // are there any base directories for this namespace prefix?
175
+ if ( false === isset( $this->prefixes[ $prefix ] ) ) {
176
+ return false;
177
+ }
178
+
179
+ // look through base directories for this namespace prefix
180
+ foreach ( $this->prefixes[ $prefix ] as $base_dir ) {
181
+
182
+ // replace the namespace prefix with the base directory,
183
+ // replace namespace separators with directory separators
184
+ // in the relative class name, append with .php
185
+ $file = $base_dir
186
+ . str_replace( '\\', '/', $relative_class )
187
+ . '.php';
188
+
189
+ // if the mapped file exists, require it
190
+ if ( $this->require_file( $file ) ) {
191
+ // yes, we're done
192
+ return $file;
193
+ }
194
+ }
195
+
196
+ // never found it
197
+ return false;
198
+ }
199
+
200
+ /**
201
+ * If a file exists, require it from the file system.
202
+ *
203
+ * @param string $file The file to require.
204
+ *
205
+ * @return bool True if the file exists, false if not.
206
+ */
207
+ protected function require_file( $file ) {
208
+ if ( file_exists( $file ) ) {
209
+ require_once $file;
210
+
211
+ return true;
212
+ }
213
+
214
+ return false;
215
+ }
216
+ }
include/compatibility/EmailLog.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class was present in versions before 2.0.
4
+ * This class is now included so that older add-ons don't generate a fatal error
5
+ * till they are deactivated by the plugin.
6
+ */
7
+
8
+ /**
9
+ * Stub of the original EmailLog class.
10
+ * This is now included so that older add-ons don't generate a fatal error.
11
+ *
12
+ * @deprecated 2.0
13
+ */
14
+ class EmailLog {
15
+ const HOOK_LOG_COLUMNS = '';
16
+ const HOOK_LOG_DISPLAY_COLUMNS = '';
17
+ const FILTER_NAME = '';
18
+ }
include/libraries/EDD_SL_Plugin_Updater.php ADDED
@@ -0,0 +1,477 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly
4
+ if ( ! defined( 'ABSPATH' ) ) exit;
5
+
6
+ /**
7
+ * Allows plugins to use their own update API.
8
+ *
9
+ * @author Easy Digital Downloads
10
+ * @version 1.6.12
11
+ */
12
+ class EDD_SL_Plugin_Updater {
13
+
14
+ private $api_url = '';
15
+ private $api_data = array();
16
+ private $name = '';
17
+ private $slug = '';
18
+ private $version = '';
19
+ private $wp_override = false;
20
+ private $cache_key = '';
21
+
22
+ /**
23
+ * Class constructor.
24
+ *
25
+ * @uses plugin_basename()
26
+ * @uses hook()
27
+ *
28
+ * @param string $_api_url The URL pointing to the custom API endpoint.
29
+ * @param string $_plugin_file Path to the plugin file.
30
+ * @param array $_api_data Optional data to send with API calls.
31
+ */
32
+ public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
33
+
34
+ global $edd_plugin_data;
35
+
36
+ $this->api_url = trailingslashit( $_api_url );
37
+ $this->api_data = $_api_data;
38
+ $this->name = plugin_basename( $_plugin_file );
39
+ $this->slug = basename( $_plugin_file, '.php' );
40
+ $this->version = $_api_data['version'];
41
+ $this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
42
+ $this->beta = ! empty( $this->api_data['beta'] ) ? true : false;
43
+ $this->cache_key = md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );
44
+
45
+ $edd_plugin_data[ $this->slug ] = $this->api_data;
46
+
47
+ // Set up hooks.
48
+ $this->init();
49
+
50
+ }
51
+
52
+ /**
53
+ * Set up WordPress filters to hook into WP's update process.
54
+ *
55
+ * @uses add_filter()
56
+ *
57
+ * @return void
58
+ */
59
+ public function init() {
60
+
61
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
62
+ add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
63
+ remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10 );
64
+ add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
65
+ add_action( 'admin_init', array( $this, 'show_changelog' ) );
66
+
67
+ }
68
+
69
+ /**
70
+ * Check for Updates at the defined API endpoint and modify the update array.
71
+ *
72
+ * This function dives into the update API just when WordPress creates its update array,
73
+ * then adds a custom API call and injects the custom plugin data retrieved from the API.
74
+ * It is reassembled from parts of the native WordPress plugin update code.
75
+ * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
76
+ *
77
+ * @uses api_request()
78
+ *
79
+ * @param array $_transient_data Update array build by WordPress.
80
+ * @return array Modified update array with custom plugin data.
81
+ */
82
+ public function check_update( $_transient_data ) {
83
+
84
+ global $pagenow;
85
+
86
+ if ( ! is_object( $_transient_data ) ) {
87
+ $_transient_data = new stdClass;
88
+ }
89
+
90
+ if ( 'plugins.php' == $pagenow && is_multisite() ) {
91
+ return $_transient_data;
92
+ }
93
+
94
+ if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) {
95
+ return $_transient_data;
96
+ }
97
+
98
+ $version_info = $this->get_cached_version_info();
99
+
100
+ if ( false === $version_info ) {
101
+ $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
102
+
103
+ $this->set_version_info_cache( $version_info );
104
+
105
+ }
106
+
107
+ if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
108
+
109
+ if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
110
+
111
+ $_transient_data->response[ $this->name ] = $version_info;
112
+
113
+ }
114
+
115
+ $_transient_data->last_checked = current_time( 'timestamp' );
116
+ $_transient_data->checked[ $this->name ] = $this->version;
117
+
118
+ }
119
+
120
+ return $_transient_data;
121
+ }
122
+
123
+ /**
124
+ * show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
125
+ *
126
+ * @param string $file
127
+ * @param array $plugin
128
+ */
129
+ public function show_update_notification( $file, $plugin ) {
130
+
131
+ if ( is_network_admin() ) {
132
+ return;
133
+ }
134
+
135
+ if( ! current_user_can( 'update_plugins' ) ) {
136
+ return;
137
+ }
138
+
139
+ if( ! is_multisite() ) {
140
+ return;
141
+ }
142
+
143
+ if ( $this->name != $file ) {
144
+ return;
145
+ }
146
+
147
+ // Remove our filter on the site transient
148
+ remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
149
+
150
+ $update_cache = get_site_transient( 'update_plugins' );
151
+
152
+ $update_cache = is_object( $update_cache ) ? $update_cache : new stdClass();
153
+
154
+ if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
155
+
156
+ $version_info = $this->get_cached_version_info();
157
+
158
+ if ( false === $version_info ) {
159
+ $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
160
+
161
+ $this->set_version_info_cache( $version_info );
162
+ }
163
+
164
+ if ( ! is_object( $version_info ) ) {
165
+ return;
166
+ }
167
+
168
+ if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
169
+
170
+ $update_cache->response[ $this->name ] = $version_info;
171
+
172
+ }
173
+
174
+ $update_cache->last_checked = current_time( 'timestamp' );
175
+ $update_cache->checked[ $this->name ] = $this->version;
176
+
177
+ set_site_transient( 'update_plugins', $update_cache );
178
+
179
+ } else {
180
+
181
+ $version_info = $update_cache->response[ $this->name ];
182
+
183
+ }
184
+
185
+ // Restore our filter
186
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
187
+
188
+ if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
189
+
190
+ // build a plugin list row, with update notification
191
+ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
192
+ # <tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange">
193
+ echo '<tr class="plugin-update-tr" id="' . $this->slug . '-update" data-slug="' . $this->slug . '" data-plugin="' . $this->slug . '/' . $file . '">';
194
+ echo '<td colspan="3" class="plugin-update colspanchange">';
195
+ echo '<div class="update-message notice inline notice-warning notice-alt">';
196
+
197
+ $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
198
+
199
+ if ( empty( $version_info->download_link ) ) {
200
+ printf(
201
+ __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'easy-digital-downloads' ),
202
+ esc_html( $version_info->name ),
203
+ '<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
204
+ esc_html( $version_info->new_version ),
205
+ '</a>'
206
+ );
207
+ } else {
208
+ printf(
209
+ __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s.', 'easy-digital-downloads' ),
210
+ esc_html( $version_info->name ),
211
+ '<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
212
+ esc_html( $version_info->new_version ),
213
+ '</a>',
214
+ '<a href="' . esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) ) .'">',
215
+ '</a>'
216
+ );
217
+ }
218
+
219
+ do_action( "in_plugin_update_message-{$file}", $plugin, $version_info );
220
+
221
+ echo '</div></td></tr>';
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Updates information on the "View version x.x details" page with custom data.
227
+ *
228
+ * @uses api_request()
229
+ *
230
+ * @param mixed $_data
231
+ * @param string $_action
232
+ * @param object $_args
233
+ * @return object $_data
234
+ */
235
+ public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
236
+
237
+ if ( $_action != 'plugin_information' ) {
238
+
239
+ return $_data;
240
+
241
+ }
242
+
243
+ if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {
244
+
245
+ return $_data;
246
+
247
+ }
248
+
249
+ $to_send = array(
250
+ 'slug' => $this->slug,
251
+ 'is_ssl' => is_ssl(),
252
+ 'fields' => array(
253
+ 'banners' => array(),
254
+ 'reviews' => false
255
+ )
256
+ );
257
+
258
+ $cache_key = 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );
259
+
260
+ // Get the transient where we store the api request for this plugin for 24 hours
261
+ $edd_api_request_transient = $this->get_cached_version_info( $cache_key );
262
+
263
+ //If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
264
+ if ( empty( $edd_api_request_transient ) ) {
265
+
266
+ $api_response = $this->api_request( 'plugin_information', $to_send );
267
+
268
+ // Expires in 3 hours
269
+ $this->set_version_info_cache( $api_response, $cache_key );
270
+
271
+ if ( false !== $api_response ) {
272
+ $_data = $api_response;
273
+ }
274
+
275
+ } else {
276
+ $_data = $edd_api_request_transient;
277
+ }
278
+
279
+ // Convert sections into an associative array, since we're getting an object, but Core expects an array.
280
+ if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
281
+ $new_sections = array();
282
+ foreach ( $_data->sections as $key => $value ) {
283
+ $new_sections[ $key ] = $value;
284
+ }
285
+
286
+ $_data->sections = $new_sections;
287
+ }
288
+
289
+ // Convert banners into an associative array, since we're getting an object, but Core expects an array.
290
+ if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
291
+ $new_banners = array();
292
+ foreach ( $_data->banners as $key => $value ) {
293
+ $new_banners[ $key ] = $value;
294
+ }
295
+
296
+ $_data->banners = $new_banners;
297
+ }
298
+
299
+ return $_data;
300
+ }
301
+
302
+ /**
303
+ * Disable SSL verification in order to prevent download update failures
304
+ *
305
+ * @param array $args
306
+ * @param string $url
307
+ * @return object $array
308
+ */
309
+ public function http_request_args( $args, $url ) {
310
+ // If it is an https request and we are performing a package download, disable ssl verification
311
+ if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
312
+ $args['sslverify'] = false;
313
+ }
314
+ return $args;
315
+ }
316
+
317
+ /**
318
+ * Calls the API and, if successfull, returns the object delivered by the API.
319
+ *
320
+ * @uses get_bloginfo()
321
+ * @uses wp_remote_post()
322
+ * @uses is_wp_error()
323
+ *
324
+ * @param string $_action The requested action.
325
+ * @param array $_data Parameters for the API action.
326
+ * @return false|object
327
+ */
328
+ private function api_request( $_action, $_data ) {
329
+
330
+ global $wp_version;
331
+
332
+ $data = array_merge( $this->api_data, $_data );
333
+
334
+ if ( $data['slug'] != $this->slug ) {
335
+ return;
336
+ }
337
+
338
+ if( $this->api_url == trailingslashit (home_url() ) ) {
339
+ return false; // Don't allow a plugin to ping itself
340
+ }
341
+
342
+ $api_params = array(
343
+ 'edd_action' => 'get_version',
344
+ 'license' => ! empty( $data['license'] ) ? $data['license'] : '',
345
+ 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
346
+ 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
347
+ 'version' => isset( $data['version'] ) ? $data['version'] : false,
348
+ 'slug' => $data['slug'],
349
+ 'author' => $data['author'],
350
+ 'url' => home_url(),
351
+ 'beta' => ! empty( $data['beta'] ),
352
+ );
353
+
354
+ $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
355
+
356
+ if ( ! is_wp_error( $request ) ) {
357
+ $request = json_decode( wp_remote_retrieve_body( $request ) );
358
+ }
359
+
360
+ if ( $request && isset( $request->sections ) ) {
361
+ $request->sections = maybe_unserialize( $request->sections );
362
+ } else {
363
+ $request = false;
364
+ }
365
+
366
+ if ( $request && isset( $request->banners ) ) {
367
+ $request->banners = maybe_unserialize( $request->banners );
368
+ }
369
+
370
+ if( ! empty( $request->sections ) ) {
371
+ foreach( $request->sections as $key => $section ) {
372
+ $request->$key = (array) $section;
373
+ }
374
+ }
375
+
376
+ return $request;
377
+ }
378
+
379
+ public function show_changelog() {
380
+
381
+ global $edd_plugin_data;
382
+
383
+ if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
384
+ return;
385
+ }
386
+
387
+ if( empty( $_REQUEST['plugin'] ) ) {
388
+ return;
389
+ }
390
+
391
+ if( empty( $_REQUEST['slug'] ) ) {
392
+ return;
393
+ }
394
+
395
+ if( ! current_user_can( 'update_plugins' ) ) {
396
+ wp_die( __( 'You do not have permission to install plugin updates', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
397
+ }
398
+
399
+ $data = $edd_plugin_data[ $_REQUEST['slug'] ];
400
+ $beta = ! empty( $data['beta'] ) ? true : false;
401
+ $cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $beta . '_version_info' );
402
+ $version_info = $this->get_cached_version_info( $cache_key );
403
+
404
+ if( false === $version_info ) {
405
+
406
+ $api_params = array(
407
+ 'edd_action' => 'get_version',
408
+ 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
409
+ 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
410
+ 'slug' => $_REQUEST['slug'],
411
+ 'author' => $data['author'],
412
+ 'url' => home_url(),
413
+ 'beta' => ! empty( $data['beta'] )
414
+ );
415
+
416
+ $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
417
+
418
+ if ( ! is_wp_error( $request ) ) {
419
+ $version_info = json_decode( wp_remote_retrieve_body( $request ) );
420
+ }
421
+
422
+
423
+ if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
424
+ $version_info->sections = maybe_unserialize( $version_info->sections );
425
+ } else {
426
+ $version_info = false;
427
+ }
428
+
429
+ if( ! empty( $version_info ) ) {
430
+ foreach( $version_info->sections as $key => $section ) {
431
+ $version_info->$key = (array) $section;
432
+ }
433
+ }
434
+
435
+ $this->set_version_info_cache( $version_info, $cache_key );
436
+
437
+ }
438
+
439
+ if( ! empty( $version_info ) && isset( $version_info->sections['changelog'] ) ) {
440
+ echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>';
441
+ }
442
+
443
+ exit;
444
+ }
445
+
446
+ public function get_cached_version_info( $cache_key = '' ) {
447
+
448
+ if( empty( $cache_key ) ) {
449
+ $cache_key = $this->cache_key;
450
+ }
451
+
452
+ $cache = get_option( $cache_key );
453
+
454
+ if( empty( $cache['timeout'] ) || current_time( 'timestamp' ) > $cache['timeout'] ) {
455
+ return false; // Cache is expired
456
+ }
457
+
458
+ return json_decode( $cache['value'] );
459
+
460
+ }
461
+
462
+ public function set_version_info_cache( $value = '', $cache_key = '' ) {
463
+
464
+ if( empty( $cache_key ) ) {
465
+ $cache_key = $this->cache_key;
466
+ }
467
+
468
+ $data = array(
469
+ 'timeout' => strtotime( '+3 hours', current_time( 'timestamp' ) ),
470
+ 'value' => json_encode( $value )
471
+ );
472
+
473
+ update_option( $cache_key, $data );
474
+
475
+ }
476
+
477
+ }
include/util/EmailHeaderParser.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php namespace EmailLog\Util;
2
+
3
+ /**
4
+ * Email Header Parser.
5
+ *
6
+ * @author Sudar
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit; // Exit if accessed directly
10
+
11
+ /**
12
+ * Class Email Header Parser.
13
+ *
14
+ * @since 1.0
15
+ */
16
+ class EmailHeaderParser {
17
+
18
+ /**
19
+ * Join email headers.
20
+ *
21
+ * @since 1.0
22
+ *
23
+ * @param array $data Headers to be joined.
24
+ *
25
+ * @return string Joined headers.
26
+ */
27
+ public function join_headers( $data ) {
28
+ $headers = '';
29
+
30
+ if ( ! empty( $data['from'] ) ) {
31
+ $headers .= 'From: ' . $data['from'] . "\r\n";
32
+ }
33
+
34
+ if ( ! empty( $data['cc'] ) ) {
35
+ $headers .= 'CC: ' . $data['cc'] . "\r\n";
36
+ }
37
+
38
+ if ( ! empty( $data['bcc'] ) ) {
39
+ $headers .= 'BCC: ' . $data['bcc'] . "\r\n";
40
+ }
41
+
42
+ if ( ! empty( $data['reply_to'] ) ) {
43
+ $headers .= 'Reply-to: ' . $data['reply_to'] . "\r\n";
44
+ }
45
+
46
+ if ( ! empty( $data['content_type'] ) ) {
47
+ $headers .= 'Content-type: ' . $data['content_type'] . "\r\n";
48
+ }
49
+
50
+ return $headers;
51
+ }
52
+
53
+ /**
54
+ * Return parsed headers.
55
+ *
56
+ * @param string $headers Headers to parse.
57
+ *
58
+ * @return array Parsed Headers.
59
+ */
60
+ public function parse_headers( $headers ) {
61
+ return $this->parse( $headers );
62
+ }
63
+
64
+ /**
65
+ * Parse Headers.
66
+ *
67
+ * @access private
68
+ *
69
+ * @param string $headers Headers to be parsed.
70
+ *
71
+ * @return array Parsed headers.
72
+ */
73
+ private function parse( $headers ) {
74
+ $data = array();
75
+ $arr_headers = explode( "\n", $headers );
76
+
77
+ foreach ( $arr_headers as $header ) {
78
+ $split_header = explode( ':', $header );
79
+ $value = $this->parse_header_line( $split_header );
80
+
81
+ if ( trim( $value ) != '' ) {
82
+ switch ( strtolower( $split_header[0] ) ) {
83
+ case 'from':
84
+ $data['from'] = $value;
85
+ break;
86
+
87
+ case 'cc':
88
+ $data['cc'] = $value;
89
+ break;
90
+
91
+ case 'bcc':
92
+ $data['bcc'] = $value;
93
+ break;
94
+
95
+ case 'reply-to':
96
+ $data['reply_to'] = $value;
97
+ break;
98
+
99
+ case 'content-type':
100
+ $data['content_type'] = $value;
101
+ break;
102
+ }
103
+ }
104
+ }
105
+
106
+ return $data;
107
+ }
108
+
109
+ /**
110
+ * Parse individual header line.
111
+ *
112
+ * @since 1.0
113
+ * @access private
114
+ *
115
+ * @param array $header Header line to be parsed.
116
+ *
117
+ * @return string Parsed value.
118
+ */
119
+ private function parse_header_line( $header ) {
120
+ $value = '';
121
+ if ( 2 == count( $header ) ) {
122
+ if ( is_array( $header[1] ) ) {
123
+ $value = trim( implode( ',', array_map( 'trim', $header[1] ) ) );
124
+ } else {
125
+ $value = trim( $header[1] );
126
+ }
127
+ }
128
+
129
+ return $value;
130
+ }
131
+ }
include/util/helper.php CHANGED
@@ -1,4 +1,5 @@
1
- <?php
 
2
  /**
3
  * Email Log Helper functions.
4
  * Some of these functions would be used the addons.
@@ -14,13 +15,13 @@
14
  *
15
  * @return string Sanitized email.
16
  */
17
- function el_sanitize_email( $email, $multiple = true ) {
18
  $emails = explode( ',', $email );
19
  if ( ! $multiple ) {
20
  $emails = array_slice( $emails, 0, 1 );
21
  }
22
 
23
- $cleaned_emails = array_map( 'el_sanitize_email_with_name', $emails );
24
 
25
  return implode( ', ', $cleaned_emails );
26
  }
@@ -30,15 +31,15 @@ function el_sanitize_email( $email, $multiple = true ) {
30
  *
31
  * @since 1.9
32
  *
33
- * @param $string $email Email string to be sanitized.
34
  *
35
- * @return string Sanitized email.
36
  */
37
- function el_sanitize_email_with_name( $string ) {
38
  $string = trim( $string );
39
 
40
  $bracket_pos = strpos( $string, '<' );
41
- if ( $bracket_pos !== false ) {
42
  // Text before the bracketed email is the name.
43
  if ( $bracket_pos > 0 ) {
44
  $name = substr( $string, 0, $bracket_pos );
@@ -48,9 +49,27 @@ function el_sanitize_email_with_name( $string ) {
48
  $email = substr( $string, $bracket_pos + 1 );
49
  $email = str_replace( '>', '', $email );
50
 
51
- return sanitize_text_field( $name ) . ' <' . sanitize_email( $email ) . '>';
52
  }
53
  }
54
 
55
- return sanitize_email( $string );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  }
1
+ <?php namespace EmailLog\Util;
2
+
3
  /**
4
  * Email Log Helper functions.
5
  * Some of these functions would be used the addons.
15
  *
16
  * @return string Sanitized email.
17
  */
18
+ function sanitize_email( $email, $multiple = true ) {
19
  $emails = explode( ',', $email );
20
  if ( ! $multiple ) {
21
  $emails = array_slice( $emails, 0, 1 );
22
  }
23
 
24
+ $cleaned_emails = array_map( __NAMESPACE__ . '\\sanitize_email_with_name', $emails );
25
 
26
  return implode( ', ', $cleaned_emails );
27
  }
31
  *
32
  * @since 1.9
33
  *
34
+ * @param string $string Email string to be sanitized.
35
  *
36
+ * @return string Sanitized email.
37
  */
38
+ function sanitize_email_with_name( $string ) {
39
  $string = trim( $string );
40
 
41
  $bracket_pos = strpos( $string, '<' );
42
+ if ( false !== $bracket_pos ) {
43
  // Text before the bracketed email is the name.
44
  if ( $bracket_pos > 0 ) {
45
  $name = substr( $string, 0, $bracket_pos );
49
  $email = substr( $string, $bracket_pos + 1 );
50
  $email = str_replace( '>', '', $email );
51
 
52
+ return sanitize_text_field( $name ) . ' <' . \sanitize_email( $email ) . '>';
53
  }
54
  }
55
 
56
+ return \sanitize_email( $string );
57
+ }
58
+
59
+ /**
60
+ * Gets the columns to export logs.
61
+ *
62
+ * If the More Fields add-on is active, additional columns are returned.
63
+ *
64
+ * @since 2.0.0
65
+ *
66
+ * @return array List of Columns to export.
67
+ */
68
+ function get_log_columns_to_export() {
69
+
70
+ if ( is_plugin_active( 'email-log-more-fields/email-log-more-fields.php' ) ) {
71
+ return array( 'id', 'sent_date', 'to_email', 'subject', 'from', 'cc', 'bcc', 'reply-to', 'attachment' );
72
+ }
73
+
74
+ return array( 'id', 'sent_date', 'to_email', 'subject' );
75
  }
languages/email-log.pot CHANGED
@@ -1,285 +1,808 @@
1
- # Copyright (C) 2016 Email Log
2
  # This file is distributed under the same license as the Email Log package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Email Log 1.9.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/email-log\n"
7
- "POT-Creation-Date: 2016-07-02 02:04:52+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2016-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
- #: dist/email-log.php:168 email-log.php:168
16
- msgid "Buy Addons"
 
 
17
  msgstr ""
18
 
19
- #. #-#-#-#-# email-log.pot (Email Log 1.9.1) #-#-#-#-#
20
- #. Plugin Name of the plugin/theme
21
- #: dist/email-log.php:181 email-log.php:181
22
- msgid "Email Log"
23
  msgstr ""
24
 
25
- #: dist/email-log.php:197 email-log.php:197
26
- msgid "Email Logs"
 
 
27
  msgstr ""
28
 
29
- #: dist/email-log.php:203 email-log.php:203
30
- msgid "1 email log deleted."
31
- msgid_plural "%s email logs deleted"
32
- msgstr[0] ""
33
- msgstr[1] ""
34
-
35
- #: dist/email-log.php:205 email-log.php:205
36
- msgid "There was some problem in deleting the email logs"
37
  msgstr ""
38
 
39
- #: dist/email-log.php:213 email-log.php:213
40
- msgid "Search Logs"
 
41
  msgstr ""
42
 
43
- #: dist/email-log.php:255 email-log.php:255
44
- #: tmp_addon/email-log-forward-email.php:152
45
- msgid "About Plugin"
46
  msgstr ""
47
 
48
- #: dist/email-log.php:257 email-log.php:257
49
- #: tmp_addon/email-log-forward-email.php:154
50
- msgid ""
51
- "Email Log WordPress Plugin, allows you to log all emails that are sent "
52
- "through WordPress."
53
  msgstr ""
54
 
55
- #: dist/email-log.php:264 email-log.php:264
56
- #: tmp_addon/email-log-forward-email.php:162
57
- msgid "More information"
58
  msgstr ""
59
 
60
- #: dist/email-log.php:265 email-log.php:265
61
- #: tmp_addon/email-log-forward-email.php:163
62
- msgid "Plugin Homepage/support"
63
  msgstr ""
64
 
65
- #: dist/email-log.php:266 email-log.php:266
66
- #: tmp_addon/email-log-forward-email.php:164
67
- msgid "Plugin author's blog"
68
  msgstr ""
69
 
70
- #: dist/email-log.php:267 email-log.php:267
71
- #: tmp_addon/email-log-forward-email.php:165
72
- msgid "Other Plugin's by Author"
73
  msgstr ""
74
 
75
- #: dist/email-log.php:274 email-log.php:274
76
- msgid "Entries per page"
 
77
  msgstr ""
78
 
79
- #: dist/email-log.php:359 email-log.php:361
80
- msgid "Log"
 
81
  msgstr ""
82
 
83
- #: dist/email-log.php:374 email-log.php:376
84
- msgid "plugin"
 
85
  msgstr ""
86
 
87
- #: dist/email-log.php:374 email-log.php:376
88
- msgid "Version"
89
  msgstr ""
90
 
91
- #: dist/email-log.php:374 email-log.php:376
92
- msgid "by"
93
  msgstr ""
94
 
95
- #: dist/include/class-email-log-list-table.php:36
96
- #: include/class-email-log-list-table.php:36
97
- msgid "More fields are available in Pro addon. "
98
  msgstr ""
99
 
100
- #: dist/include/class-email-log-list-table.php:38
101
- #: include/class-email-log-list-table.php:38
102
- msgid "Buy Now"
 
103
  msgstr ""
104
 
105
- #: dist/include/class-email-log-list-table.php:49
106
- #: include/class-email-log-list-table.php:49
107
  msgid ""
108
- "The following are the list of pro addons that are currently available for "
109
- "purchase."
 
 
 
 
 
 
 
 
 
 
110
  msgstr ""
111
 
112
- #: dist/include/class-email-log-list-table.php:55
113
- #: include/class-email-log-list-table.php:55
114
- msgid "Email Log - Resend Email"
115
  msgstr ""
116
 
117
- #: dist/include/class-email-log-list-table.php:56
118
- #: include/class-email-log-list-table.php:56
119
- msgid "Adds the ability to resend email from logs."
120
  msgstr ""
121
 
122
- #: dist/include/class-email-log-list-table.php:57
123
- #: dist/include/class-email-log-list-table.php:64
124
- #: dist/include/class-email-log-list-table.php:71
125
- #: include/class-email-log-list-table.php:57
126
- #: include/class-email-log-list-table.php:64
127
- #: include/class-email-log-list-table.php:71
128
- msgid "More Info"
129
  msgstr ""
130
 
131
- #: dist/include/class-email-log-list-table.php:58
132
- #: dist/include/class-email-log-list-table.php:65
133
- #: dist/include/class-email-log-list-table.php:72
134
- #: include/class-email-log-list-table.php:58
135
- #: include/class-email-log-list-table.php:65
136
- #: include/class-email-log-list-table.php:72
137
- msgid "Buy now"
138
  msgstr ""
139
 
140
- #: dist/include/class-email-log-list-table.php:62
141
- #: include/class-email-log-list-table.php:62
142
- msgid "Email Log - More fields"
143
  msgstr ""
144
 
145
- #: dist/include/class-email-log-list-table.php:63
146
- #: include/class-email-log-list-table.php:63
 
 
 
 
 
 
 
 
 
 
 
 
147
  msgid ""
148
- "Adds more fields (From, CC, BCC, Reply To, Attachment) to the logs page."
 
149
  msgstr ""
150
 
151
- #: dist/include/class-email-log-list-table.php:69
152
- #: include/class-email-log-list-table.php:69
153
- msgid "Email Log - Forward Email"
 
 
154
  msgstr ""
155
 
156
- #: dist/include/class-email-log-list-table.php:70
157
- #: include/class-email-log-list-table.php:70
158
  msgid ""
159
- "This addon allows you to send a copy of all emails send from WordPress to "
160
- "another email address"
161
  msgstr ""
162
 
163
- #: dist/include/class-email-log-list-table.php:89
164
- #: include/class-email-log-list-table.php:89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  msgid "Sent at"
166
  msgstr ""
167
 
168
- #: dist/include/class-email-log-list-table.php:90
169
- #: include/class-email-log-list-table.php:90
170
- #: tmp_addon/email-log-forward-email.php:180
 
 
171
  msgid "To"
172
  msgstr ""
173
 
174
- #: dist/include/class-email-log-list-table.php:91
175
- #: include/class-email-log-list-table.php:91
 
 
176
  msgid "Subject"
177
  msgstr ""
178
 
179
- #: dist/include/class-email-log-list-table.php:135
180
- #: include/class-email-log-list-table.php:135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  msgid "%s @ %s"
182
  msgstr ""
183
 
184
- #: dist/include/class-email-log-list-table.php:154
185
- #: include/class-email-log-list-table.php:154
186
  msgid "Email Content"
187
  msgstr ""
188
 
189
- #: dist/include/class-email-log-list-table.php:155
190
- #: include/class-email-log-list-table.php:155
191
  msgid "View Content"
192
  msgstr ""
193
 
194
- #: dist/include/class-email-log-list-table.php:169
195
- #: dist/include/class-email-log-list-table.php:238
196
- #: include/class-email-log-list-table.php:169
197
- #: include/class-email-log-list-table.php:238
198
  msgid "Delete"
199
  msgstr ""
200
 
201
- #: dist/include/class-email-log-list-table.php:239
202
- #: include/class-email-log-list-table.php:239
203
  msgid "Delete All Logs"
204
  msgstr ""
205
 
206
- #: dist/include/class-email-log-list-table.php:348
207
- #: include/class-email-log-list-table.php:348
208
  msgid "Your email log is empty"
209
  msgstr ""
210
 
211
- #: tmp_addon/email-log-forward-email.php:105
212
- #: tmp_addon/email-log-forward-email.php:117
213
- msgid "Forward Email"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  msgstr ""
215
 
216
- #: tmp_addon/email-log-forward-email.php:105
217
- msgid "Email Log - Forward Email Addon"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  msgstr ""
219
 
220
- #: tmp_addon/email-log-forward-email.php:127
221
- msgid "Forward Emails"
222
  msgstr ""
223
 
224
- #: tmp_addon/email-log-forward-email.php:181
225
- #: tmp_addon/email-log-more-fields.php:81
226
- #: tmp_addon/email-log-resend-email.php:51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  msgid "CC"
228
  msgstr ""
229
 
230
- #: tmp_addon/email-log-forward-email.php:182
231
- #: tmp_addon/email-log-more-fields.php:82
232
- #: tmp_addon/email-log-resend-email.php:55
233
  msgid "BCC"
234
  msgstr ""
235
 
236
- #: tmp_addon/email-log-forward-email.php:225
237
- #: tmp_addon/email-log-forward-email.php:236
238
- #: tmp_addon/email-log-forward-email.php:247
239
- msgid "Enter multiple email address by separating them using comma"
240
  msgstr ""
241
 
242
- #: tmp_addon/email-log-more-fields.php:80
243
- #: tmp_addon/email-log-resend-email.php:46
244
  msgid "From"
245
  msgstr ""
246
 
247
- #: tmp_addon/email-log-more-fields.php:83
248
- #: tmp_addon/email-log-resend-email.php:60
249
  msgid "Reply To"
250
  msgstr ""
251
 
252
- #: tmp_addon/email-log-more-fields.php:84
253
  msgid "Attachment"
254
  msgstr ""
255
 
256
- #: tmp_addon/email-log-resend-email.php:27
 
 
 
 
257
  msgid "Email Details"
258
  msgstr ""
259
 
260
- #: tmp_addon/email-log-resend-email.php:43
261
  msgid "Additional Details"
262
  msgstr ""
263
 
264
- #: tmp_addon/email-log-resend-email.php:65
265
  msgid "Content Type"
266
  msgstr ""
267
 
268
- #: tmp_addon/email-log-resend-email.php:70
269
- #: tmp_addon/email-log-resend-email.php:92
270
- msgid "Resend Email"
271
- msgstr ""
272
-
273
- #: tmp_addon/email-log-resend-email.php:195
274
  msgid "Email was successfully resent"
275
  msgstr ""
276
 
277
- #: tmp_addon/email-log-resend-email.php:197
278
  msgid "There was some problem in sending the email"
279
  msgstr ""
280
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  #. Plugin URI of the plugin/theme
282
- msgid "http://sudarmuthu.com/wordpress/email-log"
283
  msgstr ""
284
 
285
  #. Description of the plugin/theme
1
+ # Copyright (C) 2017 Email Log
2
  # This file is distributed under the same license as the Email Log package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Email Log 2.0.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/email-log\n"
7
+ "POT-Creation-Date: 2017-08-04 07:08:26+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #: dist/email-log.php:50 email-log.php:50
16
+ msgid ""
17
+ "Email Log requires at least PHP 5.3 to function properly. Please upgrade PHP "
18
+ "or use <a href=\"%s\">v1.9.1 of Email Log</a>."
19
  msgstr ""
20
 
21
+ #: dist/include/Addon/API/EDDAPI.php:114 include/Addon/API/EDDAPI.php:114
22
+ msgid ""
23
+ "Unknown error occurred while trying to contact Email Log store. Please try "
24
+ "again after sometime. If the problem persists contact support."
25
  msgstr ""
26
 
27
+ #: dist/include/Addon/API/EDDAPI.php:121 include/Addon/API/EDDAPI.php:121
28
+ msgid ""
29
+ "Unable to parse the response Email Log store response. Please try again "
30
+ "after sometime. If the problem persists contact support."
31
  msgstr ""
32
 
33
+ #: dist/include/Addon/Addon.php:127 include/Addon/Addon.php:127
34
+ msgctxt "Installed on website but not activated"
35
+ msgid "Installed"
 
 
 
 
 
36
  msgstr ""
37
 
38
+ #: dist/include/Addon/Addon.php:130 include/Addon/Addon.php:130
39
+ msgctxt "Installed and activated on website"
40
+ msgid "Activated"
41
  msgstr ""
42
 
43
+ #: dist/include/Addon/Addon.php:132 include/Addon/Addon.php:132
44
+ msgctxt "Enable addon so it may be used"
45
+ msgid "Activate"
46
  msgstr ""
47
 
48
+ #: dist/include/Addon/Addon.php:135 include/Addon/Addon.php:135
49
+ msgctxt "Download and activate addon"
50
+ msgid "Install"
 
 
51
  msgstr ""
52
 
53
+ #: dist/include/Addon/Addon.php:138 include/Addon/Addon.php:138
54
+ msgctxt "Download to your computer"
55
+ msgid "Download"
56
  msgstr ""
57
 
58
+ #: dist/include/Addon/Addon.php:147 include/Addon/Addon.php:147
59
+ msgctxt "Download and activate addon"
60
+ msgid "Activate License to Install"
61
  msgstr ""
62
 
63
+ #: dist/include/Addon/Addon.php:150 include/Addon/Addon.php:150
64
+ msgctxt "Download and activate addon"
65
+ msgid "Activate License to Use"
66
  msgstr ""
67
 
68
+ #: dist/include/Addon/Addon.php:155 include/Addon/Addon.php:155
69
+ msgid "You need an active license to install the add-on"
 
70
  msgstr ""
71
 
72
+ #: dist/include/Addon/Addon.php:165 dist/include/Addon/License/Licenser.php:103
73
+ #: include/Addon/Addon.php:165 include/Addon/License/Licenser.php:103
74
+ msgid "Activate"
75
  msgstr ""
76
 
77
+ #: dist/include/Addon/Addon.php:173 dist/include/Addon/License/Licenser.php:109
78
+ #: include/Addon/Addon.php:173 include/Addon/License/Licenser.php:109
79
+ msgid "Deactivate"
80
  msgstr ""
81
 
82
+ #: dist/include/Addon/Addon.php:179 dist/include/Addon/License/Licenser.php:112
83
+ #: include/Addon/Addon.php:179 include/Addon/License/Licenser.php:112
84
+ msgid "Your license expires on %s"
85
  msgstr ""
86
 
87
+ #: dist/include/Addon/Addon.php:184 include/Addon/Addon.php:184
88
+ msgid "Individual add-on license"
89
  msgstr ""
90
 
91
+ #: dist/include/Addon/Addon.php:189 include/Addon/Addon.php:189
92
+ msgid "Email Log License Key"
93
  msgstr ""
94
 
95
+ #: dist/include/Addon/Addon.php:190 include/Addon/Addon.php:190
96
+ msgid "%s Add-on License Key"
 
97
  msgstr ""
98
 
99
+ #: dist/include/Addon/AddonList.php:174 include/Addon/AddonList.php:174
100
+ msgid ""
101
+ "We are not able to retrieve the add-on list now. Please visit the <a href="
102
+ "\"%s\">add-on page</a> to view the add-ons."
103
  msgstr ""
104
 
105
+ #: dist/include/Addon/DependencyEnforcer.php:46
106
+ #: include/Addon/DependencyEnforcer.php:46
107
  msgid ""
108
+ "The following add-ons are not compatible with the installed version of Email "
109
+ "Log and have been deactivated."
110
+ msgstr ""
111
+
112
+ #: dist/include/Addon/DependencyEnforcer.php:54
113
+ #: include/Addon/DependencyEnforcer.php:54
114
+ msgid "Please get the latest version of these add-ons from add-on store."
115
+ msgstr ""
116
+
117
+ #: dist/include/Addon/License/BaseLicense.php:122
118
+ #: include/Addon/License/BaseLicense.php:122
119
+ msgid "Your license key expired on %s."
120
  msgstr ""
121
 
122
+ #: dist/include/Addon/License/BaseLicense.php:128
123
+ #: include/Addon/License/BaseLicense.php:128
124
+ msgid "Your license key has been disabled."
125
  msgstr ""
126
 
127
+ #: dist/include/Addon/License/BaseLicense.php:132
128
+ #: include/Addon/License/BaseLicense.php:132
129
+ msgid "Your license key is invalid."
130
  msgstr ""
131
 
132
+ #: dist/include/Addon/License/BaseLicense.php:137
133
+ #: include/Addon/License/BaseLicense.php:137
134
+ msgid "Your license is not active for this URL."
 
 
 
 
135
  msgstr ""
136
 
137
+ #: dist/include/Addon/License/BaseLicense.php:141
138
+ #: include/Addon/License/BaseLicense.php:141
139
+ msgid "Your license key is not valid for %s."
 
 
 
 
140
  msgstr ""
141
 
142
+ #: dist/include/Addon/License/BaseLicense.php:145
143
+ #: include/Addon/License/BaseLicense.php:145
144
+ msgid "Your license key has reached its activation limit."
145
  msgstr ""
146
 
147
+ #: dist/include/Addon/License/BaseLicense.php:149
148
+ #: dist/include/Addon/License/BaseLicense.php:171
149
+ #: include/Addon/License/BaseLicense.php:149
150
+ #: include/Addon/License/BaseLicense.php:171
151
+ msgid "An error occurred, please try again."
152
+ msgstr ""
153
+
154
+ #: dist/include/Addon/License/BaseLicense.php:194
155
+ #: include/Addon/License/BaseLicense.php:194
156
+ msgid "An error occurred, please try again"
157
+ msgstr ""
158
+
159
+ #: dist/include/Addon/License/Licenser.php:121
160
+ #: include/Addon/License/Licenser.php:121
161
  msgid ""
162
+ "Enter your license key to activate add-ons. If you don't have a license, "
163
+ "then you can <a href='%s' target='_blank'>buy it</a>"
164
  msgstr ""
165
 
166
+ #: dist/include/Addon/License/Licenser.php:130
167
+ #: dist/include/Addon/License/Licenser.php:131
168
+ #: include/Addon/License/Licenser.php:130
169
+ #: include/Addon/License/Licenser.php:131
170
+ msgid "Email Log Bundle License Key"
171
  msgstr ""
172
 
173
+ #: dist/include/Addon/License/Licenser.php:159
174
+ #: include/Addon/License/Licenser.php:159
175
  msgid ""
176
+ "Your license has been activated. You can now install add-ons, will receive "
177
+ "automatic updates and access to email support."
178
  msgstr ""
179
 
180
+ #: dist/include/Addon/License/Licenser.php:175
181
+ #: include/Addon/License/Licenser.php:175
182
+ msgid ""
183
+ "Your license has been deactivated. You will not receive automatic updates."
184
+ msgstr ""
185
+
186
+ #: dist/include/Addon/License/Licenser.php:218
187
+ #: include/Addon/License/Licenser.php:218
188
+ msgid ""
189
+ "Your license for %s has been activated. You will receive automatic updates "
190
+ "and access to email support."
191
+ msgstr ""
192
+
193
+ #: dist/include/Addon/License/Licenser.php:245
194
+ #: include/Addon/License/Licenser.php:245
195
+ msgid ""
196
+ "Your license for %s has been deactivated. You will not receive automatic "
197
+ "updates."
198
+ msgstr ""
199
+
200
+ #: dist/include/Core/Request/LogListAction.php:54
201
+ #: dist/include/Core/UI/ListTable/LogListTable.php:67
202
+ #: include/Core/Request/LogListAction.php:54
203
+ #: include/Core/UI/ListTable/LogListTable.php:67
204
  msgid "Sent at"
205
  msgstr ""
206
 
207
+ #: dist/include/Core/Request/LogListAction.php:58
208
+ #: dist/include/Core/UI/ListTable/LogListTable.php:68
209
+ #: include/Core/Request/LogListAction.php:58
210
+ #: include/Core/UI/ListTable/LogListTable.php:68
211
+ #: tmp_addon/ForwardEmailSetting.php:32
212
  msgid "To"
213
  msgstr ""
214
 
215
+ #: dist/include/Core/Request/LogListAction.php:62
216
+ #: dist/include/Core/UI/ListTable/LogListTable.php:69
217
+ #: include/Core/Request/LogListAction.php:62
218
+ #: include/Core/UI/ListTable/LogListTable.php:69
219
  msgid "Subject"
220
  msgstr ""
221
 
222
+ #: dist/include/Core/Request/LogListAction.php:82
223
+ #: include/Core/Request/LogListAction.php:82
224
+ msgid "HTML"
225
+ msgstr ""
226
+
227
+ #: dist/include/Core/Request/LogListAction.php:83
228
+ #: include/Core/Request/LogListAction.php:83
229
+ msgid "Text"
230
+ msgstr ""
231
+
232
+ #: dist/include/Core/Request/LogListAction.php:94
233
+ #: include/Core/Request/LogListAction.php:94
234
+ msgid "Close"
235
+ msgstr ""
236
+
237
+ #: dist/include/Core/Request/LogListAction.php:140
238
+ #: include/Core/Request/LogListAction.php:140
239
+ msgid "There was some problem in deleting the email logs"
240
+ msgstr ""
241
+
242
+ #: dist/include/Core/Request/LogListAction.php:144
243
+ #: include/Core/Request/LogListAction.php:144
244
+ msgid "1 email log deleted."
245
+ msgid_plural "%s email logs deleted"
246
+ msgstr[0] ""
247
+ msgstr[1] ""
248
+
249
+ #: dist/include/Core/UI/Component/AdminUIEnhancer.php:69
250
+ #: include/Core/UI/Component/AdminUIEnhancer.php:69
251
+ msgid "Buy Addons"
252
+ msgstr ""
253
+
254
+ #: dist/include/Core/UI/Component/AdminUIEnhancer.php:83
255
+ #: dist/include/Core/UI/Page/LogListPage.php:61
256
+ #: dist/include/Core/UI/Page/LogListPage.php:62
257
+ #: include/Core/UI/Component/AdminUIEnhancer.php:83
258
+ #: include/Core/UI/Page/LogListPage.php:61
259
+ #: include/Core/UI/Page/LogListPage.php:62
260
+ msgid "View Logs"
261
+ msgstr ""
262
+
263
+ #: dist/include/Core/UI/Component/AdminUIEnhancer.php:107
264
+ #: include/Core/UI/Component/AdminUIEnhancer.php:107
265
+ msgid "plugin"
266
+ msgstr ""
267
+
268
+ #: dist/include/Core/UI/Component/AdminUIEnhancer.php:107
269
+ #: include/Core/UI/Component/AdminUIEnhancer.php:107
270
+ msgid "Version"
271
+ msgstr ""
272
+
273
+ #: dist/include/Core/UI/Component/AdminUIEnhancer.php:107
274
+ #: include/Core/UI/Component/AdminUIEnhancer.php:107
275
+ msgid "by"
276
+ msgstr ""
277
+
278
+ #: dist/include/Core/UI/ListTable/LogListTable.php:49
279
+ #: include/Core/UI/ListTable/LogListTable.php:49
280
+ msgid "Additional fields are available in Pro add-on. "
281
+ msgstr ""
282
+
283
+ #: dist/include/Core/UI/ListTable/LogListTable.php:51
284
+ #: include/Core/UI/ListTable/LogListTable.php:51
285
+ msgid "Buy Now"
286
+ msgstr ""
287
+
288
+ #: dist/include/Core/UI/ListTable/LogListTable.php:128
289
+ #: include/Core/UI/ListTable/LogListTable.php:128
290
  msgid "%s @ %s"
291
  msgstr ""
292
 
293
+ #: dist/include/Core/UI/ListTable/LogListTable.php:146
294
+ #: include/Core/UI/ListTable/LogListTable.php:146
295
  msgid "Email Content"
296
  msgstr ""
297
 
298
+ #: dist/include/Core/UI/ListTable/LogListTable.php:147
299
+ #: include/Core/UI/ListTable/LogListTable.php:147
300
  msgid "View Content"
301
  msgstr ""
302
 
303
+ #: dist/include/Core/UI/ListTable/LogListTable.php:161
304
+ #: dist/include/Core/UI/ListTable/LogListTable.php:230
305
+ #: include/Core/UI/ListTable/LogListTable.php:161
306
+ #: include/Core/UI/ListTable/LogListTable.php:230
307
  msgid "Delete"
308
  msgstr ""
309
 
310
+ #: dist/include/Core/UI/ListTable/LogListTable.php:231
311
+ #: include/Core/UI/ListTable/LogListTable.php:231
312
  msgid "Delete All Logs"
313
  msgstr ""
314
 
315
+ #: dist/include/Core/UI/ListTable/LogListTable.php:263
316
+ #: include/Core/UI/ListTable/LogListTable.php:263
317
  msgid "Your email log is empty"
318
  msgstr ""
319
 
320
+ #: dist/include/Core/UI/ListTable/LogListTable.php:291
321
+ #: include/Core/UI/ListTable/LogListTable.php:291
322
+ msgid "Search by date"
323
+ msgstr ""
324
+
325
+ #: dist/include/Core/UI/ListTable/LogListTable.php:292
326
+ #: include/Core/UI/ListTable/LogListTable.php:292
327
+ msgid "Search by term"
328
+ msgstr ""
329
+
330
+ #: dist/include/Core/UI/Page/AddonListPage.php:23
331
+ #: dist/include/Core/UI/Page/AddonListPage.php:24
332
+ #: dist/include/Core/UI/Page/BasePage.php:78
333
+ #: include/Core/UI/Page/AddonListPage.php:23
334
+ #: include/Core/UI/Page/AddonListPage.php:24
335
+ #: include/Core/UI/Page/BasePage.php:78
336
+ msgid "Add-ons"
337
+ msgstr ""
338
+
339
+ #: dist/include/Core/UI/Page/AddonListPage.php:40
340
+ #: include/Core/UI/Page/AddonListPage.php:40
341
+ msgid "Email Log Add-ons"
342
+ msgstr ""
343
+
344
+ #: dist/include/Core/UI/Page/AddonListPage.php:44
345
+ #: include/Core/UI/Page/AddonListPage.php:44
346
+ msgid ""
347
+ "These add-ons provide additional functionality to Email Log plugin and are "
348
+ "available for purchase."
349
+ msgstr ""
350
+
351
+ #: dist/include/Core/UI/Page/AddonListPage.php:45
352
+ #: include/Core/UI/Page/AddonListPage.php:45
353
+ msgid ""
354
+ "If your license includes the add-ons below, you will be able to install them "
355
+ "from here with one-click."
356
+ msgstr ""
357
+
358
+ #: dist/include/Core/UI/Page/BasePage.php:49
359
+ #: include/Core/UI/Page/BasePage.php:49
360
+ msgid ""
361
+ "Email Log is a WordPress plugin that allows you to easily log and view all "
362
+ "emails sent from WordPress."
363
+ msgstr ""
364
+
365
+ #: dist/include/Core/UI/Page/BasePage.php:52
366
+ #: include/Core/UI/Page/BasePage.php:52
367
+ msgid "You can view the logged emails from the View Logs screen. "
368
+ msgstr ""
369
+
370
+ #: dist/include/Core/UI/Page/BasePage.php:54
371
+ #: include/Core/UI/Page/BasePage.php:54
372
+ msgid ""
373
+ "Check the <a href=\"%s\">documentation about the View Logs screen</a> for "
374
+ "more details."
375
+ msgstr ""
376
+
377
+ #: dist/include/Core/UI/Page/BasePage.php:60
378
+ #: include/Core/UI/Page/BasePage.php:60
379
+ msgid ""
380
+ "You can perform advanced actions like re-sending email, automatically "
381
+ "forwarding emails or export logs with our <a href=\"%s\">premium plugins</a>."
382
+ msgstr ""
383
+
384
+ #: dist/include/Core/UI/Page/BasePage.php:67
385
+ #: include/Core/UI/Page/BasePage.php:67
386
+ msgid "About Plugin"
387
+ msgstr ""
388
+
389
+ #: dist/include/Core/UI/Page/BasePage.php:75
390
+ #: include/Core/UI/Page/BasePage.php:75
391
+ msgid "More information"
392
+ msgstr ""
393
+
394
+ #: dist/include/Core/UI/Page/BasePage.php:76
395
+ #: include/Core/UI/Page/BasePage.php:76
396
+ msgid "Documentation"
397
+ msgstr ""
398
+
399
+ #: dist/include/Core/UI/Page/BasePage.php:77
400
+ #: include/Core/UI/Page/BasePage.php:77
401
+ msgid "Support"
402
+ msgstr ""
403
+
404
+ #. #-#-#-#-# email-log.pot (Email Log 2.0.0) #-#-#-#-#
405
+ #. Plugin Name of the plugin/theme
406
+ #: dist/include/Core/UI/Page/LogListPage.php:50
407
+ #: dist/include/Core/UI/Page/LogListPage.php:51
408
+ #: include/Core/UI/Page/LogListPage.php:50
409
+ #: include/Core/UI/Page/LogListPage.php:51
410
+ msgid "Email Log"
411
+ msgstr ""
412
+
413
+ #: dist/include/Core/UI/Page/LogListPage.php:89
414
+ #: include/Core/UI/Page/LogListPage.php:89
415
+ msgid "Email Logs"
416
+ msgstr ""
417
+
418
+ #: dist/include/Core/UI/Page/LogListPage.php:94
419
+ #: include/Core/UI/Page/LogListPage.php:94
420
+ msgid "Search Logs"
421
+ msgstr ""
422
+
423
+ #: dist/include/Core/UI/Page/LogListPage.php:119
424
+ #: include/Core/UI/Page/LogListPage.php:119
425
+ msgid "Entries per page"
426
+ msgstr ""
427
+
428
+ #: dist/include/Core/UI/Page/SettingsPage.php:93
429
+ #: dist/include/Core/UI/Page/SettingsPage.php:94
430
+ #: include/Core/UI/Page/SettingsPage.php:93
431
+ #: include/Core/UI/Page/SettingsPage.php:94
432
+ msgid "Settings"
433
+ msgstr ""
434
+
435
+ #: dist/include/Core/UI/Page/SettingsPage.php:110
436
+ #: include/Core/UI/Page/SettingsPage.php:110
437
+ msgid "Email Log Settings"
438
+ msgstr ""
439
+
440
+ #: dist/include/Core/UI/Page/SettingsPage.php:118
441
+ #: include/Core/UI/Page/SettingsPage.php:118
442
+ msgid "Save"
443
+ msgstr ""
444
+
445
+ #: dist/include/libraries/EDD_SL_Plugin_Updater.php:201
446
+ #: include/libraries/EDD_SL_Plugin_Updater.php:201
447
+ msgid ""
448
+ "There is a new version of %1$s available. %2$sView version %3$s details%4$s."
449
+ msgstr ""
450
+
451
+ #: dist/include/libraries/EDD_SL_Plugin_Updater.php:209
452
+ #: include/libraries/EDD_SL_Plugin_Updater.php:209
453
+ msgid ""
454
+ "There is a new version of %1$s available. %2$sView version %3$s details%4$s "
455
+ "or %5$supdate now%6$s."
456
+ msgstr ""
457
+
458
+ #: dist/include/libraries/EDD_SL_Plugin_Updater.php:396
459
+ #: include/libraries/EDD_SL_Plugin_Updater.php:396
460
+ msgid "You do not have permission to install plugin updates"
461
+ msgstr ""
462
+
463
+ #: dist/include/libraries/EDD_SL_Plugin_Updater.php:396
464
+ #: include/libraries/EDD_SL_Plugin_Updater.php:396
465
+ msgid "Error"
466
+ msgstr ""
467
+
468
+ #: tmp_addon/AutoDeleteLogsSetting.php:15
469
+ msgid "Auto Delete Logs Add-on Settings"
470
  msgstr ""
471
 
472
+ #: tmp_addon/AutoDeleteLogsSetting.php:24
473
+ msgid ""
474
+ "Auto Delete Logs allows you to automatically delete logs that are older than "
475
+ "specified interval (in days)."
476
+ msgstr ""
477
+
478
+ #: tmp_addon/AutoDeleteLogsSetting.php:25
479
+ msgid "Specify the interval beyond which the logs are to be auto deleted."
480
+ msgstr ""
481
+
482
+ #: tmp_addon/AutoDeleteLogsSetting.php:34
483
+ msgid "Interval"
484
+ msgstr ""
485
+
486
+ #: tmp_addon/AutoDeleteLogsSetting.php:58
487
+ msgid "Specify the interval in days."
488
+ msgstr ""
489
+
490
+ #: tmp_addon/EmailLogAddonActivator.php:94
491
+ msgid "This plugin"
492
+ msgstr ""
493
+
494
+ #: tmp_addon/EmailLogAddonActivator.php:144
495
+ msgid ""
496
+ "requires at least PHP %1$s or above! You are currently using PHP %2$s, which "
497
+ "is very old. Please contact your web host and upgrade PHP."
498
+ msgstr ""
499
+
500
+ #: tmp_addon/EmailLogAddonActivator.php:157
501
+ msgid "activate it"
502
+ msgstr ""
503
+
504
+ #: tmp_addon/EmailLogAddonActivator.php:160
505
+ msgid "install it"
506
+ msgstr ""
507
+
508
+ #: tmp_addon/EmailLogAddonActivator.php:165
509
+ msgid "requires Email Log! Please %s to continue!"
510
  msgstr ""
511
 
512
+ #: tmp_addon/EmailLogAddonActivator.php:174
513
+ msgid "update it"
514
  msgstr ""
515
 
516
+ #: tmp_addon/EmailLogAddonActivator.php:178
517
+ msgid "requires Email Log version %s or above! Please %s to continue!"
518
+ msgstr ""
519
+
520
+ #: tmp_addon/ExportLogsAddon.php:50
521
+ msgid "Export"
522
+ msgstr ""
523
+
524
+ #: tmp_addon/ExportLogsAddon.php:51
525
+ msgid "Export All Logs"
526
+ msgstr ""
527
+
528
+ #: tmp_addon/ForwardEmailSetting.php:15
529
+ msgid "Forward Email Add-on Settings"
530
+ msgstr ""
531
+
532
+ #: tmp_addon/ForwardEmailSetting.php:22
533
+ msgid ""
534
+ "Forward Email add-on allows you to automatically send a copy of all emails "
535
+ "generated by WordPress to other email addresses."
536
+ msgstr ""
537
+
538
+ #: tmp_addon/ForwardEmailSetting.php:23
539
+ msgid ""
540
+ "Specify the list of email addresses to which the emails should be forwarded."
541
+ msgstr ""
542
+
543
+ #: tmp_addon/ForwardEmailSetting.php:33 tmp_addon/MoreFieldsAddon.php:46
544
+ #: tmp_addon/ResendEmailAddon.php:113
545
  msgid "CC"
546
  msgstr ""
547
 
548
+ #: tmp_addon/ForwardEmailSetting.php:34 tmp_addon/MoreFieldsAddon.php:47
549
+ #: tmp_addon/ResendEmailAddon.php:117
 
550
  msgid "BCC"
551
  msgstr ""
552
 
553
+ #: tmp_addon/ForwardEmailSetting.php:58
554
+ msgid "You can enter multiple email address by separating them with comma."
 
 
555
  msgstr ""
556
 
557
+ #: tmp_addon/MoreFieldsAddon.php:45 tmp_addon/ResendEmailAddon.php:109
 
558
  msgid "From"
559
  msgstr ""
560
 
561
+ #: tmp_addon/MoreFieldsAddon.php:48 tmp_addon/ResendEmailAddon.php:121
 
562
  msgid "Reply To"
563
  msgstr ""
564
 
565
+ #: tmp_addon/MoreFieldsAddon.php:49
566
  msgid "Attachment"
567
  msgstr ""
568
 
569
+ #: tmp_addon/ResendEmailAddon.php:48 tmp_addon/ResendEmailAddon.php:129
570
+ msgid "Resend Email"
571
+ msgstr ""
572
+
573
+ #: tmp_addon/ResendEmailAddon.php:90
574
  msgid "Email Details"
575
  msgstr ""
576
 
577
+ #: tmp_addon/ResendEmailAddon.php:106
578
  msgid "Additional Details"
579
  msgstr ""
580
 
581
+ #: tmp_addon/ResendEmailAddon.php:125
582
  msgid "Content Type"
583
  msgstr ""
584
 
585
+ #: tmp_addon/ResendEmailAddon.php:190
 
 
 
 
 
586
  msgid "Email was successfully resent"
587
  msgstr ""
588
 
589
+ #: tmp_addon/ResendEmailAddon.php:192
590
  msgid "There was some problem in sending the email"
591
  msgstr ""
592
 
593
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/parsers.php:42
594
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/parsers.php:72
595
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/parsers.php:80
596
+ msgid "There was an error when reading this WXR file"
597
+ msgstr ""
598
+
599
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/parsers.php:43
600
+ msgid ""
601
+ "Details are shown above. The importer will now try again with a different "
602
+ "parser..."
603
+ msgstr ""
604
+
605
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/parsers.php:84
606
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/parsers.php:89
607
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/parsers.php:279
608
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/parsers.php:468
609
+ msgid ""
610
+ "This does not appear to be a WXR file, missing/invalid WXR version number"
611
+ msgstr ""
612
+
613
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:134
614
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:143
615
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:194
616
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:198
617
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:207
618
+ msgid "Sorry, there has been an error."
619
+ msgstr ""
620
+
621
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:135
622
+ msgid "The file does not exist, please try again."
623
+ msgstr ""
624
+
625
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:178
626
+ msgid "All done."
627
+ msgstr ""
628
+
629
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:178
630
+ msgid "Have fun!"
631
+ msgstr ""
632
+
633
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:179
634
+ msgid "Remember to update the passwords and roles of imported users."
635
+ msgstr ""
636
+
637
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:199
638
+ msgid ""
639
+ "The export file could not be found at <code>%s</code>. It is likely that "
640
+ "this was caused by a permissions problem."
641
+ msgstr ""
642
+
643
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:215
644
+ msgid ""
645
+ "This WXR file (version %s) may not be supported by this version of the "
646
+ "importer. Please consider updating."
647
+ msgstr ""
648
+
649
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:240
650
+ msgid ""
651
+ "Failed to import author %s. Their posts will be attributed to the current "
652
+ "user."
653
+ msgstr ""
654
+
655
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:266
656
+ msgid "Assign Authors"
657
+ msgstr ""
658
+
659
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:267
660
+ msgid ""
661
+ "To make it easier for you to edit and save the imported content, you may "
662
+ "want to reassign the author of the imported item to an existing user of this "
663
+ "site. For example, you may want to import all the entries as <code>admin</"
664
+ "code>s entries."
665
+ msgstr ""
666
+
667
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:269
668
+ msgid ""
669
+ "If a new user is created by WordPress, a new password will be randomly "
670
+ "generated and the new user&#8217;s role will be set as %s. Manually changing "
671
+ "the new user&#8217;s details will be necessary."
672
+ msgstr ""
673
+
674
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:279
675
+ msgid "Import Attachments"
676
+ msgstr ""
677
+
678
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:282
679
+ msgid "Download and import file attachments"
680
+ msgstr ""
681
+
682
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:286
683
+ msgid "Submit"
684
+ msgstr ""
685
+
686
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:299
687
+ msgid "Import author:"
688
+ msgstr ""
689
+
690
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:310
691
+ msgid "or create new user with login name:"
692
+ msgstr ""
693
+
694
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:313
695
+ msgid "as a new user:"
696
+ msgstr ""
697
+
698
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:321
699
+ msgid "assign posts to an existing user:"
700
+ msgstr ""
701
+
702
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:323
703
+ msgid "or assign posts to an existing user:"
704
+ msgstr ""
705
+
706
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:324
707
+ msgid "- Select -"
708
+ msgstr ""
709
+
710
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:374
711
+ msgid ""
712
+ "Failed to create new user for %s. Their posts will be attributed to the "
713
+ "current user."
714
+ msgstr ""
715
+
716
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:425
717
+ msgid "Failed to import category %s"
718
+ msgstr ""
719
+
720
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:465
721
+ msgid "Failed to import post tag %s"
722
+ msgstr ""
723
+
724
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:511
725
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:652
726
+ msgid "Failed to import %s %s"
727
+ msgstr ""
728
+
729
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:537
730
+ msgid "Failed to import &#8220;%s&#8221;: Invalid post type %s"
731
+ msgstr ""
732
+
733
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:559
734
+ msgid "%s &#8220;%s&#8221; already exists."
735
+ msgstr ""
736
+
737
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:618
738
+ msgid "Failed to import %s &#8220;%s&#8221;"
739
+ msgstr ""
740
+
741
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:783
742
+ msgid "Menu item skipped due to missing menu slug"
743
+ msgstr ""
744
+
745
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:790
746
+ msgid "Menu item skipped due to invalid menu slug: %s"
747
+ msgstr ""
748
+
749
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:853
750
+ msgid "Fetching attachments is not enabled"
751
+ msgstr ""
752
+
753
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:866
754
+ msgid "Invalid file type"
755
+ msgstr ""
756
+
757
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:910
758
+ msgid "Remote server did not respond"
759
+ msgstr ""
760
+
761
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:916
762
+ msgid "Remote server returned error response %1$d %2$s"
763
+ msgstr ""
764
+
765
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:923
766
+ msgid "Remote file is incorrect size"
767
+ msgstr ""
768
+
769
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:928
770
+ msgid "Zero size file downloaded"
771
+ msgstr ""
772
+
773
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:934
774
+ msgid "Remote file is too large, limit is %s"
775
+ msgstr ""
776
+
777
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:1033
778
+ msgid "Import WordPress"
779
+ msgstr ""
780
+
781
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:1040
782
+ msgid ""
783
+ "A new version of this importer is available. Please update to version %s to "
784
+ "ensure compatibility with newer export files."
785
+ msgstr ""
786
+
787
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:1055
788
+ msgid ""
789
+ "Howdy! Upload your WordPress eXtended RSS (WXR) file and we&#8217;ll import "
790
+ "the posts, pages, comments, custom fields, categories, and tags into this "
791
+ "site."
792
+ msgstr ""
793
+
794
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:1056
795
+ msgid "Choose a WXR (.xml) file to upload, then click Upload file and import."
796
+ msgstr ""
797
+
798
+ #: vendor/lucatume/wp-browser/src/data/plugins/wordpress-importer/wordpress-importer.php:1130
799
+ msgid ""
800
+ "Import <strong>posts, pages, comments, custom fields, categories, and tags</"
801
+ "strong> from a WordPress export file."
802
+ msgstr ""
803
+
804
  #. Plugin URI of the plugin/theme
805
+ msgid "https://wpemaillog.com"
806
  msgstr ""
807
 
808
  #. Description of the plugin/theme
load-email-log.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Load Email Log plugin.
4
+ *
5
+ * We need this load code in a separate file since it requires namespace
6
+ * and using namespace in PHP 5.2 will generate a fatal error.
7
+ *
8
+ * @since 2.0
9
+ */
10
+
11
+ /**
12
+ * Load Email Log plugin.
13
+ *
14
+ * @since 2.0
15
+ *
16
+ * @param string $plugin_file Main plugin file.
17
+ */
18
+ function load_email_log( $plugin_file ) {
19
+ global $email_log;
20
+
21
+ $plugin_dir = plugin_dir_path( $plugin_file );
22
+
23
+ // setup autoloader.
24
+ require_once 'include/EmailLogAutoloader.php';
25
+
26
+ $loader = new \EmailLog\EmailLogAutoloader();
27
+ $loader->add_namespace( 'EmailLog', $plugin_dir . 'include' );
28
+
29
+ if ( file_exists( $plugin_dir . 'tests/' ) ) {
30
+ // if tests are present, then add them.
31
+ $loader->add_namespace( 'EmailLog', $plugin_dir . 'tests/wp-tests' );
32
+ }
33
+
34
+ $loader->add_file( $plugin_dir . 'include/Util/helper.php' );
35
+ $loader->add_file( $plugin_dir . 'include/Addon/addon-helper.php' );
36
+
37
+ $loader->register();
38
+
39
+ $email_log = new \EmailLog\Core\EmailLog( $plugin_file, $loader, new \EmailLog\Core\DB\TableManager() );
40
+
41
+ $email_log->set_licenser( new \EmailLog\Addon\License\Licenser() );
42
+
43
+ $email_log->add_loadie( new \EmailLog\Core\EmailLogger() );
44
+ $email_log->add_loadie( new \EmailLog\Core\UI\UILoader() );
45
+ $email_log->add_loadie( new \EmailLog\Addon\DependencyEnforcer() );
46
+
47
+ $email_log->add_loadie( new \EmailLog\Core\Request\NonceChecker() );
48
+ $email_log->add_loadie( new \EmailLog\Core\Request\LogListAction() );
49
+ $email_log->add_loadie( new \EmailLog\Core\Request\OverridePluginAPI() );
50
+
51
+ // `register_activation_hook` can't be called from inside any hook.
52
+ register_activation_hook( $plugin_file, array( $email_log->table_manager, 'on_activate' ) );
53
+
54
+ // Ideally the plugin should be loaded in a later event like `init` or `wp_loaded`.
55
+ // But some plugins like EDD are sending emails in `init` event itself,
56
+ // which won't be logged if the plugin is loaded in `wp_loaded` or `init`.
57
+ add_action( 'plugins_loaded', array( $email_log, 'load' ) );
58
+ }
59
+
60
+ /**
61
+ * Return the global instance of Email Log plugin.
62
+ * Eventually the EmailLog class might become singleton.
63
+ *
64
+ * @since 2.0
65
+ *
66
+ * @global \EmailLog\Core\EmailLog $email_log
67
+ * @return \EmailLog\Core\EmailLog
68
+ */
69
+ function email_log() {
70
+ global $email_log;
71
+
72
+ return $email_log;
73
+ }
readme.txt CHANGED
@@ -1,19 +1,23 @@
1
  === Email Log ===
2
  Contributors: sudar
3
- Tags: email, log, multisite
4
- Requires at least: 3.3
5
- Tested up to: 4.5.2
6
- Stable tag: 1.9.1
7
 
8
- Logs every email sent through WordPress. Works with WordPress Multisite as well
9
 
10
  == Description ==
11
 
12
- Logs every email sent through WordPress and provides a UI where you can view them.
 
 
 
13
 
14
  ### Viewing logged emails
15
 
16
- The logged emails will be stored in a separate table and can be viewed from the admin interface. While viewing the logs, the emails can be filtered or sorted based on the date, email, subject etc.
 
17
 
18
  ### Deleting logged emails
19
 
@@ -21,11 +25,14 @@ In the admin interface, all the logged emails can be delete in bulk or can also
21
 
22
  ### Resend email (Pro addon)
23
 
24
- You can [buy the Resend email pro addon](http://sudarmuthu.com/wordpress/email-log/pro-addons#resend-email-addon), which allows you to resend the email directly from the email log. The addon allows you to modify the different fields before resending the email. The cost of the addon is $15 and you can buy it through [paypal](http://sudarmuthu.com/out/buy-email-log-resend-email-addon).
 
 
25
 
26
  ### More Fields (Pro addon)
27
 
28
- You can [buy the More Fields pro addon](http://sudarmuthu.com/wordpress/email-log/pro-addons#more-fields-addon), which shows additional fields in the email log page. The following are the additional fields that are added by this addon.
 
29
 
30
  - From
31
  - CC
@@ -33,11 +40,12 @@ You can [buy the More Fields pro addon](http://sudarmuthu.com/wordpress/email-lo
33
  - Reply To
34
  - Attachment
35
 
36
- The cost of the addon is $15 and you can buy it through [paypal](http://sudarmuthu.com/out/buy-email-log-more-fields-addon).
37
-
38
  ### Forward email (Pro addon)
39
 
40
- You can [buy the Forward email pro addon](http://sudarmuthu.com/wordpress/email-log/pro-addons#forward-email-addon), which allows you to send a copy of all the emails send from WordPress, to another email address. The addon allows you to choose whether you want to forward through to, cc or bcc fields. This can be extremely useful when you want to debug by analyzing the emails that are sent from WordPress. The cost of the addon is $15 and you can buy it through [paypal](http://sudarmuthu.com/out/buy-email-log-forward-email-addon).
 
 
 
41
 
42
  ### Cleaning up db on uninstall
43
 
@@ -47,41 +55,16 @@ As [recommended by Ozh][1], the Plugin has an uninstall hook which will clean up
47
 
48
  ### Development
49
 
50
- The development of the Plugin happens over at [github](http://github.com/sudar/email-log). If you want to contribute to the Plugin, [fork the project at github](http://github.com/sudar/email-log) and send me a pull request.
 
51
 
52
  If you are not familiar with either git or Github then refer to this [guide to see how fork and send pull request](http://sudarmuthu.com/blog/contributing-to-project-hosted-in-github).
53
 
54
- If you are looking for ideas, then you can start with one of the following TODO items :)
55
-
56
- ### TODO for Future releases
57
-
58
- The following are the features that I am thinking of adding to the Plugin, when I get some free time. If you have any feature request or want to increase the priority of a particular feature, then let me know.
59
-
60
- - Add option to automatically delete the logs periodically
61
- - Add an option to export logs as csv file
62
- - <strike>Add the ability to resend the emails</strike>. Done in Resend Email Add-on
63
- - <strike>Make it MU compatible</strike>. Done in v1.7
64
-
65
  ### Support
66
 
67
- - If you have found a bug/issue or have a feature request, then post them in [github issues](https://github.com/sudar/email-log/issues)
68
- - If you have a question about usage or need help to troubleshoot, then post in WordPress forums or leave a comment in [Plugins's home page][1]
69
- - If you like the Plugin, then kindly leave a review/feedback at [WordPress repo page][7].
70
- - If you find this Plugin useful or and wanted to say thank you, then there are ways to [make me happy](http://sudarmuthu.com/if-you-wanna-thank-me) :) and I would really appreciate if you can do one of those.
71
- - If anything else, then contact me in [twitter][2].
72
-
73
- ### Stay updated
74
-
75
- I would be posting updates about this Plugin in my [blog][3] and in [Twitter][2]. If you want to be informed when new version of this Plugin is released, then you can either subscribe to this [blog's RSS feed][4] or [follow me in Twitter][2].
76
-
77
- You can also checkout some of the [other Plugins that I have released][5].
78
-
79
- [1]: http://sudarmuthu.com/wordpress/email-log
80
- [2]: http://twitter.com/sudarmuthu
81
- [3]: http://sudarmuthu.com/blog
82
- [4]: http://sudarmuthu.com/feed
83
- [5]: http://sudarmuthu.com/wordpress
84
- [7]: http://wordpress.org/extend/plugins/email-log
85
 
86
  == Translation ==
87
 
@@ -91,7 +74,9 @@ The Plugin currently has translations for the following languages.
91
  * Lithuanian (Thanks Vincent G)
92
  * Dutch (Thanks Zjan Preijde)
93
 
94
- The pot file is available with the Plugin. If you are willing to do translation for the Plugin, use the pot file to create the .po files for your language and let me know. I will add it to the Plugin after giving credit to you.
 
 
95
 
96
  == Installation ==
97
 
@@ -103,7 +88,10 @@ Extract the zip file and just drop the contents in the wp-content/plugins/ direc
103
 
104
  ### The content of the email is not getting logged when I am using wpmandrill plugin
105
 
106
- wpmandrill plugin has a bug that prevents this plugin from logging the content of the email. More details about the bug is available at http://wordpress.org/support/topic/mandrill-is-changing-the-names-of-args-in-the-filter?replies=1. I have asked the author of the plugin to fix it and it might get fixed it the next release. Meanwhile, I have added a hack to handle this condition in v1.7.3 of my plugin. So if the content is not getting logged, then upgrade to v1.7.3.
 
 
 
107
 
108
  == Screenshots ==
109
 
@@ -111,17 +99,23 @@ wpmandrill plugin has a bug that prevents this plugin from logging the content o
111
 
112
  2. This screenshot shows how you can configure the email display screen. You can choose the fields and the number of emails per page
113
 
114
- 3. This screenshot shows the additional fields that will be added by the [more fields](http://sudarmuthu.com/wordpress/email-log/pro-addons#more-fields-addon) addon
115
 
116
- 4. The above screenshot shows how the logged emails will be displayed by the Plugin after you install the [more fields](http://sudarmuthu.com/wordpress/email-log/pro-addons#more-fields-addon) addon
117
 
118
- 5. This screenshot shows the settings page of [forward email](http://sudarmuthu.com/wordpress/email-log/pro-addons#forward-email-addon) addon
119
 
120
  == Readme Generator ==
121
 
122
  This Readme file was generated using <a href = 'http://sudarmuthu.com/wordpress/wp-readme'>wp-readme</a>, which generates readme files for WordPress Plugins.
123
  == Changelog ==
124
 
 
 
 
 
 
 
125
  = v1.9.1 - (2016-07-02) - (Dev time: 0.5 hour) =
126
  - Fix: Only allow users with `manage_option` capability to view email content.
127
 
@@ -255,6 +249,9 @@ This Readme file was generated using <a href = 'http://sudarmuthu.com/wordpress/
255
 
256
  == Upgrade Notice ==
257
 
 
 
 
258
  = 1.9.1 =
259
  - Fixed a minor security issue that allowed unprevilleged users to view content of logged emails
260
 
1
  === Email Log ===
2
  Contributors: sudar
3
+ Tags: email, log, log email, resend email, multisite
4
+ Requires at least: 4.0
5
+ Tested up to: 4.8
6
+ Stable tag: 2.0.0
7
 
8
+ Log and view all outgoing emails from WordPress. Works with WordPress Multisite as well.
9
 
10
  == Description ==
11
 
12
+ Email Log is a WordPress plugin that allows you to easily log and view all emails sent from WordPress.
13
+ This would be very useful for debugging email related problems in your WordPress site or for storing sent emails for auditing purposes.
14
+
15
+ You can perform advanced actions like re-sending email, automatically forwarding emails or export logs with our [premium add-ons](https://wpemaillog.com/store/?utm_campaign=Upsell&utm_medium=wporg&utm_source=readme&utm_content=store).
16
 
17
  ### Viewing logged emails
18
 
19
+ The logged emails will be stored in a separate table and can be viewed from the admin interface.
20
+ While viewing the logs, the emails can be filtered or sorted based on the date, email, subject etc.
21
 
22
  ### Deleting logged emails
23
 
25
 
26
  ### Resend email (Pro addon)
27
 
28
+ You can [buy the Resend email pro add-on](https://wpemaillog.com/addons/resend-email/?utm_campaign=Upsell&utm_medium=wporg&utm_source=readme&utm_content=re),
29
+ which allows you to resend the email directly from the email log.
30
+ The add-on allows you to modify the different fields before resending the email.
31
 
32
  ### More Fields (Pro addon)
33
 
34
+ You can [buy the More Fields pro add-on](https://wpemaillog.com/addons/more-fields/?utm_campaign=Upsell&utm_medium=wporg&utm_source=readme&utm_content=mf),
35
+ which shows additional fields in the email log page. The following are the additional fields that are added by this addon.
36
 
37
  - From
38
  - CC
40
  - Reply To
41
  - Attachment
42
 
 
 
43
  ### Forward email (Pro addon)
44
 
45
+ You can [buy the Forward email pro add-on](https://wpemaillog.com/addons/more-fields/?utm_campaign=Upsell&utm_medium=wporg&utm_source=readme&utm_content=fe),
46
+ which allows you to send a copy of all the emails send from WordPress, to another email address.
47
+ The addon allows you to choose whether you want to forward through to, cc or bcc fields.
48
+ This can be extremely useful when you want to debug by analyzing the emails that are sent from WordPress.
49
 
50
  ### Cleaning up db on uninstall
51
 
55
 
56
  ### Development
57
 
58
+ The development of the Plugin happens over at [github](http://github.com/sudar/email-log).
59
+ If you want to contribute to the Plugin, [fork the project at github](http://github.com/sudar/email-log) and send me a pull request.
60
 
61
  If you are not familiar with either git or Github then refer to this [guide to see how fork and send pull request](http://sudarmuthu.com/blog/contributing-to-project-hosted-in-github).
62
 
 
 
 
 
 
 
 
 
 
 
 
63
  ### Support
64
 
65
+ - If you have a question about usage of the free plugin or need help to troubleshoot, then post in [WordPress forums](https://wordpress.org/support/plugin/email-log).
66
+ - If you have a question about any of the pro add-ons or have a feature request then post them in the [support section of our site](https://wpemaillog.com/support/?utm_campaign=Upsell&utm_medium=wporg&utm_source=readme&utm_content=support).
67
+ - If you have any development related questions, then post them as [github issues](https://github.com/sudar/email-log/issues)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  == Translation ==
70
 
74
  * Lithuanian (Thanks Vincent G)
75
  * Dutch (Thanks Zjan Preijde)
76
 
77
+ The pot file is available with the Plugin.
78
+ If you are willing to do translation for the Plugin, use the pot file to create the .po files for your language and let me know.
79
+ I will add it to the Plugin after giving credit to you.
80
 
81
  == Installation ==
82
 
88
 
89
  ### The content of the email is not getting logged when I am using wpmandrill plugin
90
 
91
+ wpmandrill plugin has a bug that prevents this plugin from logging the content of the email.
92
+ More details about the bug is available at http://wordpress.org/support/topic/mandrill-is-changing-the-names-of-args-in-the-filter?replies=1.
93
+ I have asked the author of the plugin to fix it and it might get fixed it the next release.
94
+ Meanwhile, I have added a hack to handle this condition in v1.7.3 of my plugin. So if the content is not getting logged, then upgrade to v1.7.3.
95
 
96
  == Screenshots ==
97
 
99
 
100
  2. This screenshot shows how you can configure the email display screen. You can choose the fields and the number of emails per page
101
 
102
+ 3. The above screenshot shows the HTML version (if available) of the logged email that you choose to view
103
 
104
+ 4. The above screenshot shows the text version of the logged email that you choose to view
105
 
106
+ 5. The above screenshot shows how you can search logged emails by date
107
 
108
  == Readme Generator ==
109
 
110
  This Readme file was generated using <a href = 'http://sudarmuthu.com/wordpress/wp-readme'>wp-readme</a>, which generates readme files for WordPress Plugins.
111
  == Changelog ==
112
 
113
+ = v2.0.0 - (2017-08-04) =
114
+ - New: Ability to filter logs by date.
115
+ - New: Ability to filter logs by name.
116
+ - New: Complete rewrite for better performance.
117
+ - Docs: Dropped support for PHP 5.2
118
+
119
  = v1.9.1 - (2016-07-02) - (Dev time: 0.5 hour) =
120
  - Fix: Only allow users with `manage_option` capability to view email content.
121
 
249
 
250
  == Upgrade Notice ==
251
 
252
+ = 2.0.0 =
253
+ Ability to search logs by date. Dropped support to PHP 5.2
254
+
255
  = 1.9.1 =
256
  - Fixed a minor security issue that allowed unprevilleged users to view content of logged emails
257
 
uninstall.php CHANGED
@@ -1,31 +1,27 @@
1
  <?php
2
  /**
3
- * Uninstall Email Log plugin
4
  *
5
- * @package Email Log
6
- * @subpackage Uninstall
7
- * @author Sudar
8
- */
9
- // uninstall page for Email Log Plugin to clean up db.
10
- if( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN' ) )
11
- exit();
12
-
13
- if ( is_multisite() ) {
14
- global $wpdb;
15
-
16
- $original_blog_id = get_current_blog_id();
17
-
18
- $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
19
-
20
- foreach ( $blog_ids as $blog_id ) {
21
- switch_to_blog( $blog_id );
22
- email_log_delete_table();
23
- }
24
 
25
- switch_to_blog( $original_blog_id );
 
 
 
26
 
 
 
 
 
 
 
 
 
 
 
27
  } else {
28
- email_log_delete_table();
29
  }
30
 
31
  /**
@@ -36,15 +32,16 @@ if ( is_multisite() ) {
36
  * @global object $wpdb
37
  */
38
  function email_log_delete_table() {
39
- global $wpdb;
40
- $table_name = $wpdb->prefix . "email_log"; // This is hardcoded on purpose
 
 
41
 
42
- if( $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" ) == $table_name ) {
43
- // If table is present, drop it
44
- $wpdb->query( "DROP TABLE $table_name" );
45
- }
46
 
47
- // Delete the option
48
- delete_option('email-log-db');
49
  }
50
- ?>
1
  <?php
2
  /**
3
+ * Uninstall page for Email Log Plugin to clean up db.
4
  *
5
+ * This file is named uninstall.php since WordPress requires that name.
6
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
+ // exit if WordPress is not uninstalling the plugin.
9
+ if ( ! defined( 'ABSPATH' ) && ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
10
+ exit();
11
+ }
12
 
13
+ if ( is_multisite() ) {
14
+ // Note: if there are more than 10,000 blogs or
15
+ // if `wp_is_large_network` filter is set, then this may fail.
16
+ $sites = wp_get_sites();
17
+
18
+ foreach ( $sites as $site ) {
19
+ switch_to_blog( $site['blog_id'] );
20
+ email_log_delete_table();
21
+ restore_current_blog();
22
+ }
23
  } else {
24
+ email_log_delete_table();
25
  }
26
 
27
  /**
32
  * @global object $wpdb
33
  */
34
  function email_log_delete_table() {
35
+ global $wpdb;
36
+
37
+ // This is hardcoded on purpose, since the entire plugin is not loaded during uninstall.
38
+ $table_name = $wpdb->prefix . 'email_log';
39
 
40
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" ) == $table_name ) {
41
+ // If table is present, drop it
42
+ $wpdb->query( "DROP TABLE $table_name" );
43
+ }
44
 
45
+ // Delete the option
46
+ delete_option( 'email-log-db' );
47
  }