Stream - Version 3.6.0

Version Description

  • October 14, 2020 =

  • New: Introduce the wp_stream_db_query_where filter #1160, props @kidunot89 and @nprasath002.

  • Fix: Replace the deprecated jQuery .load() calls #1162, props @kidunot89.

  • Fix: Log the correct post status change #1121, props @kidunot89.

  • Fix: Update the Advanced Custom Fields connector to support versions 5 of the plugin #1118, props @kidunot89.

  • Fix: Update the Easy Digital Downloads connector to support version 2.5 of the plugin #1137, props @kidunot89.

  • Tweak: Clarify the messaging when no Stream records found #1178, props @kidunot89 and @johnbillion.

Download this release

Release Info

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

Code changes from version 3.5.1 to 3.6.0

classes/class-list-table.php CHANGED
@@ -99,7 +99,7 @@ class List_Table extends \WP_List_Table {
99
  public function no_items() {
100
  ?>
101
  <div class="stream-list-table-no-items">
102
- <p><?php esc_html_e( 'Sorry, no activity records were found.', 'stream' ); ?></p>
103
  </div>
104
  <?php
105
  }
99
  public function no_items() {
100
  ?>
101
  <div class="stream-list-table-no-items">
102
+ <p><?php esc_html_e( 'No activity records were found.', 'stream' ); ?></p>
103
  </div>
104
  <?php
105
  }
classes/class-plugin.php CHANGED
@@ -18,7 +18,7 @@ class Plugin {
18
  *
19
  * @const string
20
  */
21
- const VERSION = '3.5.1';
22
 
23
  /**
24
  * WP-CLI command
18
  *
19
  * @const string
20
  */
21
+ const VERSION = '3.6.0';
22
 
23
  /**
24
  * WP-CLI command
classes/class-query.php CHANGED
@@ -216,6 +216,16 @@ class Query {
216
 
217
  $select = implode( ', ', $selects );
218
 
 
 
 
 
 
 
 
 
 
 
219
  /**
220
  * BUILD THE FINAL QUERY
221
  */
216
 
217
  $select = implode( ', ', $selects );
218
 
219
+ /**
220
+ * Filters query WHERE statement as an alternative to filtering
221
+ * the $query using the hook below.
222
+ *
223
+ * @param string $where WHERE statement.
224
+ *
225
+ * @return string
226
+ */
227
+ $where = apply_filters( 'wp_stream_db_query_where', $where );
228
+
229
  /**
230
  * BUILD THE FINAL QUERY
231
  */
composer.json CHANGED
@@ -4,6 +4,12 @@
4
  "homepage": "https://wordpress.org/plugins/stream/",
5
  "type": "wordpress-plugin",
6
  "license": "GPL-2.0-or-later",
 
 
 
 
 
 
7
  "require": {
8
  "composer/installers": "~1.0"
9
  },
@@ -15,7 +21,10 @@
15
  "wp-cli/wp-cli-bundle": "^2.2",
16
  "wp-coding-standards/wpcs": "^2.2",
17
  "wp-phpunit/wp-phpunit": "^5.4",
18
- "wpsh/local": "^0.2.3"
 
 
 
19
  },
20
  "config": {
21
  "process-timeout": 600,
@@ -25,7 +34,10 @@
25
  }
26
  },
27
  "extra": {
28
- "wordpress-install-dir": "local/public"
 
 
 
29
  },
30
  "scripts": {
31
  "release": [
4
  "homepage": "https://wordpress.org/plugins/stream/",
5
  "type": "wordpress-plugin",
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
  },
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,
34
  }
35
  },
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": {
43
  "release": [
connectors/class-connector-acf.php CHANGED
@@ -31,6 +31,8 @@ class Connector_ACF extends Connector {
31
  * @var array
32
  */
33
  public $actions = array(
 
 
34
  'added_post_meta',
35
  'updated_post_meta',
36
  'delete_post_meta',
@@ -147,13 +149,210 @@ class Connector_ACF extends Connector {
147
  return $links;
148
  }
149
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  /**
151
  * Track addition of post meta
152
  *
153
  * @action added_post_meta
154
  */
155
  public function callback_added_post_meta() {
156
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'post', 'added' ), func_get_args() ) );
157
  }
158
 
159
  /**
@@ -162,7 +361,7 @@ class Connector_ACF extends Connector {
162
  * @action updated_post_meta
163
  */
164
  public function callback_updated_post_meta() {
165
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'post', 'updated' ), func_get_args() ) );
166
  }
167
 
168
  /**
@@ -174,7 +373,7 @@ class Connector_ACF extends Connector {
174
  * @action delete_post_meta
175
  */
176
  public function callback_delete_post_meta() {
177
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'post', 'deleted' ), func_get_args() ) );
178
  }
179
 
180
  /**
@@ -183,7 +382,7 @@ class Connector_ACF extends Connector {
183
  * @action added_user_meta
184
  */
185
  public function callback_added_user_meta() {
186
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'user', 'added' ), func_get_args() ) );
187
  }
188
 
189
  /**
@@ -192,7 +391,7 @@ class Connector_ACF extends Connector {
192
  * @action updated_user_meta
193
  */
194
  public function callback_updated_user_meta() {
195
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'user', 'updated' ), func_get_args() ) );
196
  }
197
 
198
  /**
@@ -204,7 +403,7 @@ class Connector_ACF extends Connector {
204
  * @action delete_user_meta
205
  */
206
  public function callback_delete_user_meta() {
207
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'user', 'deleted' ), func_get_args() ) );
208
  }
209
 
210
  /**
@@ -219,7 +418,7 @@ class Connector_ACF extends Connector {
219
  */
220
  public function check_meta( $type, $action, $meta_id, $object_id, $meta_key, $meta_value = null ) {
221
  $post = get_post( $object_id );
222
- if ( 'post' !== $type || ! $post || 'acf' !== $post->post_type ) {
223
  $this->check_meta_values( $type, $action, $meta_id, $object_id, $meta_key, $meta_value );
224
  return;
225
  }
@@ -274,7 +473,7 @@ class Connector_ACF extends Connector {
274
  ),
275
  $object_id,
276
  'options',
277
- 'updated'
278
  );
279
  } elseif ( 'layout' === $meta_key ) {
280
  if ( 'deleted' === $action ) {
@@ -479,10 +678,29 @@ class Connector_ACF extends Connector {
479
  return $data;
480
  }
481
 
482
- if ( 'posts' === $data['connector'] && 'acf' === $data['context'] ) {
483
- $data['context'] = 'field_groups';
484
- $data['connector'] = $this->name;
485
- $data['args']['singular_name'] = esc_html__( 'field group', 'stream' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
  }
487
 
488
  return $data;
31
  * @var array
32
  */
33
  public $actions = array(
34
+ 'save_post',
35
+ 'post_updated',
36
  'added_post_meta',
37
  'updated_post_meta',
38
  'delete_post_meta',
149
  return $links;
150
  }
151
 
152
+ /**
153
+ * Tracks the creation of custom field group fields and settings (ACF v5+ only)
154
+ *
155
+ * @action save_post
156
+ *
157
+ * @param int $post_id Post ID.
158
+ * @param WP_Post $post Post object.
159
+ * @param bool $update Whether this is an existing post being updated or not.
160
+ */
161
+ public function callback_save_post( $post_id, $post, $update ) {
162
+ // Bail if updating existing post.
163
+ if ( false !== $update ) {
164
+ return;
165
+ }
166
+
167
+ // Log new ACF field additions to field groups.
168
+ if ( 'acf-field' === $post->post_type ) {
169
+ $parent = get_post( $post->post_parent );
170
+ if ( $parent ) {
171
+ $this->log_prop( 'added', $post_id, $post, 'parent', $parent );
172
+ }
173
+ } elseif ( 'acf-field-group' === $post->post_type ) {
174
+ $props = maybe_unserialize( $post->post_content );
175
+
176
+ if ( ! empty( $props ) && is_array( $props ) ) {
177
+ foreach ( $props as $prop => $value ) {
178
+ $this->log_prop( 'added', $post_id, $post, $prop, $value );
179
+ }
180
+ }
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Tracks changes to custom field groups settings.
186
+ *
187
+ * @action post_updated
188
+ *
189
+ * @param int $post_id Post ID.
190
+ * @param \WP_Post $posts_after Newly saved post object.
191
+ * @param \WP_Post $posts_before Old post object.
192
+ * @return void
193
+ */
194
+ public function callback_post_updated( $post_id, $posts_after, $posts_before ) {
195
+ if ( 'acf-field-group' !== $posts_after->post_type ) {
196
+ return;
197
+ }
198
+
199
+ $_new = ! empty( $posts_after->post_content ) ? maybe_unserialize( $posts_after->post_content ) : array();
200
+ $_old = ! empty( $posts_before->post_content ) ? maybe_unserialize( $posts_before->post_content ) : array();
201
+
202
+ // Get updated settings.
203
+ $updated_keys = $this->get_changed_keys( $_new, $_old );
204
+ $updated_keys = empty( $updated_keys ) ? array_keys( $_new ) : $updated_keys;
205
+
206
+ // Process updated properties.
207
+ foreach ( $updated_keys as $prop ) {
208
+ $old_value = null;
209
+ $value = $_new[ $prop ];
210
+ if ( empty( $value ) && is_array( $_old ) && ! empty( $_old[ $prop ] ) ) {
211
+ $action = 'deleted';
212
+ $old_value = $_old[ $prop ];
213
+ } else {
214
+ $action = 'updated';
215
+ }
216
+
217
+ $this->log_prop( $action, $post_id, $posts_after, $prop, $value, $old_value );
218
+ }
219
+ }
220
+
221
+
222
+ /**
223
+ * Logs field/field group property changes (ACF v5 only).
224
+ *
225
+ * @param string $action Added, updated, deleted.
226
+ * @param int $post_id Post ID.
227
+ * @param WP_Post $post Post object.
228
+ * @param string $property ACF property.
229
+ * @param mixed|null $value Value assigned to property.
230
+ * @param mixed|null $old_value Old value previously assigned to property.
231
+ * @return void
232
+ */
233
+ public function log_prop( $action, $post_id, $post, $property, $value = null, $old_value = null ) {
234
+ $action_labels = $this->get_action_labels();
235
+
236
+ // Fields.
237
+ if ( 'parent' === $property ) {
238
+ if ( 'deleted' === $action ) {
239
+ $meta_value = $old_value;
240
+ }
241
+
242
+ $this->log(
243
+ /* translators: %1$s: field label, %2$s: form title, %3$s: action (e.g. "Message", "Contact", "Created") */
244
+ esc_html_x( '"%1$s" field in "%2$s" %3$s', 'acf', 'stream' ),
245
+ array(
246
+ 'label' => $post->post_title,
247
+ 'title' => $value->post_title,
248
+ 'action' => strtolower( $action_labels[ $action ] ),
249
+ 'key' => $post->post_name,
250
+ 'name' => $post->post_excerpt,
251
+ ),
252
+ $value->ID,
253
+ 'fields',
254
+ $action
255
+ );
256
+ } elseif ( 'position' === $property ) {
257
+ if ( 'deleted' === $action ) {
258
+ return;
259
+ }
260
+
261
+ $options = array(
262
+ 'acf_after_title' => esc_html_x( 'High (after title)', 'acf', 'stream' ),
263
+ 'normal' => esc_html_x( 'Normal (after content)', 'acf', 'stream' ),
264
+ 'side' => esc_html_x( 'Side', 'acf', 'stream' ),
265
+ );
266
+
267
+ $this->log(
268
+ /* translators: %1$s: form title, %2$s a position (e.g. "Contact", "Side") */
269
+ esc_html_x( 'Position of "%1$s" updated to "%2$s"', 'acf', 'stream' ),
270
+ array(
271
+ 'title' => $post->post_title,
272
+ 'option_label' => $options[ $value ],
273
+ 'option' => $property,
274
+ 'option_value' => $value,
275
+ ),
276
+ $post_id,
277
+ 'options',
278
+ 'updated'
279
+ );
280
+ } elseif ( 'layout' === $property ) {
281
+ if ( 'deleted' === $action ) {
282
+ return;
283
+ }
284
+
285
+ $options = array(
286
+ 'no_box' => esc_html_x( 'Seamless (no metabox)', 'acf', 'stream' ),
287
+ 'default' => esc_html_x( 'Standard (WP metabox)', 'acf', 'stream' ),
288
+ );
289
+
290
+ $this->log(
291
+ /* translators: %1$s: form title, %2$s a layout (e.g. "Contact", "Seamless") */
292
+ esc_html_x( 'Style of "%1$s" updated to "%2$s"', 'acf', 'stream' ),
293
+ array(
294
+ 'title' => $post->post_title,
295
+ 'option_label' => $options[ $value ],
296
+ 'option' => $property,
297
+ 'option_value' => $value,
298
+ ),
299
+ $post_id,
300
+ 'options',
301
+ 'updated'
302
+ );
303
+ } elseif ( 'hide_on_screen' === $property ) {
304
+ if ( 'deleted' === $action ) {
305
+ return;
306
+ }
307
+
308
+ $options = array(
309
+ 'permalink' => esc_html_x( 'Permalink', 'acf', 'stream' ),
310
+ 'the_content' => esc_html_x( 'Content Editor', 'acf', 'stream' ),
311
+ 'excerpt' => esc_html_x( 'Excerpt', 'acf', 'stream' ),
312
+ 'custom_fields' => esc_html_x( 'Custom Fields', 'acf', 'stream' ),
313
+ 'discussion' => esc_html_x( 'Discussion', 'acf', 'stream' ),
314
+ 'comments' => esc_html_x( 'Comments', 'acf', 'stream' ),
315
+ 'revisions' => esc_html_x( 'Revisions', 'acf', 'stream' ),
316
+ 'slug' => esc_html_x( 'Slug', 'acf', 'stream' ),
317
+ 'author' => esc_html_x( 'Author', 'acf', 'stream' ),
318
+ 'format' => esc_html_x( 'Format', 'acf', 'stream' ),
319
+ 'featured_image' => esc_html_x( 'Featured Image', 'acf', 'stream' ),
320
+ 'categories' => esc_html_x( 'Categories', 'acf', 'stream' ),
321
+ 'tags' => esc_html_x( 'Tags', 'acf', 'stream' ),
322
+ 'send-trackbacks' => esc_html_x( 'Send Trackbacks', 'acf', 'stream' ),
323
+ );
324
+
325
+ if ( is_array( $value ) && count( $options ) === count( $value ) ) {
326
+ $options_label = esc_html_x( 'All screens', 'acf', 'stream' );
327
+ } elseif ( empty( $value ) ) {
328
+ $options_label = esc_html_x( 'No screens', 'acf', 'stream' );
329
+ } else {
330
+ $options_label = implode( ', ', array_intersect_key( $options, array_flip( $value ) ) );
331
+ }
332
+
333
+ $this->log(
334
+ /* translators: %1$s: a form title, %2$s: a display option (e.g. "Contact", "All screens") */
335
+ esc_html_x( '"%1$s" set to display on "%2$s"', 'acf', 'stream' ),
336
+ array(
337
+ 'title' => $post->post_title,
338
+ 'option_label' => $options_label,
339
+ 'option' => $property,
340
+ 'option_value' => $value,
341
+ ),
342
+ $post_id,
343
+ 'options',
344
+ 'updated'
345
+ );
346
+ }
347
+ }
348
+
349
  /**
350
  * Track addition of post meta
351
  *
352
  * @action added_post_meta
353
  */
354
  public function callback_added_post_meta() {
355
+ $this->check_meta( 'post', 'added', ...func_get_args() );
356
  }
357
 
358
  /**
361
  * @action updated_post_meta
362
  */
363
  public function callback_updated_post_meta() {
364
+ $this->check_meta( 'post', 'updated', ...func_get_args() );
365
  }
366
 
367
  /**
373
  * @action delete_post_meta
374
  */
375
  public function callback_delete_post_meta() {
376
+ $this->check_meta( 'post', 'deleted', ...func_get_args() );
377
  }
378
 
379
  /**
382
  * @action added_user_meta
383
  */
384
  public function callback_added_user_meta() {
385
+ $this->check_meta( 'user', 'added', ...func_get_args() );
386
  }
387
 
388
  /**
391
  * @action updated_user_meta
392
  */
393
  public function callback_updated_user_meta() {
394
+ $this->check_meta( 'user', 'updated', ...func_get_args() );
395
  }
396
 
397
  /**
403
  * @action delete_user_meta
404
  */
405
  public function callback_delete_user_meta() {
406
+ $this->check_meta( 'user', 'deleted', ...func_get_args() );
407
  }
408
 
409
  /**
418
  */
419
  public function check_meta( $type, $action, $meta_id, $object_id, $meta_key, $meta_value = null ) {
420
  $post = get_post( $object_id );
421
+ if ( 'post' !== $type || ! $post || ! in_array( $post->post_type, array( 'acf', 'acf-field-group' ), true ) ) {
422
  $this->check_meta_values( $type, $action, $meta_id, $object_id, $meta_key, $meta_value );
423
  return;
424
  }
473
  ),
474
  $object_id,
475
  'options',
476
+ $action
477
  );
478
  } elseif ( 'layout' === $meta_key ) {
479
  if ( 'deleted' === $action ) {
678
  return $data;
679
  }
680
 
681
+ $is_acf_context = in_array( $data['context'], array( 'acf', 'acf-field-group', 'acf-field' ), true );
682
+
683
+ if ( 'posts' === $data['connector'] && $is_acf_context ) {
684
+ // If ACF field group CPT being logged.
685
+ if ( 'acf' === $data['context'] || 'acf-field-group' === $data['context'] ) {
686
+ $data['context'] = 'field_groups';
687
+ $data['connector'] = $this->name;
688
+ $data['args']['singular_name'] = esc_html__( 'field group', 'stream' );
689
+
690
+ // elseif ACF field CPT being logged (ACF v5+ only).
691
+ } elseif ( 'acf-field' === $data['context'] ) {
692
+ $field_group = get_post( wp_get_post_parent_id( $data['object_id'] ) );
693
+
694
+ $data['context'] = 'fields';
695
+ $data['connector'] = $this->name;
696
+ $data['args']['singular_name'] = ! empty( $field_group )
697
+ ? sprintf(
698
+ /* translators: %s: field group name */
699
+ esc_html__( 'field in the "%s" field group', 'stream' ),
700
+ $field_group->post_title
701
+ )
702
+ : esc_html__( 'field', 'stream' );
703
+ }
704
  }
705
 
706
  return $data;
connectors/class-connector-edd.php CHANGED
@@ -330,14 +330,8 @@ class Connector_EDD extends Connector {
330
  $replacement = str_replace( '-', '_', $option );
331
 
332
  if ( method_exists( $this, 'check_' . $replacement ) ) {
333
- call_user_func(
334
- array(
335
- $this,
336
- 'check_' . $replacement,
337
- ),
338
- $old_value,
339
- $new_value
340
- );
341
  } else {
342
  $data = $this->options[ $option ];
343
  $option_title = $data['label'];
@@ -376,6 +370,7 @@ class Connector_EDD extends Connector {
376
 
377
  foreach ( $options as $option => $option_value ) {
378
  $field = null;
 
379
 
380
  if ( 'banned_email' === $option ) {
381
  $field = array(
@@ -383,10 +378,13 @@ class Connector_EDD extends Connector {
383
  );
384
  $tab = 'general';
385
  } else {
386
- foreach ( $settings as $tab => $fields ) {
387
- if ( isset( $fields[ $option ] ) ) {
388
- $field = $fields[ $option ];
389
- break;
 
 
 
390
  }
391
  }
392
  }
@@ -401,8 +399,8 @@ class Connector_EDD extends Connector {
401
  array(
402
  'option_title' => $field['name'],
403
  'option' => $option,
404
- 'old_value' => $old_value,
405
- 'value' => $new_value,
406
  'tab' => $tab,
407
  ),
408
  null,
@@ -652,6 +650,12 @@ class Connector_EDD extends Connector {
652
  * @param bool $is_add Is this a new meta?.
653
  */
654
  public function meta( $object_id, $key, $value, $is_add = false ) {
 
 
 
 
 
 
655
  if ( ! in_array( $key, $this->user_meta, true ) ) {
656
  return false;
657
  }
@@ -662,15 +666,8 @@ class Connector_EDD extends Connector {
662
  return false;
663
  }
664
 
665
- return call_user_func(
666
- array(
667
- $this,
668
- 'meta_' . $key,
669
- ),
670
- $object_id,
671
- $value,
672
- $is_add
673
- );
674
  }
675
 
676
  /**
330
  $replacement = str_replace( '-', '_', $option );
331
 
332
  if ( method_exists( $this, 'check_' . $replacement ) ) {
333
+ $method = "check_{$replacement}";
334
+ $this->{$method}( $old_value, $new_value );
 
 
 
 
 
 
335
  } else {
336
  $data = $this->options[ $option ];
337
  $option_title = $data['label'];
370
 
371
  foreach ( $options as $option => $option_value ) {
372
  $field = null;
373
+ $tab = null;
374
 
375
  if ( 'banned_email' === $option ) {
376
  $field = array(
378
  );
379
  $tab = 'general';
380
  } else {
381
+ foreach ( $settings as $current_tab => $tab_sections ) {
382
+ foreach ( $tab_sections as $section => $section_fields ) {
383
+ if ( in_array( $option, array_keys( $section_fields ), true ) ) {
384
+ $field = $section_fields[ $option ];
385
+ $tab = $current_tab;
386
+ break;
387
+ }
388
  }
389
  }
390
  }
399
  array(
400
  'option_title' => $field['name'],
401
  'option' => $option,
402
+ 'old_value' => isset( $old_value[ $option ] ) ? $old_value[ $option ] : null,
403
+ 'value' => isset( $new_value[ $option ] ) ? $new_value[ $option ] : null,
404
  'tab' => $tab,
405
  ),
406
  null,
650
  * @param bool $is_add Is this a new meta?.
651
  */
652
  public function meta( $object_id, $key, $value, $is_add = false ) {
653
+ // For catching "edd_user_public_key" in newer versions of EDD.
654
+ if ( in_array( $value, $this->user_meta, true ) ) {
655
+ $key = $value;
656
+ $value = 1; // Probably, should avoid storing the api key.
657
+ }
658
+
659
  if ( ! in_array( $key, $this->user_meta, true ) ) {
660
  return false;
661
  }
666
  return false;
667
  }
668
 
669
+ $method = "meta_{$key}";
670
+ return $this->{$method}( $object_id, $value, $is_add );
 
 
 
 
 
 
 
671
  }
672
 
673
  /**
connectors/class-connector-posts.php CHANGED
@@ -170,7 +170,8 @@ class Connector_Posts extends Connector {
170
  return;
171
  }
172
 
173
- if ( in_array( $new, array( 'auto-draft', 'inherit' ), true ) ) {
 
174
  return;
175
  } elseif ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
176
  return;
@@ -196,7 +197,7 @@ class Connector_Posts extends Connector {
196
  '1: Post title, 2: Post type singular name',
197
  'stream'
198
  );
199
- } elseif ( 'publish' === $new && 'draft' === $old ) {
200
  /* translators: %1$s: a post title, %2$s: a post type singular name (e.g. "Hello World", "Post") */
201
  $summary = _x(
202
  '"%1$s" %2$s published',
@@ -255,7 +256,7 @@ class Connector_Posts extends Connector {
255
  );
256
  }
257
 
258
- if ( 'auto-draft' === $old && 'auto-draft' !== $new ) {
259
  $action = 'created';
260
  }
261
 
170
  return;
171
  }
172
 
173
+ $start_statuses = array( 'auto-draft', 'inherit', 'new' );
174
+ if ( in_array( $new, $start_statuses, true ) ) {
175
  return;
176
  } elseif ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
177
  return;
197
  '1: Post title, 2: Post type singular name',
198
  'stream'
199
  );
200
+ } elseif ( 'publish' === $new && ! in_array( $old, array( 'future', 'publish' ), true ) ) {
201
  /* translators: %1$s: a post title, %2$s: a post type singular name (e.g. "Hello World", "Post") */
202
  $summary = _x(
203
  '"%1$s" %2$s published',
256
  );
257
  }
258
 
259
+ if ( in_array( $old, $start_statuses, true ) && ! in_array( $new, $start_statuses, true ) ) {
260
  $action = 'created';
261
  }
262
 
connectors/class-connector-user-switching.php CHANGED
@@ -219,13 +219,9 @@ class Connector_User_Switching extends Connector {
219
  public function callback_switch_off_user( $old_user_id ) {
220
 
221
  $old_user = get_userdata( $old_user_id );
222
- $message = __(
223
- 'Switched off',
224
- 'stream'
225
- );
226
 
227
  $this->log(
228
- $message,
229
  array(),
230
  $old_user->ID,
231
  'sessions',
219
  public function callback_switch_off_user( $old_user_id ) {
220
 
221
  $old_user = get_userdata( $old_user_id );
 
 
 
 
222
 
223
  $this->log(
224
+ __( 'Switched off', 'stream' ),
225
  array(),
226
  $old_user->ID,
227
  'sessions',
languages/stream-en_US.po CHANGED
@@ -222,7 +222,7 @@ msgid "Records per page"
222
  msgstr ""
223
 
224
  #: classes/class-list-table.php:64
225
- msgid "Sorry, no activity records were found."
226
  msgstr ""
227
 
228
  #: classes/class-list-table.php:78
222
  msgstr ""
223
 
224
  #: classes/class-list-table.php:64
225
+ msgid "No activity records were found."
226
  msgstr ""
227
 
228
  #: classes/class-list-table.php:78
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.5.1
7
  License: GPLv2 or later
8
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -91,6 +91,15 @@ Past Contributors: fjarrett, shadyvb, chacha, westonruter, johnregan3, jacobschw
91
 
92
  == Changelog ==
93
 
 
 
 
 
 
 
 
 
 
94
  = 3.5.1 - August 14, 2020 =
95
 
96
  * Fix: Use the correct timestamp format when saving Stream records to ensure correct dates on newer versions of MySQL [#1149](https://github.com/xwp/stream/issues/1149), props [@kidunot89](https://github.com/kidunot89).
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
 
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).
97
+ * Fix: Replace the deprecated jQuery `.load()` calls [#1162](https://github.com/xwp/stream/pull/1162), props [@kidunot89](https://github.com/kidunot89).
98
+ * Fix: Log the correct post status change [#1121](https://github.com/xwp/stream/pull/1121), props [@kidunot89](https://github.com/kidunot89).
99
+ * Fix: Update the [Advanced Custom Fields](https://wordpress.org/plugins/advanced-custom-fields/) connector to support versions 5 of the plugin [#1118](https://github.com/xwp/stream/pull/1118), props [@kidunot89](https://github.com/kidunot89).
100
+ * Fix: Update the [Easy Digital Downloads](https://wordpress.org/plugins/easy-digital-downloads/) connector to support version 2.5 of the plugin [#1137](https://github.com/xwp/stream/pull/1137), props [@kidunot89](https://github.com/kidunot89).
101
+ * Tweak: Clarify the messaging when no Stream records found [#1178](https://github.com/xwp/stream/issues/1178), props [@kidunot89](https://github.com/kidunot89) and [@johnbillion](https://github.com/johnbillion).
102
+
103
  = 3.5.1 - August 14, 2020 =
104
 
105
  * Fix: Use the correct timestamp format when saving Stream records to ensure correct dates on newer versions of MySQL [#1149](https://github.com/xwp/stream/issues/1149), props [@kidunot89](https://github.com/kidunot89).
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.5.1
7
  * Author: XWP
8
  * Author URI: https://xwp.co
9
  * License: GPLv2+
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+
ui/js/admin.js CHANGED
@@ -141,7 +141,8 @@ jQuery(
141
  }
142
  );
143
 
144
- $( window ).load(
 
145
  function() {
146
  $( '.toplevel_page_wp_stream input[type="search"]' ).off( 'mousedown' );
147
  }
141
  }
142
  );
143
 
144
+ $( window ).on(
145
+ 'load',
146
  function() {
147
  $( '.toplevel_page_wp_stream input[type="search"]' ).off( 'mousedown' );
148
  }
ui/js/admin.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(m){"en"===wp_stream.locale&&void 0!==m.timeago&&(m.timeago.settings.strings.seconds="seconds",m.timeago.settings.strings.minute="a minute",m.timeago.settings.strings.hour="an hour",m.timeago.settings.strings.hours="%d hours",m.timeago.settings.strings.month="a month",m.timeago.settings.strings.year="a year"),m("li.toplevel_page_wp_stream ul li.wp-first-item.current").parent().parent().find(".update-plugins").remove(),m(".toplevel_page_wp_stream :input.chosen-select").each(function(e,t){function a(e){var t=m("<span>"),a=m(e.element),i="";return"- "===e.text.substring(0,2)&&(e.text=e.text.substring(2)),void 0!==e.id&&"string"==typeof e.id&&(0===e.id.indexOf("group-")?t.addClass("parent"):a.hasClass("level-2")&&t.addClass("child")),void 0!==e.icon?i=e.icon:void 0!==a&&""!==a.data("icon")&&(i=a.data("icon")),i&&t.html('<img src="'+i+'" class="wp-stream-select2-icon">'),t.append(e.text),t}function i(e){return"- "===e.text.substring(0,2)&&(e.text=e.text.substring(2)),e.text}var n={},n=0<m(t).find("option").not(":selected").not(":empty").length?{minimumResultsForSearch:10,templateResult:a,templateSelection:i,allowClear:!0,width:"165px"}:{minimumInputLength:3,allowClear:!0,width:"165px",ajax:{url:ajaxurl,delay:500,dataType:"json",quietMillis:100,data:function(e){return{action:"wp_stream_filters",nonce:m("#stream_filters_user_search_nonce").val(),filter:m(t).attr("name"),q:e.term}},processResults:function(e){var a=[];return m.each(e,function(e,t){a.push({id:t.id,text:t.label})}),{results:a}}},templateResult:a,templateSelection:i};m(t).select2(n)});var e=m.streamGetQueryVars(),t=m('.toplevel_page_wp_stream select.chosen-select[name="context"]');void 0!==e.context&&""!==e.context||void 0===e.connector||(t.val("group-"+e.connector),t.trigger("change")),m("input[type=submit]","#record-filter-form").click(function(){m("input[type=submit]",m(this).parents("form")).removeAttr("clicked"),m(this).attr("clicked","true")}),m("#record-filter-form").submit(function(){var e=m('.toplevel_page_wp_stream :input.chosen-select[name="context"]'),t=e.find("option:selected"),a=e.parent().find(".record-filter-connector"),i=t.data("group"),n=t.prop("class"),r=m(".recordactions select");"true"!==m("#record-actions-submit").attr("clicked")&&r.val(""),a.val(i),"level-1"===n&&t.val("")}),m(window).load(function(){m('.toplevel_page_wp_stream input[type="search"]').off("mousedown")}),m("body").on("click","#wp_stream_advanced_delete_all_records, #wp_stream_network_advanced_delete_all_records",function(e){window.confirm(wp_stream.i18n.confirm_purge)||e.preventDefault()}),m("body").on("click","#wp_stream_advanced_reset_site_settings, #wp_stream_network_advanced_reset_site_settings",function(e){window.confirm(wp_stream.i18n.confirm_defaults)||e.preventDefault()}),m("body").on("click","#wp_stream_uninstall",function(e){window.confirm(wp_stream.i18n.confirm_uninstall)||e.preventDefault()});var r=m(".wp_stream_screen .nav-tab-wrapper"),s=m(".wp_stream_screen .nav-tab-content table.form-table"),a=r.find(".nav-tab-active"),i=0<a.length?r.find("a").index(a):0,n=window.location.hash.match(/^#(\d+)$/),o=null!==n?n[1]:i;r.on("click","a",function(){var e,t,a,i=r.find("a").index(m(this)),n=window.location.hash.match(/^#(\d+)$/);return s.hide().eq(i).show(),r.find("a").removeClass("nav-tab-active").filter(m(this)).addClass("nav-tab-active"),""!==window.location.hash&&null===n||(window.location.hash=i),e=i,0!==(a=m('input[name="option_page"][value^="wp_stream"]').closest("form")).length&&(t=a.attr("action"),a.prop("action",t.replace(/(^[^#]*).*$/,"$1#"+e))),!1}),r.children().eq(o).trigger("click"),m(document).ready(function(){function t(){var e=!0;m('div.metabox-prefs [name="date-hide"]').is(":checked")&&(e=!1),m("div.alignleft.actions div.select2-container").each(function(){if(!m(this).is(":hidden"))return e=!1}),e?(m("input#record-query-submit").hide(),m("span.filter_info").show()):(m("input#record-query-submit").show(),m("span.filter_info").hide())}m("#enable_live_update").click(function(){var e,t=m("#stream_live_update_nonce").val(),a=m("#enable_live_update_user").val(),i="unchecked";m("#enable_live_update").is(":checked")&&(i="checked"),e=m("#enable_live_update").data("heartbeat"),m.ajax({type:"POST",url:ajaxurl,data:{action:"stream_enable_live_update",nonce:t,user:a,checked:i,heartbeat:e},dataType:"json",beforeSend:function(){m(".stream-live-update-checkbox .spinner").show().css({display:"inline-block"})},success:function(e){m(".stream-live-update-checkbox .spinner").hide(),!1===e.success&&(m("#enable_live_update").prop("checked",!1),e.data&&window.alert(e.data))}})}),m('div.metabox-prefs [name="date-hide"]').is(":checked")?m("div.date-interval").show():m("div.date-interval").hide(),m("div.actions select.chosen-select").each(function(){var e=m(this).prop("name");m('div.metabox-prefs [name="'+e+'-hide"]').is(":checked")?m(this).prev(".select2-container").show():m(this).prev(".select2-container").hide()}),t(),m('div.metabox-prefs [type="checkbox"]').click(function(){var e=m(this).prop("id");"date-hide"===e?m(this).is(":checked")?m("div.date-interval").show():m("div.date-interval").hide():(e=e.replace("-hide",""),m(this).is(":checked")?m('[name="'+e+'"]').prev(".select2-container").show():m('[name="'+e+'"]').prev(".select2-container").hide()),t()}),m("#ui-datepicker-div").addClass("stream-datepicker")}),m("table.wp-list-table").on("updated",function(){m(this).find("time.relative-time").each(function(e,t){var a=m(t);a.removeClass("relative-time"),m('<strong><time datetime="'+a.attr("datetime")+'" class="timeago"/></time></strong><br/>').prependTo(a.parent().parent()).find("time.timeago").timeago()})}).trigger("updated");var c={init:function(e){this.wrapper=e,this.save_interval(this.wrapper.find(".button-primary"),this.wrapper),this.$=this.wrapper.each(function(e,t){var a,i,n,r,s=m(t),o=s.find(".date-inputs"),c=s.find(".field-from"),d=s.find(".field-to"),l=d.prev(".date-remove"),p=c.prev(".date-remove"),u=s.children(".field-predefined"),h=m("").add(d).add(c);jQuery.datepicker&&(a=parseFloat(wp_stream.gmt_offset)-(new Date).getTimezoneOffset()/60*-1,i=new Date,n=new Date(i.getTime()+60*a*60*1e3),r=0,i.getDate()===n.getDate()&&i.getMonth()===n.getMonth()||(r=i.getTime()<n.getTime()?"+1d":"-1d"),h.datepicker({dateFormat:"yy/mm/dd",minDate:null,maxDate:r,defaultDate:n,beforeShow:function(){m(this).prop("disabled",!0)},onClose:function(){m(this).prop("disabled",!1)}}),h.datepicker("widget").addClass("stream-datepicker")),u.select2({allowClear:!0}),""!==c.val()&&p.show(),""!==d.val()&&l.show(),u.on({change:function(){var e=m(this).val(),t=u.find('[value="'+e+'"]'),a=t.data("to"),i=t.data("from");if("custom"===e)return o.show(),!1;o.hide(),h.datepicker("hide"),c.val(i).trigger("change",[!0]),d.val(a).trigger("change",[!0]),jQuery.datepicker&&h.datepicker("widget").is(":visible")&&h.datepicker("refresh").datepicker("hide")},"select2-removed":function(){u.val("").trigger("change")},check_options:function(){var e;""!==d.val()&&""!==c.val()?0!==(e=u.find("option").filter('[data-to="'+d.val()+'"]').filter('[data-from="'+c.val()+'"]')).length?u.val(e.attr("value")).trigger("change",[!0]):u.val("custom").trigger("change",[!0]):""===d.val()&&""===c.val()?u.val("").trigger("change",[!0]):u.val("custom").trigger("change",[!0])}}),c.on("change",function(){return""!==c.val()?(p.show(),d.datepicker("option","minDate",c.val())):p.hide(),!0!==arguments[arguments.length-1]&&void u.trigger("check_options")}),d.on("change",function(){return""!==d.val()?(l.show(),c.datepicker("option","maxDate",d.val())):l.hide(),!0!==arguments[arguments.length-1]&&void u.trigger("check_options")}),u.trigger("change"),m("").add(p).add(l).on("click",function(){m(this).next("input").val("").trigger("change")})})},save_interval:function(e){var t=this.wrapper;e.click(function(){var e={key:t.find("select.field-predefined").find(":selected").val(),start:t.find(".date-inputs .field-from").val(),end:t.find(".date-inputs .field-to").val()};m(this).attr("href",m(this).attr("href")+"&"+m.param(e))})}};m(document).ready(function(){c.init(m(".date-interval")),m('select[name="context"] .level-1').each(function(){var e=!0;m(this).nextUntil(".level-1").each(function(){if(m(this).is(":not(:disabled)"))return e=!1}),!0===e&&m(this).prop("disabled",!0)})})}),jQuery.extend({streamGetQueryVars:function(e){return(e||document.location.search).replace(/(^\?)/,"").split("&").map(function(e){return this[(e=e.split("="))[0]]=e[1],this}.bind({}))[0]}});
1
+ jQuery(function(m){"en"===wp_stream.locale&&void 0!==m.timeago&&(m.timeago.settings.strings.seconds="seconds",m.timeago.settings.strings.minute="a minute",m.timeago.settings.strings.hour="an hour",m.timeago.settings.strings.hours="%d hours",m.timeago.settings.strings.month="a month",m.timeago.settings.strings.year="a year"),m("li.toplevel_page_wp_stream ul li.wp-first-item.current").parent().parent().find(".update-plugins").remove(),m(".toplevel_page_wp_stream :input.chosen-select").each(function(e,t){function a(e){var t=m("<span>"),a=m(e.element),i="";return"- "===e.text.substring(0,2)&&(e.text=e.text.substring(2)),void 0!==e.id&&"string"==typeof e.id&&(0===e.id.indexOf("group-")?t.addClass("parent"):a.hasClass("level-2")&&t.addClass("child")),void 0!==e.icon?i=e.icon:void 0!==a&&""!==a.data("icon")&&(i=a.data("icon")),i&&t.html('<img src="'+i+'" class="wp-stream-select2-icon">'),t.append(e.text),t}function i(e){return"- "===e.text.substring(0,2)&&(e.text=e.text.substring(2)),e.text}var n={},n=0<m(t).find("option").not(":selected").not(":empty").length?{minimumResultsForSearch:10,templateResult:a,templateSelection:i,allowClear:!0,width:"165px"}:{minimumInputLength:3,allowClear:!0,width:"165px",ajax:{url:ajaxurl,delay:500,dataType:"json",quietMillis:100,data:function(e){return{action:"wp_stream_filters",nonce:m("#stream_filters_user_search_nonce").val(),filter:m(t).attr("name"),q:e.term}},processResults:function(e){var a=[];return m.each(e,function(e,t){a.push({id:t.id,text:t.label})}),{results:a}}},templateResult:a,templateSelection:i};m(t).select2(n)});var e=m.streamGetQueryVars(),t=m('.toplevel_page_wp_stream select.chosen-select[name="context"]');void 0!==e.context&&""!==e.context||void 0===e.connector||(t.val("group-"+e.connector),t.trigger("change")),m("input[type=submit]","#record-filter-form").click(function(){m("input[type=submit]",m(this).parents("form")).removeAttr("clicked"),m(this).attr("clicked","true")}),m("#record-filter-form").submit(function(){var e=m('.toplevel_page_wp_stream :input.chosen-select[name="context"]'),t=e.find("option:selected"),a=e.parent().find(".record-filter-connector"),i=t.data("group"),n=t.prop("class"),r=m(".recordactions select");"true"!==m("#record-actions-submit").attr("clicked")&&r.val(""),a.val(i),"level-1"===n&&t.val("")}),m(window).on("load",function(){m('.toplevel_page_wp_stream input[type="search"]').off("mousedown")}),m("body").on("click","#wp_stream_advanced_delete_all_records, #wp_stream_network_advanced_delete_all_records",function(e){window.confirm(wp_stream.i18n.confirm_purge)||e.preventDefault()}),m("body").on("click","#wp_stream_advanced_reset_site_settings, #wp_stream_network_advanced_reset_site_settings",function(e){window.confirm(wp_stream.i18n.confirm_defaults)||e.preventDefault()}),m("body").on("click","#wp_stream_uninstall",function(e){window.confirm(wp_stream.i18n.confirm_uninstall)||e.preventDefault()});var r=m(".wp_stream_screen .nav-tab-wrapper"),s=m(".wp_stream_screen .nav-tab-content table.form-table"),a=r.find(".nav-tab-active"),i=0<a.length?r.find("a").index(a):0,n=window.location.hash.match(/^#(\d+)$/),o=null!==n?n[1]:i;r.on("click","a",function(){var e,t,a,i=r.find("a").index(m(this)),n=window.location.hash.match(/^#(\d+)$/);return s.hide().eq(i).show(),r.find("a").removeClass("nav-tab-active").filter(m(this)).addClass("nav-tab-active"),""!==window.location.hash&&null===n||(window.location.hash=i),e=i,0!==(a=m('input[name="option_page"][value^="wp_stream"]').closest("form")).length&&(t=a.attr("action"),a.prop("action",t.replace(/(^[^#]*).*$/,"$1#"+e))),!1}),r.children().eq(o).trigger("click"),m(document).ready(function(){function t(){var e=!0;m('div.metabox-prefs [name="date-hide"]').is(":checked")&&(e=!1),m("div.alignleft.actions div.select2-container").each(function(){if(!m(this).is(":hidden"))return e=!1}),e?(m("input#record-query-submit").hide(),m("span.filter_info").show()):(m("input#record-query-submit").show(),m("span.filter_info").hide())}m("#enable_live_update").click(function(){var e,t=m("#stream_live_update_nonce").val(),a=m("#enable_live_update_user").val(),i="unchecked";m("#enable_live_update").is(":checked")&&(i="checked"),e=m("#enable_live_update").data("heartbeat"),m.ajax({type:"POST",url:ajaxurl,data:{action:"stream_enable_live_update",nonce:t,user:a,checked:i,heartbeat:e},dataType:"json",beforeSend:function(){m(".stream-live-update-checkbox .spinner").show().css({display:"inline-block"})},success:function(e){m(".stream-live-update-checkbox .spinner").hide(),!1===e.success&&(m("#enable_live_update").prop("checked",!1),e.data&&window.alert(e.data))}})}),m('div.metabox-prefs [name="date-hide"]').is(":checked")?m("div.date-interval").show():m("div.date-interval").hide(),m("div.actions select.chosen-select").each(function(){var e=m(this).prop("name");m('div.metabox-prefs [name="'+e+'-hide"]').is(":checked")?m(this).prev(".select2-container").show():m(this).prev(".select2-container").hide()}),t(),m('div.metabox-prefs [type="checkbox"]').click(function(){var e=m(this).prop("id");"date-hide"===e?m(this).is(":checked")?m("div.date-interval").show():m("div.date-interval").hide():(e=e.replace("-hide",""),m(this).is(":checked")?m('[name="'+e+'"]').prev(".select2-container").show():m('[name="'+e+'"]').prev(".select2-container").hide()),t()}),m("#ui-datepicker-div").addClass("stream-datepicker")}),m("table.wp-list-table").on("updated",function(){m(this).find("time.relative-time").each(function(e,t){var a=m(t);a.removeClass("relative-time"),m('<strong><time datetime="'+a.attr("datetime")+'" class="timeago"/></time></strong><br/>').prependTo(a.parent().parent()).find("time.timeago").timeago()})}).trigger("updated");var c={init:function(e){this.wrapper=e,this.save_interval(this.wrapper.find(".button-primary"),this.wrapper),this.$=this.wrapper.each(function(e,t){var a,i,n,r,s=m(t),o=s.find(".date-inputs"),c=s.find(".field-from"),d=s.find(".field-to"),l=d.prev(".date-remove"),p=c.prev(".date-remove"),u=s.children(".field-predefined"),h=m("").add(d).add(c);jQuery.datepicker&&(a=parseFloat(wp_stream.gmt_offset)-(new Date).getTimezoneOffset()/60*-1,i=new Date,n=new Date(i.getTime()+60*a*60*1e3),r=0,i.getDate()===n.getDate()&&i.getMonth()===n.getMonth()||(r=i.getTime()<n.getTime()?"+1d":"-1d"),h.datepicker({dateFormat:"yy/mm/dd",minDate:null,maxDate:r,defaultDate:n,beforeShow:function(){m(this).prop("disabled",!0)},onClose:function(){m(this).prop("disabled",!1)}}),h.datepicker("widget").addClass("stream-datepicker")),u.select2({allowClear:!0}),""!==c.val()&&p.show(),""!==d.val()&&l.show(),u.on({change:function(){var e=m(this).val(),t=u.find('[value="'+e+'"]'),a=t.data("to"),i=t.data("from");if("custom"===e)return o.show(),!1;o.hide(),h.datepicker("hide"),c.val(i).trigger("change",[!0]),d.val(a).trigger("change",[!0]),jQuery.datepicker&&h.datepicker("widget").is(":visible")&&h.datepicker("refresh").datepicker("hide")},"select2-removed":function(){u.val("").trigger("change")},check_options:function(){var e;""!==d.val()&&""!==c.val()?0!==(e=u.find("option").filter('[data-to="'+d.val()+'"]').filter('[data-from="'+c.val()+'"]')).length?u.val(e.attr("value")).trigger("change",[!0]):u.val("custom").trigger("change",[!0]):""===d.val()&&""===c.val()?u.val("").trigger("change",[!0]):u.val("custom").trigger("change",[!0])}}),c.on("change",function(){return""!==c.val()?(p.show(),d.datepicker("option","minDate",c.val())):p.hide(),!0!==arguments[arguments.length-1]&&void u.trigger("check_options")}),d.on("change",function(){return""!==d.val()?(l.show(),c.datepicker("option","maxDate",d.val())):l.hide(),!0!==arguments[arguments.length-1]&&void u.trigger("check_options")}),u.trigger("change"),m("").add(p).add(l).on("click",function(){m(this).next("input").val("").trigger("change")})})},save_interval:function(e){var t=this.wrapper;e.click(function(){var e={key:t.find("select.field-predefined").find(":selected").val(),start:t.find(".date-inputs .field-from").val(),end:t.find(".date-inputs .field-to").val()};m(this).attr("href",m(this).attr("href")+"&"+m.param(e))})}};m(document).ready(function(){c.init(m(".date-interval")),m('select[name="context"] .level-1').each(function(){var e=!0;m(this).nextUntil(".level-1").each(function(){if(m(this).is(":not(:disabled)"))return e=!1}),!0===e&&m(this).prop("disabled",!0)})})}),jQuery.extend({streamGetQueryVars:function(e){return(e||document.location.search).replace(/(^\?)/,"").split("&").map(function(e){return this[(e=e.split("="))[0]]=e[1],this}.bind({}))[0]}});