MainWP Child Reports - Version 2.0.8

Version Description

  • 9-15-2021 =
  • Fixed: An issue with logging certain actions triggered by WP Cron
  • Fixed: An issue with displaying timestamps on some setups
  • Fixed: Problems with the multibyte string functions usage
  • Preventative: Multiple security improvements
Download this release

Release Info

Developer mainwp
Plugin Icon 128x128 MainWP Child Reports
Version 2.0.8
Comparing to
See all releases

Code changes from version 2.0.7 to 2.0.8

classes/class-admin.php CHANGED
@@ -1100,7 +1100,7 @@ class Admin {
1100
  $users = array_filter(
1101
  $users,
1102
  function ( $user ) use ( $search ) {
1103
- return false !== mb_strpos( mb_strtolower( $user->display_name ), mb_strtolower( $search ) );
1104
  }
1105
  );
1106
  }
1100
  $users = array_filter(
1101
  $users,
1102
  function ( $user ) use ( $search ) {
1103
+ return false !== \mb_strpos( \mb_strtolower( $user->display_name ), \mb_strtolower( $search ) );
1104
  }
1105
  );
1106
  }
classes/class-alerts-list.php CHANGED
@@ -45,8 +45,6 @@ class Alerts_List {
45
 
46
  add_action( 'quick_edit_custom_box', array( $this, 'display_custom_quick_edit' ), 10, 2 );
47
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
48
-
49
- add_filter( 'wp_insert_post_data', array( $this, 'save_alert_inline_edit' ), 99, 2 );
50
  }
51
 
52
  /**
@@ -360,56 +358,4 @@ class Alerts_List {
360
  wp_enqueue_style( 'wp-mainwp-stream-select2' );
361
  }
362
 
363
- /**
364
- * Save alert meta after using the inline editor.
365
- *
366
- * @param array $data Filtered post data.
367
- * @param array $postarr Raw post data.
368
- *
369
- * @return array
370
- *
371
- * @uses \WP_MainWP_Stream\Alerts::POST_TYPE
372
- */
373
- public function save_alert_inline_edit( $data, $postarr ) {
374
- if ( did_action( 'customize_preview_init' ) || empty( $postarr['ID'] ) ) {
375
- return $data;
376
- }
377
-
378
- $post_id = $postarr['ID'];
379
- $post_type = wp_mainwp_stream_filter_input( INPUT_POST, 'post_type' );
380
- if ( Alerts::POST_TYPE !== $post_type ) {
381
- return $data;
382
- }
383
- if ( ! current_user_can( 'edit_post', $post_id ) ) {
384
- return $data;
385
- }
386
-
387
- $nonce = wp_mainwp_stream_filter_input( INPUT_POST, Alerts::POST_TYPE . '_edit_nonce' );
388
- if ( null === $nonce || ! wp_verify_nonce( $nonce, plugin_basename( __FILE__ ) ) ) {
389
- return $data;
390
- }
391
-
392
- $trigger_author = wp_mainwp_stream_filter_input( INPUT_POST, 'wp_mainwp_stream_trigger_author' );
393
- $trigger_connector_and_context = wp_mainwp_stream_filter_input( INPUT_POST, 'wp_mainwp_stream_trigger_connector_or_context' );
394
- $trigger_connector_and_context_split = explode( '-', $trigger_connector_and_context );
395
- $trigger_connector = $trigger_connector_and_context_split[0];
396
- $trigger_context = $trigger_connector_and_context_split[1];
397
-
398
- $trigger_action = wp_mainwp_stream_filter_input( INPUT_POST, 'wp_mainwp_stream_trigger_action' );
399
- $alert_type = wp_mainwp_stream_filter_input( INPUT_POST, 'wp_mainwp_stream_alert_type' );
400
- $alert_status = wp_mainwp_stream_filter_input( INPUT_POST, 'wp_mainwp_stream_alert_status' );
401
- $data['post_status'] = $alert_status;
402
-
403
- update_post_meta( $post_id, 'alert_type', $alert_type );
404
-
405
- $alert_meta = array(
406
- 'trigger_author' => $trigger_author,
407
- 'trigger_connector' => $trigger_connector,
408
- 'trigger_action' => $trigger_action,
409
- 'trigger_context' => $trigger_context,
410
- );
411
- $alert_meta = apply_filters( 'wp_mainwp_alerts_save_meta', $alert_meta, $alert_type );
412
- update_post_meta( $post_id, 'alert_meta', $alert_meta );
413
- return $data;
414
- }
415
  }
45
 
46
  add_action( 'quick_edit_custom_box', array( $this, 'display_custom_quick_edit' ), 10, 2 );
47
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
 
 
48
  }
49
 
50
  /**
358
  wp_enqueue_style( 'wp-mainwp-stream-select2' );
359
  }
360
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  }
classes/class-connector.php CHANGED
@@ -5,6 +5,7 @@ namespace WP_MainWP_Stream;
5
 
6
  /**
7
  * Class Connector.
 
8
  * @package WP_MainWP_Stream
9
  */
10
  abstract class Connector {
@@ -50,11 +51,18 @@ abstract class Connector {
50
  */
51
  public $register_frontend = true;
52
 
 
 
 
 
 
 
 
53
  /**
54
  * Register all context hooks
55
  */
56
  public function register() {
57
- foreach ( $this->actions as $action ) {
58
  add_action( $action, array( $this, 'callback' ), 10, 99 );
59
  }
60
 
@@ -66,9 +74,9 @@ abstract class Connector {
66
  * Looks for a class method with the convention: "callback_{action name}"
67
  */
68
  public function callback() {
69
- $action = current_filter();
70
- $callback = array( $this, 'callback_' . preg_replace( '/[^A-Za-z0-9_\-]/', '_', $action ) ); // to fix A-Z charater in callback name
71
-
72
  // For the sake of testing, trigger an action with the name of the callback
73
  if ( defined( 'WP_MAINWP_STREAM_TESTS' ) && WP_MAINWP_STREAM_TESTS ) {
74
  /**
@@ -80,15 +88,15 @@ abstract class Connector {
80
  }
81
 
82
  // Call the real function
83
- if ( is_callable( $callback ) ) {
84
  return call_user_func_array( $callback, func_get_args() );
85
- }
86
  }
87
 
88
  /**
89
  * Add action links to Stream drop row in admin list screen
90
  *
91
- * @param array $links Previous links registered
92
  * @param object $record Stream record
93
  *
94
  * @filter wp_mainwp_stream_action_links_{connector}
@@ -104,94 +112,98 @@ abstract class Connector {
104
  * Log handler
105
  *
106
  * @param string $message sprintf-ready error message string
107
- * @param array $args sprintf (and extra) arguments to use
108
- * @param int $object_id Target object id
109
  * @param string $context Context of the event
110
  * @param string $action Action of the event
111
- * @param int $user_id User responsible for the event
112
  *
113
  * @return bool
114
  */
115
- public function log( $message, $args, $object_id, $context, $action, $user_id = null ) {
116
  $connector = $this->name;
117
 
118
  $data = apply_filters(
119
  'wp_mainwp_stream_log_data',
120
- compact( 'connector', 'message', 'args', 'object_id', 'context', 'action', 'user_id' )
121
  );
122
-
123
  if ( ! $data ) {
124
  return false;
125
  } else {
126
- $connector = $data['connector'];
127
- $message = $data['message'];
128
- $args = $data['args'];
129
- $object_id = $data['object_id'];
130
- $context = $data['context'];
131
- $action = $data['action'];
132
- $user_id = $data['user_id'];
 
133
  }
134
 
135
  $created_timestamp = null;
136
-
137
- if ( !empty( $context ) && is_array($args) ) {
138
- if ( $context == "plugins" ) {
139
-
140
- if (isset($args['slug']) && ( $args['slug'] == 'mainwp-child/mainwp-child.php' || $args['slug'] == 'mainwp-child-reports/mainwp-child-reports.php' )) {
141
- $options = (array) get_option( 'wp_mainwp_stream', array() );
142
- if ( ! empty( $options['general_hide_child_plugins'] ) ) {
143
  return false; // return, do not log child/reports plugin
144
  }
145
  $branding_text = wp_mainwp_stream_get_instance()->child_helper->get_branding_title();
146
- if ( !empty( $branding_text ) ) {
147
- if ($args['slug'] == 'mainwp-child/mainwp-child.php') {
148
  $args['name'] = $branding_text;
149
  } else {
150
  $args['name'] = $branding_text . ' Reports';
151
  }
152
- }
153
- }
154
  }
155
 
156
  $addition_connector = '';
157
-
158
- $mainwp_addition_connector = array(
159
- 'mainwp_backups',
160
  'mainwp_maintenances',
161
  'mainwp_sucuri',
162
- 'mainwp_wordfence'
163
  );
164
-
165
- if ( in_array( $connector, $mainwp_addition_connector )) {
166
  $addition_connector = $connector;
167
- }
168
 
169
-
170
  $created_timestamp = 0;
171
- if ( !empty( $addition_connector ) ) {
172
-
173
- if ( is_array($args) ) {
174
- if (isset($args['backup_time'])) {
175
- $created_timestamp = $args['backup_time'];
176
- } else if (isset($args['scan_time'])) {
177
- $created_timestamp = $args['scan_time'];
178
- }
179
- }
180
-
181
- if ( empty( $created_timestamp ) )
182
- return;
183
-
184
- $query_args = array( 'connector' => $addition_connector, 'created' => date("Y-m-d H:i:s", $created_timestamp ) );
185
-
 
 
 
 
186
  $created_item = wp_mainwp_stream_get_instance()->db->get_records( $query_args );
187
-
188
- if ( $created_item )
189
- return;
190
- }
191
- }
192
-
193
-
194
- return call_user_func_array( array( wp_mainwp_stream_get_instance()->log, 'log' ), compact( 'connector', 'message', 'args', 'object_id', 'context', 'action', 'user_id', 'created_timestamp' ) );
195
  }
196
 
197
  /**
@@ -223,8 +235,8 @@ abstract class Connector {
223
  /**
224
  * Compare two values and return changed keys if they are arrays
225
  *
226
- * @param mixed $old_value Value before change
227
- * @param mixed $new_value Value after change
228
  * @param bool|int $deep Get array children changes keys as well, not just parents
229
  *
230
  * @return array
5
 
6
  /**
7
  * Class Connector.
8
+ *
9
  * @package WP_MainWP_Stream
10
  */
11
  abstract class Connector {
51
  */
52
  public $register_frontend = true;
53
 
54
+ /**
55
+ * Register connector in the WP CRON
56
+ *
57
+ * @var bool
58
+ */
59
+ public $register_cron = false;
60
+
61
  /**
62
  * Register all context hooks
63
  */
64
  public function register() {
65
+ foreach ( $this->actions as $action ) {
66
  add_action( $action, array( $this, 'callback' ), 10, 99 );
67
  }
68
 
74
  * Looks for a class method with the convention: "callback_{action name}"
75
  */
76
  public function callback() {
77
+ $action = current_filter();
78
+ $callback = array( $this, 'callback_' . preg_replace( '/[^A-Za-z0-9_\-]/', '_', $action ) ); // to fix A-Z charater in callback name
79
+
80
  // For the sake of testing, trigger an action with the name of the callback
81
  if ( defined( 'WP_MAINWP_STREAM_TESTS' ) && WP_MAINWP_STREAM_TESTS ) {
82
  /**
88
  }
89
 
90
  // Call the real function
91
+ if ( is_callable( $callback ) ) {
92
  return call_user_func_array( $callback, func_get_args() );
93
+ }
94
  }
95
 
96
  /**
97
  * Add action links to Stream drop row in admin list screen
98
  *
99
+ * @param array $links Previous links registered
100
  * @param object $record Stream record
101
  *
102
  * @filter wp_mainwp_stream_action_links_{connector}
112
  * Log handler
113
  *
114
  * @param string $message sprintf-ready error message string
115
+ * @param array $args sprintf (and extra) arguments to use
116
+ * @param int $object_id Target object id
117
  * @param string $context Context of the event
118
  * @param string $action Action of the event
119
+ * @param int $user_id User responsible for the event
120
  *
121
  * @return bool
122
  */
123
+ public function log( $message, $args, $object_id, $context, $action, $user_id = null, $forced_log = false ) {
124
  $connector = $this->name;
125
 
126
  $data = apply_filters(
127
  'wp_mainwp_stream_log_data',
128
+ compact( 'connector', 'message', 'args', 'object_id', 'context', 'action', 'user_id', 'forced_log' )
129
  );
130
+
131
  if ( ! $data ) {
132
  return false;
133
  } else {
134
+ $connector = $data['connector'];
135
+ $message = $data['message'];
136
+ $args = $data['args'];
137
+ $object_id = $data['object_id'];
138
+ $context = $data['context'];
139
+ $action = $data['action'];
140
+ $user_id = $data['user_id'];
141
+ $forced_log = $data['forced_log'];
142
  }
143
 
144
  $created_timestamp = null;
145
+
146
+ if ( ! empty( $context ) && is_array( $args ) ) {
147
+ if ( $context == 'plugins' ) {
148
+
149
+ if ( isset( $args['slug'] ) && ( $args['slug'] == 'mainwp-child/mainwp-child.php' || $args['slug'] == 'mainwp-child-reports/mainwp-child-reports.php' ) ) {
150
+ $options = (array) get_option( 'wp_mainwp_stream', array() );
151
+ if ( ! empty( $options['general_hide_child_plugins'] ) ) {
152
  return false; // return, do not log child/reports plugin
153
  }
154
  $branding_text = wp_mainwp_stream_get_instance()->child_helper->get_branding_title();
155
+ if ( ! empty( $branding_text ) ) {
156
+ if ( $args['slug'] == 'mainwp-child/mainwp-child.php' ) {
157
  $args['name'] = $branding_text;
158
  } else {
159
  $args['name'] = $branding_text . ' Reports';
160
  }
161
+ }
162
+ }
163
  }
164
 
165
  $addition_connector = '';
166
+
167
+ $mainwp_addition_connector = array(
168
+ 'mainwp_backups',
169
  'mainwp_maintenances',
170
  'mainwp_sucuri',
171
+ 'mainwp_wordfence',
172
  );
173
+
174
+ if ( in_array( $connector, $mainwp_addition_connector ) ) {
175
  $addition_connector = $connector;
176
+ }
177
 
 
178
  $created_timestamp = 0;
179
+ if ( ! empty( $addition_connector ) ) {
180
+
181
+ if ( is_array( $args ) ) {
182
+ if ( isset( $args['backup_time'] ) ) {
183
+ $created_timestamp = $args['backup_time'];
184
+ } elseif ( isset( $args['scan_time'] ) ) {
185
+ $created_timestamp = $args['scan_time'];
186
+ }
187
+ }
188
+
189
+ if ( empty( $created_timestamp ) ) {
190
+ return;
191
+ }
192
+
193
+ $query_args = array(
194
+ 'connector' => $addition_connector,
195
+ 'created' => date( 'Y-m-d H:i:s', $created_timestamp ),
196
+ );
197
+
198
  $created_item = wp_mainwp_stream_get_instance()->db->get_records( $query_args );
199
+
200
+ if ( $created_item ) {
201
+ return;
202
+ }
203
+ }
204
+ }
205
+
206
+ return call_user_func_array( array( wp_mainwp_stream_get_instance()->log, 'log' ), compact( 'connector', 'message', 'args', 'object_id', 'context', 'action', 'user_id', 'created_timestamp', 'forced_log' ) );
207
  }
208
 
209
  /**
235
  /**
236
  * Compare two values and return changed keys if they are arrays
237
  *
238
+ * @param mixed $old_value Value before change
239
+ * @param mixed $new_value Value after change
240
  * @param bool|int $deep Get array children changes keys as well, not just parents
241
  *
242
  * @return array
classes/class-connectors.php CHANGED
@@ -108,6 +108,13 @@ class Connectors {
108
  }
109
  $class = new $class_name( $this->plugin->log );
110
 
 
 
 
 
 
 
 
111
  // Check if the Connector extends WP_MainWP_Stream\Connector
112
  if ( ! is_subclass_of( $class, 'WP_MainWP_Stream\Connector' ) ) {
113
  continue;
108
  }
109
  $class = new $class_name( $this->plugin->log );
110
 
111
+ if ( $class->register_cron && wp_mainwp_stream_is_cron_doing() ) {
112
+ if ( $class->is_dependency_satisfied() ) {
113
+ $classes[ $class->name ] = $class;
114
+ continue; // load it.
115
+ }
116
+ }
117
+
118
  // Check if the Connector extends WP_MainWP_Stream\Connector
119
  if ( ! is_subclass_of( $class, 'WP_MainWP_Stream\Connector' ) ) {
120
  continue;
classes/class-install.php CHANGED
@@ -5,6 +5,7 @@ namespace WP_MainWP_Stream;
5
 
6
  /**
7
  * Class Install.
 
8
  * @package WP_MainWP_Stream
9
  */
10
  class Install {
@@ -30,15 +31,15 @@ class Install {
30
  /** @var bool Holds status of whether the database update worked */
31
  public $success_db;
32
 
33
- /**
34
- * Install constructor.
35
- *
36
- * Run each time the class is called.
37
- *
38
- * @param object $plugin Plugin class.
39
- *
40
- * @uses \WP_MainWP_Stream\Install::get_db_version()
41
- */
42
  public function __construct( $plugin ) {
43
  $this->plugin = $plugin;
44
 
@@ -61,23 +62,23 @@ class Install {
61
  * on the plugin update screen
62
  *
63
  * @return
64
- *
65
- * @uses \WP_MainWP_Stream\Install::$plugin::get_version()
66
- * @uses \WP_MainWP_Stream\Install::get_old_child_report_db_version()
67
- * @uses \WP_MainWP_Stream\Install::update()
68
- * @uses \WP_MainWP_Stream\Install::db_update_versions()
69
- * @uses \WP_MainWP_Stream\Install::update_db_option()
70
- */
71
  public function check() {
72
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
73
  return;
74
  }
75
 
76
  $update_to_new_child_report = false;
77
-
78
  if ( empty( $this->db_version ) ) {
79
  $this->install( $this->plugin->get_version() );
80
- if ( !empty( $this->get_old_child_report_db_version() ) ) {
81
  $update_to_new_child_report = true;
82
  } else {
83
  return;
@@ -96,7 +97,9 @@ class Install {
96
  if ( ! $update ) {
97
  $this->update_required = true;
98
  $this->success_db = $this->update(
99
- $this->db_version, $this->plugin->get_version(), array(
 
 
100
  'type' => 'auto',
101
  )
102
  );
@@ -104,7 +107,9 @@ class Install {
104
 
105
  if ( 'update_and_continue' === $update ) {
106
  $this->success_db = $this->update(
107
- $this->db_version, $this->plugin->get_version(), array(
 
 
108
  'type' => 'user',
109
  )
110
  );
@@ -120,52 +125,52 @@ class Install {
120
  $this->update_db_option();
121
  }
122
 
123
- /**
124
- * Recreate database tables if they do not already exist.
125
- *
126
- * @uses \WP_MainWP_Stream\Install::$plugin::db::get_table_names()
127
- * @uses \WP_MainWP_Stream\Install::$plugin::get_version()
128
- * @uses $wpdb::get_var()
129
- * @uses $wpdb::prepare()
130
- */
131
  public function recreate_tables_if_not_exist() {
132
 
133
- /** @global object $wpdb WordPress Database. */
134
  global $wpdb;
135
-
136
  check_ajax_referer( 'stream_nonce_reset', 'wp_mainwp_stream_nonce_reset' );
137
-
138
  $missing_tables = array();
139
  foreach ( $this->plugin->db->get_table_names() as $table_name ) {
140
  $table_search = $wpdb->get_var(
141
  $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name )
142
  );
143
- if ( strcasecmp($table_search,$table_name ) != 0 ) {
144
  $missing_tables[] = $table_name;
145
  }
146
  }
147
-
148
  if ( $missing_tables ) {
149
  $this->install( $this->plugin->get_version() );
150
-
151
- // for debugging only.
152
- // if( $wpdb->last_error !== '') :
153
- // $str = htmlspecialchars( $wpdb->last_result, ENT_QUOTES );
154
- // $query = htmlspecialchars( $wpdb->last_query, ENT_QUOTES );
155
- // error_log( $str );
156
- // error_log( $query );
157
- // endif;
158
- }
159
-
160
  }
161
-
162
  /**
163
  * Verify that the required DB tables exists
164
- *
165
- * @uses \WP_MainWP_Stream\Install::$plugin::db::get_table_names()
166
- * @uses \WP_MainWP_Stream\Install::$plugin::admin::notice()
167
- * @uses $wpdb::get_var()
168
- * @uses $wpdb::prepare()
169
  */
170
  public function verify_db() {
171
 
@@ -180,6 +185,10 @@ class Install {
180
  return;
181
  }
182
 
 
 
 
 
183
  if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
184
  require_once ABSPATH . '/wp-admin/includes/plugin.php';
185
  }
@@ -202,7 +211,7 @@ class Install {
202
  $table_search = $wpdb->get_var(
203
  $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name )
204
  );
205
- if ( strcasecmp($table_search,$table_name ) != 0 ) {
206
  $missing_tables[] = $table_name;
207
  }
208
  }
@@ -285,11 +294,11 @@ class Install {
285
  }
286
  }
287
 
288
- /**
289
- * Get Child Reports old database version.
290
- *
291
- * @return string $version MainWP Child Reports old database version.
292
- */
293
  public static function get_old_child_report_db_version() {
294
 
295
  $version = get_site_option( 'mainwp_child_reports_db' );
@@ -298,8 +307,8 @@ class Install {
298
  }
299
 
300
  /**
301
- * Get MainWP Child Reports Database version.
302
- *
303
  * @return string MainWP child Reports database version.
304
  */
305
  public function get_db_version() {
@@ -307,11 +316,11 @@ class Install {
307
  }
308
 
309
  /**
310
- * Update MaiNWP Child Reports database version.
311
- *
312
  * @return void
313
- *
314
- * @uses \WP_MainWP_Stream\Install::$plugin::get_version()
315
  */
316
  public function update_db_option() {
317
  if ( $this->success_db ) {
@@ -338,9 +347,9 @@ class Install {
338
  * @action admin_notices
339
  *
340
  * @return void
341
- *
342
- * @uses \WP_MainWP_Stream\Install::prompt_update()
343
- * @uses \WP_MainWP_Stream\Install::prompt_update_status()
344
  */
345
  public function update_notice_hook() {
346
  if ( ! current_user_can( $this->plugin->admin->view_cap ) ) {
@@ -391,9 +400,9 @@ class Install {
391
  * updates the stream_db version number in the database and outputs a success and continue message
392
  *
393
  * @return void
394
- *
395
- * @uses \WP_MainWP_Stream\Install::update_db_option()
396
- * @uses \WP_MainWP_Stream\Install::$plugin::get_version()
397
  */
398
  public function prompt_update_status() {
399
  check_admin_referer( 'wp_mainwp_stream_update_db' );
@@ -435,7 +444,7 @@ class Install {
435
  '3.0.2', /* @version 3.0.2 Fix uppercase values in stream table, connector column */
436
  '3.0.8', /* @version 3.0.8 Increase size of user role IDs, user_roll column */
437
  '3.5.0', /* @version 3.5.0 Fix connector values */
438
- '3.5.2', /* @version 3.5.2 Fix meta data */
439
  );
440
 
441
  /**
@@ -456,8 +465,8 @@ class Install {
456
  * @param array $update_args Update arguments.
457
  *
458
  * @return mixed Version number on success, true on no update needed, mysql error message on error.
459
- *
460
- * @uses \WP_MainWP_Stream\Install::db_update_versions()
461
  */
462
  public function update( $db_version, $current_version, $update_args ) {
463
  $versions = $this->db_update_versions();
@@ -488,9 +497,9 @@ class Install {
488
  * @param string $current_version Current version.
489
  *
490
  * @return string $current_version Current version.
491
- *
492
- * @uses \WP_MainWP_Stream\Install::plugin::get_version()
493
- * @uses \dbDelta()
494
  */
495
  public function install( $current_version ) {
496
 
@@ -507,7 +516,7 @@ class Install {
507
  user_id bigint(20) unsigned NOT NULL DEFAULT '0',
508
  user_role varchar(50) NOT NULL DEFAULT '',
509
  summary longtext NOT NULL,
510
- created datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
511
  connector varchar(100) NOT NULL,
512
  context varchar(100) NOT NULL,
513
  action varchar(100) NOT NULL,
@@ -522,7 +531,7 @@ class Install {
522
  KEY context (context),
523
  KEY action (action)
524
  )";
525
-
526
  if ( ! empty( $wpdb->charset ) ) {
527
  $sql .= " CHARACTER SET $wpdb->charset";
528
  }
5
 
6
  /**
7
  * Class Install.
8
+ *
9
  * @package WP_MainWP_Stream
10
  */
11
  class Install {
31
  /** @var bool Holds status of whether the database update worked */
32
  public $success_db;
33
 
34
+ /**
35
+ * Install constructor.
36
+ *
37
+ * Run each time the class is called.
38
+ *
39
+ * @param object $plugin Plugin class.
40
+ *
41
+ * @uses \WP_MainWP_Stream\Install::get_db_version()
42
+ */
43
  public function __construct( $plugin ) {
44
  $this->plugin = $plugin;
45
 
62
  * on the plugin update screen
63
  *
64
  * @return
65
+ *
66
+ * @uses \WP_MainWP_Stream\Install::$plugin::get_version()
67
+ * @uses \WP_MainWP_Stream\Install::get_old_child_report_db_version()
68
+ * @uses \WP_MainWP_Stream\Install::update()
69
+ * @uses \WP_MainWP_Stream\Install::db_update_versions()
70
+ * @uses \WP_MainWP_Stream\Install::update_db_option()
71
+ */
72
  public function check() {
73
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
74
  return;
75
  }
76
 
77
  $update_to_new_child_report = false;
78
+
79
  if ( empty( $this->db_version ) ) {
80
  $this->install( $this->plugin->get_version() );
81
+ if ( ! empty( $this->get_old_child_report_db_version() ) ) {
82
  $update_to_new_child_report = true;
83
  } else {
84
  return;
97
  if ( ! $update ) {
98
  $this->update_required = true;
99
  $this->success_db = $this->update(
100
+ $this->db_version,
101
+ $this->plugin->get_version(),
102
+ array(
103
  'type' => 'auto',
104
  )
105
  );
107
 
108
  if ( 'update_and_continue' === $update ) {
109
  $this->success_db = $this->update(
110
+ $this->db_version,
111
+ $this->plugin->get_version(),
112
+ array(
113
  'type' => 'user',
114
  )
115
  );
125
  $this->update_db_option();
126
  }
127
 
128
+ /**
129
+ * Recreate database tables if they do not already exist.
130
+ *
131
+ * @uses \WP_MainWP_Stream\Install::$plugin::db::get_table_names()
132
+ * @uses \WP_MainWP_Stream\Install::$plugin::get_version()
133
+ * @uses $wpdb::get_var()
134
+ * @uses $wpdb::prepare()
135
+ */
136
  public function recreate_tables_if_not_exist() {
137
 
138
+ /** @global object $wpdb WordPress Database. */
139
  global $wpdb;
140
+
141
  check_ajax_referer( 'stream_nonce_reset', 'wp_mainwp_stream_nonce_reset' );
142
+
143
  $missing_tables = array();
144
  foreach ( $this->plugin->db->get_table_names() as $table_name ) {
145
  $table_search = $wpdb->get_var(
146
  $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name )
147
  );
148
+ if ( strcasecmp( $table_search, $table_name ) != 0 ) {
149
  $missing_tables[] = $table_name;
150
  }
151
  }
152
+
153
  if ( $missing_tables ) {
154
  $this->install( $this->plugin->get_version() );
155
+
156
+ // for debugging only.
157
+ // if( $wpdb->last_error !== '') :
158
+ // $str = htmlspecialchars( $wpdb->last_result, ENT_QUOTES );
159
+ // $query = htmlspecialchars( $wpdb->last_query, ENT_QUOTES );
160
+ // error_log( $str );
161
+ // error_log( $query );
162
+ // endif;
163
+ }
164
+
165
  }
166
+
167
  /**
168
  * Verify that the required DB tables exists
169
+ *
170
+ * @uses \WP_MainWP_Stream\Install::$plugin::db::get_table_names()
171
+ * @uses \WP_MainWP_Stream\Install::$plugin::admin::notice()
172
+ * @uses $wpdb::get_var()
173
+ * @uses $wpdb::prepare()
174
  */
175
  public function verify_db() {
176
 
185
  return;
186
  }
187
 
188
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
189
+ return;
190
+ }
191
+
192
  if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
193
  require_once ABSPATH . '/wp-admin/includes/plugin.php';
194
  }
211
  $table_search = $wpdb->get_var(
212
  $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name )
213
  );
214
+ if ( strcasecmp( $table_search, $table_name ) != 0 ) {
215
  $missing_tables[] = $table_name;
216
  }
217
  }
294
  }
295
  }
296
 
297
+ /**
298
+ * Get Child Reports old database version.
299
+ *
300
+ * @return string $version MainWP Child Reports old database version.
301
+ */
302
  public static function get_old_child_report_db_version() {
303
 
304
  $version = get_site_option( 'mainwp_child_reports_db' );
307
  }
308
 
309
  /**
310
+ * Get MainWP Child Reports Database version.
311
+ *
312
  * @return string MainWP child Reports database version.
313
  */
314
  public function get_db_version() {
316
  }
317
 
318
  /**
319
+ * Update MaiNWP Child Reports database version.
320
+ *
321
  * @return void
322
+ *
323
+ * @uses \WP_MainWP_Stream\Install::$plugin::get_version()
324
  */
325
  public function update_db_option() {
326
  if ( $this->success_db ) {
347
  * @action admin_notices
348
  *
349
  * @return void
350
+ *
351
+ * @uses \WP_MainWP_Stream\Install::prompt_update()
352
+ * @uses \WP_MainWP_Stream\Install::prompt_update_status()
353
  */
354
  public function update_notice_hook() {
355
  if ( ! current_user_can( $this->plugin->admin->view_cap ) ) {
400
  * updates the stream_db version number in the database and outputs a success and continue message
401
  *
402
  * @return void
403
+ *
404
+ * @uses \WP_MainWP_Stream\Install::update_db_option()
405
+ * @uses \WP_MainWP_Stream\Install::$plugin::get_version()
406
  */
407
  public function prompt_update_status() {
408
  check_admin_referer( 'wp_mainwp_stream_update_db' );
444
  '3.0.2', /* @version 3.0.2 Fix uppercase values in stream table, connector column */
445
  '3.0.8', /* @version 3.0.8 Increase size of user role IDs, user_roll column */
446
  '3.5.0', /* @version 3.5.0 Fix connector values */
447
+ '3.5.2', /* @version 3.5.2 Fix meta data */
448
  );
449
 
450
  /**
465
  * @param array $update_args Update arguments.
466
  *
467
  * @return mixed Version number on success, true on no update needed, mysql error message on error.
468
+ *
469
+ * @uses \WP_MainWP_Stream\Install::db_update_versions()
470
  */
471
  public function update( $db_version, $current_version, $update_args ) {
472
  $versions = $this->db_update_versions();
497
  * @param string $current_version Current version.
498
  *
499
  * @return string $current_version Current version.
500
+ *
501
+ * @uses \WP_MainWP_Stream\Install::plugin::get_version()
502
+ * @uses \dbDelta()
503
  */
504
  public function install( $current_version ) {
505
 
516
  user_id bigint(20) unsigned NOT NULL DEFAULT '0',
517
  user_role varchar(50) NOT NULL DEFAULT '',
518
  summary longtext NOT NULL,
519
+ created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
520
  connector varchar(100) NOT NULL,
521
  context varchar(100) NOT NULL,
522
  action varchar(100) NOT NULL,
531
  KEY context (context),
532
  KEY action (action)
533
  )";
534
+
535
  if ( ! empty( $wpdb->charset ) ) {
536
  $sql .= " CHARACTER SET $wpdb->charset";
537
  }
classes/class-list-table.php CHANGED
@@ -293,7 +293,7 @@ class List_Table extends \WP_List_Table {
293
  );
294
  $out = $this->column_link( $date_string, 'date', get_date_from_gmt( $created, 'Y/m/d' ) );
295
  $out .= '<br />';
296
- $out .= get_date_from_gmt( $created, 'h:i:s A' );
297
  break;
298
 
299
  case 'summary':
293
  );
294
  $out = $this->column_link( $date_string, 'date', get_date_from_gmt( $created, 'Y/m/d' ) );
295
  $out .= '<br />';
296
+ $out .= date_i18n( get_option( 'time_format' ), strtotime( $record->created ), true );
297
  break;
298
 
299
  case 'summary':
classes/class-log.php CHANGED
@@ -65,7 +65,7 @@ class Log {
65
  * @uses $wp_roles::is_role()
66
  * @see https://developer.wordpress.org/reference/classes/wp_roles/is_role/
67
  */
68
- public function log( $connector, $message, $args, $object_id, $context, $action, $user_id = null, $created_timestamp = 0 ) {
69
 
70
  /** @global object $wp_roles Wordpress user roles object. */
71
  global $wp_roles;
@@ -84,7 +84,7 @@ class Log {
84
 
85
  $backup_logging = ( is_string( $connector ) && 'mainwp_backups' == $connector ) ? true : false;
86
  // WP Cron tracking requires opt-in and WP Cron to be enabled.
87
- if ( ! $wp_cron_tracking && 'wp_cron' === $agent && ! $backup_logging ) {
88
  return false;
89
  }
90
 
65
  * @uses $wp_roles::is_role()
66
  * @see https://developer.wordpress.org/reference/classes/wp_roles/is_role/
67
  */
68
+ public function log( $connector, $message, $args, $object_id, $context, $action, $user_id = null, $created_timestamp = 0, $forced_log = false ) {
69
 
70
  /** @global object $wp_roles Wordpress user roles object. */
71
  global $wp_roles;
84
 
85
  $backup_logging = ( is_string( $connector ) && 'mainwp_backups' == $connector ) ? true : false;
86
  // WP Cron tracking requires opt-in and WP Cron to be enabled.
87
+ if ( ! $wp_cron_tracking && 'wp_cron' === $agent && ! $backup_logging && ! $forced_log ) {
88
  return false;
89
  }
90
 
classes/class-plugin.php CHANGED
@@ -124,7 +124,7 @@ class Plugin {
124
 
125
  // Load WP-CLI command.
126
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
127
- \WP_CLI::add_command( self::WP_CLI_COMMAND, 'WP_MainWP_Stream\CLI' );
128
  }
129
  }
130
 
124
 
125
  // Load WP-CLI command.
126
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
127
+ \WP_CLI::add_command( self::WP_CLI_COMMAND, '\WP_MainWP_Stream\CLI' );
128
  }
129
  }
130
 
classes/class-query.php CHANGED
@@ -5,6 +5,7 @@ namespace WP_MainWP_Stream;
5
 
6
  /**
7
  * Class Query.
 
8
  * @package WP_MainWP_Stream
9
  */
10
  class Query {
@@ -88,41 +89,40 @@ class Query {
88
  }
89
 
90
  if ( ! empty( $args['date_from'] ) ) {
91
- $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_from'] . ' 00:00:00' ) ) );
92
- //$where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) >= %s", $date );
93
- $where .= " AND ($wpdb->mainwp_stream.created >= STR_TO_DATE(" . $wpdb->prepare('%s', $date) . ", '%Y-%m-%d %H:%i:%s'))";
94
  }
95
 
96
  if ( ! empty( $args['date_to'] ) ) {
97
- $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_to'] . ' 23:59:59' ) ) );
98
- //$where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) <= %s", $date );
99
- $where .= " AND ($wpdb->mainwp_stream.created <= STR_TO_DATE(" . $wpdb->prepare('%s', $date) . ", '%Y-%m-%d %H:%i:%s'))";
100
  }
101
 
102
  if ( ! empty( $args['date_after'] ) ) {
103
- $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_after'] ) ) );
104
- //$where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) > %s", $date );
105
- $where .= " AND ($wpdb->mainwp_stream.created > STR_TO_DATE(" . $wpdb->prepare('%s', $date) . ", '%Y-%m-%d %H:%i:%s'))";
106
  }
107
 
108
  if ( ! empty( $args['date_before'] ) ) {
109
- $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_before'] ) ) );
110
- //$where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) < %s", $date );
111
- $where .= " AND ($wpdb->mainwp_stream.created < STR_TO_DATE(" . $wpdb->prepare('%s', $date) . ", '%Y-%m-%d %H:%i:%s'))";
112
  }
113
-
114
-
115
  // mainwp custom parameter
116
  if ( ! empty( $args['created'] ) ) {
117
  $created = strtotime( $args['created'] );
118
- //$date = get_gmt_from_date( date( 'Y-m-d H:i:s', $created + 5 ) );
119
- $date = wp_mainwp_stream_get_iso_8601_extended_date( $created + 5, 0, true );
120
- //$where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) <= %s", $date );
121
- $where .= " AND ($wpdb->mainwp_stream.created <= STR_TO_DATE(" . $wpdb->prepare('%s', $date) . ", '%Y-%m-%d %H:%i:%s'))";
122
- //$date = get_gmt_from_date( date( 'Y-m-d H:i:s', $created - 5 ) );
123
- $date = wp_mainwp_stream_get_iso_8601_extended_date( $created - 5, 0, true );
124
- //$where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) >= %s", $date );
125
- $where .= " AND ($wpdb->mainwp_stream.created >= STR_TO_DATE(" . $wpdb->prepare('%s', $date) . ", '%Y-%m-%d %H:%i:%s'))";
126
  }
127
 
128
  /**
@@ -180,24 +180,23 @@ class Query {
180
  }
181
  }
182
  }
183
-
184
  // exclude child/report plugins from log results
185
- if (isset($args['hide_child_reports']) && $args['hide_child_reports']) {
186
  $child_record_ids = array();
187
- $sql_meta = "SELECT record_id FROM $wpdb->mainwp_streammeta WHERE meta_key = 'slug' AND (meta_value = 'mainwp-child/mainwp-child.php' OR meta_value = 'mainwp-child-reports/mainwp-child-reports.php')";
188
- $ret = $wpdb->get_results( $sql_meta, 'ARRAY_A' );
189
 
190
- if ( is_array($ret) && count($ret)> 0 ) {
191
- foreach($ret as $val) {
192
  $child_record_ids[] = $val['record_id'];
193
  }
194
  }
195
- if (count($child_record_ids) > 0) {
196
- $where .= " AND $wpdb->mainwp_stream.ID NOT IN (" . implode(",", $child_record_ids). ") ";
197
  }
198
  }
199
 
200
-
201
  /**
202
  * PARSE PAGINATION PARAMS
203
  */
@@ -213,14 +212,16 @@ class Query {
213
  /**
214
  * PARSE ORDER PARAMS
215
  */
216
- $order = esc_sql( $args['order'] );
217
- $orderby = esc_sql( $args['orderby'] );
218
-
 
 
219
  // to fix order by created
220
- if ($orderby == 'date') {
221
  $orderby = 'created';
222
  }
223
-
224
  $orderable = array( 'ID', 'site_id', 'blog_id', 'object_id', 'user_id', 'user_role', 'summary', 'created', 'connector', 'context', 'action' );
225
 
226
  if ( in_array( $orderby, $orderable, true ) ) {
@@ -234,7 +235,7 @@ class Query {
234
  }
235
 
236
  $orderby = "ORDER BY {$orderby} {$order}";
237
-
238
  /**
239
  * PARSE FIELDS PARAMETER
240
  */
@@ -265,7 +266,7 @@ class Query {
265
  WHERE 1=1 {$where}
266
  {$orderby}
267
  {$limits}";
268
-
269
  /**
270
  * Filter allows the final query to be modified before execution
271
  *
@@ -274,42 +275,41 @@ class Query {
274
  *
275
  * @return string
276
  */
277
-
278
  $query = apply_filters( 'wp_mainwp_stream_db_query', $query, $args );
279
-
280
  $items = $wpdb->get_results( $query ); // @codingStandardsIgnoreLine $query already prepared
281
-
282
  $found_row = $items ? absint( $wpdb->get_var( 'SELECT FOUND_ROWS()' ) ) : 0;
283
-
284
  // mainwp-child custom query
285
  if ( isset( $args['with-meta'] ) && $args['with-meta'] && is_array( $items ) && $items ) {
286
- $ids = array_map( 'absint', wp_list_pluck( $items, 'ID' ) );
287
- // to fix issue long query
288
- $start_slice = 0;
289
- $max_slice = 100;
290
-
291
- while( $start_slice <= count($ids)) {
292
- $slice_ids = array_slice($ids, $start_slice, $max_slice);
293
- $start_slice += $max_slice;
294
-
295
- if (!empty($slice_ids)) {
296
- $sql_meta = sprintf(
297
- "SELECT * FROM $wpdb->mainwp_streammeta WHERE record_id IN ( %s )",
298
- implode( ',', $slice_ids )
299
- );
300
-
301
- $meta_records = $wpdb->get_results( $sql_meta );
302
- $ids_flip = array_flip( $ids );
303
-
304
- foreach ( $meta_records as $meta_record ) {
305
- if ( !empty($meta_record->meta_value) ) {
306
- $items[ $ids_flip[ $meta_record->record_id ] ]->meta[ $meta_record->meta_key ][] = $meta_record->meta_value;
307
  }
308
- }
309
- }
310
- }
311
  }
312
-
313
 
314
  $result = array();
315
  /**
5
 
6
  /**
7
  * Class Query.
8
+ *
9
  * @package WP_MainWP_Stream
10
  */
11
  class Query {
89
  }
90
 
91
  if ( ! empty( $args['date_from'] ) ) {
92
+ $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_from'] . ' 00:00:00' ) ) );
93
+ // $where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) >= %s", $date );
94
+ $where .= " AND ($wpdb->mainwp_stream.created >= STR_TO_DATE(" . $wpdb->prepare( '%s', $date ) . ", '%Y-%m-%d %H:%i:%s'))";
95
  }
96
 
97
  if ( ! empty( $args['date_to'] ) ) {
98
+ $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_to'] . ' 23:59:59' ) ) );
99
+ // $where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) <= %s", $date );
100
+ $where .= " AND ($wpdb->mainwp_stream.created <= STR_TO_DATE(" . $wpdb->prepare( '%s', $date ) . ", '%Y-%m-%d %H:%i:%s'))";
101
  }
102
 
103
  if ( ! empty( $args['date_after'] ) ) {
104
+ $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_after'] ) ) );
105
+ // $where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) > %s", $date );
106
+ $where .= " AND ($wpdb->mainwp_stream.created > STR_TO_DATE(" . $wpdb->prepare( '%s', $date ) . ", '%Y-%m-%d %H:%i:%s'))";
107
  }
108
 
109
  if ( ! empty( $args['date_before'] ) ) {
110
+ $date = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( $args['date_before'] ) ) );
111
+ // $where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) < %s", $date );
112
+ $where .= " AND ($wpdb->mainwp_stream.created < STR_TO_DATE(" . $wpdb->prepare( '%s', $date ) . ", '%Y-%m-%d %H:%i:%s'))";
113
  }
114
+
 
115
  // mainwp custom parameter
116
  if ( ! empty( $args['created'] ) ) {
117
  $created = strtotime( $args['created'] );
118
+ // $date = get_gmt_from_date( date( 'Y-m-d H:i:s', $created + 5 ) );
119
+ $date = wp_mainwp_stream_get_iso_8601_extended_date( $created + 5, 0, true );
120
+ // $where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) <= %s", $date );
121
+ $where .= " AND ($wpdb->mainwp_stream.created <= STR_TO_DATE(" . $wpdb->prepare( '%s', $date ) . ", '%Y-%m-%d %H:%i:%s'))";
122
+ // $date = get_gmt_from_date( date( 'Y-m-d H:i:s', $created - 5 ) );
123
+ $date = wp_mainwp_stream_get_iso_8601_extended_date( $created - 5, 0, true );
124
+ // $where .= $wpdb->prepare( " AND DATE($wpdb->mainwp_stream.created) >= %s", $date );
125
+ $where .= " AND ($wpdb->mainwp_stream.created >= STR_TO_DATE(" . $wpdb->prepare( '%s', $date ) . ", '%Y-%m-%d %H:%i:%s'))";
126
  }
127
 
128
  /**
180
  }
181
  }
182
  }
183
+
184
  // exclude child/report plugins from log results
185
+ if ( isset( $args['hide_child_reports'] ) && $args['hide_child_reports'] ) {
186
  $child_record_ids = array();
187
+ $sql_meta = "SELECT record_id FROM $wpdb->mainwp_streammeta WHERE meta_key = 'slug' AND (meta_value = 'mainwp-child/mainwp-child.php' OR meta_value = 'mainwp-child-reports/mainwp-child-reports.php')";
188
+ $ret = $wpdb->get_results( $sql_meta, 'ARRAY_A' );
189
 
190
+ if ( is_array( $ret ) && count( $ret ) > 0 ) {
191
+ foreach ( $ret as $val ) {
192
  $child_record_ids[] = $val['record_id'];
193
  }
194
  }
195
+ if ( count( $child_record_ids ) > 0 ) {
196
+ $where .= " AND $wpdb->mainwp_stream.ID NOT IN (" . implode( ',', $child_record_ids ) . ') ';
197
  }
198
  }
199
 
 
200
  /**
201
  * PARSE PAGINATION PARAMS
202
  */
212
  /**
213
  * PARSE ORDER PARAMS
214
  */
215
+ $order = esc_sql( $args['order'] );
216
+ $order = ( 'asc' === $order ) ? 'asc' : 'desc';
217
+
218
+ $orderby = esc_sql( $args['orderby'] );
219
+
220
  // to fix order by created
221
+ if ( $orderby == 'date' ) {
222
  $orderby = 'created';
223
  }
224
+
225
  $orderable = array( 'ID', 'site_id', 'blog_id', 'object_id', 'user_id', 'user_role', 'summary', 'created', 'connector', 'context', 'action' );
226
 
227
  if ( in_array( $orderby, $orderable, true ) ) {
235
  }
236
 
237
  $orderby = "ORDER BY {$orderby} {$order}";
238
+
239
  /**
240
  * PARSE FIELDS PARAMETER
241
  */
266
  WHERE 1=1 {$where}
267
  {$orderby}
268
  {$limits}";
269
+
270
  /**
271
  * Filter allows the final query to be modified before execution
272
  *
275
  *
276
  * @return string
277
  */
278
+
279
  $query = apply_filters( 'wp_mainwp_stream_db_query', $query, $args );
280
+
281
  $items = $wpdb->get_results( $query ); // @codingStandardsIgnoreLine $query already prepared
282
+
283
  $found_row = $items ? absint( $wpdb->get_var( 'SELECT FOUND_ROWS()' ) ) : 0;
284
+
285
  // mainwp-child custom query
286
  if ( isset( $args['with-meta'] ) && $args['with-meta'] && is_array( $items ) && $items ) {
287
+ $ids = array_map( 'absint', wp_list_pluck( $items, 'ID' ) );
288
+ // to fix issue long query
289
+ $start_slice = 0;
290
+ $max_slice = 100;
291
+
292
+ while ( $start_slice <= count( $ids ) ) {
293
+ $slice_ids = array_slice( $ids, $start_slice, $max_slice );
294
+ $start_slice += $max_slice;
295
+
296
+ if ( ! empty( $slice_ids ) ) {
297
+ $sql_meta = sprintf(
298
+ "SELECT * FROM $wpdb->mainwp_streammeta WHERE record_id IN ( %s )",
299
+ implode( ',', $slice_ids )
300
+ );
301
+
302
+ $meta_records = $wpdb->get_results( $sql_meta );
303
+ $ids_flip = array_flip( $ids );
304
+
305
+ foreach ( $meta_records as $meta_record ) {
306
+ if ( ! empty( $meta_record->meta_value ) ) {
307
+ $items[ $ids_flip[ $meta_record->record_id ] ]->meta[ $meta_record->meta_key ][] = $meta_record->meta_value;
308
  }
309
+ }
310
+ }
311
+ }
312
  }
 
313
 
314
  $result = array();
315
  /**
classes/class-settings.php CHANGED
@@ -920,7 +920,7 @@ class Settings {
920
  }
921
 
922
  if ( empty( $author_or_role_selected ) && is_numeric( $author_or_role ) ) {
923
- $user = new WP_User( $author_or_role );
924
  $display_name = ( 0 === $user->ID ) ? esc_html__( 'N/A', 'mainwp-child-reports' ) : $user->display_name;
925
  $author_or_role_selected = array(
926
  'value' => $user->ID,
920
  }
921
 
922
  if ( empty( $author_or_role_selected ) && is_numeric( $author_or_role ) ) {
923
+ $user = new \WP_User( $author_or_role );
924
  $display_name = ( 0 === $user->ID ) ? esc_html__( 'N/A', 'mainwp-child-reports' ) : $user->display_name;
925
  $author_or_role_selected = array(
926
  'value' => $user->ID,
connectors/class-connector-comments.php CHANGED
@@ -278,7 +278,7 @@ class Connector_Comments extends Connector {
278
  }
279
  }
280
 
281
- $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
282
 
283
  if ( $comment->comment_parent ) {
284
  $parent_user_name = get_comment_author( $comment->comment_parent );
@@ -333,7 +333,7 @@ class Connector_Comments extends Connector {
333
  $post_type = get_post_type( $post_id );
334
  $post = get_post( $post_id );
335
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
336
- $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
337
 
338
  $this->log(
339
  // translators: Placeholders refer to a comment author, a post title, and a comment type
@@ -399,7 +399,7 @@ class Connector_Comments extends Connector {
399
  $post_type = get_post_type( $post_id );
400
  $post = get_post( $post_id );
401
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
402
- $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
403
 
404
  if ( $this->delete_post === $post_id ) {
405
  return;
@@ -439,7 +439,7 @@ class Connector_Comments extends Connector {
439
  $post_type = get_post_type( $post_id );
440
  $post = get_post( $post_id );
441
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
442
- $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
443
 
444
  $this->log(
445
  // translators: Placeholders refer to a comment author, a post title, and a comment type
@@ -475,7 +475,7 @@ class Connector_Comments extends Connector {
475
  $post_type = get_post_type( $post_id );
476
  $post = get_post( $post_id );
477
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
478
- $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
479
 
480
  $this->log(
481
  // translators: Placeholders refer to a comment author, a post title, and a comment type
@@ -511,7 +511,7 @@ class Connector_Comments extends Connector {
511
  $post_type = get_post_type( $post_id );
512
  $post = get_post( $post_id );
513
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
514
- $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
515
 
516
  $this->log(
517
  // translators: Placeholders refer to a comment author, a post title, and a comment type
@@ -547,7 +547,7 @@ class Connector_Comments extends Connector {
547
  $post_type = get_post_type( $post_id );
548
  $post = get_post( $post_id );
549
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
550
- $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
551
 
552
  $this->log(
553
  // translators: Placeholders refer to a comment author, a post title, and a comment type
@@ -630,7 +630,7 @@ class Connector_Comments extends Connector {
630
  $post_type = get_post_type( $post_id );
631
  $post = get_post( $post_id );
632
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
633
- $comment_type = mb_strtolower( $this->get_comment_type_label( $comment_id ) );
634
 
635
  $this->log(
636
  // translators: Placeholders refer to a comment author, a post title, and a comment type
278
  }
279
  }
280
 
281
+ $comment_type = \mb_strtolower( $this->get_comment_type_label( $comment_id ) );
282
 
283
  if ( $comment->comment_parent ) {
284
  $parent_user_name = get_comment_author( $comment->comment_parent );
333
  $post_type = get_post_type( $post_id );
334
  $post = get_post( $post_id );
335
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
336
+ $comment_type = \mb_strtolower( $this->get_comment_type_label( $comment_id ) );
337
 
338
  $this->log(
339
  // translators: Placeholders refer to a comment author, a post title, and a comment type
399
  $post_type = get_post_type( $post_id );
400
  $post = get_post( $post_id );
401
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
402
+ $comment_type = \mb_strtolower( $this->get_comment_type_label( $comment_id ) );
403
 
404
  if ( $this->delete_post === $post_id ) {
405
  return;
439
  $post_type = get_post_type( $post_id );
440
  $post = get_post( $post_id );
441
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
442
+ $comment_type = \mb_strtolower( $this->get_comment_type_label( $comment_id ) );
443
 
444
  $this->log(
445
  // translators: Placeholders refer to a comment author, a post title, and a comment type
475
  $post_type = get_post_type( $post_id );
476
  $post = get_post( $post_id );
477
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
478
+ $comment_type = \mb_strtolower( $this->get_comment_type_label( $comment_id ) );
479
 
480
  $this->log(
481
  // translators: Placeholders refer to a comment author, a post title, and a comment type
511
  $post_type = get_post_type( $post_id );
512
  $post = get_post( $post_id );
513
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
514
+ $comment_type = \mb_strtolower( $this->get_comment_type_label( $comment_id ) );
515
 
516
  $this->log(
517
  // translators: Placeholders refer to a comment author, a post title, and a comment type
547
  $post_type = get_post_type( $post_id );
548
  $post = get_post( $post_id );
549
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
550
+ $comment_type = \mb_strtolower( $this->get_comment_type_label( $comment_id ) );
551
 
552
  $this->log(
553
  // translators: Placeholders refer to a comment author, a post title, and a comment type
630
  $post_type = get_post_type( $post_id );
631
  $post = get_post( $post_id );
632
  $post_title = $post ? "\"$post->post_title\"" : esc_html__( 'a post', 'mainwp-child-reports' );
633
+ $comment_type = \mb_strtolower( $this->get_comment_type_label( $comment_id ) );
634
 
635
  $this->log(
636
  // translators: Placeholders refer to a comment author, a post title, and a comment type
connectors/class-connector-installer.php CHANGED
@@ -30,6 +30,7 @@ class Connector_Installer extends Connector {
30
  'mainwp_child_installPluginTheme',
31
  'mainwp_child_plugin_action',
32
  'mainwp_child_theme_action',
 
33
  );
34
 
35
  /** @var array Old plugins array. */
@@ -38,6 +39,8 @@ class Connector_Installer extends Connector {
38
  /** @var bool Register connector in the WP Frontend. */
39
  public $register_frontend = false;
40
 
 
 
41
  /**
42
  * Return translated connector label.
43
  *
@@ -429,6 +432,40 @@ class Connector_Installer extends Connector {
429
  }
430
  }
431
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  /**
433
  * Core updated successfully callback.
434
  *
@@ -457,7 +494,7 @@ class Connector_Installer extends Connector {
457
  $message,
458
  compact( 'new_version', 'old_version', 'auto_updated' ),
459
  null,
460
- 'WordPress',
461
  'updated'
462
  );
463
  }
30
  'mainwp_child_installPluginTheme',
31
  'mainwp_child_plugin_action',
32
  'mainwp_child_theme_action',
33
+ 'automatic_updates_complete',
34
  );
35
 
36
  /** @var array Old plugins array. */
39
  /** @var bool Register connector in the WP Frontend. */
40
  public $register_frontend = false;
41
 
42
+ public $register_cron = true;
43
+
44
  /**
45
  * Return translated connector label.
46
  *
432
  }
433
  }
434
 
435
+ /**
436
+ * Logs WordPress core upgrades
437
+ *
438
+ * @action automatic_updates_complete
439
+ *
440
+ * @param string $update_results Update results.
441
+ * @return void
442
+ */
443
+ public function callback_automatic_updates_complete( $update_results ) {
444
+ global $pagenow, $wp_version;
445
+
446
+ if ( ! is_array( $update_results ) || ! isset( $update_results['core'] ) ) {
447
+ return false;
448
+ }
449
+
450
+ $info = $update_results['core'][0];
451
+
452
+ $old_version = $wp_version;
453
+ $new_version = $info->item->version;
454
+ $auto_updated = true;
455
+
456
+ $message = esc_html__( 'WordPress auto-updated to %s', 'stream' );
457
+
458
+ $this->log(
459
+ $message,
460
+ compact( 'new_version', 'old_version', 'auto_updated' ),
461
+ null,
462
+ 'wordpress', // phpcs:ignore -- fix format text.
463
+ 'updated',
464
+ null,
465
+ true // forced log - $forced_log.
466
+ );
467
+ }
468
+
469
  /**
470
  * Core updated successfully callback.
471
  *
494
  $message,
495
  compact( 'new_version', 'old_version', 'auto_updated' ),
496
  null,
497
+ 'wordpress', // phpcs:ignore -- fix format text.
498
  'updated'
499
  );
500
  }
connectors/class-connector-mainwp-backups.php CHANGED
@@ -14,6 +14,8 @@ class Connector_MainWP_Backups extends Connector {
14
  /** @var string Connector slug. */
15
  public $name = 'mainwp_backups';
16
 
 
 
17
  /** @var array Actions registered for this connector. */
18
  public $actions = array(
19
  'mainwp_backup',
14
  /** @var string Connector slug. */
15
  public $name = 'mainwp_backups';
16
 
17
+ public $register_cron = true; // to fix cron backups.
18
+
19
  /** @var array Actions registered for this connector. */
20
  public $actions = array(
21
  'mainwp_backup',
connectors/class-connector-woocommerce.php CHANGED
@@ -4,6 +4,7 @@ namespace WP_MainWP_Stream;
4
 
5
  /**
6
  * Class Connector_Woocommerce
 
7
  * @package WP_MainWP_Stream
8
  *
9
  * @uses \WP_MainWP_Stream\Connector
@@ -19,7 +20,7 @@ class Connector_Woocommerce extends Connector {
19
  /** @var array Actions registered for this context. */
20
  public $actions = array(
21
  'wp_mainwp_stream_record_array',
22
- //'updated_option',
23
  'transition_post_status',
24
  'deleted_post',
25
  'woocommerce_order_status_changed',
@@ -31,8 +32,8 @@ class Connector_Woocommerce extends Connector {
31
  'woocommerce_tax_rate_deleted',
32
  );
33
 
34
- /** @var string[] Array of taxonomies. */
35
- public $taxonomies = array(
36
  'product_type',
37
  'product_cat',
38
  'product_tag',
@@ -40,32 +41,32 @@ class Connector_Woocommerce extends Connector {
40
  'shop_order_status',
41
  );
42
 
43
- /** @var string[] Array of post types. */
44
- public $post_types = array(
45
  'product',
46
  'product_variation',
47
  'shop_order',
48
  'shop_coupon',
49
  );
50
 
51
- /** @var bool Return TRUE if order update has logged, or FALSE on failure. */
52
- private $order_update_logged = false;
53
 
54
- /** @var array Holds settings pages. */
55
- private $settings_pages = array();
56
 
57
- /** @var array Settings array. */
58
- private $settings = array();
59
 
60
- /** @var string Current WooCommerce plugin version. */
61
- private $plugin_version = null;
62
 
63
- /**
64
- * Register WooCommerce Connector with parent class.
65
- *
66
- * @uses \WP_MainWP_Stream\Connector::register()
67
- */
68
- public function register() {
69
  parent::register();
70
 
71
  add_filter( 'wp_mainwp_stream_posts_exclude_post_types', array( $this, 'exclude_order_post_types' ) );
@@ -219,7 +220,7 @@ class Connector_Woocommerce extends Connector {
219
  *
220
  * @filter wp_mainwp_stream_action_links_{connector}.
221
  *
222
- * @param array $links Previous links registered.
223
  * @param Record $record Stream record.
224
  *
225
  * @return array Action links.
@@ -303,8 +304,8 @@ class Connector_Woocommerce extends Connector {
303
  *
304
  * @action transition_post_status.
305
  *
306
- * @param string $new Post status.
307
- * @param string $old Post status.
308
  * @param \WP_Post $post WP_Posts object.
309
  */
310
  public function callback_transition_post_status( $new, $old, $post ) {
@@ -436,7 +437,7 @@ class Connector_Woocommerce extends Connector {
436
  *
437
  * @action woocommerce_order_status_changed.
438
  *
439
- * @param int $order_id Order ID.
440
  * @param string $old Post status.
441
  * @param string $new Post status.
442
  */
@@ -462,10 +463,10 @@ class Connector_Woocommerce extends Connector {
462
  $old_status_name = $old_status->name;
463
  }
464
 
465
- /**
466
- * translators: Placeholders refer to an order title, and order status,
467
- * and another order status (e.g. "Order #42", "processing", "complete").
468
- */
469
  $message = esc_html_x(
470
  '%1$s status changed from %2$s to %3$s',
471
  '1. Order title, 2. Old status, 3. New status',
@@ -498,7 +499,7 @@ class Connector_Woocommerce extends Connector {
498
  *
499
  * @action woocommerce_attribute_added
500
  *
501
- * @param int $attribute_id Attribute ID.
502
  * @param array $attribute Attribute array.
503
  */
504
  public function callback_woocommerce_attribute_added( $attribute_id, $attribute ) {
@@ -521,8 +522,8 @@ class Connector_Woocommerce extends Connector {
521
  *
522
  * @action woocommerce_attribute_updated
523
  *
524
- * @param int $attribute_id Attribute ID.
525
- * @param array $attribute Attribute array.
526
  */
527
  public function callback_woocommerce_attribute_updated( $attribute_id, $attribute ) {
528
  $this->log(
@@ -544,7 +545,7 @@ class Connector_Woocommerce extends Connector {
544
  *
545
  * @action woocommerce_attribute_updated
546
  *
547
- * @param int $attribute_id Attribute ID.
548
  * @param string $attribute_name Attribute name.
549
  */
550
  public function callback_woocommerce_attribute_deleted( $attribute_id, $attribute_name ) {
@@ -569,7 +570,7 @@ class Connector_Woocommerce extends Connector {
569
  *
570
  * @action woocommerce_tax_rate_added
571
  *
572
- * @param int $tax_rate_id Tax rate ID.
573
  * @param array $tax_rate Tax rate array.
574
  */
575
  public function callback_woocommerce_tax_rate_added( $tax_rate_id, $tax_rate ) {
@@ -592,8 +593,8 @@ class Connector_Woocommerce extends Connector {
592
  *
593
  * @action woocommerce_tax_rate_updated
594
  *
595
- * @param int $tax_rate_id Tax rate ID.
596
- * @param array $tax_rate Tax rate array.
597
  */
598
  public function callback_woocommerce_tax_rate_updated( $tax_rate_id, $tax_rate ) {
599
 
@@ -616,11 +617,11 @@ class Connector_Woocommerce extends Connector {
616
  *
617
  * @action woocommerce_tax_rate_updated
618
  *
619
- * @param int $tax_rate_id Tax rate ID.
620
  */
621
  public function callback_woocommerce_tax_rate_deleted( $tax_rate_id ) {
622
 
623
- /** @global object $wpdb WordPress DB object. */
624
  global $wpdb;
625
 
626
  $tax_rate_name = $wpdb->get_var(
@@ -680,14 +681,14 @@ class Connector_Woocommerce extends Connector {
680
  return $recordarr;
681
  }
682
 
683
- /**
684
- * Updated option callback.
685
- *
686
- * @param string $option_key Option Key.
687
- * @param string $old_value Old options value.
688
- * @param string $value New options value.
689
- */
690
- public function callback_updated_option($option_key, $old_value, $value ) {
691
  $options = array( $option_key );
692
 
693
  if ( is_array( $old_value ) || is_array( $value ) ) {
@@ -721,12 +722,12 @@ class Connector_Woocommerce extends Connector {
721
  }
722
  }
723
 
724
- /**
725
- * Get WooCommerce settings fileds.
726
- *
727
- * @return array|bool Return WooCommerce settings array, or FALSE on failure.
728
- */
729
- public function get_woocommerce_settings_fields() {
730
  if ( ! defined( 'WC_VERSION' ) || ! class_exists( 'WC_Admin_Settings' ) ) {
731
  return false;
732
  }
@@ -751,10 +752,14 @@ class Connector_Woocommerce extends Connector {
751
 
752
  foreach ( \WC_Admin_Settings::get_settings_pages() as $page ) {
753
 
754
- /**
755
- * Get ID / Label of the page, since they're protected, by hacking into
756
- * the callback filter for 'woocommerce_settings_tabs_array'.
757
- */
 
 
 
 
758
  $info = $page->add_settings_page( array() );
759
  $page_id = key( $info );
760
  $page_label = current( $info );
@@ -770,22 +775,27 @@ class Connector_Woocommerce extends Connector {
770
  $fields = array();
771
 
772
  foreach ( $sections as $section_key => $section_label ) {
773
- $_fields = array_filter(
774
- $page->get_settings( $section_key ),
775
- function( $item ) {
776
- return isset( $item['id'] ) && ( ! in_array( $item['type'], array( 'title', 'sectionend' ), true ) );
777
- }
778
- );
779
-
780
- foreach ( $_fields as $field ) {
781
- $title = isset( $field['title'] ) ? $field['title'] : ( isset( $field['desc'] ) ? $field['desc'] : 'N/A' );
782
- $fields[ $field['id'] ] = array(
783
- 'title' => $title,
784
- 'page' => 'wc-settings',
785
- 'tab' => $page_id,
786
- 'section' => $section_key,
787
- 'type' => esc_html__( 'setting', 'mainwp-child-reports' ),
788
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
789
  }
790
  }
791
 
@@ -795,7 +805,8 @@ class Connector_Woocommerce extends Connector {
795
 
796
  // Provide additional context for each of the settings pages.
797
  array_walk(
798
- $settings_pages, function( &$value ) {
 
799
  $value .= ' ' . esc_html__( 'Settings', 'mainwp-child-reports' );
800
  }
801
  );
4
 
5
  /**
6
  * Class Connector_Woocommerce
7
+ *
8
  * @package WP_MainWP_Stream
9
  *
10
  * @uses \WP_MainWP_Stream\Connector
20
  /** @var array Actions registered for this context. */
21
  public $actions = array(
22
  'wp_mainwp_stream_record_array',
23
+ // 'updated_option',
24
  'transition_post_status',
25
  'deleted_post',
26
  'woocommerce_order_status_changed',
32
  'woocommerce_tax_rate_deleted',
33
  );
34
 
35
+ /** @var string[] Array of taxonomies. */
36
+ public $taxonomies = array(
37
  'product_type',
38
  'product_cat',
39
  'product_tag',
41
  'shop_order_status',
42
  );
43
 
44
+ /** @var string[] Array of post types. */
45
+ public $post_types = array(
46
  'product',
47
  'product_variation',
48
  'shop_order',
49
  'shop_coupon',
50
  );
51
 
52
+ /** @var bool Return TRUE if order update has logged, or FALSE on failure. */
53
+ private $order_update_logged = false;
54
 
55
+ /** @var array Holds settings pages. */
56
+ private $settings_pages = array();
57
 
58
+ /** @var array Settings array. */
59
+ private $settings = array();
60
 
61
+ /** @var string Current WooCommerce plugin version. */
62
+ private $plugin_version = null;
63
 
64
+ /**
65
+ * Register WooCommerce Connector with parent class.
66
+ *
67
+ * @uses \WP_MainWP_Stream\Connector::register()
68
+ */
69
+ public function register() {
70
  parent::register();
71
 
72
  add_filter( 'wp_mainwp_stream_posts_exclude_post_types', array( $this, 'exclude_order_post_types' ) );
220
  *
221
  * @filter wp_mainwp_stream_action_links_{connector}.
222
  *
223
+ * @param array $links Previous links registered.
224
  * @param Record $record Stream record.
225
  *
226
  * @return array Action links.
304
  *
305
  * @action transition_post_status.
306
  *
307
+ * @param string $new Post status.
308
+ * @param string $old Post status.
309
  * @param \WP_Post $post WP_Posts object.
310
  */
311
  public function callback_transition_post_status( $new, $old, $post ) {
437
  *
438
  * @action woocommerce_order_status_changed.
439
  *
440
+ * @param int $order_id Order ID.
441
  * @param string $old Post status.
442
  * @param string $new Post status.
443
  */
463
  $old_status_name = $old_status->name;
464
  }
465
 
466
+ /**
467
+ * translators: Placeholders refer to an order title, and order status,
468
+ * and another order status (e.g. "Order #42", "processing", "complete").
469
+ */
470
  $message = esc_html_x(
471
  '%1$s status changed from %2$s to %3$s',
472
  '1. Order title, 2. Old status, 3. New status',
499
  *
500
  * @action woocommerce_attribute_added
501
  *
502
+ * @param int $attribute_id Attribute ID.
503
  * @param array $attribute Attribute array.
504
  */
505
  public function callback_woocommerce_attribute_added( $attribute_id, $attribute ) {
522
  *
523
  * @action woocommerce_attribute_updated
524
  *
525
+ * @param int $attribute_id Attribute ID.
526
+ * @param array $attribute Attribute array.
527
  */
528
  public function callback_woocommerce_attribute_updated( $attribute_id, $attribute ) {
529
  $this->log(
545
  *
546
  * @action woocommerce_attribute_updated
547
  *
548
+ * @param int $attribute_id Attribute ID.
549
  * @param string $attribute_name Attribute name.
550
  */
551
  public function callback_woocommerce_attribute_deleted( $attribute_id, $attribute_name ) {
570
  *
571
  * @action woocommerce_tax_rate_added
572
  *
573
+ * @param int $tax_rate_id Tax rate ID.
574
  * @param array $tax_rate Tax rate array.
575
  */
576
  public function callback_woocommerce_tax_rate_added( $tax_rate_id, $tax_rate ) {
593
  *
594
  * @action woocommerce_tax_rate_updated
595
  *
596
+ * @param int $tax_rate_id Tax rate ID.
597
+ * @param array $tax_rate Tax rate array.
598
  */
599
  public function callback_woocommerce_tax_rate_updated( $tax_rate_id, $tax_rate ) {
600
 
617
  *
618
  * @action woocommerce_tax_rate_updated
619
  *
620
+ * @param int $tax_rate_id Tax rate ID.
621
  */
622
  public function callback_woocommerce_tax_rate_deleted( $tax_rate_id ) {
623
 
624
+ /** @global object $wpdb WordPress DB object. */
625
  global $wpdb;
626
 
627
  $tax_rate_name = $wpdb->get_var(
681
  return $recordarr;
682
  }
683
 
684
+ /**
685
+ * Updated option callback.
686
+ *
687
+ * @param string $option_key Option Key.
688
+ * @param string $old_value Old options value.
689
+ * @param string $value New options value.
690
+ */
691
+ public function callback_updated_option( $option_key, $old_value, $value ) {
692
  $options = array( $option_key );
693
 
694
  if ( is_array( $old_value ) || is_array( $value ) ) {
722
  }
723
  }
724
 
725
+ /**
726
+ * Get WooCommerce settings fileds.
727
+ *
728
+ * @return array|bool Return WooCommerce settings array, or FALSE on failure.
729
+ */
730
+ public function get_woocommerce_settings_fields() {
731
  if ( ! defined( 'WC_VERSION' ) || ! class_exists( 'WC_Admin_Settings' ) ) {
732
  return false;
733
  }
752
 
753
  foreach ( \WC_Admin_Settings::get_settings_pages() as $page ) {
754
 
755
+ if ( ! is_object( $page ) || ! property_exists( $page, 'add_settings_page' )) {
756
+ continue;
757
+ }
758
+
759
+ /**
760
+ * Get ID / Label of the page, since they're protected, by hacking into
761
+ * the callback filter for 'woocommerce_settings_tabs_array'.
762
+ */
763
  $info = $page->add_settings_page( array() );
764
  $page_id = key( $info );
765
  $page_label = current( $info );
775
  $fields = array();
776
 
777
  foreach ( $sections as $section_key => $section_label ) {
778
+ $section_settings = $page->get_settings( $section_key );
779
+ if ( is_array( $section_settings ) ) {
780
+ $_fields = array_filter(
781
+ $page->get_settings( $section_key ),
782
+ function( $item ) {
783
+ return isset( $item['id'] ) && ( ! in_array( $item['type'], array( 'title', 'sectionend' ), true ) );
784
+ }
 
 
 
 
 
 
 
 
785
  );
786
+
787
+ if ( ! empty( $_fields ) ) {
788
+ foreach ( $_fields as $field ) {
789
+ $title = isset( $field['title'] ) ? $field['title'] : ( isset( $field['desc'] ) ? $field['desc'] : 'N/A' );
790
+ $fields[ $field['id'] ] = array(
791
+ 'title' => $title,
792
+ 'page' => 'wc-settings',
793
+ 'tab' => $page_id,
794
+ 'section' => $section_key,
795
+ 'type' => esc_html__( 'setting', 'mainwp-child-reports' ),
796
+ );
797
+ }
798
+ }
799
  }
800
  }
801
 
805
 
806
  // Provide additional context for each of the settings pages.
807
  array_walk(
808
+ $settings_pages,
809
+ function( &$value ) {
810
  $value .= ' ' . esc_html__( 'Settings', 'mainwp-child-reports' );
811
  }
812
  );
includes/functions.php CHANGED
@@ -49,7 +49,7 @@ function wp_mainwp_stream_filter_var( $var, $filter = null, $options = array() )
49
  */
50
  function wp_mainwp_stream_get_iso_8601_extended_date( $time = false, $offset = 0, $mysql_date_string = false ) {
51
  if ( $time ) {
52
- $microtime = (float) $time . '.0000';
53
  } else {
54
  $microtime = microtime( true );
55
  }
@@ -140,6 +140,15 @@ function wp_mainwp_stream_is_cron_enabled() {
140
  }
141
 
142
 
 
 
 
 
 
 
 
 
 
143
  /**
144
  * Get the asset min suffix if defined.
145
  *
49
  */
50
  function wp_mainwp_stream_get_iso_8601_extended_date( $time = false, $offset = 0, $mysql_date_string = false ) {
51
  if ( $time ) {
52
+ $microtime = (float) ( $time . '.0000' );
53
  } else {
54
  $microtime = microtime( true );
55
  }
140
  }
141
 
142
 
143
+ /**
144
+ * True if native WP Cron is enabled, otherwise false
145
+ *
146
+ * @return bool
147
+ */
148
+ function wp_mainwp_stream_is_cron_doing() {
149
+ return ( defined( 'DOING_CRON' ) && DOING_CRON ) ? true : false;
150
+ }
151
+
152
  /**
153
  * Get the asset min suffix if defined.
154
  *
mainwp-child-reports.php CHANGED
@@ -7,7 +7,7 @@
7
  * Description: The MainWP Child Report plugin tracks Child sites for the MainWP Client Reports Extension. The plugin is only useful if you are using MainWP and the Client Reports Extension.
8
  * Author: MainWP
9
  * Author URI: https://mainwp.com
10
- * Version: 2.0.7
11
  * Requires at least: 3.6
12
  * Text Domain: mainwp-child-reports
13
  * License: GPLv3 or later
7
  * Description: The MainWP Child Report plugin tracks Child sites for the MainWP Client Reports Extension. The plugin is only useful if you are using MainWP and the Client Reports Extension.
8
  * Author: MainWP
9
  * Author URI: https://mainwp.com
10
+ * Version: 2.0.8
11
  * Requires at least: 3.6
12
  * Text Domain: mainwp-child-reports
13
  * License: GPLv3 or later
readme.txt CHANGED
@@ -5,9 +5,9 @@ Author: mainwp
5
  Author URI: https://mainwp.com
6
  Plugin URI: https://mainwp.com
7
  Requires at least: 3.6
8
- Tested up to: 5.8
9
  Requires PHP: 7.0
10
- Stable tag: 2.0.7
11
  License: GPLv3 or later
12
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
13
 
@@ -36,6 +36,12 @@ Credit to the [Stream Plugin](https://wordpress.org/plugins/stream/) which the M
36
 
37
  == Changelog ==
38
 
 
 
 
 
 
 
39
  = 2.0.7 - 2-4-2021 =
40
  * Fixed: An issue with logging deleted plugins
41
  * Updated: exclusion rules for certain custom post types
5
  Author URI: https://mainwp.com
6
  Plugin URI: https://mainwp.com
7
  Requires at least: 3.6
8
+ Tested up to: 6.1
9
  Requires PHP: 7.0
10
+ Stable tag: 2.0.8
11
  License: GPLv3 or later
12
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
13
 
36
 
37
  == Changelog ==
38
 
39
+ = 2.0.8 - 9-15-2021 =
40
+ * Fixed: An issue with logging certain actions triggered by WP Cron
41
+ * Fixed: An issue with displaying timestamps on some setups
42
+ * Fixed: Problems with the multibyte string functions usage
43
+ * Preventative: Multiple security improvements
44
+
45
  = 2.0.7 - 2-4-2021 =
46
  * Fixed: An issue with logging deleted plugins
47
  * Updated: exclusion rules for certain custom post types
ui/js/admin.js CHANGED
@@ -113,7 +113,7 @@ jQuery(
113
  $contextInput.trigger( 'change' );
114
  }
115
 
116
- $( 'input[type=submit]', '#record-filter-form' ).click(
117
  function() {
118
  $( 'input[type=submit]', $( this ).parents( 'form' ) ).removeAttr( 'clicked' );
119
  $( this ).attr( 'clicked', 'true' );
@@ -226,7 +226,7 @@ jQuery(
226
  function() {
227
 
228
  // Enable Live Updates checkbox ajax
229
- $( '#enable_live_update' ).click(
230
  function() {
231
  var nonce = $( '#mainwp_stream_live_update_nonce' ).val(),
232
  user = $( '#mainwp_enable_live_update_user' ).val(),
@@ -318,7 +318,7 @@ jQuery(
318
 
319
  toggle_filter_submit();
320
 
321
- $( 'div.metabox-prefs [type="checkbox"]' ).click(
322
  function() {
323
  var id = $( this ).prop( 'id' );
324
 
@@ -525,8 +525,7 @@ jQuery(
525
 
526
  save_interval: function( $btn ) {
527
  var $wrapper = this.wrapper;
528
- $btn.click(
529
- function() {
530
  var data = {
531
  key: $wrapper.find( 'select.field-predefined' ).find( ':selected' ).val(),
532
  start: $wrapper.find( '.date-inputs .field-from' ).val(),
113
  $contextInput.trigger( 'change' );
114
  }
115
 
116
+ $( 'input[type=submit]', '#record-filter-form' ).on( 'click',
117
  function() {
118
  $( 'input[type=submit]', $( this ).parents( 'form' ) ).removeAttr( 'clicked' );
119
  $( this ).attr( 'clicked', 'true' );
226
  function() {
227
 
228
  // Enable Live Updates checkbox ajax
229
+ $( '#enable_live_update' ).on( 'click',
230
  function() {
231
  var nonce = $( '#mainwp_stream_live_update_nonce' ).val(),
232
  user = $( '#mainwp_enable_live_update_user' ).val(),
318
 
319
  toggle_filter_submit();
320
 
321
+ $( 'div.metabox-prefs [type="checkbox"]' ).on( 'click',
322
  function() {
323
  var id = $( this ).prop( 'id' );
324
 
525
 
526
  save_interval: function( $btn ) {
527
  var $wrapper = this.wrapper;
528
+ $btn.on( 'click', function() {
 
529
  var data = {
530
  key: $wrapper.find( 'select.field-predefined' ).find( ':selected' ).val(),
531
  start: $wrapper.find( '.date-inputs .field-from' ).val(),