-
Notifications
You must be signed in to change notification settings - Fork 2
/
class-event-log.php
198 lines (170 loc) · 5.9 KB
/
class-event-log.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
<?php
/**
* Newspack Hub Event Log Store
*
* @package Newspack
*/
namespace Newspack_Network\Hub\Stores;
use Newspack_Network\Accepted_Actions;
use Newspack_Network\Debugger;
use Newspack_Network\Incoming_Events\Abstract_Incoming_Event;
use Newspack_Network\Hub\Node;
use Newspack_Network\Hub\Nodes;
use Newspack_Network\Hub\Database\Event_Log as Database;
/**
* Class to handle Event Log Store
*/
class Event_Log {
/**
* Get event log items
*
* @param array $args See {@see self::build_where_clause()} for supported arguments.
* @param int $per_page Number of items to return per page.
* @param int $page Page number to return.
* @param string $order Order to return the items in. ASC or DESC.
* @return Abstract_Event_Log_Item[]
*/
public static function get( $args, $per_page = 10, $page = 1, $order = 'DESC' ) {
global $wpdb;
$offset = ( $page - 1 ) * $per_page;
$table_name = Database::get_table_name();
$order_string = "ORDER BY ID $order";
$query = $wpdb->prepare( "SELECT * FROM $table_name WHERE 1=1 [args] $order_string LIMIT %d OFFSET %d", $per_page, $offset ); //phpcs:ignore
$query = str_replace( '[args]', self::build_where_clause( $args ), $query );
$db = $wpdb->get_results( $query ); //phpcs:ignore
$results = [];
foreach ( $db as $item ) {
if ( empty( Accepted_Actions::ACTIONS[ $item->action_name ] ) ) {
continue;
}
$class_name = 'Newspack_Network\\Hub\\Stores\\Event_Log_Items\\' . Accepted_Actions::ACTIONS[ $item->action_name ];
if ( ! class_exists( $class_name ) ) {
$class_name = 'Newspack_Network\\Hub\\Stores\\Event_Log_Items\\Generic';
}
$results[] = new $class_name(
[
'id' => $item->id,
'node' => new Node( $item->node_id ),
'action_name' => $item->action_name,
'email' => $item->email,
'data' => $item->data,
'timestamp' => $item->timestamp,
]
);
}
return $results;
}
/**
* Gets a list of all the emails in the event log
*
* @return array
*/
public static function get_all_emails() {
global $wpdb;
$table_name = Database::get_table_name();
$query = "SELECT DISTINCT email FROM $table_name ORDER BY email";
return $wpdb->get_col( $query ); //phpcs:ignore
}
/**
* Get the total number of items for a query
*
* @param array $args See {@see self::build_where_clause()} for supported arguments.
* @return int
*/
public static function get_total_items( $args ) {
global $wpdb;
$table_name = Database::get_table_name();
$query = "SELECT COUNT(*) FROM $table_name WHERE 1=1 [args]";
$query = str_replace( '[args]', self::build_where_clause( $args ), $query );
$result = $wpdb->get_var( $query ); //phpcs:ignore
return $result;
}
/**
* Build the WHERE clause for the query
*
* @param array $args {
* The query arguments. Supported arguments are below.
*
* @type string $search Search string to search for in the event log. It will search in the email, action_name and data fields.
* @type int $node_id The ID of the node to filter by.
* @type int $excluded_node_id The ID of the node to exclude from results.
* @type int $id_greater_than Retrieve events with ID greater than this value.
* @type string $email The email of the event to filter by.
* @type string $action_name The name of the action to filter by.
* @type array $action_name_in List of action names to include in the results.
* }
* @return string The WHERE clause for the query.
*/
protected static function build_where_clause( $args ) {
global $wpdb;
$where = '';
// remove empty values.
$args = array_filter(
$args,
function( $v ) {
return is_array( $v ) || strlen( (string) $v ); // Zero is a valid value for node id, thus we don't use empty().
}
);
if ( isset( $args['node_id'] ) ) {
$where .= $wpdb->prepare( ' AND node_id = %d', $args['node_id'] );
}
if ( isset( $args['excluded_node_id'] ) ) {
$where .= $wpdb->prepare( ' AND node_id <> %d', $args['excluded_node_id'] );
}
if ( ! empty( $args['id_greater_than'] ) ) {
$where .= $wpdb->prepare( ' AND id > %d', $args['id_greater_than'] );
}
if ( ! empty( $args['email'] ) ) {
$where .= $wpdb->prepare( ' AND email = %s', $args['email'] );
}
if ( ! empty( $args['action_name'] ) ) {
$where .= $wpdb->prepare( ' AND action_name = %s', $args['action_name'] );
}
if ( ! empty( $args['action_name_in'] ) && is_array( $args['action_name_in'] ) ) {
$escaped_actions = array_map(
function( $a ) {
return "'" . esc_sql( $a ) . "'";
},
$args['action_name_in']
);
$where .= ' AND action_name IN (' . implode( ',', $escaped_actions ) . ')';
}
if ( ! empty( $args['search'] ) ) {
$where .= $wpdb->prepare( ' AND ( email LIKE %s ', '%' . $args['search'] . '%' );
$where .= $wpdb->prepare( ' OR action_name LIKE %s ', '%' . $args['search'] . '%' );
$where .= $wpdb->prepare( ' OR data LIKE %s ', '%' . $args['search'] . '%' );
$where .= ')';
}
return $where;
}
/**
* Persists an event to the database
*
* @param Abstract_Incoming_Event $event The Incoming Event to be persisted.
* @return int|false The ID of the inserted row, or false on failure.
*/
public static function persist( Abstract_Incoming_Event $event ) {
global $wpdb;
Debugger::log( 'Persisting Event' );
$node = Nodes::get_node_by_url( $event->get_site() );
$node_id = 0;
if ( $node instanceof Node ) {
$node_id = $node->get_id();
}
$insert = $wpdb->insert( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
Database::get_table_name(),
[
'node_id' => $node_id,
'action_name' => $event->get_action_name(),
'email' => $event->get_email(),
'data' => wp_json_encode( $event->get_data() ),
'timestamp' => $event->get_timestamp(),
]
);
Debugger::log( $insert );
if ( ! $insert ) {
return false;
}
return $wpdb->insert_id;
}
}