├── tests
├── _output
│ └── .gitignore
├── _data
│ └── dump.sql
├── unit
│ └── _bootstrap.php
├── functional
│ ├── _bootstrap.php
│ └── LogPageTestCept.php
├── integration
│ └── _bootstrap.php
├── _bootstrap.php
├── acceptance
│ └── _bootstrap.php
├── unit.suite.yml
├── _support
│ ├── Helper
│ │ ├── Unit.php
│ │ ├── Acceptance.php
│ │ ├── Functional.php
│ │ └── Integration.php
│ ├── UnitTester.php
│ ├── AcceptanceTester.php
│ ├── FunctionalTester.php
│ ├── IntegrationTester.php
│ └── _generated
│ │ └── IntegrationTesterActions.php
├── integration.suite.yml
├── functional.suite.yml
├── acceptance.suite.yml
└── wp-tests
│ ├── Core
│ ├── DB
│ │ └── TableManagerTest.php
│ ├── EmailLoggerTest.php
│ ├── UI
│ │ ├── ListTable
│ │ │ └── LogListTableTest.php
│ │ └── Component
│ │ │ └── AdminUIEnhancerTest.php
│ └── EmailLogTest.php
│ ├── Util
│ ├── CheckedArrayTest.php
│ ├── SanitizeEmailTest.php
│ └── EmailHeaderParserTest.php
│ ├── bootstrap.php
│ ├── uninstall
│ ├── UninstallWithoutDeleteTest.php
│ └── UninstallWithDeleteTest.php
│ └── EmailLogAutoloaderTest.php
├── .scrutinizer.yml
├── .gitignore
├── languages
├── email-log-de_DE.mo
├── email-log-lt_LT.mo
├── email-log-nl_NL.mo
├── email-log-de_DE.po
├── email-log-lt_LT.po
└── email-log-nl_NL.po
├── assets-wp-repo
├── icon-128x128.png
├── icon-256x256.png
├── screenshot-1.png
├── screenshot-2.png
├── screenshot-3.png
├── screenshot-4.png
├── screenshot-5.png
├── banner-1544x500.png
├── banner-772x250.png
├── banner-772x250-rtl.png
└── banner-1544x500-rtl.png
├── AUTHORS.md
├── bin
├── phpcs.sh
└── install-wp-tests.sh
├── include
├── Core
│ ├── UI
│ │ ├── Setting
│ │ │ ├── SettingField.php
│ │ │ ├── SettingSection.php
│ │ │ └── Setting.php
│ │ ├── Component
│ │ │ ├── DashboardWidget.php
│ │ │ ├── AdminUIEnhancer.php
│ │ │ └── EmailLogSystemInfo.php
│ │ ├── Page
│ │ │ ├── AddonListPage.php
│ │ │ ├── SystemInfoPage.php
│ │ │ ├── SettingsPage.php
│ │ │ ├── BasePage.php
│ │ │ └── LogListPage.php
│ │ └── UILoader.php
│ ├── Loadie.php
│ ├── AdminCapabilityGiver.php
│ ├── Request
│ │ ├── OverridePluginAPI.php
│ │ ├── NonceChecker.php
│ │ └── LogListAction.php
│ ├── EmailLog.php
│ └── EmailLogger.php
├── compatibility
│ ├── EmailLog.php
│ └── wpmandrill.php
├── Addon
│ ├── License
│ │ ├── AddonLicense.php
│ │ ├── BundleLicense.php
│ │ └── BaseLicense.php
│ ├── addon-helper.php
│ ├── EmailLogAddon.php
│ ├── AddonUpdater.php
│ ├── DependencyEnforcer.php
│ ├── API
│ │ ├── EDDUpdater.php
│ │ └── EDDAPI.php
│ ├── Upseller.php
│ └── AddonList.php
├── Util
│ └── EmailHeaderParser.php
└── EmailLogAutoloader.php
├── phpdoc.dist.xml
├── .editorconfig
├── assets
├── js
│ └── admin
│ │ ├── addon-list.js
│ │ └── view-logs.js
└── css
│ └── admin
│ ├── view-logs.css
│ └── addon-list.css
├── phpunit.xml.dist
├── composer.json
├── package.json
├── phpcs.xml
├── codeception.yml
├── uninstall.php
├── .styleci.yml
├── Gruntfile.js
├── email-log.php
├── .travis.yml
├── load-email-log.php
└── README.md
/tests/_output/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/tests/_data/dump.sql:
--------------------------------------------------------------------------------
1 | /* Replace this file with actual dump of your database */
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | tools:
2 | external_code_coverage:
3 | timeout: 600
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 |
3 | dist/
4 | code-coverage/
5 | node_modules/
6 | vendor/
7 |
8 | tests/_output/*
9 |
--------------------------------------------------------------------------------
/tests/unit/_bootstrap.php:
--------------------------------------------------------------------------------
1 | wantTo('Ensure the log page is displayed');
4 |
5 | $I->loginAsAdmin();
6 |
7 | $I->amOnPluginsPage();
8 |
9 | $I->seePluginActivated('email-log');
10 |
--------------------------------------------------------------------------------
/tests/_support/Helper/Unit.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | Bulk Delete
4 |
5 | docs/codex
6 |
7 |
8 | docs/codex
9 |
10 |
11 | .
12 | include/libraries/*
13 | test/*
14 | dist/*
15 | node_modules/*
16 | vendor/*
17 | docs/*
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # This file is for unifying the coding style for different editors and IDEs
2 | # editorconfig.org
3 |
4 | # WordPress Coding Standards
5 | # https://make.wordpress.org/core/handbook/coding-standards/
6 |
7 | root = true
8 |
9 | [*]
10 | charset = utf-8
11 | end_of_line = lf
12 | insert_final_newline = true
13 | trim_trailing_whitespace = true
14 | indent_style = tab
15 |
16 | [{.jshintrc, *.json, *.yml}]
17 | indent_style = space
18 | indent_size = 2
19 |
20 | [{*.txt,wp-config-sample.php}]
21 | end_of_line = crlf
22 |
--------------------------------------------------------------------------------
/include/Core/Loadie.php:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | ./tests/wp-tests/
12 |
13 |
14 |
15 |
16 |
17 | uninstall
18 | uninstall-delete
19 |
20 |
21 |
22 |
23 |
24 | include
25 | email-log.php
26 | uninstall.php
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/include/Addon/License/AddonLicense.php:
--------------------------------------------------------------------------------
1 | license_data ) ) {
19 | return parent::get_license_key();
20 | }
21 |
22 | return $this->license_data->license_key;
23 | }
24 |
25 | /**
26 | * Option name in which individual license data is stored.
27 | * This method should be called only after setting the add-on name.
28 | *
29 | * @return string Option name.
30 | */
31 | protected function get_option_name() {
32 | return 'el_license_' . md5( $this->get_addon_name() );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/assets/css/admin/view-logs.css:
--------------------------------------------------------------------------------
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-pre {
12 | height: 100%;
13 | width: 100%;
14 | }
15 |
16 | #tabs-preview,
17 | #tabs-text {
18 | height: 335px;
19 | overflow: auto;
20 | }
21 |
22 | #thickbox-footer-close {
23 | margin-top: 10px;
24 | }
25 |
26 | #thickbox-footer-close:hover {
27 | background: #eee;
28 | color: #666;
29 | }
30 |
31 | #TB_ajaxContent {
32 | padding-bottom: 10px !important; /* Override the default Thickbox css values. */
33 | }
34 |
35 | #el-pro-msg {
36 | display: inline-block;
37 | margin: 7px 0;
38 | }
39 |
40 | .column-result .dashicons {
41 | font-size: xx-large;
42 | }
43 |
44 | .column-result .dashicons-yes-alt {
45 | color: #00C853;
46 | }
47 |
48 | .column-result .dashicons-dismiss {
49 | color: #E53935;
50 | }
51 |
--------------------------------------------------------------------------------
/tests/wp-tests/Core/DB/TableManagerTest.php:
--------------------------------------------------------------------------------
1 | table_manager = new TableManager;
11 | }
12 |
13 | public function test_get_log_table_name() {
14 | global $wpdb;
15 |
16 | $expected = $wpdb->prefix . 'email_log';
17 | $actual = $this->table_manager->get_log_table_name();
18 |
19 | $this->assertEquals( $expected, $actual );
20 | }
21 |
22 | public function test_on_delete_blog() {
23 | $tables = array(
24 | 'some-table-name',
25 | );
26 |
27 | $table_name = $this->table_manager->get_log_table_name();
28 | $expected = array_merge( $tables, array( $table_name ) );
29 |
30 | $actual = $this->table_manager->delete_table_from_deleted_blog( $tables );
31 |
32 | $this->assertEquals( $expected, $actual );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/include/Addon/addon-helper.php:
--------------------------------------------------------------------------------
1 | loader->add_namespace( 'EmailLog', $addon_dir . 'include' );
25 |
26 | $addon_updater = null;
27 |
28 | if ( \EmailLog\Util\is_admin_non_ajax_request() ) {
29 | $addon_updater = new \EmailLog\Addon\AddonUpdater( $addon_file );
30 | }
31 |
32 | $addon = new $addon_class( $addon_file, $addon_updater );
33 |
34 | add_action( 'el_loaded', array( $addon, 'load' ) );
35 |
36 | return $addon;
37 | }
38 |
--------------------------------------------------------------------------------
/tests/wp-tests/Core/EmailLoggerTest.php:
--------------------------------------------------------------------------------
1 | getMockBuilder( '\\EmailLog\\Core\\DB\\TableManager' )->getMock();
15 | $table_manager_stub->method( 'insert_log' );
16 |
17 | $email_log->table_manager = $table_manager_stub;
18 |
19 | $this->logger = new EmailLogger();
20 | }
21 |
22 | public function test_filter_doesnt_change_mailinfo() {
23 | $mail_info = array(
24 | 'attachments' => array(),
25 | 'to' => array( 'sudar@sudarmuthu.com' ),
26 | 'subject' => 'Email subject',
27 | 'headers' => array(),
28 | );
29 |
30 | $actual = $this->logger->log_email( $mail_info );
31 |
32 | $this->assertEquals( $mail_info, $actual );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sudar/email-log",
3 | "description": "Email Log WordPress plugin",
4 | "type": "wordpress-plugin",
5 | "license": "GPL-2.0-or-later",
6 | "authors": [
7 | {
8 | "name": "Sudar Muthu",
9 | "homepage": "https://sudarmuthu.com"
10 | }
11 | ],
12 | "support": {
13 | "issues": "https://github.com/sudar/email-log/issues"
14 | },
15 | "config": {
16 | "sort-packages": true
17 | },
18 | "repositories": [
19 | {
20 | "type": "vcs",
21 | "url": "https://github.com/sudar/wp-system-info"
22 | }
23 | ],
24 | "require": {
25 | "php": ">=5.6",
26 | "ext-json": "*",
27 | "collizo4sky/persist-admin-notices-dismissal": "^1.4",
28 | "sudar/wp-system-info": "dev-master"
29 | },
30 | "require-dev": {
31 | "phpunit/phpunit": "^5.0",
32 | "codeception/codeception": "^2.2",
33 | "lucatume/wp-browser": "^1.14",
34 | "jdgrimes/wp-plugin-uninstall-tester": "~0.6",
35 | "squizlabs/php_codesniffer": "^3.0",
36 | "dealerdirect/phpcodesniffer-composer-installer": "^0.5",
37 | "phpcompatibility/php-compatibility": "^9.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/wp-tests/Util/CheckedArrayTest.php:
--------------------------------------------------------------------------------
1 | array( 'editor', 'author', 'subscriber' ),
21 | 'current' => 'editor'
22 | ),
23 | "checked='checked'"
24 | ),
25 | // Failure test case.
26 | array(
27 | array(
28 | 'values' => 'editor',
29 | 'current' => 'editor'
30 | ),
31 | ''
32 | )
33 | );
34 | }
35 |
36 | /**
37 | * Test $values is array.
38 | *
39 | * @dataProvider provider_to_test_checked_array
40 | */
41 | function test_checked_array( $input, $expected ) {
42 | ob_start();
43 | checked_array( $input['values'], $input['current'] );
44 | $actual = ob_get_clean();
45 | $this->assertSame( $expected, $actual );
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/tests/wp-tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | file = str_replace( 'tests/wp-tests/Core/', '', __FILE__ );
26 | $page = new MockLogListPage( $this->file );
27 | $page->load();
28 | $this->log_list_table = new LogListTable( $page );
29 | }
30 |
31 | public function test_get_columns() {
32 | $actual = $this->log_list_table->get_columns();
33 |
34 | $this->assertArrayHasKey( 'cb', $actual );
35 | $this->assertArrayHasKey( 'sent_date', $actual );
36 | $this->assertArrayHasKey( 'to_email', $actual );
37 | $this->assertArrayHasKey( 'subject', $actual );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/include/compatibility/wpmandrill.php:
--------------------------------------------------------------------------------
1 | file = str_replace( 'tests/wp-tests/Core/', '', __FILE__ );
14 |
15 | // Create a stub for EmailLogAutoloader class.
16 | $loader_stub = $this->getMockBuilder( '\\EmailLog\\EmailLogAutoloader' )->getMock();
17 |
18 | // Create a stub for Table Manager class.
19 | $table_manager_stub = $this->getMockBuilder( '\\EmailLog\\Core\\DB\\TableManager' )->getMock();
20 | $table_manager_stub->method( 'load' );
21 |
22 | // Create a stub for Email Logger class.
23 | $email_logger_stub = $this->getMockBuilder( '\\EmailLog\\Core\\EmailLogger' )->getMock();
24 | $email_logger_stub->method( 'load' );
25 |
26 | $this->email_log = new EmailLog( $this->file, $loader_stub, $table_manager_stub );
27 | }
28 |
29 | public function tearDown() {
30 | parent::tearDown();
31 | }
32 |
33 | /**
34 | * Test translations_path.
35 | */
36 | public function test_translations_path() {
37 | $this->email_log->load();
38 |
39 | $expected = dirname( plugin_basename( $this->file ) ) . '/languages/';
40 | $actual = $this->email_log->translations_path;
41 |
42 | $this->assertEquals( $expected, $actual );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/assets/css/admin/addon-list.css:
--------------------------------------------------------------------------------
1 | .el-addon-list {
2 | display: grid;
3 | grid-gap: 10px;
4 | grid-template-columns: repeat(auto-fit, 350px);
5 | }
6 |
7 | .el-addon {
8 | background: #FFF;
9 | border: 1px solid #ccc;
10 | box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
11 | padding: 10px;
12 | }
13 |
14 | .el-addon-image,
15 | .individual-license .el-license {
16 | width: 330px;
17 | }
18 |
19 | .el-addon-list .disabled {
20 | cursor: not-allowed !important;
21 | }
22 |
23 | .bundle-license {
24 | margin-bottom: 3%;
25 | }
26 |
27 | .bundle-license .notice {
28 | padding-top: 10px;
29 | padding-bottom: 10px;
30 | }
31 |
32 | .bundle-license .el-license, .bundle-license .button {
33 | font-size: 1.7em;
34 | }
35 |
36 | .bundle-license .el-license,
37 | .bundle-license .button,
38 | .individual-license .el-license,
39 | .individual-license .button {
40 | line-height: 2;
41 | }
42 |
43 | .bundle-license .expires {
44 | margin-left: 5px;
45 | margin-top: 5px;
46 | }
47 |
48 | .individual-license {
49 | padding-top: 10px;
50 | }
51 |
52 | .individual-license .el-license {
53 | padding-left: 10px;
54 | }
55 |
56 | .individual-license .button {
57 | margin-top: 10px;
58 | }
59 |
60 | .el-expander {
61 | float: right;
62 | font-size: 40px;
63 | margin-top: -5px;
64 | margin-right: 10px;
65 | }
66 |
67 | @media screen and (max-width: 782px) {
68 | .bundle-license .el-license, .bundle-license .button {
69 | font-size: 0.8em;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/tests/wp-tests/uninstall/UninstallWithoutDeleteTest.php:
--------------------------------------------------------------------------------
1 | plugin_file = 'email-log/email-log.php';
25 |
26 | parent::setUp();
27 | }
28 |
29 | /**
30 | * Test installation and uninstallation without deleting table.
31 | */
32 | public function test_uninstall_without_deleting_table() {
33 | global $wpdb;
34 |
35 | /*
36 | * First test that the plugin installed itself properly.
37 | */
38 |
39 | // Check that a database table was added.
40 | $this->assertTableExists( $wpdb->prefix . 'email_log' );
41 |
42 | // Check that an option was added to the database.
43 | $this->assertEquals( '0.3', get_option( 'email-log-db' ) );
44 |
45 | /*
46 | * Now, test that it uninstalls itself properly.
47 | * By default table should not be deleted.
48 | */
49 |
50 | // You must call this to perform uninstallation.
51 | $this->uninstall();
52 |
53 | // Check that the table was deleted.
54 | $this->assertTableExists( $wpdb->prefix . 'email_log' );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/include/Core/UI/Setting/SettingSection.php:
--------------------------------------------------------------------------------
1 | fields[] = $field;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/include/Addon/EmailLogAddon.php:
--------------------------------------------------------------------------------
1 | addon_file = $addon_file;
43 | $this->updater = $updater;
44 |
45 | $this->initialize();
46 | }
47 |
48 | /**
49 | * Load the add-on and setup hooks.
50 | */
51 | public function load() {
52 | if ( \EmailLog\Util\is_admin_non_ajax_request() ) {
53 | $email_log = email_log();
54 |
55 | if ( ! $email_log->is_plugin_api_overridden() ) {
56 | $override_plugin_api = new \EmailLog\Core\Request\OverridePluginAPI();
57 | $override_plugin_api->load();
58 |
59 | $email_log->plugin_api_overridden();
60 | }
61 | }
62 |
63 | if ( is_null( $this->updater ) ) {
64 | return;
65 | }
66 |
67 | $this->updater->set_addon_data( $this->addon_name, $this->addon_version, $this->addon_author );
68 | $this->updater->load();
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/include/Core/AdminCapabilityGiver.php:
--------------------------------------------------------------------------------
1 | roles ) ) {
34 | return $allcaps;
35 | }
36 |
37 | if ( array_key_exists( LogListPage::CAPABILITY, $allcaps ) ) {
38 | return $allcaps;
39 | }
40 |
41 | $allcaps[ LogListPage::CAPABILITY ] = true;
42 |
43 | return $allcaps;
44 | }
45 |
46 | /**
47 | * Add Manage Email Logs capability to administrator role.
48 | * This will be called on install.
49 | */
50 | public function add_cap_to_admin() {
51 | $admin = get_role( 'administrator' );
52 |
53 | if ( is_null( $admin ) ) {
54 | return;
55 | }
56 |
57 | $admin->add_cap( LogListPage::CAPABILITY );
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/include/Addon/AddonUpdater.php:
--------------------------------------------------------------------------------
1 | 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 | $licenser = $email_log->get_licenser();
56 |
57 | if ( is_null( $licenser ) ) {
58 | return;
59 | }
60 |
61 | $license_key = $licenser->get_addon_license_key( $this->addon_name );
62 |
63 | $updater = new EDDUpdater( $email_log->get_store_url(), $this->addon_file, array(
64 | 'version' => $this->addon_version,
65 | 'license' => $license_key,
66 | 'item_name' => $this->addon_name,
67 | 'author' => $this->addon_author,
68 | )
69 | );
70 |
71 | $licenser->add_updater( $updater );
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/include/Core/UI/Component/DashboardWidget.php:
--------------------------------------------------------------------------------
1 | table_manager->get_logs_count();
40 | ?>
41 |
42 |
43 | :
44 |
45 |
46 |
55 |
56 |
57 | - Email Logs', 'email-log' ), 'admin.php?page=email-log' ); ?> |
58 | - Settings', 'email-log' ), 'admin.php?page=email-log-settings' ); ?> |
59 | - Addons', 'email-log' ), 'admin.php?page=email-log-addons' ); ?>
60 |
61 |
62 |
2 |
3 | Email Log coding standard
4 |
5 | ./
6 |
7 |
8 | docs/*
9 | dist/*
10 | code-coverage/*
11 | node_modules/*
12 | test/*
13 | tests/*
14 | vendor/*
15 | Gruntfile.js
16 |
17 |
18 | include/libraries/*
19 |
20 |
21 | assets/css/vendor/*
22 | assets/css/*.min.css
23 |
24 | assets/js/vendor/*
25 | assets/js/*.min.js
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/tests/wp-tests/Core/UI/Component/AdminUIEnhancerTest.php:
--------------------------------------------------------------------------------
1 | plugin_basename;
15 | }
16 | }
17 |
18 | /**
19 | * Test PluginList Enhancer.
20 | *
21 | * @since 2.0
22 | */
23 | class AdminUIEnhancerTest extends \PHPUnit_Framework_TestCase {
24 |
25 | protected $file;
26 | protected $plugin_list_enhancer;
27 |
28 | public function setUp() {
29 | parent::setUp();
30 | $this->file = str_replace( 'tests/wp-tests/Core/UI/', '', __FILE__ );
31 |
32 | $this->plugin_list_enhancer = new MockAdminUIEnhancerClass( $this->file );
33 | }
34 |
35 | public function test_plugin_basename() {
36 | $expected = plugin_basename( $this->file );
37 | $actual = $this->plugin_list_enhancer->get_plugin_basename();
38 |
39 | $this->assertEquals( $expected, $actual );
40 | }
41 |
42 | public function test_row_meta_filter_not_changed_for_other_plugin() {
43 | $links = array();
44 | $plugin = 'some-other-plugin';
45 |
46 | $actual = $this->plugin_list_enhancer->insert_addon_store_link( $links, $plugin );
47 |
48 | $this->assertcount( count( $links ), $actual );
49 | }
50 |
51 | public function test_row_meta_filter_changed_for_plugin() {
52 | $links = array();
53 | $plugin = $this->plugin_list_enhancer->get_plugin_basename();
54 |
55 | $actual = $this->plugin_list_enhancer->insert_addon_store_link( $links, $plugin );
56 |
57 | $this->assertcount( count( $links ) + 1, $actual );
58 | }
59 |
60 | public function test_link_is_inserted() {
61 | $links = array();
62 |
63 | $actual = $this->plugin_list_enhancer->insert_view_logs_link( $links );
64 |
65 | $this->assertCount( count( $links ) + 2, $actual );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/codeception.yml:
--------------------------------------------------------------------------------
1 | actor: Tester
2 | paths:
3 | tests: tests
4 | log: tests/_output
5 | data: tests/_data
6 | helpers: tests/_support
7 | settings:
8 | bootstrap: _bootstrap.php
9 | colors: true
10 | memory_limit: 1024M
11 | modules:
12 | config:
13 | Db:
14 | dsn: 'mysql:host=localhost;dbname=wordpress-tests'
15 | user: root
16 | password: root
17 | dump: tests/_data/dump.sql
18 | WPBrowser:
19 | url: 'http://local.wordpress.dev'
20 | adminUsername: sudar
21 | adminPassword: localsudar
22 | adminUrl: /wp-admin
23 | WPDb:
24 | dsn: 'mysql:host=local.wordpress.dev;dbname=wordpress_default'
25 | user: external
26 | password: external
27 | dump: tests/_data/dump.sql
28 | populate: false
29 | cleanup: false
30 | url: 'http://local.wordpress.dev'
31 | tablePrefix: wp_
32 | WPLoader:
33 | #wpRootFolder: /srv/www/wordpress-default/
34 | wpRootFolder: /Users/sudar/dev/vvv/www/wordpress-default/
35 | dbName: emaillog_test
36 | dbHost: local.wordpress.dev
37 | dbUser: external
38 | dbPassword: external
39 | wpDebug: true
40 | dbCharset: utf8
41 | dbCollate: ''
42 | tablePrefix: wptests_
43 | domain: local.wordpress.dev
44 | adminEmail: admin@wp.local
45 | title: 'WP Tests'
46 | phpBinary: php
47 | language: ''
48 | plugins: [email-log/email-log.php]
49 | activatePlugins: [email-log/email-log.php]
50 | bootstrapActions: []
51 | WPWebDriver:
52 | url: 'http://local.wordpress.dev'
53 | browser: phantomjs
54 | port: 4444
55 | restart: true
56 | wait: 2
57 | adminUsername: admin
58 | adminPassword: password
59 | adminUrl: /wp-admin
60 |
--------------------------------------------------------------------------------
/tests/_support/_generated/IntegrationTesterActions.php:
--------------------------------------------------------------------------------
1 | getScenario()->runStep(new \Codeception\Step\Action('ensureDbModuleCompat', func_get_args()));
27 | }
28 |
29 |
30 | /**
31 | * [!] Method is generated. Documentation taken from corresponding module.
32 | *
33 | * Calls a list of user-defined actions needed in tests.
34 | * @see \Codeception\Module\WPLoader::bootstrapActions()
35 | */
36 | public function bootstrapActions() {
37 | return $this->getScenario()->runStep(new \Codeception\Step\Action('bootstrapActions', func_get_args()));
38 | }
39 |
40 |
41 | /**
42 | * [!] Method is generated. Documentation taken from corresponding module.
43 | *
44 | *
45 | * @see \Codeception\Module\WPLoader::activatePlugins()
46 | */
47 | public function activatePlugins() {
48 | return $this->getScenario()->runStep(new \Codeception\Step\Action('activatePlugins', func_get_args()));
49 | }
50 |
51 |
52 | /**
53 | * [!] Method is generated. Documentation taken from corresponding module.
54 | *
55 | * Loads the plugins required by the test.
56 | * @see \Codeception\Module\WPLoader::loadPlugins()
57 | */
58 | public function loadPlugins() {
59 | return $this->getScenario()->runStep(new \Codeception\Step\Action('loadPlugins', func_get_args()));
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/include/Addon/License/BundleLicense.php:
--------------------------------------------------------------------------------
1 | license_data ) ) {
33 | return parent::get_license_key();
34 | }
35 |
36 | return $this->license_data->bundle_license_key;
37 | }
38 |
39 | /**
40 | * The option name in which the bundle license data will be stored.
41 | *
42 | * @return string Option name.
43 | */
44 | protected function get_option_name() {
45 | return 'el_bundle_license';
46 | }
47 |
48 | /**
49 | * Get the license key of an add-on from Bundle.
50 | *
51 | * @param string $addon_name Add-on name.
52 | *
53 | * @return bool|string False if no license key is found, otherwise license key.
54 | */
55 | public function get_addon_license_key( $addon_name ) {
56 | if ( empty( $this->license_data ) ) {
57 | return false;
58 | }
59 |
60 | if ( ! isset( $this->license_data->bundled_licenses->{$addon_name} ) ) {
61 | return false;
62 | }
63 |
64 | return $this->license_data->bundled_licenses->{$addon_name}->license_key;
65 | }
66 |
67 | /**
68 | * Is the bundle license a lifetime license.
69 | *
70 | * @since 2.4.1
71 | *
72 | * @return bool True if it is a lifetime license, False otherwise.
73 | */
74 | public function is_lifetime_license() {
75 | if ( empty( $this->license_data ) || ! isset( $this->license_data->expires ) ) {
76 | return false;
77 | }
78 |
79 | return ( false === $this->license_data->expires );
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/tests/wp-tests/uninstall/UninstallWithDeleteTest.php:
--------------------------------------------------------------------------------
1 | plugin_file = 'email-log/email-log.php';
25 |
26 | parent::setUp();
27 | }
28 |
29 | /**
30 | * Test installation and uninstallation with deleting table.
31 | */
32 | public function test_uninstall_with_deleting_table() {
33 | global $wpdb;
34 |
35 | /*
36 | * First test that the plugin installed itself properly.
37 | */
38 |
39 | // Check that a database table was added.
40 | $this->assertTableExists( $wpdb->prefix . 'email_log' );
41 |
42 | // Check that an option was added to the database.
43 | $this->assertEquals( '0.3', get_option( 'email-log-db' ) );
44 |
45 | // add the option that will delete the table during uninstall.
46 | $value = array(
47 | 'allowed_user_roles' => array(),
48 | 'remove_on_uninstall' => 'true',
49 | );
50 | update_option( 'email-log-core', $value );
51 |
52 | $this->uninstall();
53 |
54 | // Check that the table was deleted.
55 | $this->assertTableNotExists( $wpdb->prefix . 'email_log' );
56 |
57 | // Check that all options with a prefix was deleted.
58 | $this->assertNoOptionsWithPrefix( 'email-log' );
59 |
60 | // check the capability has been removed from all user roles.
61 | $roles = get_editable_roles();
62 | foreach ( $roles as $role_name => $role_obj ) {
63 | $role = get_role( $role_name );
64 |
65 | if ( ! is_null( $role ) ) {
66 | $this->assertFalse( $role->has_cap( 'manage_email_logs' ), 'Capability is not cleaned up' );
67 | }
68 | }
69 |
70 | // check whether the license options got deleted.
71 | $this->assertNoOptionsWithPrefix( 'el_bundle_license' );
72 | $this->assertNoOptionsWithPrefix( 'el_license_' );
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/uninstall.php:
--------------------------------------------------------------------------------
1 | blog_id );
20 | email_log_delete_db_data();
21 | restore_current_blog();
22 | }
23 | } else {
24 | email_log_delete_db_data();
25 | }
26 |
27 | /**
28 | * Delete all email log data from db.
29 | *
30 | * The data include email log table, options, capability and add-on license data.
31 | *
32 | * @since 1.7
33 | *
34 | * @global object $wpdb
35 | */
36 | function email_log_delete_db_data() {
37 | global $wpdb;
38 |
39 | $remove_data_on_uninstall = false;
40 |
41 | $option = get_option( 'email-log-core' );
42 | if ( is_array( $option ) && array_key_exists( 'remove_on_uninstall', $option ) &&
43 | 'true' === strtolower( $option['remove_on_uninstall'] ) ) {
44 |
45 | $remove_data_on_uninstall = true;
46 | }
47 |
48 | // This is hardcoded on purpose, since the entire plugin is not loaded during uninstall.
49 | $table_name = $wpdb->prefix . 'email_log';
50 |
51 | if ( $remove_data_on_uninstall ) {
52 | if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" ) == $table_name ) {
53 | $wpdb->query( "DROP TABLE $table_name" );
54 | }
55 |
56 | delete_option( 'email-log-db' );
57 | delete_option( 'email-log-core' );
58 |
59 | $roles = get_editable_roles();
60 | foreach ( $roles as $role_name => $role_obj ) {
61 | $role = get_role( $role_name );
62 |
63 | if ( ! is_null( $role ) ) {
64 | $role->remove_cap( 'manage_email_logs' );
65 | }
66 | }
67 | // Mask Fields addon adds this option.
68 | delete_option( 'el_mask_fields' );
69 |
70 | delete_option( 'el_bundle_license' );
71 | $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'el_license_%'" );
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: none
2 |
3 | enabled:
4 | - align_double_arrow
5 | - align_equals
6 | - align_phpdoc
7 | - alpha_ordered_imports
8 | - binary_operator_spaces
9 | - blank_line_after_namespace
10 | - blank_line_before_continue
11 | - blank_line_before_return
12 | - blank_line_before_throw
13 | - blank_line_before_try
14 | - cast_spaces
15 | - combine_consecutive_unsets
16 | - concat_with_spaces
17 | - elseif
18 | - encoding
19 | - function_typehint_space
20 | - hash_to_slash_comment
21 | - include
22 | - lowercase_cast
23 | - lowercase_constants
24 | - lowercase_keywords
25 | - method_visibility_required
26 | - native_function_casing
27 | - no_blank_lines_after_phpdoc
28 | - no_blank_lines_after_return
29 | - no_blank_lines_after_throw
30 | - no_closing_tag
31 | - no_empty_comment
32 | - no_empty_phpdoc
33 | - no_empty_statement
34 | - no_extra_consecutive_blank_lines
35 | - no_leading_namespace_whitespace
36 | - no_short_echo_tag
37 | - no_spaces_after_function_name
38 | - no_trailing_comma_in_list_call
39 | - no_trailing_comma_in_singleline_array
40 | - no_trailing_whitespace
41 | - no_trailing_whitespace_in_comment
42 | - no_unused_imports
43 | - no_whitespace_before_comma_in_array
44 | - no_whitespace_in_blank_line
45 | - not_operator_with_space
46 | - phpdoc_add_missing_param_annotation
47 | - phpdoc_align
48 | - phpdoc_indent
49 | - phpdoc_no_package
50 | - phpdoc_no_useless_inheritdoc
51 | - phpdoc_order
52 | - phpdoc_scalar
53 | - phpdoc_separation
54 | - phpdoc_single_line_var_spacing
55 | - phpdoc_summary
56 | - phpdoc_types
57 | - phpdoc_types_order
58 | - phpdoc_var_without_name
59 | - property_visibility_required
60 | - return_type_declaration
61 | - short_scalar_cast
62 | - single_blank_line_at_eof
63 | - single_class_element_per_statement
64 | - single_import_per_statement
65 | - single_line_after_imports
66 | - single_quote
67 | - standardize_not_equals
68 | - switch_case_semicolon_to_colon
69 | - ternary_operator_spaces
70 | - trailing_comma_in_multiline_array
71 | - unix_line_endings
72 | - whitespace_after_comma_in_array
73 |
74 | finder:
75 | not-path:
76 | - "libraries"
77 | exclude:
78 | - "tests"
79 | name:
80 | - "*.php"
81 | not-name:
82 | - "EmailLogger.php"
83 |
--------------------------------------------------------------------------------
/include/Core/UI/Page/AddonListPage.php:
--------------------------------------------------------------------------------
1 | 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 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | get_licenser();
58 | if ( ! is_null( $licenser ) ) {
59 | $licenser->get_addon_list()->render();
60 | }
61 | ?>
62 |
63 | render_page_footer();
66 | }
67 |
68 | /**
69 | * Enqueue static assets needed for this page.
70 | */
71 | public function enqueue_assets() {
72 | $email_log = email_log();
73 |
74 | wp_enqueue_style( 'el_addon_list', plugins_url( 'assets/css/admin/addon-list.css', $email_log->get_plugin_file() ), array(), $email_log->get_version() );
75 | 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 );
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/include/Core/UI/UILoader.php:
--------------------------------------------------------------------------------
1 | initialize_components();
37 | $this->initialize_pages();
38 |
39 | foreach ( $this->components as $component ) {
40 | $component->load();
41 | }
42 |
43 | foreach ( $this->pages as $page ) {
44 | $page->load();
45 | }
46 | }
47 |
48 | public function is_show_dashboard_widget() {
49 | $this->components['core_settings'] = new Setting\CoreSetting();
50 | $dashboard_status = false;
51 | $options = get_option( 'email-log-core' );
52 | if( isset( $options['hide_dashboard_widget'] ) ) {
53 | $dashboard_status = $options['hide_dashboard_widget'];
54 | }
55 |
56 | return $dashboard_status;
57 | }
58 |
59 | /**
60 | * Initialize UI component Objects.
61 | *
62 | * This method may be overwritten in tests.
63 | *
64 | * @access protected
65 | */
66 | protected function initialize_components() {
67 | if ( current_user_can( LogListPage::CAPABILITY ) ) {
68 | $this->components['admin_ui_enhancer'] = new Component\AdminUIEnhancer();
69 | if( ! $this->is_show_dashboard_widget() ) {
70 | $this->components['dashboard_widget'] = new Component\DashboardWidget();
71 | }
72 | }
73 | }
74 |
75 | /**
76 | * Initialize Admin page Objects.
77 | *
78 | * This method may be overwritten in tests.
79 | *
80 | * @access protected
81 | */
82 | protected function initialize_pages() {
83 | $this->pages['log_list_page'] = new Page\LogListPage();
84 | $this->pages['settings_page'] = new Page\SettingsPage();
85 | $this->pages['addon_list_page'] = new Page\AddonListPage();
86 | $this->pages['system_info_page'] = new Page\SystemInfoPage();
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /* global module, require */
2 | module.exports = function( grunt ) {
3 | 'use strict';
4 |
5 | // Load all grunt tasks
6 | require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
7 |
8 | // Project configuration
9 | grunt.initConfig( {
10 | pkg: grunt.file.readJSON( 'package.json' ),
11 |
12 | clean : {
13 | dist: ['dist/']
14 | },
15 |
16 | copy: {
17 | dist: {
18 | files : [
19 | {
20 | expand: true,
21 | src: [
22 | '**',
23 | '!dist/**',
24 | '!assets-wp-repo/**',
25 | '!code-coverage/**',
26 | '!codeception.yml',
27 | '!node_modules/**',
28 | '!assets/vendor/**',
29 | 'assets/vendor/insertion-query/insQ.min.js',
30 | 'assets/vendor/jquery-ui/themes/base/jquery-ui.min.css',
31 | '!assets/js/src/**',
32 | '!assets/css/src/**',
33 | '!Gruntfile.js',
34 | '!bower.json',
35 | '!package.json',
36 | '!package-lock.json',
37 | '!composer.json',
38 | '!composer.lock',
39 | '!phpcs.xml',
40 | '!phpdoc.dist.xml',
41 | '!phpunit.xml.dist',
42 | '!bin/**',
43 | '!tests/**',
44 | '!.idea/**',
45 | '!tags',
46 | '!vendor/**',
47 | "vendor/sudar/wp-system-info/**",
48 | "vendor/collizo4sky/persist-admin-notices-dismissal/**"
49 | ],
50 | dest: 'dist/'
51 | }
52 | ]
53 | },
54 | jqueryUi: {
55 | files: [
56 | {
57 | src : "node_modules/components-jqueryui/themes/base/jquery-ui.min.css",
58 | dest: "assets/vendor/jquery-ui/themes/base/jquery-ui.min.css"
59 | },
60 | {
61 | expand: true,
62 | src: ["node_modules/components-jqueryui/themes/base/images/*"],
63 | dest: "assets/vendor/jquery-ui/themes/base/images/",
64 | flatten: true,
65 | filter: "isFile"
66 | }
67 | ]
68 | },
69 | insertionQ: {
70 | files: [
71 | {
72 | src : "node_modules/insertion-query/insQ.min.js",
73 | dest: "assets/vendor/insertion-query/insQ.min.js"
74 | }
75 | ]
76 | },
77 | },
78 |
79 | makepot: {
80 | target: {
81 | options: {
82 | exclude: ['vendor/.*', 'dist/.*'],
83 | updateTimestamp: false,
84 | }
85 | }
86 | },
87 |
88 | watch: {
89 | all: {
90 | files: ['**', '!dist/**'],
91 | tasks: ['build']
92 | }
93 | }
94 | } );
95 |
96 | require('time-grunt')(grunt);
97 |
98 | grunt.registerTask("vendor", ["copy:jqueryUi", "copy:insertionQ"]);
99 | grunt.registerTask("build", ["vendor", "clean", "copy:dist"]);
100 |
101 | grunt.util.linefeed = '\n';
102 | };
103 |
--------------------------------------------------------------------------------
/include/Core/Request/OverridePluginAPI.php:
--------------------------------------------------------------------------------
1 | get_licenser();
34 |
35 | if ( is_null( $licenser ) ) {
36 | return;
37 | }
38 |
39 | $inactive_addons = $licenser->get_addon_list()->get_inactive_addons();
40 |
41 | foreach ( $inactive_addons as $inactive_addon ) {
42 | $license_key = $licenser->get_addon_license_key( $inactive_addon->name );
43 |
44 | $updater = new EDDUpdater(
45 | $email_log->get_store_url(),
46 | $inactive_addon->file,
47 | array(
48 | 'version' => $inactive_addon->get_version(),
49 | 'license' => $license_key,
50 | 'item_name' => $inactive_addon->name,
51 | 'author' => $inactive_addon->author,
52 | )
53 | );
54 |
55 | $licenser->add_updater( $updater );
56 | }
57 | }
58 |
59 | /**
60 | * Add version attribute to plugin API response.
61 | *
62 | * The API response generated by EDD doesn't have the version attribute and it results in some warnings.
63 | * This method fixes it by manually adding the version attribute to the API response.
64 | *
65 | * @since 2.1.0
66 | *
67 | * @param object $response API Response.
68 | * @param string $action Action name.
69 | * @param array $args Arguments for the function.
70 | *
71 | * @return object Modified API response.
72 | */
73 | public function add_version_to_plugin_api_response( $response, $action, $args ) {
74 | if ( 'plugin_information' !== $action ) {
75 | return $response;
76 | }
77 |
78 | if ( ! isset( $args->slug ) || ( substr( $args->slug, 0, 10 ) != 'email-log-' ) ) {
79 | return $response;
80 | }
81 |
82 | if ( isset( $response->version ) ) {
83 | return $response;
84 | }
85 |
86 | if ( ! isset( $response->new_version ) ) {
87 | return $response;
88 | }
89 |
90 | $response->version = $response->new_version;
91 |
92 | return $response;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/email-log.php:
--------------------------------------------------------------------------------
1 |
47 |
48 |
49 | v1.9.1 of Email Log.', 'email-log' ), // @codingStandardsIgnoreLine
52 | 'https://downloads.wordpress.org/plugin/email-log.1.9.1.zip'
53 | );
54 | ?>
55 |
56 |
57 | parse( $headers );
61 | }
62 |
63 | /**
64 | * Parse Headers.
65 | *
66 | * @access private
67 | *
68 | * @param string $headers Headers to be parsed.
69 | *
70 | * @return array Parsed headers.
71 | */
72 | private function parse( $headers ) {
73 | $data = array();
74 | $arr_headers = explode( "\n", $headers );
75 |
76 | foreach ( $arr_headers as $header ) {
77 | $split_header = explode( ':', $header );
78 | $value = $this->parse_header_line( $split_header );
79 |
80 | if ( trim( $value ) != '' ) {
81 | switch ( strtolower( $split_header[0] ) ) {
82 | case 'from':
83 | $data['from'] = $value;
84 | break;
85 |
86 | case 'cc':
87 | $data['cc'] = $value;
88 | break;
89 |
90 | case 'bcc':
91 | $data['bcc'] = $value;
92 | break;
93 |
94 | case 'reply-to':
95 | $data['reply_to'] = $value;
96 | break;
97 |
98 | case 'content-type':
99 | $data['content_type'] = $value;
100 | break;
101 | }
102 | }
103 | }
104 |
105 | return $data;
106 | }
107 |
108 | /**
109 | * Parse individual header line.
110 | *
111 | * @since 1.0
112 | * @access private
113 | *
114 | * @param array $header Header line to be parsed.
115 | *
116 | * @return string Parsed value.
117 | */
118 | private function parse_header_line( $header ) {
119 | $value = '';
120 | if ( 2 == count( $header ) ) {
121 | if ( is_array( $header[1] ) ) {
122 | $value = trim( implode( ',', array_map( 'trim', $header[1] ) ) );
123 | } else {
124 | $value = trim( $header[1] );
125 | }
126 | }
127 |
128 | return $value;
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/load-email-log.php:
--------------------------------------------------------------------------------
1 | add_namespace( 'EmailLog', $plugin_dir . 'include' );
29 | $loader->add_namespace( 'Sudar\\WPSystemInfo', $plugin_dir . 'vendor/sudar/wp-system-info/src/' );
30 |
31 | if ( file_exists( $plugin_dir . 'tests/' ) ) {
32 | // if tests are present, then add them.
33 | $loader->add_namespace( 'EmailLog', $plugin_dir . 'tests/wp-tests' );
34 | }
35 |
36 | $loader->add_file( $plugin_dir . 'include/Util/helper.php' );
37 | $loader->add_file( $plugin_dir . 'include/Addon/addon-helper.php' );
38 | $loader->add_file( $plugin_dir . 'vendor/collizo4sky/persist-admin-notices-dismissal/persist-admin-notices-dismissal.php' );
39 |
40 | $loader->register();
41 |
42 | $email_log = new \EmailLog\Core\EmailLog( $plugin_file, $loader, new \EmailLog\Core\DB\TableManager() );
43 |
44 | if ( \EmailLog\Util\is_admin_non_ajax_request() ) {
45 | // Loading licenser in frontend or ajax request is resulting in huge performance issues.
46 | $email_log->set_licenser( new \EmailLog\Addon\License\Licenser() );
47 |
48 | $email_log->add_loadie( new \EmailLog\Addon\Upseller() );
49 | $email_log->add_loadie( new \EmailLog\Addon\DependencyEnforcer() );
50 | }
51 |
52 | $email_log->add_loadie( new \EmailLog\Core\EmailLogger() );
53 | $email_log->add_loadie( new \EmailLog\Core\UI\UILoader() );
54 |
55 | $email_log->add_loadie( new \EmailLog\Core\Request\NonceChecker() );
56 | $email_log->add_loadie( new \EmailLog\Core\Request\LogListAction() );
57 |
58 | $capability_giver = new \EmailLog\Core\AdminCapabilityGiver();
59 | $email_log->add_loadie( $capability_giver );
60 |
61 | // `register_activation_hook` can't be called from inside any hook.
62 | register_activation_hook( $plugin_file, array( $email_log->table_manager, 'on_activate' ) );
63 | register_activation_hook( $plugin_file, array( $capability_giver, 'add_cap_to_admin' ) );
64 |
65 | // Ideally the plugin should be loaded in a later event like `init` or `wp_loaded`.
66 | // But some plugins like EDD are sending emails in `init` event itself,
67 | // which won't be logged if the plugin is loaded in `wp_loaded` or `init`.
68 | add_action( 'plugins_loaded', array( $email_log, 'load' ), 101 );
69 | }
70 |
71 | /**
72 | * Return the global instance of Email Log plugin.
73 | * Eventually the EmailLog class might become singleton.
74 | *
75 | * @since 2.0
76 | *
77 | * @global \EmailLog\Core\EmailLog $email_log
78 | *
79 | * @return \EmailLog\Core\EmailLog
80 | */
81 | function email_log() {
82 | global $email_log;
83 |
84 | return $email_log;
85 | }
86 |
--------------------------------------------------------------------------------
/include/Core/UI/Page/SystemInfoPage.php:
--------------------------------------------------------------------------------
1 | system_info = new EmailLogSystemInfo( 'email-log' );
35 | $this->system_info->load();
36 | }
37 |
38 | public function register_page() {
39 | $this->page = add_submenu_page(
40 | LogListPage::PAGE_SLUG,
41 | __( 'System Info', 'email-log' ),
42 | __( 'System Info', 'email-log' ),
43 | self::CAPABILITY,
44 | self::PAGE_SLUG,
45 | array( $this, 'render_page' )
46 | );
47 |
48 | add_action( "load-{$this->page}", array( $this, 'render_help_tab' ) );
49 |
50 | /**
51 | * Fires before loading Sytem Info page.
52 | *
53 | * @since 2.3.0
54 | *
55 | * @param string $page Page slug.
56 | */
57 | do_action( 'el_load_system_info_page', $this->page );
58 | }
59 |
60 | /**
61 | * Render the page.
62 | */
63 | public function render_page() {
64 | ?>
65 |
66 |
99 |
100 | render_page_footer();
102 | }
103 |
104 | /**
105 | * Download System info file.
106 | */
107 | public function download_system_info() {
108 | $this->system_info->download_as_file();
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/include/Addon/DependencyEnforcer.php:
--------------------------------------------------------------------------------
1 | '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 |
45 |
46 |
47 |
48 | ' . esc_html( $addon ) . '';
51 | } );
52 | ?>
53 |
54 |
55 |
56 |
57 | get_outdated_active_addons();
71 | foreach ( $outdated_active_addons as $addon_file_name => $outdated_active_addon ) {
72 | deactivate_plugins( plugin_basename( $addon_file_name ) );
73 | $deactivated_active_addons[] = $outdated_active_addon['Name'] . ' ' . $outdated_active_addon['Version'];
74 | }
75 |
76 | return $deactivated_active_addons;
77 | }
78 |
79 | /**
80 | * Get the list of add-ons that are outdated and are active.
81 | *
82 | * @access private
83 | *
84 | * @return array List of outdated and active add-ons.
85 | */
86 | private function get_outdated_active_addons() {
87 | $outdated_active_addons = array();
88 | $plugins = get_plugins();
89 |
90 | foreach ( $this->addon_dependency_map as $addon => $required_version ) {
91 | if ( is_plugin_active( $addon ) ) {
92 | $active_addon = $plugins[ $addon ];
93 |
94 | if ( version_compare( $active_addon['Version'], $required_version, '<' ) ) {
95 | $outdated_active_addons[ $addon ] = $active_addon;
96 | }
97 | }
98 | }
99 |
100 | return $outdated_active_addons;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/include/Addon/API/EDDUpdater.php:
--------------------------------------------------------------------------------
1 | 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 | * The name part of the add-on file without .php extension.
19 | *
20 | * The base class already has a slug property but it is private.
21 | * So we have to create a duplicate to handle that.
22 | *
23 | * @var string
24 | */
25 | protected $addon_slug;
26 |
27 | /**
28 | * Directory and filename of the add-on.
29 | *
30 | * The base class already has a slug property but it is private.
31 | * So we have to create a duplicate to handle that.
32 | *
33 | * @since 2.2.4
34 | *
35 | * @var string
36 | */
37 | protected $addon_name;
38 |
39 | /**
40 | * Extract add-on slug alone and then pass everything to parent.
41 | *
42 | * @param string $_api_url The URL pointing to the custom API endpoint.
43 | * @param string $_plugin_file Path to the plugin file.
44 | * @param array|null $_api_data Optional data to send with API calls.
45 | */
46 | public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
47 | $this->addon_slug = basename( $_plugin_file, '.php' );
48 | $this->addon_name = plugin_basename( $_plugin_file );
49 |
50 | parent::__construct( $_api_url, $_plugin_file, $_api_data );
51 | }
52 |
53 | /**
54 | * Overridden to disable `check_update` on the add-ons that are not installed.
55 | *
56 | * @inheritdoc
57 | *
58 | * @since 2.2.0
59 | */
60 | public function init() {
61 | parent::init();
62 |
63 | $installed_plugins = array_keys( get_plugins() );
64 |
65 | if ( in_array( $this->get_name(), $installed_plugins, true ) ) {
66 | return;
67 | }
68 |
69 | remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
70 | }
71 |
72 | /**
73 | * Get add-on slug.
74 | *
75 | * The name part of the add-on file without .php extension.
76 | *
77 | * @return string Add-on slug.
78 | */
79 | public function get_slug() {
80 | return $this->addon_slug;
81 | }
82 |
83 | /**
84 | * Get the add-on name.
85 | *
86 | * Directory and filename of the add-on.
87 | *
88 | * @since 2.2.4
89 | *
90 | * @return string Add-on name.
91 | */
92 | public function get_name() {
93 | return $this->addon_name;
94 | }
95 |
96 | /**
97 | * Get Download URL.
98 | *
99 | * We can't call `api_request` method directly since it is declared as private in parent class.
100 | * So we call the `plugins_api_filter` method instead.
101 | *
102 | * @return string Download url.
103 | */
104 | public function get_download_url() {
105 | $args = new \stdClass();
106 | $args->slug = $this->get_slug();
107 |
108 | $response = $this->plugins_api_filter( null, 'plugin_information', $args );
109 |
110 | if ( ! $response instanceof \stdClass || ! property_exists( $response, 'package' ) ) {
111 | return '';
112 | }
113 |
114 | return $response->package;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/include/Core/UI/Page/SettingsPage.php:
--------------------------------------------------------------------------------
1 | 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 | *
76 | * @param \EmailLog\Core\UI\Setting\SettingSection[] List of SettingSections.
77 | */
78 | return apply_filters( 'el_setting_sections', array() );
79 | }
80 |
81 | /**
82 | * Register page.
83 | */
84 | public function register_page() {
85 |
86 | $sections = $this->get_setting_sections();
87 |
88 | if ( empty( $sections ) ) {
89 | return;
90 | }
91 |
92 | $this->page = add_submenu_page(
93 | LogListPage::PAGE_SLUG,
94 | __( 'Settings', 'email-log' ),
95 | __( 'Settings', 'email-log' ),
96 | 'manage_options',
97 | self::PAGE_SLUG,
98 | array( $this, 'render_page' )
99 | );
100 |
101 | add_action( "load-{$this->page}", array( $this, 'render_help_tab' ) );
102 | }
103 |
104 | /**
105 | * Render the page.
106 | * //TODO: Convert these sections into tabs.
107 | */
108 | public function render_page() {
109 | ?>
110 |
111 |
112 |
113 |
122 |
123 |
124 | render_page_footer();
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/tests/wp-tests/EmailLogAutoloaderTest.php:
--------------------------------------------------------------------------------
1 | class_files = $class_files;
16 | }
17 |
18 | protected function require_file( $file ) {
19 | return in_array( $file, $this->class_files );
20 | }
21 |
22 | public function get_files() {
23 | return $this->files;
24 | }
25 | }
26 |
27 | /**
28 | * Test Autoloader
29 | * @package EmailLog
30 | */
31 | class EmailLogAutoloaderTest extends \PHPUnit_Framework_TestCase {
32 | protected $loader;
33 |
34 | protected function setUp() {
35 | $this->loader = new MockEmailLogAutoloaderClass;
36 |
37 | $this->loader->set_class_files( array(
38 | '/vendor/foo.bar/src/ClassName.php',
39 | '/vendor/foo.bar/src/DoomClassName.php',
40 | '/vendor/foo.bar/tests/ClassNameTest.php',
41 | '/vendor/foo.bardoom/src/ClassName.php',
42 | '/vendor/foo.bar.baz.dib/src/ClassName.php',
43 | '/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php',
44 | ) );
45 |
46 | $this->loader->add_namespace(
47 | 'Foo\Bar',
48 | '/vendor/foo.bar/src'
49 | );
50 |
51 | $this->loader->add_namespace(
52 | 'Foo\Bar',
53 | '/vendor/foo.bar/tests'
54 | );
55 |
56 | $this->loader->add_namespace(
57 | 'Foo\BarDoom',
58 | '/vendor/foo.bardoom/src'
59 | );
60 |
61 | $this->loader->add_namespace(
62 | 'Foo\Bar\Baz\Dib',
63 | '/vendor/foo.bar.baz.dib/src'
64 | );
65 |
66 | $this->loader->add_namespace(
67 | 'Foo\Bar\Baz\Dib\Zim\Gir',
68 | '/vendor/foo.bar.baz.dib.zim.gir/src'
69 | );
70 | }
71 |
72 | public function testExistingFile() {
73 | $actual = $this->loader->load_class( 'Foo\Bar\ClassName' );
74 | $expect = '/vendor/foo.bar/src/ClassName.php';
75 | $this->assertSame( $expect, $actual );
76 |
77 | $actual = $this->loader->load_class( 'Foo\Bar\ClassNameTest' );
78 | $expect = '/vendor/foo.bar/tests/ClassNameTest.php';
79 | $this->assertSame( $expect, $actual );
80 | }
81 |
82 | public function testMissingFile() {
83 | $actual = $this->loader->load_class( 'No_Vendor\No_Package\NoClass' );
84 | $this->assertFalse( $actual );
85 | }
86 |
87 | public function testDeepFile() {
88 | $actual = $this->loader->load_class( 'Foo\Bar\Baz\Dib\Zim\Gir\ClassName' );
89 | $expect = '/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php';
90 | $this->assertSame( $expect, $actual );
91 | }
92 |
93 | public function testConfusion() {
94 | $actual = $this->loader->load_class( 'Foo\Bar\DoomClassName' );
95 | $expect = '/vendor/foo.bar/src/DoomClassName.php';
96 | $this->assertSame( $expect, $actual );
97 |
98 | $actual = $this->loader->load_class( 'Foo\BarDoom\ClassName' );
99 | $expect = '/vendor/foo.bardoom/src/ClassName.php';
100 | $this->assertSame( $expect, $actual );
101 | }
102 |
103 | public function testFileIsAdded() {
104 | $file_name = 'path/to/some/file';
105 | $this->loader->add_file( $file_name );
106 |
107 | $actual = in_array( $file_name, $this->loader->get_files() );
108 |
109 | $this->assertTrue( $actual );
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/include/Core/Request/NonceChecker.php:
--------------------------------------------------------------------------------
1 | Bulk actions from the top dropdown.
31 | * action2 => Bulk actions from the bottom dropdown.
32 | */
33 | public function check_nonce() {
34 | if ( ! isset( $_POST['el-action'] ) && ! isset( $_REQUEST['action'] ) && ! isset( $_REQUEST['action2'] ) ) {
35 | return;
36 | }
37 |
38 | if ( isset( $_POST['el-action'] ) ) {
39 | $action = sanitize_text_field( $_POST['el-action'] );
40 |
41 | $allowed_actions = [
42 | 'el-download-system-info',
43 | 'el_license_activate',
44 | 'el_license_deactivate',
45 | 'el_bundle_license_activate',
46 | 'el_bundle_license_deactivate',
47 | 'el-log-list-export',
48 | 'el-log-list-export-all',
49 | 'el-export-logs-with-columns'
50 | ];
51 |
52 | if ( ! in_array( $action, $allowed_actions ) ) {
53 | return;
54 | }
55 |
56 | if ( ! isset( $_POST[ $action . '_nonce' ] ) ) {
57 | return;
58 | }
59 |
60 | if ( ! wp_verify_nonce( $_POST[ $action . '_nonce' ], $action ) ) {
61 | return;
62 | }
63 | }
64 |
65 | if ( isset( $_REQUEST['action'] ) || isset( $_REQUEST['action2'] ) ) {
66 | $action = sanitize_text_field( $_REQUEST['action'] );
67 |
68 | if ( '-1' === $action ) {
69 | if ( ! isset( $_REQUEST['action2'] ) ) {
70 | return;
71 | }
72 |
73 | $action = sanitize_text_field( $_REQUEST['action2'] );
74 | }
75 |
76 | if ( strpos( $action, 'el-log-list-' ) !== 0 && strpos( $action, 'el-cron-' ) !== 0 ) {
77 | return;
78 | }
79 |
80 | if ( strpos( $action, 'el-log-list-' ) === 0 ) {
81 | if ( ! isset( $_REQUEST[ LogListPage::LOG_LIST_ACTION_NONCE_FIELD ] ) ) {
82 | return;
83 | }
84 |
85 | if ( ! wp_verify_nonce( $_REQUEST[ LogListPage::LOG_LIST_ACTION_NONCE_FIELD ], LogListPage::LOG_LIST_ACTION_NONCE ) ) {
86 | return;
87 | }
88 | }
89 |
90 | if ( strpos( $action, 'el-cron-' ) === 0 ) {
91 | if ( ! isset( $_REQUEST[ $action . '-nonce-field' ] ) ) {
92 | return;
93 | }
94 |
95 | if ( ! wp_verify_nonce( $_REQUEST[ $action . '-nonce-field' ], $action . '-nonce' ) ) {
96 | return;
97 | }
98 | }
99 | }
100 |
101 | /**
102 | * Perform `el` action.
103 | * Nonce check has already happened at this point.
104 | *
105 | * @since 2.0.0
106 | *
107 | * @param string $action Action name.
108 | * @param array $_REQUEST Request data.
109 | */
110 | do_action( 'el_action', $action, $_REQUEST );
111 |
112 | /**
113 | * Perform `el` action.
114 | * Nonce check has already happened at this point.
115 | *
116 | * @since 2.0.0
117 | *
118 | * @param array $_REQUEST Request data.
119 | */
120 | do_action( $action, $_REQUEST );
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/include/Core/UI/Page/BasePage.php:
--------------------------------------------------------------------------------
1 | ' .
49 | __( 'Email Log is a WordPress plugin that allows you to easily log and view all emails sent from WordPress.', 'email-log' ) .
50 | '' .
51 | '' .
52 | __( 'You can view the logged emails from the View Logs screen. ', 'email-log' ) .
53 | sprintf(
54 | __( 'Check the documentation about the View Logs screen 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 | '
' .
58 | '' .
59 | sprintf(
60 | __( 'You can perform advanced actions like re-sending email, automatically forwarding emails or export logs with our premium plugins.', 'email-log' ),
61 | 'https://wpemaillog.com/store/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=help&utm_content=store-content'
62 | ) .
63 | '
';
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 | '' . __( 'More information', 'email-log' ) . '
' .
76 | '' . __( 'Documentation', 'email-log' ) . '
' .
77 | '' . __( 'Support', 'email-log' ) . '
' .
78 | '' . __( 'Add-ons', 'email-log' ) . '
'
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 | }
107 |
--------------------------------------------------------------------------------
/include/Core/UI/Component/AdminUIEnhancer.php:
--------------------------------------------------------------------------------
1 | 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 | *
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[] = '' .
69 | __( 'Buy Addons', 'email-log' ) . '';
70 | }
71 |
72 | return $links;
73 | }
74 |
75 | /**
76 | * Add link to 'View logs' page in plugin listing page.
77 | *
78 | * @since 2.3.0 Added Settings link.
79 | *
80 | * @param array $links List of links.
81 | *
82 | * @return array Modified list of links.
83 | */
84 | public function insert_view_logs_link( $links ) {
85 | $view_logs_link = '' . __( 'View Logs', 'email-log' ) . '';
86 | $settings_link = '' . __( 'Settings', 'email-log' ) . '';
87 | array_unshift( $links, $view_logs_link, $settings_link );
88 |
89 | return $links;
90 | }
91 |
92 | /**
93 | * Hook Footer links.
94 | */
95 | public function hook_footer_links() {
96 | add_action( 'in_admin_footer', array( $this, 'add_credit_links' ) );
97 | }
98 |
99 | /**
100 | * Adds Footer links.
101 | *
102 | * @since Genesis
103 | * @see Function relied on
104 | * @link http://striderweb.com/nerdaphernalia/2008/06/give-your-wordpress-plugin-credit/
105 | */
106 | public function add_credit_links() {
107 | $plugin_data = get_plugin_data( $this->plugin_file );
108 | printf(
109 | '%1$s ' . __( 'plugin', 'email-log' ) . ' | ' . __( 'Version', 'email-log' ) . ' %2$s | ' . __( 'by', 'email-log' ) . ' %3$s
',
110 | $plugin_data['Title'],
111 | $plugin_data['Version'],
112 | $plugin_data['Author']
113 | );
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/include/Addon/API/EDDAPI.php:
--------------------------------------------------------------------------------
1 | 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 | * @throws \Exception If there is any error while making the request.
98 | *
99 | * TODO: Make the errors more user friendly and provide links to support.
100 | *
101 | * @return object API Response in JSON.
102 | */
103 | protected function call_edd_api( $params ) {
104 | $response = wp_remote_post( $this->store_url, array(
105 | 'timeout' => 15,
106 | 'body' => $params,
107 | ) );
108 |
109 | if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
110 |
111 | if ( is_wp_error( $response ) ) {
112 | throw new \Exception( $response->get_error_message() );
113 | }
114 |
115 | 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' ) );
116 | }
117 |
118 | $body = wp_remote_retrieve_body( $response );
119 | $data = json_decode( $body );
120 |
121 | if ( empty( $data ) ) {
122 | 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' ) );
123 | }
124 |
125 | return $data;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/include/Core/UI/Setting/Setting.php:
--------------------------------------------------------------------------------
1 | section = new SettingSection();
24 |
25 | $this->initialize();
26 |
27 | $this->section->fields = $this->get_fields();
28 | $this->section->callback = array( $this, 'render' );
29 | $this->section->sanitize_callback = array( $this, 'sanitize' );
30 | }
31 |
32 | /**
33 | * Setup hooks and filters.
34 | */
35 | public function load() {
36 | add_filter( 'el_setting_sections', array( $this, 'register' ) );
37 | }
38 |
39 | /**
40 | * Register the setting using the filter.
41 | *
42 | * @param SettingSection[] $sections List of existing SettingSections.
43 | *
44 | * @return SettingSection[] Modified list of SettingSections.
45 | */
46 | public function register( $sections ) {
47 | $sections[] = $this->section;
48 |
49 | return $sections;
50 | }
51 |
52 | /**
53 | * Get the value stored in the option.
54 | * If no values are found then the default values are returned.
55 | *
56 | * @return array Stored value.
57 | */
58 | public function get_value() {
59 | $value = get_option( $this->section->option_name );
60 |
61 | return wp_parse_args( $value, $this->section->default_value );
62 | }
63 |
64 | /**
65 | * Customize the SettingSection.
66 | *
67 | * @return void
68 | */
69 | abstract protected function initialize();
70 |
71 | /**
72 | * Get the list of SettingFields.
73 | *
74 | * @return SettingField[] List of fields for the Setting.
75 | */
76 | protected function get_fields() {
77 | return $this->build_fields();
78 | }
79 |
80 | /**
81 | * Render the Settings section.
82 | *
83 | * By default it does nothing.
84 | */
85 | public function render() {
86 | return;
87 | }
88 |
89 | /**
90 | * Sanitize the option values.
91 | *
92 | * @param mixed $values User entered values.
93 | *
94 | * @return mixed Sanitized values.
95 | */
96 | public function sanitize( $values ) {
97 | if ( ! is_array( $values ) ) {
98 | return array();
99 | }
100 |
101 | $values = wp_parse_args( $values, $this->section->default_value );
102 | $sanitized_values = array();
103 |
104 | foreach ( $this->section->field_labels as $field_id => $label ) {
105 | $callback = array( $this, 'sanitize_' . $field_id );
106 |
107 | if ( is_callable( $callback ) ) {
108 | $sanitized_values[ $field_id ] = call_user_func( $callback, $values[ $field_id ] );
109 | } else {
110 | $sanitized_values[ $field_id ] = $values[ $field_id ];
111 | }
112 | }
113 |
114 | return $sanitized_values;
115 | }
116 |
117 | /**
118 | * Build SettingField objects from field id and labels.
119 | *
120 | * @since 2.1.0
121 | *
122 | * @return \EmailLog\Core\UI\Setting\SettingField[] Built SettingFields.
123 | */
124 | protected function build_fields() {
125 | $fields = array();
126 |
127 | foreach ( $this->section->field_labels as $field_id => $label ) {
128 | $field = new SettingField();
129 | $field->id = $field_id;
130 | $field->title = $label;
131 | $field->args = array( 'id' => $field_id );
132 | $field->callback = array( $this, 'render_' . $field_id . '_settings' );
133 |
134 | $fields[] = $field;
135 | }
136 |
137 | return $fields;
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/bin/install-wp-tests.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [ $# -lt 3 ]; then
4 | echo "usage: $0 [db-host] [wp-version] [skip-database-creation]"
5 | exit 1
6 | fi
7 |
8 | DB_NAME=$1
9 | DB_USER=$2
10 | DB_PASS=$3
11 | DB_HOST=${4-localhost}
12 | WP_VERSION=${5-latest}
13 | SKIP_DB_CREATE=${6-false}
14 |
15 | WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib}
16 | WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/}
17 |
18 | download() {
19 | if [ `which curl` ]; then
20 | curl -s "$1" > "$2";
21 | elif [ `which wget` ]; then
22 | wget -nv -O "$2" "$1"
23 | fi
24 | }
25 |
26 | if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then
27 | WP_TESTS_TAG="tags/$WP_VERSION"
28 | elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
29 | WP_TESTS_TAG="trunk"
30 | else
31 | # http serves a single offer, whereas https serves multiple. we only want one
32 | download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
33 | grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
34 | LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
35 | if [[ -z "$LATEST_VERSION" ]]; then
36 | echo "Latest WordPress version could not be found"
37 | exit 1
38 | fi
39 | WP_TESTS_TAG="tags/$LATEST_VERSION"
40 | fi
41 |
42 | set -ex
43 |
44 | install_wp() {
45 |
46 | if [ -d $WP_CORE_DIR ]; then
47 | return;
48 | fi
49 |
50 | mkdir -p $WP_CORE_DIR
51 |
52 | if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
53 | mkdir -p /tmp/wordpress-nightly
54 | download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip
55 | unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/
56 | mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR
57 | else
58 | if [ $WP_VERSION == 'latest' ]; then
59 | local ARCHIVE_NAME='latest'
60 | else
61 | local ARCHIVE_NAME="wordpress-$WP_VERSION"
62 | fi
63 | download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz
64 | tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
65 | fi
66 |
67 | download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
68 | }
69 |
70 | install_test_suite() {
71 | # portable in-place argument for both GNU sed and Mac OSX sed
72 | if [[ $(uname -s) == 'Darwin' ]]; then
73 | local ioption='-i .bak'
74 | else
75 | local ioption='-i'
76 | fi
77 |
78 | # set up testing suite if it doesn't yet exist
79 | if [ ! -d $WP_TESTS_DIR ]; then
80 | # set up testing suite
81 | mkdir -p $WP_TESTS_DIR
82 | svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
83 | fi
84 |
85 | if [ ! -f wp-tests-config.php ]; then
86 | download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
87 | # remove all forward slashes in the end
88 | WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
89 | sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
90 | sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
91 | sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
92 | sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
93 | sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
94 | fi
95 |
96 | }
97 |
98 | install_db() {
99 |
100 | if [ ${SKIP_DB_CREATE} = "true" ]; then
101 | return 0
102 | fi
103 |
104 | # parse DB_HOST for port or socket references
105 | local PARTS=(${DB_HOST//\:/ })
106 | local DB_HOSTNAME=${PARTS[0]};
107 | local DB_SOCK_OR_PORT=${PARTS[1]};
108 | local EXTRA=""
109 |
110 | if ! [ -z $DB_HOSTNAME ] ; then
111 | if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
112 | EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
113 | elif ! [ -z $DB_SOCK_OR_PORT ] ; then
114 | EXTRA=" --socket=$DB_SOCK_OR_PORT"
115 | elif ! [ -z $DB_HOSTNAME ] ; then
116 | EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
117 | fi
118 | fi
119 |
120 | # create database
121 | mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
122 | }
123 |
124 | install_wp
125 | install_test_suite
126 | install_db
127 |
--------------------------------------------------------------------------------
/include/Addon/Upseller.php:
--------------------------------------------------------------------------------
1 | ';
33 | _e( 'Additional fields are available through More Fields add-on. ', 'email-log' );
34 |
35 | if ( $this->is_bundle_license_valid() ) {
36 | echo '';
37 | _e( 'Install it', 'email-log' );
38 | echo '';
39 | } else {
40 | echo '';
41 | _e( 'Buy Now', 'email-log' );
42 | echo '';
43 | }
44 |
45 | echo '';
46 | }
47 |
48 | /**
49 | * Renders Upsell message for Auto delete logs add-on in Log list page
50 | * if the number of logs is greater than 5000.
51 | *
52 | * @param int $total_logs Total number of logs.
53 | *
54 | */
55 | public function upsell_auto_delete_logs_in_log_list_page( $total_logs ) {
56 | if ( $total_logs < 5000 ) {
57 | return;
58 | }
59 |
60 | if ( $this->is_addon_active( 'Auto Delete Logs' ) ) {
61 | return;
62 | }
63 |
64 | if ( ! class_exists( 'PAnD' ) || ! \PAnD::is_admin_notice_active( 'disable-DL-upsell-notice-5000' ) ) {
65 | return;
66 | }
67 | ?>
68 |
69 |
70 |
71 | Auto Delete Logs'
76 | );
77 | ?>
78 |
79 |
80 |
81 | is_addon_active( 'Auto Delete Logs' ) ) {
89 | return;
90 | }
91 |
92 | ?>
93 |
94 |
95 | Auto Delete Logs'
99 | );
100 | ?>
101 |
102 |
103 | get_licenser();
115 |
116 | if ( $licenser->is_bundle_license_valid() ) {
117 | return true;
118 | }
119 |
120 | return $licenser->is_addon_active( $addon_name );
121 | }
122 |
123 | /**
124 | * Has valid bundle license?
125 | *
126 | * @return bool True if bundle license is valid, false otherwise.
127 | */
128 | protected function is_bundle_license_valid() {
129 | $licenser = email_log()->get_licenser();
130 |
131 | if ( $licenser->is_bundle_license_valid() ) {
132 | return true;
133 | }
134 |
135 | return false;
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/tests/wp-tests/Util/SanitizeEmailTest.php:
--------------------------------------------------------------------------------
1 | assertEquals( $expected, $actual );
15 | }
16 |
17 | function test_email_is_valid() {
18 | $invalid_email = 'sudar@sudarmuthu';
19 |
20 | $expected = '';
21 | $actual = sanitize_email( $invalid_email );
22 |
23 | $this->assertEquals( $expected, $actual );
24 | }
25 |
26 | function test_email_with_name() {
27 | $email_with_name = 'Sudar Muthu';
28 |
29 | $expected = 'Sudar Muthu ';
30 | $actual_1 = sanitize_email( $email_with_name );
31 | $actual_2 = sanitize_email_with_name( $email_with_name );
32 |
33 | $this->assertEquals( $expected, $actual_1 );
34 | $this->assertEquals( $expected, $actual_2 );
35 | }
36 |
37 | function test_email_with_name_and_space() {
38 | $email_with_name_and_space = ' Sudar Muthu ';
39 |
40 | $expected = 'Sudar Muthu ';
41 | $actual = sanitize_email( $email_with_name_and_space );
42 |
43 | $this->assertEquals( $expected, $actual);
44 | }
45 |
46 | function test_multiple_simple_email_returns_first() {
47 | $multiple_emails = 'sudar@sudarmuthu.com, muthu@sudarmuthu.com';
48 |
49 | $expected = 'sudar@sudarmuthu.com';
50 | $actual = sanitize_email( $multiple_emails, false );
51 |
52 | $this->assertEquals( $expected, $actual );
53 | }
54 |
55 | function test_trimed_multiple_simple_email_returns_first() {
56 | $multiple_emails = ' sudar@sudarmuthu.com, muthu@sudarmuthu.com ';
57 |
58 | $expected = 'sudar@sudarmuthu.com';
59 | $actual = sanitize_email( $multiple_emails, false );
60 |
61 | $this->assertEquals( $expected, $actual );
62 | }
63 |
64 | function test_multiple_simple_email_returns_all() {
65 | $multiple_emails = 'sudar@sudarmuthu.com, muthu@sudarmuthu.com';
66 |
67 | $expected = 'sudar@sudarmuthu.com, muthu@sudarmuthu.com';
68 | $actual = sanitize_email( $multiple_emails, true );
69 |
70 | $this->assertEquals( $expected, $actual );
71 | }
72 |
73 | function test_trimed_multiple_simple_email_returns_all() {
74 | $multiple_emails = ' sudar@sudarmuthu.com , muthu@sudarmuthu.com ';
75 |
76 | $expected = 'sudar@sudarmuthu.com, muthu@sudarmuthu.com';
77 | $actual = sanitize_email( $multiple_emails, true );
78 |
79 | $this->assertEquals( $expected, $actual );
80 | }
81 |
82 | function test_multiple_simple_email() {
83 | $multiple_emails = 'sudar@sudarmuthu.com, muthu@sudarmuthu.com';
84 |
85 | $expected = 'sudar@sudarmuthu.com, muthu@sudarmuthu.com';
86 | $actual = sanitize_email( $multiple_emails );
87 |
88 | $this->assertEquals( $expected, $actual );
89 | }
90 |
91 | function test_trimed_multiple_simple_email() {
92 | $multiple_emails = ' sudar@sudarmuthu.com , muthu@sudarmuthu.com ';
93 |
94 | $expected = 'sudar@sudarmuthu.com, muthu@sudarmuthu.com';
95 | $actual = sanitize_email( $multiple_emails );
96 |
97 | $this->assertEquals( $expected, $actual );
98 | }
99 |
100 | function test_multiple_email_with_name() {
101 | $multiple_emails = 'Sudar Muthu , Muthu';
102 |
103 | $expected = 'Sudar Muthu , Muthu ';
104 | $actual = sanitize_email( $multiple_emails );
105 |
106 | $this->assertEquals( $expected, $actual );
107 | }
108 |
109 | function test_multiple_email_with_name_and_quotes() {
110 | $multiple_emails = '"Sudar Muthu" , "Muthu"';
111 |
112 | $expected = '"Sudar Muthu" , "Muthu" ';
113 | $actual = sanitize_email( $multiple_emails );
114 |
115 | $this->assertEquals( $expected, $actual );
116 | }
117 |
118 | function test_multiple_email_with_name_returns_first() {
119 | $multiple_emails = 'Sudar Muthu , Muthu ';
120 |
121 | $expected = 'Sudar Muthu ';
122 | $actual = sanitize_email( $multiple_emails, false );
123 |
124 | $this->assertEquals( $expected, $actual );
125 | }
126 | }
127 |
128 |
--------------------------------------------------------------------------------
/include/Core/UI/Component/EmailLogSystemInfo.php:
--------------------------------------------------------------------------------
1 |
40 | -- Email Log Configuration --
41 |
42 | Email Log Version:
43 | Number of Logs: table_manager->get_logs_count() . "\n"; ?>
44 | Email Log DB Version:
45 |
46 | Additional allowed user roles:
47 | Remove All Data on Uninstallation:
48 | Disable DashBoard Widget:
49 |
50 |
51 | get_bundle_license();
60 |
61 | if ( ! is_null( $bundle_license ) ) {
62 | $this->print_bundle_license_details( $bundle_license );
63 | } else {
64 | $this->print_individual_addon_license();
65 | }
66 | }
67 |
68 | /**
69 | * Get Bundle license.
70 | *
71 | * @return \EmailLog\Addon\License\BundleLicense|null Bundle license or null if no bundle license.
72 | */
73 | protected function get_bundle_license() {
74 | $email_log = email_log();
75 |
76 | $licenser = $email_log->get_licenser();
77 | $bundle_license = $licenser->get_bundle_license();
78 |
79 | $bundle_license_key = $bundle_license->get_license_key();
80 | if ( ! empty( $bundle_license_key ) ) {
81 | return $bundle_license;
82 | }
83 |
84 | return null;
85 | }
86 |
87 | /**
88 | * Print bundle license details.
89 | *
90 | * @param \EmailLog\Addon\License\BundleLicense $bundle_license Bundle license.
91 | *
92 | * PHPCS is disabled for this function since alignment will mess up the system info output.
93 | * phpcs:disable
94 | */
95 | protected function print_bundle_license_details( $bundle_license ) {
96 | ?>
97 | -- Email Log Bundle License --
98 |
99 | License Key: get_license_key(), "\n"; ?>
100 | License Expiry Date: get_expiry_date(), "\n"; ?>
101 | is_valid() ) : ?>
102 | License Valid:
103 |
104 | License Valid:
105 |
106 |
107 | get_licenser();
121 | $addons = $licenser->get_addon_list()->get_addons();
122 | ?>
123 | -- Email Log Addon License --
124 |
125 | name;
128 |
129 | $license_key = $addon->get_addon_license_key();
130 |
131 | if ( ! empty( $license_key ) ) {
132 | $addon_license = $addon->get_license();
133 | echo ' (', $license_key, ' - ', $addon_license->get_expiry_date(), ')';
134 | }
135 |
136 | echo "\n";
137 | }
138 | echo "\n";
139 | }
140 | // phpcs:enable
141 |
142 | /**
143 | * Change the default config.
144 | *
145 | * @return array Modified config.
146 | */
147 | protected function get_default_config() {
148 | $config = parent::get_default_config();
149 |
150 | $config['show_posts'] = false;
151 | $config['show_taxonomies'] = false;
152 | $config['show_users'] = false;
153 |
154 | return $config;
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/include/Core/EmailLog.php:
--------------------------------------------------------------------------------
1 | plugin_file = $file;
108 | $this->loader = $loader;
109 | $this->table_manager = $table_manager;
110 |
111 | $this->add_loadie( $table_manager );
112 |
113 | $this->translations_path = dirname( plugin_basename( $this->plugin_file ) ) . '/languages/' ;
114 | }
115 |
116 | /**
117 | * Set Licenser.
118 | *
119 | * @param \EmailLog\Addon\License\Licenser $licenser Add-on Licenser.
120 | */
121 | public function set_licenser( $licenser ) {
122 | if ( $this->add_loadie( $licenser ) ) {
123 | $this->licenser = $licenser;
124 | }
125 | }
126 |
127 | /**
128 | * Get Licenser.
129 | *
130 | * @return \EmailLog\Addon\License\Licenser|null
131 | */
132 | public function get_licenser() {
133 | return $this->licenser;
134 | }
135 |
136 | /**
137 | * Add an Email Log Loadie.
138 | * The `load()` method of the Loadies will be called when Email Log is loaded.
139 | *
140 | * @param \EmailLog\Core\Loadie $loadie Loadie to be loaded.
141 | *
142 | * @return bool False if Email Log is already loaded or if $loadie is not of `Loadie` type. True otherwise.
143 | */
144 | public function add_loadie( $loadie ) {
145 | if ( $this->loaded ) {
146 | return false;
147 | }
148 |
149 | if ( ! $loadie instanceof Loadie ) {
150 | return false;
151 | }
152 |
153 | $this->loadies[] = $loadie;
154 |
155 | return true;
156 | }
157 |
158 | /**
159 | * Load the plugin.
160 | */
161 | public function load() {
162 | if ( $this->loaded ) {
163 | return;
164 | }
165 |
166 | load_plugin_textdomain( 'email-log', false, $this->translations_path );
167 |
168 | $this->table_manager->load();
169 |
170 | foreach ( $this->loadies as $loadie ) {
171 | $loadie->load();
172 | }
173 |
174 | $this->loaded = true;
175 |
176 | /**
177 | * Email Log plugin loaded.
178 | *
179 | * @since 2.0
180 | */
181 | do_action( 'el_loaded' );
182 | }
183 |
184 | /**
185 | * Plugin API has been overridden.
186 | *
187 | * @since 2.4.5
188 | */
189 | public function plugin_api_overridden() {
190 | $this->plugins_api_overridden = true;
191 | }
192 |
193 | /**
194 | * Has the plugin API have been overridden?
195 | *
196 | * @since 2.4.5
197 | *
198 | * @return bool True if overridden, False otherwise.
199 | */
200 | public function is_plugin_api_overridden() {
201 | return $this->plugins_api_overridden;
202 | }
203 |
204 | /**
205 | * Return Email Log version.
206 | *
207 | * @return string Email Log Version.
208 | */
209 | public function get_version() {
210 | return self::VERSION;
211 | }
212 |
213 | /**
214 | * Return the Email Log plugin directory path.
215 | *
216 | * @return string Plugin directory path.
217 | */
218 | public function get_plugin_path() {
219 | return plugin_dir_path( $this->plugin_file );
220 | }
221 |
222 | /**
223 | * Return the Email Log plugin file.
224 | *
225 | * @since 2.0.0
226 | *
227 | * @return string Plugin directory path.
228 | */
229 | public function get_plugin_file() {
230 | return $this->plugin_file;
231 | }
232 |
233 | /**
234 | * Get Email Log Store URL.
235 | *
236 | * @since 2.0.0
237 | *
238 | * @return string Store URL
239 | */
240 | public function get_store_url() {
241 | return self::STORE_URL;
242 | }
243 | }
244 |
--------------------------------------------------------------------------------
/tests/wp-tests/Util/EmailHeaderParserTest.php:
--------------------------------------------------------------------------------
1 | object = new EmailHeaderParser();
13 | }
14 |
15 | public function tearDown() {
16 | parent::tearDown();
17 | }
18 |
19 | /**
20 | * Test `join_headers` method.
21 | *
22 | * Include all the headers in the mock data.
23 | */
24 | function test_join_headers_with_all_data() {
25 | $mock_data = array(
26 | 'from' => 'mariadanieldeepak@gmail.com',
27 | 'cc' => 'maria.danieldeepak@gmail.com',
28 | 'bcc' => 'mariadaniel.deepak@gmail.com',
29 | 'reply_to' => 'mariadanieldeepak@gmail.com',
30 | 'content_type' => 'text/html; charset=iso-8859-1',
31 | );
32 |
33 | $line_break = "\r\n";
34 | $expected = 'From: mariadanieldeepak@gmail.com' . $line_break;
35 | $expected .= 'CC: maria.danieldeepak@gmail.com' . $line_break;
36 | $expected .= 'BCC: mariadaniel.deepak@gmail.com' . $line_break;
37 | $expected .= 'Reply-to: mariadanieldeepak@gmail.com' . $line_break;
38 | $expected .= 'Content-type: text/html; charset=iso-8859-1' . $line_break;
39 | $actual = $this->object->join_headers( $mock_data );
40 |
41 | $this->assertEquals( $expected, $actual );
42 | }
43 |
44 | /**
45 | * Test `join_headers` method.
46 | *
47 | * Include few headers in the mock data.
48 | */
49 | function test_join_headers_with_few_data() {
50 | $mock_data = array(
51 | 'from' => 'mariadanieldeepak@gmail.com',
52 | 'reply_to' => 'mariadanieldeepak@gmail.com'
53 | );
54 |
55 | $line_break = "\r\n";
56 | $expected = 'From: mariadanieldeepak@gmail.com' . $line_break;
57 | $expected .= 'Reply-to: mariadanieldeepak@gmail.com' . $line_break;
58 | $actual = $this->object->join_headers( $mock_data );
59 |
60 | $this->assertEquals( $expected, $actual );
61 | }
62 |
63 | /**
64 | * Test `join_headers` method.
65 | *
66 | * Test with mock data that has no header information.
67 | */
68 | function test_join_headers_with_empty_data() {
69 | $mock_data = array(
70 | 'from' => '',
71 | 'cc' => '',
72 | 'bcc' => '',
73 | 'reply_to' => '',
74 | 'content_type' => '',
75 | );
76 |
77 | $expected = '';
78 | $actual = $this->object->join_headers( $mock_data );
79 |
80 | $this->assertEquals( $expected, $actual );
81 | }
82 |
83 | /**
84 | * Test `parse_headers` method.
85 | *
86 | * Test with all headers.
87 | */
88 | function test_parse_with_all_data() {
89 | $line_break = "\r\n";
90 | $mock_headers = 'From: mariadanieldeepak@gmail.com' . $line_break;
91 | $mock_headers .= 'CC: maria.danieldeepak@gmail.com' . $line_break;
92 | $mock_headers .= 'BCC: mariadaniel.deepak@gmail.com' . $line_break;
93 | $mock_headers .= 'Reply-to: mariadanieldeepak@gmail.com' . $line_break;
94 | $mock_headers .= 'Content-type: text/html; charset=iso-8859-1' . $line_break;
95 |
96 | $expected = array(
97 | 'from' => 'mariadanieldeepak@gmail.com',
98 | 'cc' => 'maria.danieldeepak@gmail.com',
99 | 'bcc' => 'mariadaniel.deepak@gmail.com',
100 | 'reply_to' => 'mariadanieldeepak@gmail.com',
101 | 'content_type' => 'text/html; charset=iso-8859-1',
102 | );
103 | $actual = $this->object->parse_headers( $mock_headers );
104 |
105 | $this->assertEquals( $expected, $actual );
106 | }
107 |
108 | /**
109 | * Test `parse_headers` method.
110 | *
111 | * Test with quotes in headers.
112 | */
113 | function test_parse_with_quotes() {
114 | $line_break = "\r\n";
115 | $mock_headers = 'From: "Maria Daniel" ' . $line_break;
116 | $mock_headers .= 'CC: maria.danieldeepak@gmail.com' . $line_break;
117 | $mock_headers .= 'BCC: mariadaniel.deepak@gmail.com' . $line_break;
118 | $mock_headers .= 'Reply-to: "Maria Daniel" ' . $line_break;
119 | $mock_headers .= 'Content-type: text/html; charset=iso-8859-1' . $line_break;
120 |
121 | $expected = array(
122 | 'from' => '"Maria Daniel" ',
123 | 'cc' => 'maria.danieldeepak@gmail.com',
124 | 'bcc' => 'mariadaniel.deepak@gmail.com',
125 | 'reply_to' => '"Maria Daniel" ',
126 | 'content_type' => 'text/html; charset=iso-8859-1',
127 | );
128 | $actual = $this->object->parse_headers( $mock_headers );
129 |
130 | $this->assertEquals( $expected, $actual );
131 | }
132 | /**
133 | * Test `parse_headers` method.
134 | *
135 | * Test with few headers information.
136 | */
137 | function test_parse_with_few_data() {
138 | $line_break = "\r\n";
139 | $mock_headers = 'CC: maria.danieldeepak@gmail.com' . $line_break;
140 | $mock_headers .= 'BCC: mariadaniel.deepak@gmail.com' . $line_break;
141 | $mock_headers .= 'Content-type: text/html; charset=iso-8859-1' . $line_break;
142 |
143 | $expected = array(
144 | 'cc' => 'maria.danieldeepak@gmail.com',
145 | 'bcc' => 'mariadaniel.deepak@gmail.com',
146 | 'content_type' => 'text/html; charset=iso-8859-1',
147 | );
148 | $actual = $this->object->parse_headers( $mock_headers );
149 |
150 | $this->assertEquals( $expected, $actual );
151 | }
152 |
153 | /**
154 | * Test `parse_headers` method.
155 | *
156 | * Test with no header information.
157 | */
158 | function test_parse_with_no_data() {
159 | $mock_headers = '';
160 | $expected = array();
161 | $actual = $this->object->parse_headers( $mock_headers );
162 |
163 | $this->assertEquals( $expected, $actual );
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/include/Addon/AddonList.php:
--------------------------------------------------------------------------------
1 | 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 | * Is an add-on active?
66 | *
67 | * @since 2.4.0
68 | *
69 | * @param string $name Add-on name.
70 | *
71 | * @return bool True if add-on is present and is active, false otherwise.
72 | */
73 | public function is_addon_active( $name ) {
74 | $addon = $this->get_addon_by_name( $name );
75 |
76 | if ( ! $addon instanceof Addon ) {
77 | return false;
78 | }
79 |
80 | return $addon->is_active();
81 | }
82 |
83 | /**
84 | * Is an add-on installed?
85 | *
86 | * @since 2.4.0
87 | *
88 | * @param string $name Add-on name.
89 | *
90 | * @return bool True if add-on is present and is installed, false otherwise.
91 | */
92 | public function is_addon_installed( $name ) {
93 | $addon = $this->get_addon_by_name( $name );
94 |
95 | if ( ! $addon instanceof Addon ) {
96 | return false;
97 | }
98 |
99 | return $addon->is_installed();
100 | }
101 |
102 | /**
103 | * Get all add-ons that are not active (either not installed or not activated).
104 | *
105 | * @return \EmailLog\Addon\Addon[] List of inactive add-ons.
106 | */
107 | public function get_inactive_addons() {
108 | $inactive_addons = array();
109 |
110 | foreach ( $this->addons as $addon ) {
111 | if ( ! $addon->is_active() ) {
112 | $inactive_addons[] = $addon;
113 | }
114 | }
115 |
116 | return $inactive_addons;
117 | }
118 |
119 | /**
120 | * Setup page to render the list of add-ons.
121 | */
122 | public function render() {
123 | ?>
124 |
125 |
126 | render_addons(); ?>
127 |
128 | get_api_url() );
141 |
142 | if ( is_wp_error( $response ) || ! is_array( $response ) ) {
143 | return [];
144 | }
145 |
146 | $json = json_decode( wp_remote_retrieve_body( $response ), true );
147 |
148 | if ( ! is_array( $json ) ) {
149 | return array();
150 | }
151 |
152 | set_transient( self::CACHE_KEY, $json, self::CACHE_EXPIRY_IN_HRS * HOUR_IN_SECONDS );
153 | }
154 |
155 | return $this->parse_response( $json );
156 | }
157 |
158 | /**
159 | * Parse the response and get the list of add-on.
160 | *
161 | * @param array $data JSON Data array.
162 | *
163 | * @return array List of Add-ons.
164 | */
165 | protected function parse_response( $data ) {
166 | if ( ! array_key_exists( 'products', $data ) ) {
167 | return array();
168 | }
169 |
170 | return $this->build_addon_list( $data['products'] );
171 | }
172 |
173 | /**
174 | * Build a list of Addon objects from products data array.
175 | *
176 | * @param array $products Products data array.
177 | *
178 | * @return Addon[] List of Addons.
179 | */
180 | protected function build_addon_list( $products ) {
181 | $addons = array();
182 |
183 | foreach ( $products as $product ) {
184 | $addon = new Addon( $product );
185 | $addons[ $addon->name ] = $addon;
186 | }
187 |
188 | return $addons;
189 | }
190 |
191 | /**
192 | * Render the add-on list or display an error if the list can't be retrieved.
193 | */
194 | protected function render_addons() {
195 | if ( empty( $this->addons ) ) {
196 | $this->render_empty_list();
197 | }
198 |
199 | foreach ( $this->addons as $addon ) {
200 | $addon->render();
201 | }
202 | }
203 |
204 | /**
205 | * Display a notice if the list of add-on can't be retrieved.
206 | */
207 | protected function render_empty_list() {
208 | ?>
209 |
210 | add-on page to view the add-ons.', 'email-log' ), // @codingStandardsIgnoreLine
213 | 'https://wpemaillog.com/store/?utm_campaign=Upsell&utm_medium=wpadmin&utm_source=addon-grid-failed'
214 | );
215 | ?>
216 |
217 | store_url . '/json/products.json';
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/include/Core/UI/Page/LogListPage.php:
--------------------------------------------------------------------------------
1 | page = add_submenu_page(
67 | self::PAGE_SLUG,
68 | __( 'View Logs', 'email-log'),
69 | __( 'View Logs', 'email-log'),
70 | self::CAPABILITY,
71 | self::PAGE_SLUG,
72 | array( $this, 'render_page' )
73 | );
74 |
75 | add_action( "load-{$this->page}", array( $this, 'load_page' ) );
76 |
77 | /**
78 | * Fires before loading log list page.
79 | *
80 | * @since 2.0
81 | *
82 | * @param string $page Page slug.
83 | */
84 | do_action( 'el_load_log_list_page', $this->page );
85 | }
86 |
87 | /**
88 | * Render page.
89 | */
90 | public function render_page() {
91 | if ( ! current_user_can( self::CAPABILITY ) ) {
92 | return;
93 | }
94 |
95 | add_thickbox();
96 |
97 | $this->log_list_table->prepare_items();
98 | ?>
99 |
100 |
101 |
102 |
103 |
113 |
114 | render_page_footer();
116 | }
117 |
118 | /**
119 | * Load page.
120 | */
121 | public function load_page() {
122 | $this->render_help_tab();
123 |
124 | // Add screen options
125 | $this->get_screen()->add_option(
126 | 'per_page',
127 | array(
128 | 'label' => __( 'Entries per page', 'email-log' ),
129 | 'default' => 20,
130 | 'option' => 'per_page',
131 | )
132 | );
133 |
134 | $this->log_list_table = new LogListTable( $this );
135 | }
136 |
137 | /**
138 | * Gets the per page option.
139 | *
140 | * @return int Number of logs a user wanted to be displayed in a page.
141 | */
142 | public function get_per_page() {
143 | $screen = get_current_screen();
144 | $option = $screen->get_option( 'per_page', 'option' );
145 |
146 | $per_page = get_user_meta( get_current_user_id(), $option, true );
147 |
148 | if ( empty( $per_page ) || $per_page < 1 ) {
149 | $per_page = $screen->get_option( 'per_page', 'default' );
150 | }
151 |
152 | return $per_page;
153 | }
154 |
155 | /**
156 | * Get nonce args.
157 | *
158 | * @return array Nonce args.
159 | */
160 | public function get_nonce_args() {
161 | return array(
162 | self::LOG_LIST_ACTION_NONCE_FIELD => wp_create_nonce( self::LOG_LIST_ACTION_NONCE ),
163 | );
164 | }
165 |
166 | /**
167 | * Get TableManager instance.
168 | *
169 | * @return TableManager TableManager instance.
170 | */
171 | public function get_table_manager() {
172 | $email_log = email_log();
173 |
174 | return $email_log->table_manager;
175 | }
176 |
177 | /**
178 | * Saves Screen options.
179 | *
180 | * @since Genesis
181 | *
182 | * @param bool|int $status Screen option value. Default false to skip.
183 | * @param string $option The option name.
184 | * @param int $value The number of rows to use.
185 | *
186 | * @return bool|int
187 | */
188 | public function save_screen_options( $status, $option, $value ) {
189 | if ( 'per_page' == $option ) {
190 | return $value;
191 | } else {
192 | return $status;
193 | }
194 | }
195 |
196 | /**
197 | * Loads assets on the Log List page.
198 | *
199 | * @since 2.0.0
200 | *
201 | * @param string $hook The current admin page.
202 | */
203 | public function load_view_logs_assets( $hook ) {
204 | // Don't load assets if not View Logs page.
205 | if ( 'toplevel_page_email-log' !== $hook ) {
206 | return;
207 | }
208 |
209 | $email_log = email_log();
210 | $plugin_dir_url = plugin_dir_url( $email_log->get_plugin_file() );
211 |
212 | wp_register_style( 'jquery-ui-css', $plugin_dir_url . 'assets/vendor/jquery-ui/themes/base/jquery-ui.min.css', array(), '1.12.1' );
213 | wp_enqueue_style( 'el-view-logs-css', $plugin_dir_url . 'assets/css/admin/view-logs.css', array( 'jquery-ui-css' ), $email_log->get_version() );
214 |
215 | wp_register_script( 'insertionQ', $plugin_dir_url . 'assets/vendor/insertion-query/insQ.min.js', array( 'jquery' ), '1.0.4', true );
216 |
217 | wp_enqueue_script( 'el-view-logs', $plugin_dir_url . 'assets/js/admin/view-logs.js', array( 'insertionQ', 'jquery-ui-core', 'jquery-ui-datepicker', 'jquery-ui-tooltip', 'jquery-ui-tabs' ), $email_log->get_version(), true );
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/include/Core/EmailLogger.php:
--------------------------------------------------------------------------------
1 | '',
59 | 'subject' => '',
60 | 'message' => '',
61 | 'headers' => '',
62 | 'attachments' => array(),
63 | )
64 | );
65 |
66 | $log = array(
67 | 'to_email' => \EmailLog\Util\stringify( $mail_info['to'] ),
68 | 'subject' => $mail_info['subject'],
69 | 'message' => $mail_info['message'],
70 | 'headers' => \EmailLog\Util\stringify( $mail_info['headers'], "\n" ),
71 | 'attachment_name' => \EmailLog\Util\stringify( $mail_info['attachments'] ),
72 | 'sent_date' => current_time( 'mysql' ),
73 | 'ip_address' => $_SERVER['REMOTE_ADDR'],
74 | 'result' => 1,
75 | );
76 |
77 | if ( empty( $log['attachment_name'] ) ) {
78 | $log['attachments'] = 'false';
79 | } else {
80 | $log['attachments'] = 'true';
81 | }
82 |
83 | /**
84 | * Filters the mail info right before inserting on the table.
85 | *
86 | * Masked fields would use this filter to avoid modifying the original data sent to
87 | * `wp_mail() function`
88 | *
89 | * @param array $log Email Log that is about to be inserted into db.
90 | * @param array $original_mail_info Original mail info that was passed to `wp_mail` filter.
91 | *
92 | * @since 2.3.2
93 | */
94 | $log = apply_filters( 'el_email_log_before_insert', $log, $original_mail_info );
95 |
96 | $email_log = email_log();
97 | $email_log->table_manager->insert_log( $log );
98 |
99 | /**
100 | * Fires the `el_email_log_inserted` action right after the log is inserted in to DB.
101 | *
102 | * @since 2.3.0
103 | *
104 | * @param array $log {
105 | * @type string $to
106 | * @type string $subject
107 | * @type string $message
108 | * @type string $headers
109 | * @type string $attachments
110 | * @type string $attachment_name
111 | * @type string $sent_date
112 | * @type string $ip_address
113 | * @type bool $result
114 | * }
115 | */
116 | do_action( 'el_email_log_inserted', $log );
117 |
118 | return $original_mail_info;
119 | }
120 |
121 | /**
122 | * Updates the failed email in the DB.
123 | *
124 | * @param \WP_Error $wp_error The error instance.
125 | *
126 | * @since 2.4.0 Use is_wp_error() to validate the type of $wp_error.
127 | * @since 2.3.0
128 | *
129 | * @see is_wp_error()
130 | * @see email_log()
131 | */
132 | public function on_email_failed( $wp_error ) {
133 | if ( ! is_wp_error( $wp_error ) ) {
134 | return;
135 | }
136 |
137 | // @see wp-includes/pluggable.php#500
138 | $mail_error_data = $wp_error->get_error_data( 'wp_mail_failed' );
139 | $mail_error_message = $wp_error->get_error_message( 'wp_mail_failed' );
140 |
141 | $this->mark_email_log_as_failed( $mail_error_data, $mail_error_message );
142 | }
143 |
144 | /**
145 | * Prepare BuddyPress emails to log into database.
146 | *
147 | * @since 2.3.2
148 | *
149 | * @param bool $status Mail sent status.
150 | * @param \BP_Email $bp_mail Information about email.
151 | */
152 | public function log_buddy_press_email( $status, $bp_mail ) {
153 | if ( ! class_exists( '\\BP_Email' ) ) {
154 | return;
155 | }
156 |
157 | if ( $bp_mail instanceof \BP_Email ) {
158 | return;
159 | }
160 |
161 | $log = array(
162 | 'to' => array_shift( $bp_mail->get_to() )->get_address(),
163 | 'subject' => $bp_mail->get_subject( 'replace-tokens' ),
164 | 'message' => $bp_mail->get_content( 'replace-tokens' ),
165 | 'headers' => $bp_mail->get_headers( 'replace-tokens ' ),
166 | );
167 |
168 | $this->log_email( $log );
169 |
170 | if ( ! $status ) {
171 | $this->mark_email_log_as_failed( $log );
172 | }
173 | }
174 |
175 | /**
176 | * Mark email log as failed.
177 | *
178 | * @param array $log Email Log.
179 | * @param string $error_message Error message.
180 | *
181 | * @since 2.3.2
182 | * @since 2.4.0 Store the error message.
183 | */
184 | protected function mark_email_log_as_failed( $log, $error_message = '' ) {
185 | if ( ! is_array( $log ) ) {
186 | return;
187 | }
188 |
189 | if ( ! isset( $log['to'], $log['subject'] ) ) {
190 | return;
191 | }
192 |
193 | $email_log = email_log();
194 |
195 | $log_item_id = $email_log->table_manager->fetch_log_id_by_data( $log );
196 |
197 | if ( empty( $log_item_id ) ) {
198 | return;
199 | }
200 |
201 | $email_log->table_manager->mark_log_as_failed( $log_item_id, $error_message );
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/languages/email-log-de_DE.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: Email Log WordPress Plugin 0.2\n"
4 | "Report-Msgid-Bugs-To: http://wordpress.org/tag/email-log\n"
5 | "POT-Creation-Date: 2009-10-08 17:51+0000\n"
6 | "PO-Revision-Date: \n"
7 | "Last-Translator: \n"
8 | "Language-Team: Frank Weichbrodt\n"
9 | "MIME-Version: 1.0\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "X-Poedit-Language: German\n"
13 | "X-Poedit-Country: GERMANY\n"
14 |
15 | #. #-#-#-#-# email-log.pot (Email Log 0.1) #-#-#-#-#
16 | #. Plugin Name of an extension
17 | #: email-log.php:58
18 | msgid "Email Log"
19 | msgstr "E-Mail Log"
20 |
21 | #: email-log.php:69
22 | msgid "Settings"
23 | msgstr "Einstellungen"
24 |
25 | #: email-log.php:79
26 | msgid "plugin"
27 | msgstr "Plugin"
28 |
29 | #: email-log.php:79
30 | msgid "Version"
31 | msgstr "Version"
32 |
33 | #: email-log.php:79
34 | msgid "by"
35 | msgstr "von"
36 |
37 | #: email-log.php:109
38 | #: email-log.php:463
39 | #: email-log.php:487
40 | msgid "Delete Logs"
41 | msgstr "Logs löschen"
42 |
43 | #: email-log.php:118
44 | #, php-format
45 | msgid "All Email Logs For email id %s Have Been Deleted."
46 | msgstr "Alle E-Mail Logs mit ID %s wurden gelöscht."
47 |
48 | #: email-log.php:120
49 | #, php-format
50 | msgid "An Error Has Occured while deleting All Email Logs For email id %s."
51 | msgstr "Beim Löschen der E-Mail Logs mit der ID %s ist ein Fehler aufgetreten."
52 |
53 | #: email-log.php:128
54 | #, php-format
55 | msgid "All Email Logs With Subject %s Have Been Deleted."
56 | msgstr "Alle E-Mail Logs mit dem Betreff %s wurden gelöscht."
57 |
58 | #: email-log.php:130
59 | #, php-format
60 | msgid "An Error Has Occured While Deleting All Email Logs With Subject %s."
61 | msgstr "Beim Löschen der E-Mail Logs mit dem Betreff %s ist ein Fehler aufgetreten."
62 |
63 | #: email-log.php:138
64 | msgid "All Email log Has Been Deleted."
65 | msgstr "Alle E-Mail Logs wurden gelöscht."
66 |
67 | #: email-log.php:140
68 | msgid "An Error Has Occured While Deleting All Email Logs"
69 | msgstr "Beim Löschen aller E-Mail Logs ist ein Fehler aufgetreten."
70 |
71 | #: email-log.php:174
72 | #: email-log.php:311
73 | #: email-log.php:346
74 | #: email-log.php:430
75 | msgid "ID"
76 | msgstr "ID"
77 |
78 | #: email-log.php:178
79 | #: email-log.php:431
80 | #: email-log.php:480
81 | msgid "To Email"
82 | msgstr "Empfänger"
83 |
84 | #: email-log.php:182
85 | #: email-log.php:314
86 | #: email-log.php:349
87 | #: email-log.php:432
88 | #: email-log.php:482
89 | msgid "Subject"
90 | msgstr "Betreff"
91 |
92 | #: email-log.php:187
93 | #: email-log.php:433
94 | msgid "Date"
95 | msgstr "Datum"
96 |
97 | #: email-log.php:194
98 | #: email-log.php:437
99 | msgid "Ascending"
100 | msgstr "aufsteigend"
101 |
102 | #: email-log.php:199
103 | #: email-log.php:438
104 | msgid "Descending"
105 | msgstr "absteigend"
106 |
107 | #: email-log.php:248
108 | msgid "Email Log Settings"
109 | msgstr "E-Mail Log - Einstellungen"
110 |
111 | #: email-log.php:249
112 | #, php-format
113 | msgid "Displaying %s to %s of %s Email log entries."
114 | msgstr "Anzeige: %s bis %s von %s Einträgen."
115 |
116 | #: email-log.php:250
117 | #, php-format
118 | msgid "Sorted by %s in %s order."
119 | msgstr "Sortiert nach %s in %ser Reihenfolge."
120 |
121 | #: email-log.php:261
122 | #: email-log.php:361
123 | msgid "Previous Page"
124 | msgstr "Vorherige Seite"
125 |
126 | #: email-log.php:268
127 | #: email-log.php:368
128 | #, php-format
129 | msgid "Pages (%s): "
130 | msgstr "Seiten (%s): "
131 |
132 | #: email-log.php:271
133 | #: email-log.php:371
134 | msgid "Go to First Page"
135 | msgstr "Gehe zur ersten Seite"
136 |
137 | #: email-log.php:271
138 | #: email-log.php:371
139 | msgid "First"
140 | msgstr "Erste"
141 |
142 | #: email-log.php:274
143 | #: email-log.php:286
144 | #: email-log.php:374
145 | #: email-log.php:386
146 | msgid "Go to Page"
147 | msgstr "Gehe zu Seite"
148 |
149 | #: email-log.php:281
150 | #: email-log.php:381
151 | msgid "Page"
152 | msgstr "Seite"
153 |
154 | #: email-log.php:289
155 | #: email-log.php:389
156 | msgid "Go to Last Page"
157 | msgstr "Gehe zur letzten Seite"
158 |
159 | #: email-log.php:289
160 | #: email-log.php:389
161 | msgid "Last"
162 | msgstr "Letzte"
163 |
164 | #: email-log.php:296
165 | #: email-log.php:396
166 | msgid "Next Page"
167 | msgstr "Nächste Seite"
168 |
169 | #: email-log.php:312
170 | #: email-log.php:347
171 | msgid "Date / Time"
172 | msgstr "Datum / Zeit"
173 |
174 | #: email-log.php:313
175 | #: email-log.php:348
176 | msgid "To"
177 | msgstr "An"
178 |
179 | #: email-log.php:328
180 | #, php-format
181 | msgid "%s @ %s"
182 | msgstr "%s @ %s"
183 |
184 | #: email-log.php:340
185 | msgid "No email Logs Found"
186 | msgstr "Keine E-Mail Logs gefunden."
187 |
188 | #: email-log.php:416
189 | msgid "Filter Options:"
190 | msgstr "Filter Optionen:"
191 |
192 | #: email-log.php:418
193 | msgid "ID:"
194 | msgstr "ID:"
195 |
196 | #: email-log.php:420
197 | msgid "To Email:"
198 | msgstr "Empfänger:"
199 |
200 | #: email-log.php:422
201 | msgid "Subject:"
202 | msgstr "Betreff:"
203 |
204 | #: email-log.php:427
205 | msgid "Sort Options:"
206 | msgstr "Sortierung:"
207 |
208 | #: email-log.php:445
209 | #: email-log.php:447
210 | msgid "Per Page"
211 | msgstr "je Seite"
212 |
213 | #: email-log.php:455
214 | msgid "Go"
215 | msgstr "Los"
216 |
217 | #: email-log.php:469
218 | msgid "Delete Type : "
219 | msgstr "Löschen:"
220 |
221 | #: email-log.php:472
222 | msgid "Based on"
223 | msgstr "wenn Bedingung zutrifft"
224 |
225 | #: email-log.php:473
226 | msgid "All Logs"
227 | msgstr "alle Einträge"
228 |
229 | #: email-log.php:478
230 | msgid "Condition:"
231 | msgstr "Bedingung:"
232 |
233 | #: email-log.php:481
234 | msgid "or"
235 | msgstr "oder"
236 |
237 | #: email-log.php:487
238 | msgid ""
239 | "You Are About To Delete Email Logs.\\n"
240 | "This Action Is Not Reversible.\\n"
241 | "\\n"
242 | " Choose \\'Cancel\\' to stop, \\'OK\\' to delete."
243 | msgstr ""
244 | "Du willst die E-Mail Logs löschen.\\n"
245 | "Diese Aktion lässt sich nicht rückgängig machen."
246 |
247 | #. Plugin URI of an extension
248 | msgid "http://sudarmuthu.com/wordpress/email-log"
249 | msgstr "http://sudarmuthu.com/wordpress/email-log"
250 |
251 | #. Description of an extension
252 | msgid "Logs every email sent through WordPress. Compatiable with WPMU too."
253 | msgstr "Logt jede von WordPress gesendete E-Mail. Kompatibel mit WPMU."
254 |
255 | #. Author of an extension
256 | msgid "Sudar"
257 | msgstr "Sudar"
258 |
259 | #. Author URI of an extension
260 | msgid "http://sudarmuthu.com/"
261 | msgstr "http://sudarmuthu.com/"
262 |
263 |
--------------------------------------------------------------------------------
/include/EmailLogAutoloader.php:
--------------------------------------------------------------------------------
1 | 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 | * files as $file ) {
79 | $this->require_file( $file );
80 | }
81 | }
82 |
83 | /**
84 | * Adds a base directory for a namespace prefix.
85 | *
86 | * @param string $prefix The namespace prefix.
87 | * @param string $base_dir A base directory for class files in the
88 | * namespace.
89 | * @param bool $prepend If true, prepend the base directory to the stack
90 | * instead of appending it; this causes it to be searched first rather
91 | * than last.
92 | *
93 | * @return void
94 | */
95 | public function add_namespace( $prefix, $base_dir, $prepend = false ) {
96 | // normalize namespace prefix
97 | $prefix = trim( $prefix, '\\' ) . '\\';
98 |
99 | // normalize the base directory with a trailing separator
100 | $base_dir = rtrim( $base_dir, DIRECTORY_SEPARATOR ) . '/';
101 |
102 | // initialize the namespace prefix array
103 | if ( false === isset( $this->prefixes[ $prefix ] ) ) {
104 | $this->prefixes[ $prefix ] = array();
105 | }
106 |
107 | // retain the base directory for the namespace prefix
108 | if ( $prepend ) {
109 | array_unshift( $this->prefixes[ $prefix ], $base_dir );
110 | } else {
111 | array_push( $this->prefixes[ $prefix ], $base_dir );
112 | }
113 | }
114 |
115 | /**
116 | * Add a file to be autoloaded.
117 | *
118 | * @param string $filename File to be autoloaded.
119 | */
120 | public function add_file( $filename ) {
121 | if ( ! in_array( $filename, $this->files, true ) ) {
122 | $this->files[] = $filename;
123 | }
124 | }
125 |
126 | /**
127 | * Loads the class file for a given class name.
128 | *
129 | * @param string $class The fully-qualified class name.
130 | *
131 | * @return false|string The mapped file name on success, or boolean false on
132 | * failure.
133 | */
134 | public function load_class( $class ) {
135 | // the current namespace prefix
136 | $prefix = $class;
137 |
138 | // work backwards through the namespace names of the fully-qualified
139 | // class name to find a mapped file name
140 | while ( false !== $pos = strrpos( $prefix, '\\' ) ) {
141 |
142 | // retain the trailing namespace separator in the prefix
143 | $prefix = substr( $class, 0, $pos + 1 );
144 |
145 | // the rest is the relative class name
146 | $relative_class = substr( $class, $pos + 1 );
147 |
148 | // try to load a mapped file for the prefix and relative class
149 | $mapped_file = $this->load_mapped_file( $prefix, $relative_class );
150 | if ( $mapped_file !== false ) {
151 | return $mapped_file;
152 | }
153 |
154 | // remove the trailing namespace separator for the next iteration
155 | // of strrpos()
156 | $prefix = rtrim( $prefix, '\\' );
157 | }
158 |
159 | // never found a mapped file
160 | return false;
161 | }
162 |
163 | /**
164 | * Load the mapped file for a namespace prefix and relative class.
165 | *
166 | * @param string $prefix The namespace prefix.
167 | * @param string $relative_class The relative class name.
168 | *
169 | * @return false|string Boolean false if no mapped file can be loaded, or the
170 | * name of the mapped file that was loaded.
171 | */
172 | protected function load_mapped_file( $prefix, $relative_class ) {
173 | // are there any base directories for this namespace prefix?
174 | if ( false === isset( $this->prefixes[ $prefix ] ) ) {
175 | return false;
176 | }
177 |
178 | // look through base directories for this namespace prefix
179 | foreach ( $this->prefixes[ $prefix ] as $base_dir ) {
180 |
181 | // replace the namespace prefix with the base directory,
182 | // replace namespace separators with directory separators
183 | // in the relative class name, append with .php
184 | $file = $base_dir
185 | . str_replace( '\\', '/', $relative_class )
186 | . '.php';
187 |
188 | // if the mapped file exists, require it
189 | if ( $this->require_file( $file ) ) {
190 | // yes, we're done
191 | return $file;
192 | }
193 | }
194 |
195 | // never found it
196 | return false;
197 | }
198 |
199 | /**
200 | * If a file exists, require it from the file system.
201 | *
202 | * @param string $file The file to require.
203 | *
204 | * @return bool True if the file exists, false if not.
205 | */
206 | protected function require_file( $file ) {
207 | if ( file_exists( $file ) ) {
208 | require_once $file;
209 |
210 | return true;
211 | }
212 |
213 | return false;
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/languages/email-log-lt_LT.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: Email Log WordPress Plugin 0.2\n"
4 | "Report-Msgid-Bugs-To: http://wordpress.org/tag/email-log\n"
5 | "POT-Creation-Date: 2009-10-08 17:51+0000\n"
6 | "PO-Revision-Date: \n"
7 | "Last-Translator: \n"
8 | "Language-Team: Frank Weichbrodt\n"
9 | "MIME-Version: 1.0\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "X-Poedit-Language: German\n"
13 | "X-Poedit-Country: GERMANY\n"
14 |
15 | #. #-#-#-#-# email-log.pot (Email Log 0.1) #-#-#-#-#
16 | #. Plugin Name of an extension
17 | #: email-log.php:58
18 | msgid "Email Log"
19 | msgstr "Email Log"
20 |
21 | #: email-log.php:69
22 | msgid "Settings"
23 | msgstr "Nuostatos"
24 |
25 | #: email-log.php:79
26 | msgid "plugin"
27 | msgstr "papildinio"
28 |
29 | #: email-log.php:79
30 | msgid "Version"
31 | msgstr "Versija"
32 |
33 | #: email-log.php:79
34 | msgid "by"
35 | msgstr "pagal"
36 |
37 | #: email-log.php:109
38 | #: email-log.php:463
39 | #: email-log.php:487
40 | msgid "Delete Logs"
41 | msgstr "Ištrinti Žurnalo įrašus"
42 |
43 | #: email-log.php:118
44 | #, php-format
45 | msgid "All Email Logs For email id %s Have Been Deleted."
46 | msgstr "Visi Elektroninio pašto Žurnalo įrašai, Priskirti elektroninio pašto adresui su identifikatoriumi %s Buvo Ištrinti."
47 |
48 | #: email-log.php:120
49 | #, php-format
50 | msgid "An Error Has Occured while deleting All Email Logs For email id %s."
51 | msgstr "Įvyko Klaida, ištrinant Visus Elektroninio pašto Žurnalo įrašus, priskirtus elektroniniam paštui su identfiikatoriumi %s."
52 |
53 | #: email-log.php:128
54 | #, php-format
55 | msgid "All Email Logs With Subject %s Have Been Deleted."
56 | msgstr "Visi Elektroninio pašto Žurnalo įrašai, su antrašte %s Buvo Ištrinti."
57 |
58 | #: email-log.php:130
59 | #, php-format
60 | msgid "An Error Has Occured While Deleting All Email Logs With Subject %s."
61 | msgstr "Įvyko Klaida, ištrinant Visus Elekektroninio pašto Žurnalo įrašus su antrašte %s."
62 |
63 | #: email-log.php:138
64 | msgid "All Email log Has Been Deleted."
65 | msgstr "Visi Elektroninio pašto žurnalai buvo Ištrinti."
66 |
67 | #: email-log.php:140
68 | msgid "An Error Has Occured While Deleting All Email Logs"
69 | msgstr "Įvyko Klaida, Ištrinant Visus Elektroninio pašto Žurnalo Įrašus"
70 |
71 | #: email-log.php:174
72 | #: email-log.php:311
73 | #: email-log.php:346
74 | #: email-log.php:430
75 | msgid "ID"
76 | msgstr "Identifikatorius"
77 |
78 | #: email-log.php:178
79 | #: email-log.php:431
80 | #: email-log.php:480
81 | msgid "To Email"
82 | msgstr "Į Elektroninį paštą"
83 |
84 | #: email-log.php:182
85 | #: email-log.php:314
86 | #: email-log.php:349
87 | #: email-log.php:432
88 | #: email-log.php:482
89 | msgid "Subject"
90 | msgstr "Antraštė"
91 |
92 | #: email-log.php:187
93 | #: email-log.php:433
94 | msgid "Date"
95 | msgstr "Data"
96 |
97 | #: email-log.php:194
98 | #: email-log.php:437
99 | msgid "Ascending"
100 | msgstr "Didėjanti"
101 |
102 | #: email-log.php:199
103 | #: email-log.php:438
104 | msgid "Descending"
105 | msgstr "Mažėjanti"
106 |
107 | #: email-log.php:248
108 | msgid "Email Log Settings"
109 | msgstr "Email Log Nuostatos"
110 |
111 | #: email-log.php:249
112 | #, php-format
113 | msgid "Displaying %s to %s of %s Email log entries."
114 | msgstr "Rodoma %s iki %s iš %s Elektroninio pašto žurnalo įrašų."
115 |
116 | #: email-log.php:250
117 | #, php-format
118 | msgid "Sorted by %s in %s order."
119 | msgstr "Išrikiuota pagal %s po %ser tvarką."
120 |
121 | #: email-log.php:261
122 | #: email-log.php:361
123 | msgid "Previous Page"
124 | msgstr "Ankstesnis Puslapis"
125 |
126 | #: email-log.php:268
127 | #: email-log.php:368
128 | #, php-format
129 | msgid "Pages (%s): "
130 | msgstr "Puslapiai (%s):"
131 |
132 | #: email-log.php:271
133 | #: email-log.php:371
134 | msgid "Go to First Page"
135 | msgstr "Eiti į Pirmąjį Puslapį"
136 |
137 | #: email-log.php:271
138 | #: email-log.php:371
139 | msgid "First"
140 | msgstr "Pirmas"
141 |
142 | #: email-log.php:274
143 | #: email-log.php:286
144 | #: email-log.php:374
145 | #: email-log.php:386
146 | msgid "Go to Page"
147 | msgstr "Eiti į Puslapį"
148 |
149 | #: email-log.php:281
150 | #: email-log.php:381
151 | msgid "Page"
152 | msgstr "Puslapis"
153 |
154 | #: email-log.php:289
155 | #: email-log.php:389
156 | msgid "Go to Last Page"
157 | msgstr "Eiti į Paskutinį Puslapį"
158 |
159 | #: email-log.php:289
160 | #: email-log.php:389
161 | msgid "Last"
162 | msgstr "Paskutinis"
163 |
164 | #: email-log.php:296
165 | #: email-log.php:396
166 | msgid "Next Page"
167 | msgstr "Sekantis Puslapis"
168 |
169 | #: email-log.php:312
170 | #: email-log.php:347
171 | msgid "Date / Time"
172 | msgstr "Data / Laikas"
173 |
174 | #: email-log.php:313
175 | #: email-log.php:348
176 | msgid "To"
177 | msgstr "Į"
178 |
179 | #: email-log.php:328
180 | #, php-format
181 | msgid "%s @ %s"
182 | msgstr "%s @ %s"
183 |
184 | #: email-log.php:340
185 | msgid "No email Logs Found"
186 | msgstr "Nerasta jokių elektroninio pašto Žurnalo įrašų"
187 |
188 | #: email-log.php:416
189 | msgid "Filter Options:"
190 | msgstr "Filtravimo Parinktys:"
191 |
192 | #: email-log.php:418
193 | msgid "ID:"
194 | msgstr "Identifikatorius:"
195 |
196 | #: email-log.php:420
197 | msgid "To Email:"
198 | msgstr "Į Elektroninį paštą:"
199 |
200 | #: email-log.php:422
201 | msgid "Subject:"
202 | msgstr "Antraštė:"
203 |
204 | #: email-log.php:427
205 | msgid "Sort Options:"
206 | msgstr "Rikiavimo Parinktys:"
207 |
208 | #: email-log.php:445
209 | #: email-log.php:447
210 | msgid "Per Page"
211 | msgstr "Puslapyje"
212 |
213 | #: email-log.php:455
214 | msgid "Go"
215 | msgstr "Eiti"
216 |
217 | #: email-log.php:469
218 | msgid "Delete Type : "
219 | msgstr "Ištrinti Tipą:"
220 |
221 | #: email-log.php:472
222 | msgid "Based on"
223 | msgstr "Pagrįsta"
224 |
225 | #: email-log.php:473
226 | msgid "All Logs"
227 | msgstr "Visi Žurnalai"
228 |
229 | #: email-log.php:478
230 | msgid "Condition:"
231 | msgstr "Sąlyga:"
232 |
233 | #: email-log.php:481
234 | msgid "or"
235 | msgstr "arba"
236 |
237 | #: email-log.php:487
238 | msgid ""
239 | "You Are About To Delete Email Logs.\\n"
240 | "This Action Is Not Reversible.\\n"
241 | "\\n"
242 | " Choose \\'Cancel\\' to stop, \\'OK\\' to delete."
243 | msgstr ""
244 | "Jūs Mėginate Ištrinti Visus Elektroninio Pašto Žurnalus. \\n"
245 | "Šio veiksmo padariniai yra neatstatomi. \\n"
246 | "\\n"
247 | "Pasirinkite \\'Cancel\\', kad sustabdytumėte procesą, \\'OK\\'. kad tęstumėte trynimą."
248 |
249 | #. Plugin URI of an extension
250 | msgid "http://sudarmuthu.com/wordpress/email-log"
251 | msgstr "http://sudarmuthu.com/wordpress/email-log"
252 |
253 | #. Description of an extension
254 | msgid "Logs every email sent through WordPress. Compatiable with WPMU too."
255 | msgstr "Į žurnalą įrašo kiekvieną per WordPress išsiųstą elektroninį laišką. Taip pat suderinamas su WPMU."
256 |
257 | #. Author of an extension
258 | msgid "Sudar"
259 | msgstr "Sudar"
260 |
261 | #. Author URI of an extension
262 | msgid "http://sudarmuthu.com/"
263 | msgstr "http://sudarmuthu.com/"
264 |
265 |
--------------------------------------------------------------------------------
/include/Core/Request/LogListAction.php:
--------------------------------------------------------------------------------
1 | .
17 | *
18 | * @inheritdoc
19 | */
20 | public function load() {
21 | add_action( 'wp_ajax_el-log-list-view-message', array( $this, 'view_log_message' ) );
22 |
23 | add_action( 'el-log-list-delete', array( $this, 'delete_logs' ) );
24 | add_action( 'el-log-list-delete-all', array( $this, 'delete_all_logs' ) );
25 | add_action( 'el-log-list-manage-user-roles-changed', array( $this, 'update_capabilities_for_user_roles' ), 10, 2 );
26 | }
27 |
28 | /**
29 | * AJAX callback for displaying email content.
30 | *
31 | * @since 2.4.0 Show Active Tab based on the Email's content type.
32 | * @since 1.6
33 | */
34 | public function view_log_message() {
35 | if ( ! current_user_can( LogListPage::CAPABILITY ) ) {
36 | wp_die();
37 | }
38 |
39 | $id = absint( $_GET['log_id'] );
40 |
41 | if ( $id <= 0 ) {
42 | wp_die();
43 | }
44 |
45 | $log_items = $this->get_table_manager()->fetch_log_items_by_id( array( $id ) );
46 | if ( count( $log_items ) > 0 ) {
47 | $log_item = $log_items[0];
48 |
49 | $headers = array();
50 | if ( ! empty( $log_item['headers'] ) ) {
51 | $parser = new \EmailLog\Util\EmailHeaderParser();
52 | $headers = $parser->parse_headers( $log_item['headers'] );
53 | }
54 |
55 | $active_tab = '0';
56 | if ( isset( $headers['content_type'] ) && 'text/html' === $headers['content_type'] ) {
57 | $active_tab = '1';
58 | }
59 |
60 | ob_start();
61 | ?>
62 |
63 |
64 | | : |
65 | |
66 |
67 |
68 | | : |
69 | |
70 |
71 |
72 | | : |
73 | |
74 |
75 |
76 |
87 |
88 |
89 |
90 |
91 |
95 |
96 |
99 |
100 |
101 | el_kses_allowed_html( 'post' ) ); ?>
102 |
103 |
104 |
105 |
108 |
109 | get_table_manager()->delete_logs( $id_list );
136 | $this->render_log_deleted_notice( $logs_deleted );
137 | }
138 |
139 | /**
140 | * Delete all log entries.
141 | */
142 | public function delete_all_logs() {
143 | $logs_deleted = $this->get_table_manager()->delete_all_logs();
144 | $this->render_log_deleted_notice( $logs_deleted );
145 | }
146 |
147 | /**
148 | * Update user role capabilities when the allowed user role list is changed.
149 | *
150 | * The capability will be removed from old user roles and added to new user roles.
151 | *
152 | * @since 2.1.0
153 | *
154 | * @param array $old_roles Old user roles.
155 | * @param array $new_roles New user roles.
156 | */
157 | public function update_capabilities_for_user_roles( $old_roles, $new_roles ) {
158 | foreach ( $old_roles as $old_role ) {
159 | $role = get_role( $old_role );
160 |
161 | if ( ! is_null( $role ) ) {
162 | $role->remove_cap( LogListPage::CAPABILITY );
163 | }
164 | }
165 |
166 | foreach ( $new_roles as $new_role ) {
167 | $role = get_role( $new_role );
168 |
169 | if ( ! is_null( $role ) ) {
170 | $role->add_cap( LogListPage::CAPABILITY );
171 | }
172 | }
173 | }
174 |
175 | /**
176 | * Render Logs deleted notice.
177 | *
178 | * @param false|int $logs_deleted Number of entries deleted, False otherwise.
179 | */
180 | protected function render_log_deleted_notice( $logs_deleted ) {
181 | $message = __( 'There was some problem in deleting the email logs', 'email-log' );
182 | $type = 'error';
183 |
184 | if ( absint( $logs_deleted ) > 0 ) {
185 | $message = sprintf( _n( '1 email log deleted.', '%s email logs deleted', $logs_deleted, 'email-log' ), $logs_deleted );
186 | $type = 'updated';
187 | }
188 |
189 | add_settings_error(
190 | 'log-list',
191 | 'deleted-email-logs',
192 | $message,
193 | $type
194 | );
195 | }
196 |
197 | /**
198 | * Get TableManager instance.
199 | *
200 | * @return \EmailLog\Core\DB\TableManager TableManager instance.
201 | */
202 | protected function get_table_manager() {
203 | $email_log = email_log();
204 |
205 | return $email_log->table_manager;
206 | }
207 |
208 | /**
209 | * Allows `` tag in wp_kses().
210 | *
211 | * Gets the list of allowed HTML for the `post` context.
212 | * Appends tag to the above list and returns the array.
213 | *
214 | * @since 2.3.0
215 | *
216 | * @param string $context Optional. Default `post`. The context for which to retrieve tags.
217 | *
218 | * @return array List of allowed tags and their allowed attributes.
219 | */
220 | protected function el_kses_allowed_html( $context = 'post' ) {
221 | $allowed_tags = wp_kses_allowed_html( $context );
222 |
223 | $allowed_tags['link'] = array(
224 | 'rel' => true,
225 | 'href' => true,
226 | 'type' => true,
227 | 'media' => true,
228 | );
229 |
230 | return $allowed_tags;
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Email Log #
2 | **Contributors:** sudar
3 | **Tags:** email, log, log email, resend email, multisite
4 | **Requires PHP:** 5.6
5 | **Requires at least:** 4.0
6 | **Tested up to:** 6.4.2
7 | **Stable tag:** 2.4.9
8 | []() []() []() []() [](https://scrutinizer-ci.com/g/sudar/email-log/build-status/master) [](https://scrutinizer-ci.com/g/sudar/email-log/?branch=master) [](https://scrutinizer-ci.com/g/sudar/email-log/?branch=master) [](https://styleci.io/repos/7374859) [](https://wordpress.org/about/license/)
9 |
10 | Log and view all outgoing emails from WordPress. Very useful if you have to debug email related problems or have to store sent emails for auditing.
11 |
12 | ## Description ##
13 |
14 | Email Log is a WordPress plugin that allows you to easily log and view all emails that were sent from WordPress.
15 |
16 | This would be very useful for debugging email related problems in your WordPress site or for storing sent emails for auditing purposes, especially on ecommerce sites that are setup with either WooCommerce or Easy Digital Downloads.
17 |
18 | 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).
19 |
20 | Works with WordPress Multisite as well.
21 | ### Viewing logged emails
22 |
23 | The logged emails will be stored in a separate table and can be viewed from the admin interface.
24 |
25 | While viewing the logs, the emails can be filtered or sorted based on the date, email, subject etc.
26 |
27 | ### Deleting logged emails
28 |
29 | In the admin interface, all the logged emails can be delete in bulk or can also be selectively deleted based on date, email and subject.
30 |
31 | If you want to automatically delete the email logs after some days, then you can use the [Auto Delete Logs](https://wpemaillog.com/addons/auto-delete-logs/?utm_campaign=Upsell&utm_medium=wporg&utm_source=readme&utm_content=dl) add-on.
32 |
33 | ### Resend email (Pro addon)
34 |
35 | 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),
36 | which allows you to resend the email directly from the email log.
37 |
38 | The add-on allows you to modify the different fields of the email before resending it.
39 |
40 | ### More Fields (Pro addon)
41 |
42 | 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),
43 | which shows additional fields in the email log page. The following are the additional fields that are added by this addon.
44 |
45 | - From
46 | - CC
47 | - BCC
48 | - Reply To
49 | - Attachment
50 |
51 | ### Forward email (Pro addon)
52 |
53 | 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),
54 | which allows you to send a copy of all the emails send from WordPress to another email address.
55 |
56 | The addon allows you to choose whether you want to forward through to, cc or bcc fields.
57 |
58 | This can be extremely useful when you want to debug by analyzing the emails that are sent from WordPress.
59 |
60 | ### Export email logs (Pro addon)
61 |
62 | You can buy the [Export Email Logs add-on](https://wpemaillog.com/addons/export-logs/?utm_campaign=Upsell&utm_medium=wporg&utm_source=readme&utm_content=el), which allows you to export the email logs as a csv file for further processing or record keeping.
63 |
64 | ### Cleaning up db on uninstall
65 |
66 | As [recommended by Ozh][1], the Plugin has an uninstall hook which will clean up the database and options when the Plugin is uninstalled.
67 |
68 | [1]: https://sudarmuthu.com/blog/lessons-from-wordpress-plugin-competition/
69 |
70 | ### Documentation
71 |
72 | You can find fully searchable documentation about using the plugin in the [doc section of the Email Log](https://wpemaillog.com/docs/) website.
73 |
74 | ### Development
75 |
76 | The development of the Plugin happens over at [github](http://github.com/sudar/email-log).
77 |
78 | 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.
79 |
80 | 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).
81 |
82 | ### Support
83 |
84 | - 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).
85 | - 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).
86 | - If you have any development related questions, then post them as [github issues](https://github.com/sudar/email-log/issues)
87 |
88 | ## Translation ##
89 |
90 | The Plugin currently has translations for the following languages.
91 |
92 | * German (Thanks Frank)
93 | * Lithuanian (Thanks Vincent G)
94 | * Dutch (Thanks Zjan Preijde)
95 |
96 | The pot file is available with the Plugin.
97 |
98 | 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.
99 |
100 | I will add it to the Plugin after giving credit to you.
101 |
102 | ## Installation ##
103 |
104 | ### Normal WordPress installations
105 |
106 | Extract the zip file and just drop the contents in the wp-content/plugins/ directory of your WordPress installation and then activate the Plugin from Plugins page.
107 |
108 | ## Frequently Asked Questions ##
109 |
110 | ### The content of the email is not getting logged when I am using wpmandrill plugin
111 |
112 | wpmandrill plugin has a bug that prevents this plugin from logging the content of the email.
113 |
114 | 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.
115 |
116 | I have asked the author of the plugin to fix it and it might get fixed it the next release.
117 |
118 | 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.
119 |
120 | ## Screenshots ##
121 |
122 | 
123 | The above screenshot shows how the logged emails will be displayed by the Plugin
124 |
125 | 
126 | This screenshot shows how you can configure the email display screen. You can choose the fields and the number of emails per page
127 |
128 | 
129 | The above screenshot shows the HTML version (if available) of the logged email that you choose to view
130 |
131 | 
132 | The above screenshot shows the text version of the logged email that you choose to view
133 |
134 | 
135 | The above screenshot shows how you can search logged emails by date
136 |
137 | ## Readme Generator ##
138 |
139 | This Readme file was generated using wp-readme, which generates readme files for WordPress Plugins.
140 |
--------------------------------------------------------------------------------
/languages/email-log-nl_NL.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: Email Log WordPress Plugin 0.2\n"
4 | "Report-Msgid-Bugs-To: http://wordpress.org/tag/email-log\n"
5 | "POT-Creation-Date: 2012-04-29 17:11:23+00:00\n"
6 | "PO-Revision-Date: \n"
7 | "Last-Translator: Zjan Preijde \n"
8 | "Language-Team: Frank Weichbrodt\n"
9 | "MIME-Version: 1.0\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "X-Poedit-Language: German\n"
13 | "X-Poedit-Country: GERMANY\n"
14 |
15 | #. #-#-#-#-# plugin.pot (Email Log 0.6) #-#-#-#-#
16 | #. Plugin Name of the plugin/theme
17 | #: email-log.php:85
18 | msgid "Email Log"
19 | msgstr "E-Mail Log"
20 |
21 | #: email-log.php:106
22 | msgid "About Plugin"
23 | msgstr "Over de plugin"
24 |
25 | #: email-log.php:108
26 | msgid "Email Log WordPress Plugin, allows you to log all emails that are sent through WordPress."
27 | msgstr "Email Log WordPress Plugin, maakt het mogelijk al je e-mails te loggen die verstuurd worden via Wordpress."
28 |
29 | #: email-log.php:115
30 | msgid "More information"
31 | msgstr "Meer informatie"
32 |
33 | #: email-log.php:116
34 | msgid "Plugin Homepage/support"
35 | msgstr "Plugin Homepage/support"
36 |
37 | #: email-log.php:117
38 | msgid "Plugin author's blog"
39 | msgstr "Blog van plugin auteur"
40 |
41 | #: email-log.php:118
42 | msgid "Other Plugin's by Author"
43 | msgstr "Andere plugins door deze auteur"
44 |
45 | #: email-log.php:125
46 | msgid "Entries per page"
47 | msgstr "Logs per pagina"
48 |
49 | #: email-log.php:163
50 | msgid "Settings"
51 | msgstr "Instellingen"
52 |
53 | #: email-log.php:173
54 | msgid "plugin"
55 | msgstr "plugin"
56 |
57 | #: email-log.php:173
58 | msgid "Version"
59 | msgstr "Versie"
60 |
61 | #: email-log.php:173
62 | msgid "by"
63 | msgstr "door"
64 |
65 | #: email-log.php:203
66 | #: email-log.php:555
67 | #: email-log.php:578
68 | msgid "Delete Logs"
69 | msgstr "Logs verwijderen"
70 |
71 | #: email-log.php:212
72 | msgid "The selected Email Logs have been deleted."
73 | msgstr "De geselecteerde e-mail logs zijn verwijderd."
74 |
75 | #: email-log.php:214
76 | msgid "An error has occurred while deleting the selected Email logs"
77 | msgstr "Bij het verwijderen van de geselecteerde e-mail logs is er een fout opgetreden."
78 |
79 | #: email-log.php:223
80 | msgid "All Email Logs For email id %s Have Been Deleted."
81 | msgstr "Alle e-mail logs met ID %s zijn verwijderd."
82 |
83 | #: email-log.php:225
84 | msgid "An error has occurred while deleting All Email Logs For email id %s."
85 | msgstr "Bij het verwijderen van alle e-mail logs met ID %s is er een fout opgetreden."
86 |
87 | #: email-log.php:233
88 | msgid "All Email Logs With Subject %s Have Been Deleted."
89 | msgstr "Alle e-mail logs met het onderwerp %s zijn verwijderd."
90 |
91 | #: email-log.php:235
92 | msgid "An Error Has Occurred While Deleting All Email Logs With Subject %s."
93 | msgstr "Bij het verwijderen van alle e-mail logs met onderwerp %s is er een fout opgetreden."
94 |
95 | #: email-log.php:243
96 | msgid "All Email log Has Been Deleted."
97 | msgstr "Alle e-mail logs zijn verwijderd."
98 |
99 | #: email-log.php:245
100 | msgid "An Error Has Occurred While Deleting All Email Logs"
101 | msgstr "Bij het verwijderen van alle e-mail logs is er een fout opgetreden"
102 |
103 | #: email-log.php:275
104 | #: email-log.php:370
105 | #: email-log.php:452
106 | #: email-log.php:489
107 | msgid "ID"
108 | msgstr "ID"
109 |
110 | #: email-log.php:279
111 | #: email-log.php:371
112 | #: email-log.php:571
113 | msgid "To Email"
114 | msgstr "Ontvanger"
115 |
116 | #: email-log.php:283
117 | #: email-log.php:372
118 | #: email-log.php:455
119 | #: email-log.php:492
120 | #: email-log.php:573
121 | msgid "Subject"
122 | msgstr "Onderwerp"
123 |
124 | #: email-log.php:288
125 | #: email-log.php:373
126 | msgid "Date"
127 | msgstr "Datum"
128 |
129 | #: email-log.php:295
130 | #: email-log.php:377
131 | msgid "Ascending"
132 | msgstr "Oplopend"
133 |
134 | #: email-log.php:300
135 | #: email-log.php:378
136 | msgid "Descending"
137 | msgstr "Aflopend"
138 |
139 | #: email-log.php:348
140 | msgid "Email Log Settings"
141 | msgstr "E-mail log - Instellingen"
142 |
143 | #: email-log.php:356
144 | msgid "Filter Options:"
145 | msgstr "Filter Opties:"
146 |
147 | #: email-log.php:358
148 | msgid "ID:"
149 | msgstr "ID:"
150 |
151 | #: email-log.php:360
152 | msgid "To Email:"
153 | msgstr "Ontvanger:"
154 |
155 | #: email-log.php:362
156 | msgid "Subject:"
157 | msgstr "Onderwerp:"
158 |
159 | #: email-log.php:367
160 | msgid "Sort Options:"
161 | msgstr "Sorteer opties:"
162 |
163 | #: email-log.php:383
164 | msgid "Filter"
165 | msgstr "Filter"
166 |
167 | #: email-log.php:388
168 | msgid "Displaying %s to %s of %s Email log entries."
169 | msgstr "Getoond: %s tot %s van %s e-mail logs."
170 |
171 | #: email-log.php:389
172 | msgid "Sorted by %s in %s order."
173 | msgstr "Gesorteerd op %s in %se volgorde."
174 |
175 | #: email-log.php:401
176 | #: email-log.php:504
177 | msgid "Previous Page"
178 | msgstr "Vorige pagina"
179 |
180 | #: email-log.php:408
181 | #: email-log.php:511
182 | msgid "Pages (%s): "
183 | msgstr "Pagina's (%s): "
184 |
185 | #: email-log.php:411
186 | #: email-log.php:514
187 | msgid "Go to First Page"
188 | msgstr "Ga naar de eerste pagina"
189 |
190 | #: email-log.php:411
191 | #: email-log.php:514
192 | msgid "First"
193 | msgstr "Eerste"
194 |
195 | #: email-log.php:414
196 | #: email-log.php:426
197 | #: email-log.php:517
198 | #: email-log.php:529
199 | msgid "Go to Page"
200 | msgstr "Ga naar pagina"
201 |
202 | #: email-log.php:421
203 | #: email-log.php:524
204 | msgid "Page"
205 | msgstr "Pagina"
206 |
207 | #: email-log.php:429
208 | #: email-log.php:532
209 | msgid "Go to Last Page"
210 | msgstr "Ga naar laatste pagina"
211 |
212 | #: email-log.php:429
213 | #: email-log.php:532
214 | msgid "Last"
215 | msgstr "Laatste"
216 |
217 | #: email-log.php:436
218 | #: email-log.php:539
219 | msgid "Next Page"
220 | msgstr "Volgende pagina"
221 |
222 | #: email-log.php:453
223 | #: email-log.php:490
224 | msgid "Date / Time"
225 | msgstr "Datum / Tijd"
226 |
227 | #: email-log.php:454
228 | #: email-log.php:491
229 | msgid "To"
230 | msgstr "Aan"
231 |
232 | #: email-log.php:469
233 | msgid "%s @ %s"
234 | msgstr "%s @ %s"
235 |
236 | #: email-log.php:482
237 | msgid "No email Logs Found"
238 | msgstr "Geen e-mail logs gevonden"
239 |
240 | #: email-log.php:559
241 | msgid "Delete Type : "
242 | msgstr "Verwijder type:"
243 |
244 | #: email-log.php:562
245 | msgid "Selected entries"
246 | msgstr "Geselecteerde logs"
247 |
248 | #: email-log.php:563
249 | msgid "Based on"
250 | msgstr "Gebaseerd op"
251 |
252 | #: email-log.php:564
253 | msgid "All Logs"
254 | msgstr "Alle logs"
255 |
256 | #: email-log.php:569
257 | msgid "Condition:"
258 | msgstr "Voorwaarde:"
259 |
260 | #: email-log.php:572
261 | msgid "or"
262 | msgstr "of"
263 |
264 | #: email-log.php:578
265 | msgid ""
266 | "You Are About To Delete Email Logs.\\n"
267 | "This Action Is Not Reversible.\\n"
268 | "\\n"
269 | " Choose \\'Cancel\\' to stop, \\'OK\\' to delete."
270 | msgstr ""
271 | "Je gaat je e-mail logs verwijderen.\\n"
272 | "Deze actie kan niet ongedaan gemaakt worden.\\n"
273 |
274 | #. Plugin URI of the plugin/theme
275 | msgid "http://sudarmuthu.com/wordpress/email-log"
276 | msgstr "http://sudarmuthu.com/wordpress/email-log"
277 |
278 | #. Description of the plugin/theme
279 | msgid "Logs every email sent through WordPress. Compatiable with WPMU too."
280 | msgstr "Logt alle door WordPress verzonden e-mail. Compatibel met WPMU."
281 |
282 | #. Author of the plugin/theme
283 | msgid "Sudar"
284 | msgstr "Sudar"
285 |
286 | #. Author URI of the plugin/theme
287 | msgid "http://sudarmuthu.com/"
288 | msgstr "http://sudarmuthu.com/"
289 |
290 | #~ msgid "Per Page"
291 | #~ msgstr "Per pagina"
292 |
293 | #~ msgid "Go"
294 | #~ msgstr "Ga"
295 |
--------------------------------------------------------------------------------
/include/Addon/License/BaseLicense.php:
--------------------------------------------------------------------------------
1 | edd_api = $edd_api;
44 | }
45 |
46 | /**
47 | * Set the license Key.
48 | *
49 | * @param string $license_key License Key.
50 | */
51 | public function set_license_key( $license_key ) {
52 | $this->license_key = $license_key;
53 | }
54 |
55 | /**
56 | * Get the license key.
57 | *
58 | * @return string|null License Key.
59 | */
60 | public function get_license_key() {
61 | return $this->license_key;
62 | }
63 |
64 | /**
65 | * Set add-on name.
66 | *
67 | * @param string $addon_name Add-on Name.
68 | */
69 | public function set_addon_name( $addon_name ) {
70 | $this->addon_name = $addon_name;
71 | }
72 |
73 | /**
74 | * Get the add-on name.
75 | *
76 | * @return string Add-on name.
77 | */
78 | public function get_addon_name() {
79 | return $this->addon_name;
80 | }
81 |
82 | /**
83 | * Get the expiry date of the license.
84 | *
85 | * @return false|string Expiry date in `yyyy-mm-dd hh:mm:ss` format if license is valid, False otherwise.
86 | */
87 | public function get_expiry_date() {
88 | if ( ! empty( $this->license_data ) && isset( $this->license_data->expires ) ) {
89 | return $this->license_data->expires;
90 | }
91 |
92 | return false;
93 | }
94 |
95 | /**
96 | * Has the bundle license expired?
97 | *
98 | * @since 2.3.0
99 | *
100 | * @return bool True if expired, False otherwise.
101 | */
102 | public function has_expired() {
103 | $is_valid = $this->is_valid();
104 |
105 | if ( ! $is_valid ) {
106 | return true;
107 | }
108 |
109 | $expiry_date = $this->get_expiry_date();
110 |
111 | if ( ! $expiry_date ) {
112 | return true;
113 | }
114 |
115 | return ( strtotime( $expiry_date ) < time() );
116 | }
117 |
118 | /**
119 | * Is the license activated and valid?
120 | *
121 | * @since 2.3.0 Moved to BaseLicense class.
122 | *
123 | * @return bool True if license is active, False otherwise.
124 | */
125 | public function is_valid() {
126 | if ( ! $this->license_data instanceof \stdClass || ! isset( $this->license_data->license ) ) {
127 | return false;
128 | }
129 |
130 | return ( 'valid' === $this->license_data->license );
131 | }
132 |
133 | /**
134 | * Get the renewal link for bundle license.
135 | *
136 | * @since 2.3.0
137 | *
138 | * @return string Renewal link.
139 | */
140 | public function get_renewal_link() {
141 | $license_key = $this->get_license_key();
142 |
143 | if ( empty( $license_key ) ) {
144 | return 'https://wpemaillog.com/store/?utm_campaign=Renewal&utm_medium=wpadmin&utm_source=renewal-notice';
145 | }
146 |
147 | return sprintf( 'https://wpemaillog.com/checkout/?edd_license_key=%s&utm_campaign=Renewal&utm_medium=wpadmin&utm_source=renewal-notice', $license_key );
148 | }
149 |
150 | /**
151 | * Activate License by calling EDD API.
152 | * The license data returned by API is stored in an option.
153 | *
154 | * @throws \Exception In case of communication errors or License Issues.
155 | *
156 | * @return object API Response JSON Object.
157 | */
158 | public function activate() {
159 | $response = $this->edd_api->activate_license( $this->get_license_key(), $this->get_addon_name() );
160 |
161 | if ( $response->success && 'valid' === $response->license ) {
162 | $response->license_key = $this->get_license_key();
163 |
164 | $this->store( $response );
165 |
166 | return $response;
167 | }
168 |
169 | switch ( $response->error ) {
170 | case 'expired':
171 | $message = sprintf(
172 | /* translators: 1 License expiry date, 2 License Renewal link */
173 | __( 'Your license key expired on %1$s. Please renew it to receive automatic updates and support.', 'email-log' ),
174 | date_i18n( get_option( 'date_format' ), strtotime( $response->expires, current_time( 'timestamp' ) ) ),
175 | 'https://wpemaillog.com/checkout/?edd_license_key=' . $this->get_license_key() . '&utm_campaign=Renewal&utm_medium=wpadmin&utm_source=activation-failed'
176 | );
177 | break;
178 |
179 | case 'revoked':
180 | $message = __( 'Your license key has been disabled.', 'email-log' );
181 | break;
182 |
183 | case 'missing':
184 | $message = __( 'Your license key is invalid.', 'email-log' );
185 | break;
186 |
187 | case 'invalid':
188 | case 'site_inactive':
189 | $message = __( 'Your license is not active for this URL.', 'email-log' );
190 | break;
191 |
192 | case 'item_name_mismatch':
193 | /* translators: 1 Add-on name */
194 | $message = sprintf( __( 'Your license key is not valid for %s.', 'email-log' ), $this->get_addon_name() );
195 | break;
196 |
197 | case 'no_activations_left':
198 | $message = sprintf(
199 | /* translators: 1 License Upgrade link */
200 | __( 'Your license key has reached its activation limit. Please upgrade your license.', 'email-log' ),
201 | 'https://wpemaillog.com/account/?utm_campaign=Upgrade&utm_medium=wpadmin&utm_source=activation-failed'
202 | );
203 | break;
204 |
205 | default:
206 | $message = __( 'An error occurred, please try again.', 'email-log' );
207 | break;
208 | }
209 |
210 | throw new \Exception( $message );
211 | }
212 |
213 | /**
214 | * Deactivate the license by calling EDD API.
215 | * The stored license data will be cleared.
216 | *
217 | * @throws \Exception In case of communication errors.
218 | *
219 | * @return object API Response JSON object.
220 | */
221 | public function deactivate() {
222 | $response = $this->edd_api->deactivate_license( $this->get_license_key(), $this->get_addon_name() );
223 |
224 | if ( $response->success && 'deactivated' === $response->license ) {
225 | $this->clear();
226 |
227 | return $response;
228 | }
229 |
230 | if ( $response->expires < time() ) {
231 | // license has expired. Expired license can't be de-activated. So let's just clear it.
232 | $this->clear();
233 |
234 | return $response;
235 | }
236 |
237 | $message = __( 'An error occurred, please try again.', 'email-log' );
238 |
239 | if ( isset( $response->error ) ) {
240 | $message .= ' ' . $response->error;
241 | }
242 |
243 | throw new \Exception( $message );
244 | }
245 |
246 | /**
247 | * Get version information by calling EDD API.
248 | * // TODO: Currently not used. Will be removed eventually.
249 | *
250 | * @throws \Exception In case of communication errors.
251 | *
252 | * @return object API Response JSON Object.
253 | */
254 | public function get_version() {
255 | $response = $this->edd_api->get_version( $this->get_license_key(), $this->get_addon_name() );
256 |
257 | if ( isset( $response->new_version ) && ! isset( $response->msg ) ) {
258 | return $response;
259 | }
260 |
261 | $message = __( 'An error occurred, please try again', 'email-log' ) . $response->error;
262 |
263 | throw new \Exception( $message );
264 | }
265 |
266 | /**
267 | * Load the license data from DB option.
268 | */
269 | public function load() {
270 | $this->license_data = get_option( $this->get_option_name(), null );
271 | }
272 |
273 | /**
274 | * Store License data in DB option.
275 | *
276 | * @access protected
277 | *
278 | * @param object $license_data License data.
279 | */
280 | protected function store( $license_data ) {
281 | $this->license_data = $license_data;
282 | update_option( $this->get_option_name(), $license_data );
283 | }
284 |
285 | /**
286 | * Clear stored license data.
287 | *
288 | * @access protected
289 | */
290 | protected function clear() {
291 | $this->license_data = null;
292 | $this->license_key = null;
293 | delete_option( $this->get_option_name() );
294 | }
295 | }
296 |
--------------------------------------------------------------------------------