PluginProbe
FluentSMTP – WP Mail SMTP Plugin with Amazon SES, SendGrid, Mailgun, Postmark, Cloudflare, toSend, Gmail and Any SMTP / trunk
FluentSMTP – WP Mail SMTP Plugin with Amazon SES, SendGrid, Mailgun, Postmark, Cloudflare, toSend, Gmail and Any SMTP vtrunk
2.4.0 trunk 1.0.1 1.1.0 1.1.1 1.2.0 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.71 2.2.72 2.2.73 2.2.80 2.2.81 All 32 releases
fluent-smtp / database / migrations / EmailLogs.php

EmailLogs.php in FluentSMTP – WP Mail SMTP Plugin with Amazon SES, SendGrid, Mailgun, Postmark, Cloudflare, toSend, Gmail and Any SMTP trunk, at database/migrations/EmailLogs.php

98 lines 3.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentMailMigrations;
4
5 class EmailLogs
6 {
7 /**
8 * Migrate the table.
9 *
10 * @return void
11 */
12 public static function migrate()
13 {
14 global $wpdb;
15
16 $charsetCollate = $wpdb->get_charset_collate();
17
18 $table = $wpdb->prefix . FLUENT_MAIL_DB_PREFIX.'email_logs';
19
20 // Table name is static/hard-coded, so wpdb->prepare() is sufficient
21 if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table)) != $table) {
22 $sql = "CREATE TABLE $table (
23 `id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
24 `site_id` INT UNSIGNED NULL,
25 `to` VARCHAR(255),
26 `from` VARCHAR(255),
27 `subject` VARCHAR(255),
28 `body` LONGTEXT NULL,
29 `headers` LONGTEXT NULL,
30 `attachments` LONGTEXT NULL,
31 `status` VARCHAR(20) DEFAULT 'pending',
32 `response` TEXT NULL,
33 `extra` TEXT NULL,
34 `retries` INT UNSIGNED NULL DEFAULT 0,
35 `resent_count` INT UNSIGNED NULL DEFAULT 0,
36 `source` VARCHAR(255) NULL,
37 `created_at` TIMESTAMP NULL,
38 `updated_at` TIMESTAMP NULL,
39 INDEX `created_at_status` (`created_at`, `status`)
40 ) $charsetCollate;";
41
42 dbDelta($sql);
43 } else {
44 self::maybeUpgradeIndexes($table);
45 }
46 }
47
48 /**
49 * Replace the old single-column `status` index with one that leads on
50 * `created_at`.
51 *
52 * Every query against this table constrains a date range - the dashboard
53 * counters pair it with a status, while the report chart, the day/time
54 * heatmap and the pruning cron filter on the date alone. Leading with
55 * `created_at` therefore serves all of them from one index. Leading with
56 * `status` would only serve the first group, and barely: a log is
57 * overwhelmingly 'sent', so that column narrows almost nothing.
58 *
59 * This only runs from migrate(), i.e. on activation and on new-site
60 * creation - never on a normal page load. Reindexing a table that can hold
61 * millions of rows is not free, so it must stay off the request path.
62 *
63 * @param string $table
64 * @return void
65 */
66 private static function maybeUpgradeIndexes($table)
67 {
68 global $wpdb;
69
70 if (!self::hasIndex($table, 'created_at_status')) {
71 $wpdb->query("ALTER TABLE $table ADD INDEX `created_at_status` (`created_at`, `status`)");
72 }
73
74 /*
75 * Dropped last, and only once the replacement is confirmed present, so
76 * the table is never left with no index covering `status` at all.
77 */
78 if (self::hasIndex($table, 'status') && self::hasIndex($table, 'created_at_status')) {
79 $wpdb->query("ALTER TABLE $table DROP INDEX `status`");
80 }
81 }
82
83 /**
84 * @param string $table
85 * @param string $indexName
86 * @return bool
87 */
88 private static function hasIndex($table, $indexName)
89 {
90 global $wpdb;
91
92 // Table name is static/hard-coded, so wpdb->prepare() is sufficient
93 return (bool)$wpdb->get_var(
94 $wpdb->prepare("SHOW INDEX FROM $table WHERE Key_name = %s", $indexName)
95 );
96 }
97 }
98