Stream - Version 3.6.1

Version Description

  • January 12, 2020 =

  • New: Action add for when a blog is deleted #1177, props @kidunot89

  • Fix: Refactored Stream's Records table custom column functionality to output the correct column values #1185, props @Nikschavan, @kidunot89, and @derekherman

  • Fix: Refactored deprecated SQL statement for retrieving the result count #1203, props @kidunot89

  • Fix: Fixed a namespace of a call to the Closure class #1215, props @szepeviktor

  • Fix: The default options are made available during the "wp_stream_auto_purge" callback #1159, props @kidunot89

  • Fix: Expensive functions removed #1201, props @kidunot89

  • Tweak: Remove redundant textdomain initialization #1213, props @szepeviktor

  • Tweak: Cleaned up PHP version check #1212, props @szepeviktor

  • Development: Unit test added for Menu connector class #1164, props @kidunot89

  • Development: Unit test added for Blog connector class #1177, props @kidunot89

  • Development Fix: Micro patch provided for Mercator actions register to deprecated hooks #1217, props @kidunot89

  • Development: Unit test added for Mercator connector class #1180, props @kidunot89

  • Development: Unit test added for Settings connector class #1165, props @kidunot89

  • Development: Unit test added for Installer connector class #1155, props @kidunot89

  • Development: Unit test added for User connector class #1151, props @kidunot89

  • Development: Unit test added for Editor connector class #1138, props @kidunot89

  • Development: Unit test added for Comments connector class #1134, props @kidunot89

Download this release

Release Info

Developer kasparsd
Plugin Icon 128x128 Stream
Version 3.6.1
Comparing to
See all releases

Code changes from version 3.6.0 to 3.6.1

classes/class-admin.php CHANGED
@@ -143,7 +143,7 @@ class Admin {
143
  add_filter( 'role_has_cap', array( $this, 'filter_role_caps' ), 10, 3 );
144
 
145
  if ( is_multisite() && $plugin->is_network_activated() && ! is_network_admin() ) {
146
- $options = (array) get_site_option( 'wp_stream_network', array() );
147
  $option = isset( $options['general_site_access'] ) ? absint( $options['general_site_access'] ) : 1;
148
 
149
  $this->disable_access = ( $option ) ? false : true;
@@ -746,10 +746,11 @@ class Admin {
746
  return;
747
  }
748
 
 
749
  if ( is_multisite() && $this->plugin->is_network_activated() ) {
750
- $options = (array) get_site_option( 'wp_stream_network', array() );
751
  } else {
752
- $options = (array) get_option( 'wp_stream', array() );
753
  }
754
 
755
  if ( ! empty( $options['general_keep_records_indefinitely'] ) || ! isset( $options['general_records_ttl'] ) ) {
143
  add_filter( 'role_has_cap', array( $this, 'filter_role_caps' ), 10, 3 );
144
 
145
  if ( is_multisite() && $plugin->is_network_activated() && ! is_network_admin() ) {
146
+ $options = (array) get_site_option( 'wp_stream_network', $plugin->settings->get_defaults() );
147
  $option = isset( $options['general_site_access'] ) ? absint( $options['general_site_access'] ) : 1;
148
 
149
  $this->disable_access = ( $option ) ? false : true;
746
  return;
747
  }
748
 
749
+ $defaults = $this->plugin->settings->get_defaults();
750
  if ( is_multisite() && $this->plugin->is_network_activated() ) {
751
+ $options = (array) get_site_option( 'wp_stream_network', $defaults );
752
  } else {
753
+ $options = (array) get_option( 'wp_stream', $defaults );
754
  }
755
 
756
  if ( ! empty( $options['general_keep_records_indefinitely'] ) || ! isset( $options['general_records_ttl'] ) ) {
classes/class-install.php CHANGED
@@ -71,12 +71,6 @@ class Install {
71
  $this->db_version = $this->get_db_version();
72
  $this->stream_url = self_admin_url( $this->plugin->admin->admin_parent_page . '&page=' . $this->plugin->admin->settings_page_slug );
73
 
74
- // Check DB and display an admin notice if there are tables missing.
75
- add_action( 'init', array( $this, 'verify_db' ) );
76
-
77
- // Install the plugin.
78
- add_action( 'wp_stream_before_db_notices', array( $this, 'check' ) );
79
-
80
  register_activation_hook( $this->plugin->locations['plugin'], array( $this, 'check' ) );
81
  }
82
 
@@ -137,87 +131,6 @@ class Install {
137
  $this->update_db_option();
138
  }
139
 
140
- /**
141
- * Verify that the required DB tables exists
142
- *
143
- * @return void
144
- */
145
- public function verify_db() {
146
- /**
147
- * Filter will halt install() if set to true
148
- *
149
- * @param bool
150
- *
151
- * @return bool
152
- */
153
- if ( apply_filters( 'wp_stream_no_tables', false ) ) {
154
- return;
155
- }
156
-
157
- if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
158
- require_once ABSPATH . '/wp-admin/includes/plugin.php';
159
- }
160
-
161
- /**
162
- * Fires before admin notices are triggered for missing database tables.
163
- */
164
- do_action( 'wp_stream_before_db_notices' );
165
-
166
- global $wpdb;
167
-
168
- $database_message = '';
169
- $uninstall_message = '';
170
-
171
- // Check if all needed DB is present.
172
- $missing_tables = array();
173
-
174
- foreach ( $this->plugin->db->get_table_names() as $table_name ) {
175
- $table_search = $wpdb->get_var(
176
- $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name )
177
- );
178
- if ( $table_search !== $table_name ) {
179
- $missing_tables[] = $table_name;
180
- }
181
- }
182
-
183
- if ( $missing_tables ) {
184
- $database_message .= sprintf(
185
- '%s <strong>%s</strong>',
186
- _n(
187
- 'The following table is not present in the WordPress database:',
188
- 'The following tables are not present in the WordPress database:',
189
- count( $missing_tables ),
190
- 'stream'
191
- ),
192
- esc_html( implode( ', ', $missing_tables ) )
193
- );
194
- }
195
-
196
- if ( $this->plugin->is_network_activated() && current_user_can( 'manage_network_plugins' ) ) {
197
- $uninstall_message = sprintf(
198
- /* translators: %#$s: HTML Link tags (e.g. "<a href="https://foo.com/wp-admin/">") */
199
- __( 'Please %1$suninstall%2$s the Stream plugin and activate it again.', 'stream' ),
200
- '<a href="' . network_admin_url( 'plugins.php#stream' ) . '">',
201
- '</a>'
202
- );
203
- } elseif ( current_user_can( 'activate_plugins' ) ) {
204
- $uninstall_message = sprintf(
205
- /* translators: %#$s: HTML Link tags (e.g. "<a href="https://foo.com/wp-admin/">") */
206
- __( 'Please %1$suninstall%2$s the Stream plugin and activate it again.', 'stream' ),
207
- '<a href="' . admin_url( 'plugins.php#stream' ) . '">',
208
- '</a>'
209
- );
210
- }
211
-
212
- if ( ! empty( $database_message ) ) {
213
- $this->plugin->admin->notice( $database_message );
214
-
215
- if ( ! empty( $uninstall_message ) ) {
216
- $this->plugin->admin->notice( $uninstall_message );
217
- }
218
- }
219
- }
220
-
221
  /**
222
  * Register a routine to be called when stream or a stream connector has been updated
223
  * It works by comparing the current version with the version previously stored in the database.
71
  $this->db_version = $this->get_db_version();
72
  $this->stream_url = self_admin_url( $this->plugin->admin->admin_parent_page . '&page=' . $this->plugin->admin->settings_page_slug );
73
 
 
 
 
 
 
 
74
  register_activation_hook( $this->plugin->locations['plugin'], array( $this, 'check' ) );
75
  }
76
 
131
  $this->update_db_option();
132
  }
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  /**
135
  * Register a routine to be called when stream or a stream connector has been updated
136
  * It works by comparing the current version with the version previously stored in the database.
classes/class-list-table.php CHANGED
@@ -389,10 +389,11 @@ class List_Table extends \WP_List_Table {
389
  * Registers new Columns to be inserted into the table. The cell contents of this column is set
390
  * below with 'wp_stream_insert_column_default_'
391
  *
 
 
392
  * @return array
393
  */
394
- $new_columns = array();
395
- $inserted_columns = apply_filters( 'wp_stream_register_column_defaults', $new_columns );
396
 
397
  if ( ! empty( $inserted_columns ) && is_array( $inserted_columns ) ) {
398
  foreach ( $inserted_columns as $column_title ) {
@@ -404,21 +405,20 @@ class List_Table extends \WP_List_Table {
404
  * Also, note that the action name must include the $column_title registered
405
  * with wp_stream_register_column_defaults
406
  */
407
- if ( $column_title === $column_name && has_filter( "wp_stream_insert_column_default_{$column_title}" ) ) {
408
  /**
409
  * Allows for the addition of content under a specified column.
410
  *
411
- * @param object $record Contents of the row
 
 
412
  *
413
  * @return string
414
  */
415
- $out = apply_filters( "wp_stream_insert_column_default_{$column_title}", $column_name, $record );
416
- } else {
417
- $out = $column_name;
418
  }
419
  }
420
- } else {
421
- $out = $column_name;
422
  }
423
  }
424
 
389
  * Registers new Columns to be inserted into the table. The cell contents of this column is set
390
  * below with 'wp_stream_insert_column_default_'
391
  *
392
+ * @param array $new_columns Columns injected in the table.
393
+ *
394
  * @return array
395
  */
396
+ $inserted_columns = apply_filters( 'wp_stream_register_column_defaults', array() );
 
397
 
398
  if ( ! empty( $inserted_columns ) && is_array( $inserted_columns ) ) {
399
  foreach ( $inserted_columns as $column_title ) {
405
  * Also, note that the action name must include the $column_title registered
406
  * with wp_stream_register_column_defaults
407
  */
408
+ if ( $column_title === $column_name ) {
409
  /**
410
  * Allows for the addition of content under a specified column.
411
  *
412
+ * @param string $out Column content.
413
+ * @param object $record Record with row content.
414
+ * @param string $column_name Column name.
415
  *
416
  * @return string
417
  */
418
+ $out = apply_filters( "wp_stream_insert_column_default_{$column_title}", $out, $record, $column_name );
419
+ break;
 
420
  }
421
  }
 
 
422
  }
423
  }
424
 
classes/class-plugin.php CHANGED
@@ -18,7 +18,7 @@ class Plugin {
18
  *
19
  * @const string
20
  */
21
- const VERSION = '3.6.0';
22
 
23
  /**
24
  * WP-CLI command
18
  *
19
  * @const string
20
  */
21
+ const VERSION = '3.6.1';
22
 
23
  /**
24
  * WP-CLI command
classes/class-query.php CHANGED
@@ -229,7 +229,7 @@ class Query {
229
  /**
230
  * BUILD THE FINAL QUERY
231
  */
232
- $query = "SELECT SQL_CALC_FOUND_ROWS {$select}
233
  FROM $wpdb->stream
234
  {$join}
235
  WHERE 1=1 {$where}
@@ -246,12 +246,29 @@ class Query {
246
  */
247
  $query = apply_filters( 'wp_stream_db_query', $query, $args );
248
 
249
- $result = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  /**
251
  * QUERY THE DATABASE FOR RESULTS
252
  */
253
- $result['items'] = $wpdb->get_results( $query ); // @codingStandardsIgnoreLine $query already prepared
254
- $result['count'] = $result['items'] ? absint( $wpdb->get_var( 'SELECT FOUND_ROWS()' ) ) : 0;
 
 
255
 
256
  return $result;
257
  }
229
  /**
230
  * BUILD THE FINAL QUERY
231
  */
232
+ $query = "SELECT {$select}
233
  FROM $wpdb->stream
234
  {$join}
235
  WHERE 1=1 {$where}
246
  */
247
  $query = apply_filters( 'wp_stream_db_query', $query, $args );
248
 
249
+ // Build result count query.
250
+ $count_query = "SELECT COUNT(*) as found
251
+ FROM $wpdb->stream
252
+ {$join}
253
+ WHERE 1=1 {$where}";
254
+
255
+ /**
256
+ * Filter allows the result count query to be modified before execution.
257
+ *
258
+ * @param string $query
259
+ * @param array $args
260
+ *
261
+ * @return string
262
+ */
263
+ $count_query = apply_filters( 'wp_stream_db_count_query', $count_query, $args );
264
+
265
  /**
266
  * QUERY THE DATABASE FOR RESULTS
267
  */
268
+ $result = array(
269
+ 'items' => $wpdb->get_results( $query ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
270
+ 'count' => absint( $wpdb->get_var( $count_query ) ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
271
+ );
272
 
273
  return $result;
274
  }
composer.json CHANGED
@@ -6,25 +6,26 @@
6
  "license": "GPL-2.0-or-later",
7
  "repositories": [
8
  {
9
- "type":"composer",
10
- "url":"https://wpackagist.org"
11
  }
12
  ],
13
  "require": {
14
  "composer/installers": "~1.0"
15
  },
16
  "require-dev": {
17
- "johnpbloch/wordpress": "^5.4",
18
  "automattic/vipwpcs": "^2.0.0",
 
 
19
  "php-coveralls/php-coveralls": "^2.1",
20
  "phpunit/phpunit": "^5.7",
21
  "wp-cli/wp-cli-bundle": "^2.2",
22
  "wp-coding-standards/wpcs": "^2.2",
23
  "wp-phpunit/wp-phpunit": "^5.4",
24
- "wpsh/local": "^0.2.3",
25
  "wpackagist-plugin/advanced-custom-fields": "5.8.12",
26
  "wpackagist-plugin/easy-digital-downloads": "^2.9.23",
27
- "wpackagist-plugin/user-switching": "^1.5.5"
 
28
  },
29
  "config": {
30
  "process-timeout": 600,
@@ -36,7 +37,8 @@
36
  "extra": {
37
  "wordpress-install-dir": "local/public",
38
  "installer-paths": {
39
- "local/public/wp-content/plugins/{$name}/": ["type:wordpress-plugin"]
 
40
  }
41
  },
42
  "scripts": {
6
  "license": "GPL-2.0-or-later",
7
  "repositories": [
8
  {
9
+ "type": "composer",
10
+ "url": "https://wpackagist.org"
11
  }
12
  ],
13
  "require": {
14
  "composer/installers": "~1.0"
15
  },
16
  "require-dev": {
 
17
  "automattic/vipwpcs": "^2.0.0",
18
+ "humanmade/mercator": "^1.0",
19
+ "johnpbloch/wordpress": "^5.4",
20
  "php-coveralls/php-coveralls": "^2.1",
21
  "phpunit/phpunit": "^5.7",
22
  "wp-cli/wp-cli-bundle": "^2.2",
23
  "wp-coding-standards/wpcs": "^2.2",
24
  "wp-phpunit/wp-phpunit": "^5.4",
 
25
  "wpackagist-plugin/advanced-custom-fields": "5.8.12",
26
  "wpackagist-plugin/easy-digital-downloads": "^2.9.23",
27
+ "wpackagist-plugin/user-switching": "^1.5.5",
28
+ "wpsh/local": "^0.2.3"
29
  },
30
  "config": {
31
  "process-timeout": 600,
37
  "extra": {
38
  "wordpress-install-dir": "local/public",
39
  "installer-paths": {
40
+ "local/public/wp-content/plugins/{$name}/": ["type:wordpress-plugin"],
41
+ "local/public/wp-content/mu-plugins/{$name}/": ["type:wordpress-muplugin"]
42
  }
43
  },
44
  "scripts": {
connectors/class-connector-blogs.php CHANGED
@@ -24,7 +24,8 @@ class Connector_Blogs extends Connector {
24
  * @var array
25
  */
26
  public $actions = array(
27
- 'wpmu_new_blog',
 
28
  'wpmu_activate_blog',
29
  'wpmu_new_user',
30
  'add_user_to_blog',
@@ -127,14 +128,16 @@ class Connector_Blogs extends Connector {
127
  }
128
 
129
  /**
130
- * Blog created
131
  *
132
- * @action wpmu_new_blog
133
  *
134
- * @param int $blog_id Blog ID.
 
135
  */
136
- public function callback_wpmu_new_blog( $blog_id ) {
137
- $blog = get_blog_details( $blog_id );
 
138
 
139
  $this->log(
140
  /* translators: %s: site name (e.g. "FooBar Blog") */
@@ -144,14 +147,42 @@ class Connector_Blogs extends Connector {
144
  'stream'
145
  ),
146
  array(
147
- 'site_name' => $blog->blogname,
 
 
148
  ),
149
  $blog_id,
150
- sanitize_key( $blog->blogname ),
151
  'created'
152
  );
153
  }
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  /**
156
  * Blog registered
157
  *
@@ -161,7 +192,7 @@ class Connector_Blogs extends Connector {
161
  * @param int $user_id User ID.
162
  */
163
  public function callback_wpmu_activate_blog( $blog_id, $user_id ) {
164
- $blog = get_blog_details( $blog_id );
165
 
166
  $this->log(
167
  /* translators: %s: site name (e.g. "FooBar Blog") */
@@ -172,6 +203,8 @@ class Connector_Blogs extends Connector {
172
  ),
173
  array(
174
  'site_name' => $blog->blogname,
 
 
175
  ),
176
  $blog_id,
177
  sanitize_key( $blog->blogname ),
@@ -190,7 +223,7 @@ class Connector_Blogs extends Connector {
190
  * @param int $blog_id Blog ID.
191
  */
192
  public function callback_add_user_to_blog( $user_id, $role, $blog_id ) {
193
- $blog = get_blog_details( $blog_id );
194
  $user = get_user_by( 'id', $user_id );
195
 
196
  if ( ! is_a( $user, 'WP_User' ) ) {
@@ -207,6 +240,8 @@ class Connector_Blogs extends Connector {
207
  array(
208
  'user_name' => $user->display_name,
209
  'site_name' => $blog->blogname,
 
 
210
  'role_name' => $role,
211
  ),
212
  $blog_id,
@@ -224,7 +259,7 @@ class Connector_Blogs extends Connector {
224
  * @param int $blog_id Blog ID.
225
  */
226
  public function callback_remove_user_from_blog( $user_id, $blog_id ) {
227
- $blog = get_blog_details( $blog_id );
228
  $user = get_user_by( 'id', $user_id );
229
 
230
  if ( ! is_a( $user, 'WP_User' ) ) {
@@ -241,6 +276,8 @@ class Connector_Blogs extends Connector {
241
  array(
242
  'user_name' => $user->display_name,
243
  'site_name' => $blog->blogname,
 
 
244
  ),
245
  $blog_id,
246
  sanitize_key( $blog->blogname ),
@@ -322,7 +359,7 @@ class Connector_Blogs extends Connector {
322
  * @param int $blog_id Blog ID.
323
  */
324
  public function callback_make_delete_blog( $blog_id ) {
325
- $this->callback_update_blog_status( $blog_id, esc_html__( 'deleted', 'stream' ), 'deleted' );
326
  }
327
 
328
  /**
@@ -333,7 +370,7 @@ class Connector_Blogs extends Connector {
333
  * @param int $blog_id Blog ID.
334
  */
335
  public function callback_make_undelete_blog( $blog_id ) {
336
- $this->callback_update_blog_status( $blog_id, esc_html__( 'restored', 'stream' ), 'updated' );
337
  }
338
 
339
  /**
@@ -345,7 +382,7 @@ class Connector_Blogs extends Connector {
345
  * @param string $value Status flag.
346
  */
347
  public function callback_update_blog_public( $blog_id, $value ) {
348
- if ( $value ) {
349
  $status = esc_html__( 'marked as public', 'stream' );
350
  } else {
351
  $status = esc_html__( 'marked as private', 'stream' );
@@ -364,8 +401,7 @@ class Connector_Blogs extends Connector {
364
  * @param string $action Action.
365
  */
366
  public function callback_update_blog_status( $blog_id, $status, $action ) {
367
- $blog = get_blog_details( $blog_id );
368
-
369
  $this->log(
370
  /* translators: %1$s: a site name, %2$s: a blog status (e.g. "FooBar Blog", "archived") */
371
  _x(
@@ -375,6 +411,8 @@ class Connector_Blogs extends Connector {
375
  ),
376
  array(
377
  'site_name' => $blog->blogname,
 
 
378
  'status' => $status,
379
  ),
380
  $blog_id,
24
  * @var array
25
  */
26
  public $actions = array(
27
+ 'wp_initialize_site',
28
+ 'wp_delete_site',
29
  'wpmu_activate_blog',
30
  'wpmu_new_user',
31
  'add_user_to_blog',
128
  }
129
 
130
  /**
131
+ * Blog created.
132
  *
133
+ * @action wp_initialize_site
134
  *
135
+ * @param WP_Site $new_site New site object.
136
+ * @param array $args Arguments for the initialization.
137
  */
138
+ public function callback_wp_initialize_site( $new_site, $args ) {
139
+ $blogname = ! empty( $args['title'] ) ? $args['title'] : $new_site->blogname;
140
+ $blog_id = $new_site->blog_id;
141
 
142
  $this->log(
143
  /* translators: %s: site name (e.g. "FooBar Blog") */
147
  'stream'
148
  ),
149
  array(
150
+ 'site_name' => ! empty( $blogname ) ? $blogname : 'Site %d',
151
+ 'siteurl' => $new_site->siteurl,
152
+ 'id' => $new_site->blog_id,
153
  ),
154
  $blog_id,
155
+ sanitize_key( $blogname ),
156
  'created'
157
  );
158
  }
159
 
160
+ /**
161
+ * A site has been deleted from the database.
162
+ *
163
+ * @action wp_delete_site
164
+ *
165
+ * @param WP_Site $old_site Deleted site object.
166
+ */
167
+ public function callback_wp_delete_site( $old_site ) {
168
+ $this->log(
169
+ /* translators: %s: site name (e.g. "FooBar Blog") */
170
+ _x(
171
+ '"%s" site was deleted',
172
+ '1. Site name',
173
+ 'stream'
174
+ ),
175
+ array(
176
+ 'site_name' => $old_site->blogname,
177
+ 'siteurl' => $old_site->siteurl,
178
+ 'id' => $old_site->blog_id,
179
+ ),
180
+ $old_site->blog_id,
181
+ sanitize_key( $old_site->blogname ),
182
+ 'deleted'
183
+ );
184
+ }
185
+
186
  /**
187
  * Blog registered
188
  *
192
  * @param int $user_id User ID.
193
  */
194
  public function callback_wpmu_activate_blog( $blog_id, $user_id ) {
195
+ $blog = get_site( $blog_id );
196
 
197
  $this->log(
198
  /* translators: %s: site name (e.g. "FooBar Blog") */
203
  ),
204
  array(
205
  'site_name' => $blog->blogname,
206
+ 'siteurl' => $blog->siteurl,
207
+ 'id' => $blog->blog_id,
208
  ),
209
  $blog_id,
210
  sanitize_key( $blog->blogname ),
223
  * @param int $blog_id Blog ID.
224
  */
225
  public function callback_add_user_to_blog( $user_id, $role, $blog_id ) {
226
+ $blog = get_site( $blog_id );
227
  $user = get_user_by( 'id', $user_id );
228
 
229
  if ( ! is_a( $user, 'WP_User' ) ) {
240
  array(
241
  'user_name' => $user->display_name,
242
  'site_name' => $blog->blogname,
243
+ 'siteurl' => $blog->siteurl,
244
+ 'id' => $blog->blog_id,
245
  'role_name' => $role,
246
  ),
247
  $blog_id,
259
  * @param int $blog_id Blog ID.
260
  */
261
  public function callback_remove_user_from_blog( $user_id, $blog_id ) {
262
+ $blog = get_site( $blog_id );
263
  $user = get_user_by( 'id', $user_id );
264
 
265
  if ( ! is_a( $user, 'WP_User' ) ) {
276
  array(
277
  'user_name' => $user->display_name,
278
  'site_name' => $blog->blogname,
279
+ 'siteurl' => $blog->siteurl,
280
+ 'id' => $blog->blog_id,
281
  ),
282
  $blog_id,
283
  sanitize_key( $blog->blogname ),
359
  * @param int $blog_id Blog ID.
360
  */
361
  public function callback_make_delete_blog( $blog_id ) {
362
+ $this->callback_update_blog_status( $blog_id, esc_html__( 'trashed', 'stream' ), 'trashed' );
363
  }
364
 
365
  /**
370
  * @param int $blog_id Blog ID.
371
  */
372
  public function callback_make_undelete_blog( $blog_id ) {
373
+ $this->callback_update_blog_status( $blog_id, esc_html__( 'restored', 'stream' ), 'restored' );
374
  }
375
 
376
  /**
382
  * @param string $value Status flag.
383
  */
384
  public function callback_update_blog_public( $blog_id, $value ) {
385
+ if ( absint( $value ) ) {
386
  $status = esc_html__( 'marked as public', 'stream' );
387
  } else {
388
  $status = esc_html__( 'marked as private', 'stream' );
401
  * @param string $action Action.
402
  */
403
  public function callback_update_blog_status( $blog_id, $status, $action ) {
404
+ $blog = get_site( $blog_id );
 
405
  $this->log(
406
  /* translators: %1$s: a site name, %2$s: a blog status (e.g. "FooBar Blog", "archived") */
407
  _x(
411
  ),
412
  array(
413
  'site_name' => $blog->blogname,
414
+ 'siteurl' => $blog->siteurl,
415
+ 'id' => $blog->blog_id,
416
  'status' => $status,
417
  ),
418
  $blog_id,
connectors/class-connector-comments.php CHANGED
@@ -613,7 +613,9 @@ class Connector_Comments extends Connector {
613
  */
614
  public function callback_comment_duplicate_trigger( $comment_data ) {
615
  global $wpdb;
616
- unset( $comment_data );
 
 
617
 
618
  $comment_id = $wpdb->last_result[0]->comment_ID;
619
  $comment = get_comment( $comment_id );
613
  */
614
  public function callback_comment_duplicate_trigger( $comment_data ) {
615
  global $wpdb;
616
+ if ( ! empty( $wpdb->last_result ) ) {
617
+ return;
618
+ }
619
 
620
  $comment_id = $wpdb->last_result[0]->comment_ID;
621
  $comment = get_comment( $comment_id );
connectors/class-connector-menus.php CHANGED
@@ -91,6 +91,15 @@ class Connector_Menus extends Connector {
91
  add_action( 'update_option_theme_mods_' . get_option( 'stylesheet' ), array( $this, 'callback_update_option_theme_mods' ), 10, 2 );
92
  }
93
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Add action links to Stream drop row in admin list screen
96
  *
@@ -173,7 +182,7 @@ class Connector_Menus extends Connector {
173
  unset( $tt_id );
174
 
175
  $name = $deleted_term->name;
176
- $menu_id = $term->term_id;
177
 
178
  $this->log(
179
  /* translators: %s: a menu name (e.g. "Primary Menu") */
91
  add_action( 'update_option_theme_mods_' . get_option( 'stylesheet' ), array( $this, 'callback_update_option_theme_mods' ), 10, 2 );
92
  }
93
 
94
+ /**
95
+ * Unregister connection actions.
96
+ */
97
+ public function unregister() {
98
+ parent::unregister();
99
+
100
+ remove_action( 'update_option_theme_mods_' . get_option( 'stylesheet' ), array( $this, 'callback_update_option_theme_mods' ), 10 );
101
+ }
102
+
103
  /**
104
  * Add action links to Stream drop row in admin list screen
105
  *
182
  unset( $tt_id );
183
 
184
  $name = $deleted_term->name;
185
+ $menu_id = $term;
186
 
187
  $this->log(
188
  /* translators: %s: a menu name (e.g. "Primary Menu") */
connectors/class-connector-settings.php CHANGED
@@ -31,7 +31,7 @@ class Connector_Settings extends Connector {
31
  * @var array
32
  */
33
  public $actions = array(
34
- 'whitelist_options',
35
  'update_option',
36
  'update_site_option',
37
  'update_option_permalink_structure',
@@ -572,7 +572,7 @@ class Connector_Settings extends Connector {
572
  // The first applicable rule wins.
573
  $rule = array_shift( $applicable_rules );
574
  $menu_slug = $rule['menu_slug'];
575
- $submenu_slug = ( is_object( $rule['submenu_slug'] ) && $rule['submenu_slug'] instanceof Closure ? $rule['submenu_slug']( $record ) : $rule['submenu_slug'] );
576
  $url = $rule['url']( $rule, $record );
577
 
578
  if ( isset( $submenu[ $menu_slug ] ) ) {
@@ -618,12 +618,12 @@ class Connector_Settings extends Connector {
618
  * @action update_option
619
  *
620
  * @param string $option Option name.
621
- * @param mixed $value Option new value.
622
  * @param mixed $old_value Option old value.
 
623
  */
624
- public function callback_update_option( $option, $value, $old_value ) {
625
  if ( ( defined( '\WP_CLI' ) && \WP_CLI || did_action( 'customize_save' ) ) && array_key_exists( $option, $this->labels ) ) {
626
- $this->callback_updated_option( $option, $value, $old_value );
627
  }
628
  }
629
 
@@ -636,7 +636,7 @@ class Connector_Settings extends Connector {
636
  *
637
  * @return array
638
  */
639
- public function callback_whitelist_options( $options ) {
640
  add_action( 'updated_option', array( $this, 'callback' ), 10, 3 );
641
 
642
  return $options;
@@ -664,7 +664,7 @@ class Connector_Settings extends Connector {
664
  * @param mixed $old_value Option old value.
665
  */
666
  public function callback_update_site_option( $option, $value, $old_value ) {
667
- $this->callback_updated_option( $option, $value, $old_value );
668
  }
669
 
670
  /**
31
  * @var array
32
  */
33
  public $actions = array(
34
+ 'allowed_options',
35
  'update_option',
36
  'update_site_option',
37
  'update_option_permalink_structure',
572
  // The first applicable rule wins.
573
  $rule = array_shift( $applicable_rules );
574
  $menu_slug = $rule['menu_slug'];
575
+ $submenu_slug = ( is_object( $rule['submenu_slug'] ) && $rule['submenu_slug'] instanceof \Closure ? $rule['submenu_slug']( $record ) : $rule['submenu_slug'] );
576
  $url = $rule['url']( $rule, $record );
577
 
578
  if ( isset( $submenu[ $menu_slug ] ) ) {
618
  * @action update_option
619
  *
620
  * @param string $option Option name.
 
621
  * @param mixed $old_value Option old value.
622
+ * @param mixed $value Option new value.
623
  */
624
+ public function callback_update_option( $option, $old_value, $value ) {
625
  if ( ( defined( '\WP_CLI' ) && \WP_CLI || did_action( 'customize_save' ) ) && array_key_exists( $option, $this->labels ) ) {
626
+ $this->callback_updated_option( $option, $old_value, $value );
627
  }
628
  }
629
 
636
  *
637
  * @return array
638
  */
639
+ public function callback_allowed_options( $options ) {
640
  add_action( 'updated_option', array( $this, 'callback' ), 10, 3 );
641
 
642
  return $options;
664
  * @param mixed $old_value Option old value.
665
  */
666
  public function callback_update_site_option( $option, $value, $old_value ) {
667
+ $this->callback_updated_option( $option, $old_value, $value );
668
  }
669
 
670
  /**
connectors/class-connector-user-switching.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /**
3
- * Connector for User-Switching
4
  *
5
  * @package WP_Stream
6
  */
1
  <?php
2
  /**
3
+ * Connector for the User-Switching plugin
4
  *
5
  * @package WP_Stream
6
  */
connectors/class-connector-users.php CHANGED
@@ -41,6 +41,7 @@ class Connector_Users extends Connector {
41
  'delete_user',
42
  'deleted_user',
43
  'set_user_role',
 
44
  );
45
 
46
  /**
@@ -242,7 +243,7 @@ class Connector_Users extends Connector {
242
  /* translators: %s: a user display name (e.g. "Jane Doe") */
243
  __( '%s\'s password was reset', 'stream' ),
244
  array(
245
- 'email' => $user->display_name,
246
  ),
247
  $user->ID,
248
  'profiles',
@@ -313,7 +314,8 @@ class Connector_Users extends Connector {
313
  * @action clear_auth_cookie
314
  */
315
  public function callback_clear_auth_cookie() {
316
- $user = wp_get_current_user();
 
317
 
318
  // For some reason, incognito mode calls clear_auth_cookie on failed login attempts.
319
  if ( empty( $user ) || ! $user->exists() ) {
@@ -323,9 +325,7 @@ class Connector_Users extends Connector {
323
  $this->log(
324
  /* translators: %s: a user display name (e.g. "Jane Doe") */
325
  __( '%s logged out', 'stream' ),
326
- array(
327
- 'display_name' => $user->display_name,
328
- ),
329
  $user->ID,
330
  'sessions',
331
  'logout',
41
  'delete_user',
42
  'deleted_user',
43
  'set_user_role',
44
+ 'set_current_user',
45
  );
46
 
47
  /**
243
  /* translators: %s: a user display name (e.g. "Jane Doe") */
244
  __( '%s\'s password was reset', 'stream' ),
245
  array(
246
+ 'display_name' => $user->display_name,
247
  ),
248
  $user->ID,
249
  'profiles',
314
  * @action clear_auth_cookie
315
  */
316
  public function callback_clear_auth_cookie() {
317
+ $user_id = get_current_user_id();
318
+ $user = get_user_by( 'ID', $user_id );
319
 
320
  // For some reason, incognito mode calls clear_auth_cookie on failed login attempts.
321
  if ( empty( $user ) || ! $user->exists() ) {
325
  $this->log(
326
  /* translators: %s: a user display name (e.g. "Jane Doe") */
327
  __( '%s logged out', 'stream' ),
328
+ array( 'display_name' => $user->display_name ),
 
 
329
  $user->ID,
330
  'sessions',
331
  'logout',
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: xwp
3
  Tags: wp stream, stream, activity, logs, track
4
  Requires at least: 4.5
5
  Tested up to: 5.5
6
- Stable tag: 3.6.0
7
  License: GPLv2 or later
8
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -91,6 +91,27 @@ Past Contributors: fjarrett, shadyvb, chacha, westonruter, johnregan3, jacobschw
91
 
92
  == Changelog ==
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  = 3.6.0 - October 14, 2020 =
95
 
96
  * New: Introduce the `wp_stream_db_query_where` filter [#1160](https://github.com/xwp/stream/pull/1160), props [@kidunot89](https://github.com/kidunot89) and [@nprasath002](https://github.com/nprasath002).
3
  Tags: wp stream, stream, activity, logs, track
4
  Requires at least: 4.5
5
  Tested up to: 5.5
6
+ Stable tag: 3.6.1
7
  License: GPLv2 or later
8
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
9
 
91
 
92
  == Changelog ==
93
 
94
+ = 3.6.1 - January 12, 2020 =
95
+
96
+ * New: Action add for when a blog is deleted [#1177](https://github.com/xwp/stream/pull/1177), props [@kidunot89](https://github.com/kidunot89)
97
+ * Fix: Refactored Stream's Records table custom column functionality to output the correct column values [#1185](https://github.com/xwp/stream/pull/1185), props [@Nikschavan](https://github.com/Nikschavan), [@kidunot89](https://github.com/kidunot89), and [@derekherman](https://github.com/derekherman)
98
+ * Fix: Refactored deprecated SQL statement for retrieving the result count [#1203](https://github.com/xwp/stream/pull/1203), props [@kidunot89](https://github.com/kidunot89)
99
+ * Fix: Fixed a namespace of a call to the Closure class [#1215](https://github.com/xwp/stream/pull/1215), props [@szepeviktor](https://github.com/szepeviktor)
100
+ * Fix: The default options are made available during the "wp_stream_auto_purge" callback [#1159](https://github.com/xwp/stream/pull/1159), props [@kidunot89](https://github.com/kidunot89)
101
+ * Fix: Expensive functions removed [#1201](https://github.com/xwp/stream/pull/1201), props [@kidunot89](https://github.com/kidunot89)
102
+ * Tweak: Remove redundant textdomain initialization [#1213](https://github.com/xwp/stream/pull/1213), props [@szepeviktor](https://github.com/szepeviktor)
103
+ * Tweak: Cleaned up PHP version check [#1212](https://github.com/xwp/stream/pull/1212), props [@szepeviktor](https://github.com/szepeviktor)
104
+ * Development: Unit test added for Menu connector class [#1164](https://github.com/xwp/stream/pull/1164), props [@kidunot89](https://github.com/kidunot89)
105
+ * Development: Unit test added for Blog connector class [#1177](https://github.com/xwp/stream/pull/1177), props [@kidunot89](https://github.com/kidunot89)
106
+ * Development Fix: Micro patch provided for Mercator actions register to deprecated hooks [#1217](https://github.com/xwp/stream/pull/1217), props [@kidunot89](https://github.com/kidunot89)
107
+ * Development: Unit test added for Mercator connector class [#1180](https://github.com/xwp/stream/pull/1180), props [@kidunot89](https://github.com/kidunot89)
108
+ * Development: Unit test added for Settings connector class [#1165](https://github.com/xwp/stream/pull/1165), props [@kidunot89](https://github.com/kidunot89)
109
+ * Development: Unit test added for Installer connector class [#1155](https://github.com/xwp/stream/pull/1155), props [@kidunot89](https://github.com/kidunot89)
110
+ * Development: Unit test added for User connector class [#1151](https://github.com/xwp/stream/pull/1151), props [@kidunot89](https://github.com/kidunot89)
111
+ * Development: Unit test added for Editor connector class [#1138](https://github.com/xwp/stream/pull/1138), props [@kidunot89](https://github.com/kidunot89)
112
+ * Development: Unit test added for Comments connector class [#1134](https://github.com/xwp/stream/pull/1134), props [@kidunot89](https://github.com/kidunot89)
113
+
114
+
115
  = 3.6.0 - October 14, 2020 =
116
 
117
  * New: Introduce the `wp_stream_db_query_where` filter [#1160](https://github.com/xwp/stream/pull/1160), props [@kidunot89](https://github.com/kidunot89) and [@nprasath002](https://github.com/nprasath002).
stream.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Stream
4
  * Plugin URI: https://xwp.co/work/stream/
5
  * Description: Stream tracks logged-in user activity so you can monitor every change made on your WordPress site in beautifully organized detail. All activity is organized by context, action and IP address for easy filtering. Developers can extend Stream with custom connectors to log any kind of action.
6
- * Version: 3.6.0
7
  * Author: XWP
8
  * Author URI: https://xwp.co
9
  * License: GPLv2+
@@ -31,8 +31,7 @@
31
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
  */
33
 
34
- if ( ! version_compare( PHP_VERSION, '5.3', '>=' ) ) {
35
- load_plugin_textdomain( 'stream', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
36
  add_action( 'shutdown', 'wp_stream_fail_php_version' );
37
  } else {
38
  require __DIR__ . '/classes/class-plugin.php';
3
  * Plugin Name: Stream
4
  * Plugin URI: https://xwp.co/work/stream/
5
  * Description: Stream tracks logged-in user activity so you can monitor every change made on your WordPress site in beautifully organized detail. All activity is organized by context, action and IP address for easy filtering. Developers can extend Stream with custom connectors to log any kind of action.
6
+ * Version: 3.6.1
7
  * Author: XWP
8
  * Author URI: https://xwp.co
9
  * License: GPLv2+
31
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
  */
33
 
34
+ if ( version_compare( PHP_VERSION, '5.3', '<' ) ) {
 
35
  add_action( 'shutdown', 'wp_stream_fail_php_version' );
36
  } else {
37
  require __DIR__ . '/classes/class-plugin.php';