Simple History - Version 2.35.0

Version Description

Download this release

Release Info

Developer eskapism
Plugin Icon 128x128 Simple History
Version 2.35.0
Comparing to
See all releases

Code changes from version 2.34.0 to 2.35.0

Files changed (7) hide show
  1. code.md +2 -0
  2. composer.json +0 -1
  3. gruntfile.js +27 -27
  4. inc/SimpleHistory.php +281 -295
  5. index.php +2 -2
  6. loggers/Plugin_Redirection.php +4 -2
  7. readme.txt +13 -5
code.md CHANGED
@@ -10,6 +10,8 @@ Since I always forget what standards I use in different projects this file is he
10
  - phpcs to lint while editing. Lots of code is old but working but was written
11
  before my editor had nice linting, so much of the code does not lint. This will be fixed.
12
 
 
 
13
  ## How to use in Visual Studio Code
14
 
15
  - Run `composer install`
10
  - phpcs to lint while editing. Lots of code is old but working but was written
11
  before my editor had nice linting, so much of the code does not lint. This will be fixed.
12
 
13
+ * Changelog: try to use format from https://keepachangelog.com.
14
+
15
  ## How to use in Visual Studio Code
16
 
17
  - Run `composer install`
composer.json CHANGED
@@ -15,7 +15,6 @@
15
  "require": {
16
  "php": ">=5.2.0"
17
  },
18
- "version": "2.33.2",
19
  "authors": [
20
  {
21
  "name": "Pär Thernström",
15
  "require": {
16
  "php": ">=5.2.0"
17
  },
 
18
  "authors": [
19
  {
20
  "name": "Pär Thernström",
gruntfile.js CHANGED
@@ -1,4 +1,4 @@
1
- module.exports = function(grunt) {
2
  require("time-grunt")(grunt);
3
 
4
  // Require all grunt-tasks instead of manually initialize them.
@@ -7,13 +7,13 @@ module.exports = function(grunt) {
7
  var pkg = grunt.file.readJSON("package.json");
8
  var gig = require("gitignore-globs");
9
  var gag = require("gitattributes-globs");
10
- var ignored_gitignore = gig(".gitignore", { negate: true }).map(function(
11
  value
12
  ) {
13
  return value.replace(/^!\//, "!");
14
  });
15
  var ignored_gitattributes = gag(".gitattributes", { negate: true }).map(
16
- function(value) {
17
  return value.replace(/^!\//, "!");
18
  }
19
  );
@@ -25,25 +25,25 @@ module.exports = function(grunt) {
25
  config.version = {
26
  main: {
27
  options: {
28
- prefix: "Version:[\\s]+"
29
  },
30
- src: ["index.php"]
31
  },
32
  main2: {
33
  options: {
34
- prefix: "'SIMPLE_HISTORY_VERSION', '"
35
  },
36
- src: ["index.php"]
37
  },
38
  readme: {
39
  options: {
40
- prefix: "Stable tag:[\\s]+"
41
  },
42
- src: ["readme.txt"]
43
  },
44
  pkg: {
45
- src: ["package.json"]
46
- }
47
  };
48
 
49
  config.makepot = {
@@ -59,13 +59,13 @@ module.exports = function(grunt) {
59
  potFilename: "", // Name of the POT file.
60
  potHeaders: {
61
  poedit: true, // Includes common Poedit headers.
62
- "x-poedit-keywordslist": true // Include a list of all possible gettext functions.
63
  }, // Headers to add to the generated POT file.
64
  processPot: null, // A callback function for manipulating the POT file.
65
  type: "wp-plugin", // Type of project (wp-plugin or wp-theme).
66
- updateTimestamp: true // Whether the POT-Creation-Date should be updated without other changes.
67
- }
68
- }
69
  };
70
 
71
  config.wp_deploy = {
@@ -77,8 +77,8 @@ module.exports = function(grunt) {
77
  plugin_main_file: "index.php",
78
  build_dir: "build",
79
  assets_dir: "assets-wp-repo",
80
- svn_user: "eskapism"
81
- }
82
  },
83
  assets: {
84
  options: {
@@ -88,13 +88,13 @@ module.exports = function(grunt) {
88
  plugin_main_file: "<%= wp_deploy.deploy.options.plugin_main_file %>",
89
  build_dir: "<%= wp_deploy.deploy.options.build_dir %>",
90
  assets_dir: "<%= wp_deploy.deploy.options.assets_dir %>",
91
- svn_user: "<%= wp_deploy.deploy.options.svn_user %>"
92
- }
93
- }
94
  };
95
 
96
  config.clean = {
97
- main: ["<%= wp_deploy.deploy.options.build_dir %>"]
98
  };
99
 
100
  config.copy = {
@@ -107,24 +107,24 @@ module.exports = function(grunt) {
107
  "!<%= wp_deploy.deploy.options.build_dir %>/**",
108
  "!README.md",
109
  ignored_gitignore,
110
- ignored_gitattributes
111
  ],
112
- dest: "<%= wp_deploy.deploy.options.build_dir %>/"
113
- }
114
  };
115
 
116
  grunt.initConfig(config);
117
 
118
  // Task(s) to run. Default is default.
119
  grunt.registerTask("makepot", "Make .POT-files for languages/translation.", [
120
- "makepot"
121
  ]);
122
 
123
  grunt.registerTask("build", "Clean and copy", ["clean", "copy"]);
124
 
125
  grunt.registerTask("deploy", "Deploy plugin to WordPress plugin repository", [
126
  "build",
127
- "wp_deploy:deploy"
128
  ]);
129
 
130
  grunt.registerTask(
@@ -136,7 +136,7 @@ module.exports = function(grunt) {
136
  grunt.registerTask(
137
  "bump",
138
  "Bump version in major, minor, patch or custom steps.",
139
- function(version) {
140
  if (!version) {
141
  grunt.fail.fatal(
142
  "No version specified. Usage: bump:major, bump:minor, bump:patch, bump:x.y.z"
1
+ module.exports = function (grunt) {
2
  require("time-grunt")(grunt);
3
 
4
  // Require all grunt-tasks instead of manually initialize them.
7
  var pkg = grunt.file.readJSON("package.json");
8
  var gig = require("gitignore-globs");
9
  var gag = require("gitattributes-globs");
10
+ var ignored_gitignore = gig(".gitignore", { negate: true }).map(function (
11
  value
12
  ) {
13
  return value.replace(/^!\//, "!");
14
  });
15
  var ignored_gitattributes = gag(".gitattributes", { negate: true }).map(
16
+ function (value) {
17
  return value.replace(/^!\//, "!");
18
  }
19
  );
25
  config.version = {
26
  main: {
27
  options: {
28
+ prefix: "Version:[\\s]+",
29
  },
30
+ src: ["index.php"],
31
  },
32
  main2: {
33
  options: {
34
+ prefix: "'SIMPLE_HISTORY_VERSION', '",
35
  },
36
+ src: ["index.php"],
37
  },
38
  readme: {
39
  options: {
40
+ prefix: "Stable tag:[\\s]+",
41
  },
42
+ src: ["readme.txt"],
43
  },
44
  pkg: {
45
+ src: ["package.json"],
46
+ },
47
  };
48
 
49
  config.makepot = {
59
  potFilename: "", // Name of the POT file.
60
  potHeaders: {
61
  poedit: true, // Includes common Poedit headers.
62
+ "x-poedit-keywordslist": true, // Include a list of all possible gettext functions.
63
  }, // Headers to add to the generated POT file.
64
  processPot: null, // A callback function for manipulating the POT file.
65
  type: "wp-plugin", // Type of project (wp-plugin or wp-theme).
66
+ updateTimestamp: true, // Whether the POT-Creation-Date should be updated without other changes.
67
+ },
68
+ },
69
  };
70
 
71
  config.wp_deploy = {
77
  plugin_main_file: "index.php",
78
  build_dir: "build",
79
  assets_dir: "assets-wp-repo",
80
+ svn_user: "eskapism",
81
+ },
82
  },
83
  assets: {
84
  options: {
88
  plugin_main_file: "<%= wp_deploy.deploy.options.plugin_main_file %>",
89
  build_dir: "<%= wp_deploy.deploy.options.build_dir %>",
90
  assets_dir: "<%= wp_deploy.deploy.options.assets_dir %>",
91
+ svn_user: "<%= wp_deploy.deploy.options.svn_user %>",
92
+ },
93
+ },
94
  };
95
 
96
  config.clean = {
97
+ main: ["<%= wp_deploy.deploy.options.build_dir %>"],
98
  };
99
 
100
  config.copy = {
107
  "!<%= wp_deploy.deploy.options.build_dir %>/**",
108
  "!README.md",
109
  ignored_gitignore,
110
+ ignored_gitattributes,
111
  ],
112
+ dest: "<%= wp_deploy.deploy.options.build_dir %>/",
113
+ },
114
  };
115
 
116
  grunt.initConfig(config);
117
 
118
  // Task(s) to run. Default is default.
119
  grunt.registerTask("makepot", "Make .POT-files for languages/translation.", [
120
+ "makepot",
121
  ]);
122
 
123
  grunt.registerTask("build", "Clean and copy", ["clean", "copy"]);
124
 
125
  grunt.registerTask("deploy", "Deploy plugin to WordPress plugin repository", [
126
  "build",
127
+ "wp_deploy:deploy",
128
  ]);
129
 
130
  grunt.registerTask(
136
  grunt.registerTask(
137
  "bump",
138
  "Bump version in major, minor, patch or custom steps.",
139
+ function (version) {
140
  if (!version) {
141
  grunt.fail.fatal(
142
  "No version specified. Usage: bump:major, bump:minor, bump:patch, bump:x.y.z"
inc/SimpleHistory.php CHANGED
@@ -50,12 +50,12 @@ class SimpleHistory
50
  * Required to automagically determine orginal text and text domain
51
  * for calls like this `SimpleLogger()->log( __("My translated message") );`
52
  */
53
- public $gettextLatestTranslations = array();
54
 
55
  /**
56
  * All registered settings tabs
57
  */
58
- private $arr_settings_tabs = array();
59
 
60
  const DBTABLE = 'simple_history';
61
  const DBTABLE_CONTEXTS = 'simple_history_contexts';
@@ -91,30 +91,30 @@ class SimpleHistory
91
  $this->setup_variables();
92
 
93
  // Actions and filters, ordered by order specified in codex: http://codex.wordpress.org/Plugin_API/Action_Reference
94
- add_action('after_setup_theme', array( $this, 'load_plugin_textdomain' ));
95
- add_action('after_setup_theme', array( $this, 'add_default_settings_tabs' ));
96
 
97
  // Plugins and dropins are loaded using the "after_setup_theme" filter so
98
  // themes can use filters to modify the loading of them.
99
  // The drawback with this is that for example logouts done when plugins like
100
  // iThemes Security is installed is not logged, because those plugins fire wp_logout()
101
  // using filter "plugins_loaded", i.e. before simple history has loaded its filters.
102
- add_action('after_setup_theme', array( $this, 'load_loggers' ));
103
- add_action('after_setup_theme', array( $this, 'load_dropins' ));
104
 
105
  // Run before loading of loggers and before menu items are added.
106
- add_action('after_setup_theme', array( $this, 'check_for_upgrade' ), 5);
107
 
108
- add_action('after_setup_theme', array( $this, 'setup_cron' ));
109
 
110
  // Filters and actions not called during regular boot.
111
- add_filter('gettext', array( $this, 'filter_gettext' ), 20, 3);
112
- add_filter('gettext_with_context', array( $this, 'filter_gettext_with_context' ), 20, 4);
113
 
114
- add_filter('gettext', array( $this, 'filter_gettext_storeLatestTranslations' ), 10, 3);
115
 
116
- add_action('admin_bar_menu', array( $this, 'add_admin_bar_network_menu_item' ), 40);
117
- add_action('admin_bar_menu', array( $this, 'add_admin_bar_menu_item' ), 40);
118
 
119
  /**
120
  * Filter that is used to log things, without the need to check that simple history is available
@@ -129,7 +129,7 @@ class SimpleHistory
129
  *
130
  * @since 2.13
131
  */
132
- add_filter('simple_history_log', array( $this, 'on_filter_simple_history_log' ), 10, 3);
133
 
134
  /**
135
  * Filter to log with specific log level, for example:
@@ -138,14 +138,14 @@ class SimpleHistory
138
  *
139
  * @since 2.17
140
  */
141
- add_filter('simple_history_log_emergency', array( $this, 'on_filter_simple_history_log_emergency' ), 10, 3);
142
- add_filter('simple_history_log_alert', array( $this, 'on_filter_simple_history_log_alert' ), 10, 2);
143
- add_filter('simple_history_log_critical', array( $this, 'on_filter_simple_history_log_critical' ), 10, 2);
144
- add_filter('simple_history_log_error', array( $this, 'on_filter_simple_history_log_error' ), 10, 2);
145
- add_filter('simple_history_log_warning', array( $this, 'on_filter_simple_history_log_warning' ), 10, 2);
146
- add_filter('simple_history_log_notice', array( $this, 'on_filter_simple_history_log_notice' ), 10, 2);
147
- add_filter('simple_history_log_info', array( $this, 'on_filter_simple_history_log_info' ), 10, 2);
148
- add_filter('simple_history_log_debug', array( $this, 'on_filter_simple_history_log_debug' ), 10, 2);
149
 
150
  if (is_admin()) {
151
  $this->add_admin_actions();
@@ -269,24 +269,24 @@ class SimpleHistory
269
  */
270
  private function add_admin_actions()
271
  {
272
- add_action('admin_menu', array( $this, 'add_admin_pages' ));
273
- add_action('admin_menu', array( $this, 'add_settings' ));
274
 
275
- add_action('admin_footer', array( $this, 'add_js_templates' ));
276
 
277
- add_action('wp_dashboard_setup', array( $this, 'add_dashboard_widget' ));
278
 
279
- add_action('admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ));
280
 
281
- add_action('admin_head', array( $this, 'onAdminHead' ));
282
- add_action('admin_footer', array( $this, 'onAdminFooter' ));
283
 
284
- add_action('simple_history/history_page/before_gui', array( $this, 'output_quick_stats' ));
285
- add_action('simple_history/dashboard/before_gui', array( $this, 'output_quick_stats' ));
286
 
287
- add_action('wp_ajax_simple_history_api', array( $this, 'api' ));
288
 
289
- add_filter('plugin_action_links_simple-history/index.php', array( $this, 'plugin_action_links' ), 10, 4);
290
  }
291
 
292
  /**
@@ -307,27 +307,27 @@ class SimpleHistory
307
  */
308
  $add_items = apply_filters('simple_history/add_admin_bar_network_menu_item', true);
309
 
310
- if (! $add_items) {
311
  return;
312
  }
313
 
314
  // Don't show for logged out users or single site mode.
315
- if (! is_user_logged_in() || ! is_multisite()) {
316
  return;
317
  }
318
 
319
  // Show only when the user has at least one site, or they're a super admin.
320
- if (count($wp_admin_bar->user->blogs) < 1 && ! is_super_admin()) {
321
  return;
322
  }
323
 
324
  // Setting to show as page must be true
325
- if (! $this->setting_show_as_page()) {
326
  return;
327
  }
328
 
329
  // User must have capability to view the history page
330
- if (! current_user_can($this->get_view_history_capability())) {
331
  return;
332
  }
333
 
@@ -341,20 +341,22 @@ class SimpleHistory
341
 
342
  if (is_plugin_active(SIMPLE_HISTORY_BASENAME)) {
343
  $menu_id = 'simple-history-blog-' . $blog->userblog_id;
344
- $parent_menu_id = 'blog-' . $blog->userblog_id;
345
- $url = admin_url(apply_filters('simple_history/admin_location', 'index') . '.php?page=simple_history_page');
 
 
346
 
347
  // Each network site is added by WP core with id "blog-1", "blog-2" ... "blog-n"
348
  // https://codex.wordpress.org/Function_Reference/add_node
349
- $args = array(
350
- 'id' => $menu_id,
351
  'parent' => $parent_menu_id,
352
  'title' => _x('View History', 'Admin bar network name', 'simple-history'),
353
- 'href' => $url,
354
- 'meta' => array(
355
- 'class' => 'ab-item--simplehistory'
356
- )
357
- );
358
 
359
  $wp_admin_bar->add_node($args);
360
  } // End if().
@@ -381,22 +383,22 @@ class SimpleHistory
381
  */
382
  $add_item = apply_filters('simple_history/add_admin_bar_menu_item', true);
383
 
384
- if (! $add_item) {
385
  return;
386
  }
387
 
388
  // Don't show for logged out users
389
- if (! is_user_logged_in()) {
390
  return;
391
  }
392
 
393
  // Setting to show as page must be true
394
- if (! $this->setting_show_as_page()) {
395
  return;
396
  }
397
 
398
  // User must have capability to view the history page
399
- if (! current_user_can($this->get_view_history_capability())) {
400
  return;
401
  }
402
 
@@ -404,18 +406,18 @@ class SimpleHistory
404
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
405
 
406
  $menu_id = 'simple-history-view-history';
407
- $parent_menu_id = 'site-name';
408
  $url = admin_url(apply_filters('simple_history/admin_location', 'index') . '.php?page=simple_history_page');
409
 
410
- $args = array(
411
- 'id' => $menu_id,
412
  'parent' => $parent_menu_id,
413
  'title' => _x('Simple History', 'Admin bar name', 'simple-history'),
414
- 'href' => $url,
415
- 'meta' => array(
416
- 'class' => 'ab-item--simplehistory'
417
- )
418
- );
419
 
420
  $wp_admin_bar->add_node($args);
421
  } // func
@@ -427,7 +429,7 @@ class SimpleHistory
427
  */
428
  public static function get_instance()
429
  {
430
- if (! isset(self::$instance)) {
431
  self::$instance = new SimpleHistory();
432
  }
433
 
@@ -437,7 +439,7 @@ class SimpleHistory
437
  public function filter_gettext_storeLatestTranslations($translation, $text, $domain)
438
  {
439
  // Check that translation is a string or integer, i.ex. the valid values for an array key
440
- if (! is_string($translation) || ! is_integer($translation)) {
441
  return $translation;
442
  }
443
 
@@ -449,11 +451,11 @@ class SimpleHistory
449
  // global $sh_latest_translations;
450
  $sh_latest_translations = $this->gettextLatestTranslations;
451
 
452
- $sh_latest_translations[ $translation ] = array(
453
  'translation' => $translation,
454
  'text' => $text,
455
- 'domain' => $domain
456
- );
457
 
458
  $arr_length = sizeof($sh_latest_translations);
459
  if ($arr_length > $array_max_size) {
@@ -467,9 +469,9 @@ class SimpleHistory
467
 
468
  public function setup_cron()
469
  {
470
- add_filter('simple_history/maybe_purge_db', array( $this, 'maybe_purge_db' ));
471
 
472
- if (! wp_next_scheduled('simple_history/maybe_purge_db')) {
473
  wp_schedule_event(time(), 'daily', 'simple_history/maybe_purge_db');
474
  } else {
475
  }
@@ -570,7 +572,9 @@ class SimpleHistory
570
  <div class="SimpleHistory-modal__background"></div>
571
  <div class="SimpleHistory-modal__content">
572
  <div class="SimpleHistory-modal__contentInner">
573
- <img class="SimpleHistory-modal__contentSpinner" src="<?php echo esc_url(admin_url('/images/spinner.gif')); ?>" alt="">
 
 
574
  </div>
575
  <div class="SimpleHistory-modal__contentClose">
576
  <button class="button">✕</button>
@@ -590,27 +594,17 @@ class SimpleHistory
590
  <div class="SimpleHistoryLogitem__secondcol">
591
  <div class="SimpleHistoryLogitem__text">
592
  <?php _e('Sorry, but there are too many similar events to show.', 'simple-history'); ?>
593
- <!-- <br>occasionsCount: {{ data.occasionsCount }}
594
- <br>occasionsCountMaxReturn: {{ data.occasionsCountMaxReturn }}
595
- <br>diff: {{ data.occasionsCount - data.occasionsCountMaxReturn }}
596
- Suggestions:
597
- <ul>
598
- <li>- dig into database directly
599
- <li>- Export
600
- </ul>
601
- -->
602
  </div>
603
  </div>
604
  </li>
605
  </script>
606
 
607
- <?php // Call plugins so they can add their js
608
  foreach ($this->instantiatedLoggers as $one_logger) {
609
  if (method_exists($one_logger['instance'], 'adminJS')) {
610
  $one_logger['instance']->adminJS();
611
  }
612
- }
613
- }// End if().
614
  }
615
 
616
  /**
@@ -633,24 +627,24 @@ class SimpleHistory
633
  // Type = overview | ...
634
  $type = isset($_GET['type']) ? $_GET['type'] : null;
635
 
636
- if (empty($args) || ! $type) {
637
- wp_send_json_error(array(
638
- _x('Not enough args specified', 'API: not enought arguments passed', 'simple-history')
639
- ));
640
  }
641
 
642
  // User must have capability to view the history page
643
- if (! current_user_can($this->get_view_history_capability())) {
644
- wp_send_json_error(array(
645
- 'error' => 'CAPABILITY_ERROR'
646
- ));
647
  }
648
 
649
  if (isset($args['id'])) {
650
- $args['post__in'] = array($args['id']);
651
  }
652
 
653
- $data = array();
654
 
655
  switch ($type) {
656
  case 'overview':
@@ -664,15 +658,15 @@ class SimpleHistory
664
 
665
  // Output can be array or HMTL
666
  if (isset($args['format']) && 'html' === $args['format']) {
667
- $data['log_rows_raw'] = array();
668
 
669
  foreach ($data['log_rows'] as $key => $oneLogRow) {
670
- $args = array();
671
  if ($type == 'single') {
672
  $args['type'] = 'single';
673
  }
674
 
675
- $data['log_rows'][ $key ] = $this->getLogRowHTMLOutput($oneLogRow, $args);
676
  $data['num_queries'] = get_num_queries();
677
  }
678
  } else {
@@ -683,7 +677,7 @@ class SimpleHistory
683
 
684
  default:
685
  $data[] = 'Nah.';
686
- }// End switch().
687
 
688
  wp_send_json_success($data);
689
  }
@@ -696,12 +690,12 @@ class SimpleHistory
696
  public function filter_gettext($translated_text, $untranslated_text, $domain)
697
  {
698
  if (isset($this->doFilterGettext) && $this->doFilterGettext) {
699
- $this->doFilterGettext_currentLogger->messages[] = array(
700
  'untranslated_text' => $untranslated_text,
701
  'translated_text' => $translated_text,
702
  'domain' => $domain,
703
- 'context' => null
704
- );
705
  }
706
 
707
  return $translated_text;
@@ -713,12 +707,12 @@ class SimpleHistory
713
  public function filter_gettext_with_context($translated_text, $untranslated_text, $context, $domain)
714
  {
715
  if (isset($this->doFilterGettext) && $this->doFilterGettext) {
716
- $this->doFilterGettext_currentLogger->messages[] = array(
717
  'untranslated_text' => $untranslated_text,
718
  'translated_text' => $translated_text,
719
  'domain' => $domain,
720
- 'context' => $context
721
- );
722
  }
723
 
724
  return $translated_text;
@@ -746,10 +740,10 @@ class SimpleHistory
746
  */
747
  public function setup_variables()
748
  {
749
- $this->externalLoggers = array();
750
- $this->externalDropins = array();
751
- $this->instantiatedLoggers = array();
752
- $this->instantiatedDropins = array();
753
 
754
  $this->plugin_basename = SIMPLE_HISTORY_BASENAME;
755
  }
@@ -803,27 +797,27 @@ class SimpleHistory
803
  public function add_default_settings_tabs()
804
  {
805
  // Add default settings tabs
806
- $this->arr_settings_tabs = array(
807
- array(
808
  'slug' => 'settings',
809
  'name' => __('Settings', 'simple-history'),
810
- 'function' => array($this, 'settings_output_general')
811
- )
812
- );
813
 
814
  if (defined('SIMPLE_HISTORY_DEV') && SIMPLE_HISTORY_DEV) {
815
- $arr_dev_tabs = array(
816
- array(
817
  'slug' => 'log',
818
  'name' => __('Log (debug)', 'simple-history'),
819
- 'function' => array($this, 'settings_output_log')
820
- ),
821
- array(
822
  'slug' => 'styles-example',
823
  'name' => __('Styles example (debug)', 'simple-history'),
824
- 'function' => array($this, 'settings_output_styles_example')
825
- )
826
- );
827
 
828
  $this->arr_settings_tabs = array_merge($this->arr_settings_tabs, $arr_dev_tabs);
829
  }
@@ -863,7 +857,7 @@ class SimpleHistory
863
  {
864
  $loggersDir = SIMPLE_HISTORY_PATH . 'loggers/';
865
 
866
- $loggersFiles = array(
867
  // Main loggers.
868
  $loggersDir . 'SimpleCommentsLogger.php',
869
  $loggersDir . 'SimpleCoreUpdatesLogger.php',
@@ -892,8 +886,8 @@ class SimpleHistory
892
  $loggersDir . 'Plugin_Redirection.php',
893
  $loggersDir . 'Plugin_DuplicatePost.php',
894
  $loggersDir . 'Plugin_ACF.php',
895
- $loggersDir . 'Plugin_BeaverBuilder.php'
896
- );
897
 
898
  // SimpleLogger.php must be loaded first and always since the other loggers extend it.
899
  // Include it manually so no risk of anyone using filters or similar disables it.
@@ -913,7 +907,7 @@ class SimpleHistory
913
 
914
  // Array with slug of loggers to instantiate.
915
  // Slug of logger must also be the name of the logger class.
916
- $arr_loggers_to_instantiate = array();
917
 
918
  // $one_logger_file = "SimpleCommentsLogger.php", "class-privacy-logger.php", and so on.
919
  foreach ($loggersFiles as $one_logger_file) {
@@ -939,7 +933,7 @@ class SimpleHistory
939
  $load_logger = true;
940
  }
941
 
942
- if (! $load_logger) {
943
  continue;
944
  }
945
 
@@ -967,8 +961,8 @@ class SimpleHistory
967
  * (
968
  * [0] => SimpleCommentsLogger
969
  * [1] => SimpleCoreUpdatesLogger
970
- * ...
971
- * )
972
  *
973
  * @since 2.0
974
  *
@@ -1000,14 +994,14 @@ class SimpleHistory
1000
  }
1001
 
1002
  // Continue to load next logger if no valid logger class found.
1003
- if (! $logger_class_name) {
1004
  continue;
1005
  }
1006
 
1007
  // Init found logger class.
1008
  $logger_instance = new $logger_class_name($this);
1009
 
1010
- if (! is_subclass_of($logger_instance, 'SimpleLogger') && ! is_a($logger_instance, 'SimpleLogger')) {
1011
  continue;
1012
  }
1013
 
@@ -1022,7 +1016,7 @@ class SimpleHistory
1022
  // Check so no logger has a logger slug with more than 30 chars,
1023
  // because db column is only 30 chars.
1024
  if (strlen($logger_instance->slug) > 30) {
1025
- add_action('admin_notices', array( $this, 'admin_notice_logger_slug_to_long' ));
1026
  }
1027
 
1028
  // Un-tell gettext filter.
@@ -1033,14 +1027,14 @@ class SimpleHistory
1033
  // Add messages to the loggerInstance.
1034
  $loopNum = 0;
1035
 
1036
- $arr_messages_by_message_key = array();
1037
 
1038
  if (isset($logger_info['messages']) && is_array($logger_info['messages'])) {
1039
  foreach ((array) $logger_info['messages'] as $message_key => $message_translated) {
1040
  // Find message in array with both translated and non translated strings.
1041
  foreach ($logger_instance->messages as $one_message_with_translation_info) {
1042
  if ($message_translated == $one_message_with_translation_info['translated_text']) {
1043
- $arr_messages_by_message_key[ $message_key ] = $one_message_with_translation_info;
1044
  continue;
1045
  }
1046
  }
@@ -1050,11 +1044,11 @@ class SimpleHistory
1050
  $logger_instance->messages = $arr_messages_by_message_key;
1051
 
1052
  // Add logger to array of loggers.
1053
- $this->instantiatedLoggers[ $logger_instance->slug ] = array(
1054
  'name' => $logger_info['name'],
1055
- 'instance' => $logger_instance
1056
- );
1057
- }// End foreach().
1058
 
1059
  do_action('simple_history/loggers_loaded');
1060
  }
@@ -1067,7 +1061,7 @@ class SimpleHistory
1067
  {
1068
  $dropinsDir = SIMPLE_HISTORY_PATH . 'dropins/';
1069
 
1070
- $dropinsFiles = array(
1071
  $dropinsDir . 'SimpleHistoryPluginPatchesDropin.php',
1072
  $dropinsDir . 'SimpleHistoryDonateDropin.php',
1073
  $dropinsDir . 'SimpleHistoryExportDropin.php',
@@ -1083,7 +1077,7 @@ class SimpleHistory
1083
  $dropinsDir . 'SimpleHistorySidebarSettings.php',
1084
  $dropinsDir . 'SimpleHistoryWPCLIDropin.php',
1085
  $dropinsDir . 'SimpleHistoryDebugDropin.php',
1086
- );
1087
 
1088
  /**
1089
  * Filter the array with absolute paths to files as returned by glob function.
@@ -1096,7 +1090,7 @@ class SimpleHistory
1096
  */
1097
  $dropinsFiles = apply_filters('simple_history/dropins_files', $dropinsFiles);
1098
 
1099
- $arrDropinsToInstantiate = array();
1100
 
1101
  foreach ($dropinsFiles as $oneDropinFile) {
1102
  // path/path/simplehistory/dropins/SimpleHistoryDonateDropin.php => SimpleHistoryDonateDropin
@@ -1125,14 +1119,14 @@ class SimpleHistory
1125
  */
1126
  $load_dropin = apply_filters('simple_history/dropin/load_dropin', $load_dropin, $oneDropinFileBasename);
1127
 
1128
- if (! $load_dropin) {
1129
  continue;
1130
  }
1131
 
1132
  include_once $oneDropinFile;
1133
 
1134
  $arrDropinsToInstantiate[] = $oneDropinFileBasename;
1135
- }// End foreach().
1136
 
1137
  /**
1138
  * Action that dropins can use to add their custom loggers.
@@ -1157,14 +1151,14 @@ class SimpleHistory
1157
 
1158
  // Instantiate each dropin
1159
  foreach ($arrDropinsToInstantiate as $oneDropinName) {
1160
- if (! class_exists($oneDropinName)) {
1161
  continue;
1162
  }
1163
 
1164
- $this->instantiatedDropins[ $oneDropinName ] = array(
1165
  'name' => $oneDropinName,
1166
- 'instance' => new $oneDropinName($this)
1167
- );
1168
  }
1169
  }
1170
 
@@ -1219,7 +1213,7 @@ class SimpleHistory
1219
  public function plugin_action_links($actions, $b, $c, $d)
1220
  {
1221
  // Only add link if user has the right to view the settings page
1222
- if (! current_user_can($this->get_view_settings_capability())) {
1223
  return $actions;
1224
  }
1225
 
@@ -1227,10 +1221,10 @@ class SimpleHistory
1227
 
1228
  if (empty($actions)) {
1229
  // Create array if actions is empty (and therefore is assumed to be a string by PHP & results in PHP 7.1+ fatal error due to trying to make array modifications on what's assumed to be a string)
1230
- $actions = array();
1231
  } elseif (is_string($actions)) {
1232
  // Convert the string (which it might've been retrieved as) to an array for future use as an array
1233
- $actions = array( $actions );
1234
  }
1235
  $actions[] = "<a href='$settings_page_url'>" . __('Settings', 'simple-history') . '</a>';
1236
 
@@ -1255,11 +1249,10 @@ class SimpleHistory
1255
  $show_dashboard_widget = apply_filters('simple_history/show_dashboard_widget', true);
1256
 
1257
  if ($show_dashboard_widget) {
1258
- wp_add_dashboard_widget(
1259
- 'simple_history_dashboard_widget',
1260
- __('Simple History', 'simple-history'),
1261
- array($this, 'dashboard_widget_output')
1262
- );
1263
  }
1264
  }
1265
  }
@@ -1293,13 +1286,17 @@ class SimpleHistory
1293
  $current_screen = get_current_screen();
1294
 
1295
  $basePrefix = apply_filters('simple_history/admin_location', 'index');
1296
- $basePrefix = ( $basePrefix === 'index' ) ? 'dashboard' : $basePrefix;
1297
 
1298
  if ($current_screen && $current_screen->base == 'settings_page_' . SimpleHistory::SETTINGS_MENU_SLUG) {
1299
  return true;
1300
- } elseif ($current_screen && $current_screen->base == $basePrefix. '_page_simple_history_page') {
1301
  return true;
1302
- } elseif (( $hook == 'settings_page_' . SimpleHistory::SETTINGS_MENU_SLUG ) || ( $this->setting_show_on_dashboard() && $hook == 'index.php' ) || ( $this->setting_show_as_page() && $hook == $basePrefix . '_page_simple_history_page' )) {
 
 
 
 
1303
  return true;
1304
  } elseif ($current_screen && $current_screen->base == 'dashboard' && $this->setting_show_on_dashboard()) {
1305
  return true;
@@ -1327,31 +1324,31 @@ class SimpleHistory
1327
  wp_enqueue_script(
1328
  'simple_history_script',
1329
  SIMPLE_HISTORY_DIR_URL . 'js/scripts.js',
1330
- array('jquery', 'backbone', 'wp-util'),
1331
  SIMPLE_HISTORY_VERSION,
1332
  true
1333
  );
1334
 
1335
- wp_enqueue_script('select2', SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.full.min.js', array( 'jquery' ));
1336
  wp_enqueue_style('select2', SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.min.css');
1337
 
1338
  // Translations that we use in JavaScript
1339
- wp_localize_script('simple_history_script', 'simple_history_script_vars', array(
1340
- 'settingsConfirmClearLog' => __('Remove all log items?', 'simple-history'),
1341
- 'pagination' => array(
1342
- 'goToTheFirstPage' => __('Go to the first page', 'simple-history'),
1343
- 'goToThePrevPage' => __('Go to the previous page', 'simple-history'),
1344
- 'goToTheNextPage' => __('Go to the next page', 'simple-history'),
1345
- 'goToTheLastPage' => __('Go to the last page', 'simple-history'),
1346
- 'currentPage' => __('Current page', 'simple-history')
1347
- ),
1348
- 'loadLogAPIError' => __('Oups, the log could not be loaded right now.', 'simple-history'),
1349
  'ajaxLoadError' => __(
1350
  'Hm, the log could not be loaded right now. Perhaps another plugin is giving some errors. Anyway, below is the output I got from the server.',
1351
  'simple-history'
1352
  ),
1353
- 'logNoHits' => __('Your search did not match any history events.', 'simple-history')
1354
- ));
1355
 
1356
  // Call plugins adminCSS-method, so they can add their CSS
1357
  foreach ($this->instantiatedLoggers as $one_logger) {
@@ -1364,21 +1361,21 @@ class SimpleHistory
1364
  wp_enqueue_script(
1365
  'timeago',
1366
  SIMPLE_HISTORY_DIR_URL . 'js/timeago/jquery.timeago.js',
1367
- array('jquery'),
1368
  '1.5.2',
1369
  true
1370
  );
1371
 
1372
  // Determine current locale to load timeago locale
1373
- $locale = strtolower(substr(get_locale(), 0, 2));
1374
  $locale_url_path = SIMPLE_HISTORY_DIR_URL . 'js/timeago/locales/jquery.timeago.%s.js';
1375
  $locale_dir_path = SIMPLE_HISTORY_PATH . 'js/timeago/locales/jquery.timeago.%s.js';
1376
 
1377
  // Only enqueue if locale-file exists on file system
1378
  if (file_exists(sprintf($locale_dir_path, $locale))) {
1379
- wp_enqueue_script('timeago-locale', sprintf($locale_url_path, $locale), array( 'jquery' ), '1.5.2', true);
1380
  } else {
1381
- wp_enqueue_script('timeago-locale', sprintf($locale_url_path, 'en'), array( 'jquery' ), '1.5.2', true);
1382
  }
1383
  // end add timeago
1384
  // Load Select2 locale
@@ -1386,7 +1383,7 @@ class SimpleHistory
1386
  $locale_dir_path = SIMPLE_HISTORY_PATH . 'js/select2/i18n/%s.js';
1387
 
1388
  if (file_exists(sprintf($locale_dir_path, $locale))) {
1389
- wp_enqueue_script('select2-locale', sprintf($locale_url_path, $locale), array( 'jquery' ), '3.5.1', true);
1390
  }
1391
 
1392
  /**
@@ -1398,7 +1395,7 @@ class SimpleHistory
1398
  * @param SimpleHistory $SimpleHistory This class.
1399
  */
1400
  do_action('simple_history/enqueue_admin_scripts', $this);
1401
- }// End if().
1402
  }
1403
 
1404
  public function filter_option_page_capability($capability)
@@ -1467,19 +1464,19 @@ class SimpleHistory
1467
 
1468
  // Check that all options we use are set to their defaults, if they miss value
1469
  // Each option that is missing a value will make a sql call otherwise = unnecessary
1470
- $arr_options = array(
1471
- array(
1472
  'name' => 'simple_history_show_as_page',
1473
- 'default_value' => 1
1474
- ),
1475
- array(
1476
  'name' => 'simple_history_show_on_dashboard',
1477
- 'default_value' => 1
1478
- )
1479
- );
1480
 
1481
  foreach ($arr_options as $one_option) {
1482
- if (false === ( $option_value = get_option($one_option['name']) )) {
1483
  // Value is not set in db, so set it to a default
1484
  update_option($one_option['name'], $one_option['default_value']);
1485
  }
@@ -1547,7 +1544,7 @@ class SimpleHistory
1547
 
1548
  // Say welcome, however loggers are not added this early so we need to
1549
  // use a filter to load it later
1550
- add_action('simple_history/loggers_loaded', array( $this, 'addWelcomeLogMessage' ));
1551
  } // End if().
1552
 
1553
  /**
@@ -1590,7 +1587,7 @@ class SimpleHistory
1590
  // Some installs on 2.2.2 got failed installs
1591
  // We detect these by checking for db_version and then running the install stuff again
1592
  if (4 == intval($db_version)) {
1593
- if (! $this->does_database_have_data()) {
1594
  // not ok, decrease db number so installs will run again and hopefully fix things
1595
  $db_version = 0;
1596
  } else {
@@ -1635,25 +1632,25 @@ class SimpleHistory
1635
  $pluginLogger = $this->getInstantiatedLoggerBySlug('SimplePluginLogger');
1636
  if ($pluginLogger) {
1637
  // Add plugin installed message
1638
- $context = array(
1639
  'plugin_name' => 'Simple History',
1640
  'plugin_description' =>
1641
  'Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.',
1642
- 'plugin_url' => 'http://simple-history.com',
1643
  'plugin_version' => SIMPLE_HISTORY_VERSION,
1644
- 'plugin_author' => 'Pär Thernström'
1645
- );
1646
 
1647
  $pluginLogger->infoMessage('plugin_installed', $context);
1648
 
1649
  // Add plugin activated message
1650
  $context['plugin_slug'] = 'simple-history';
1651
- $context['plugin_title'] = '<a href="http://simple-history.com/">Simple History</a>';
1652
 
1653
  $pluginLogger->infoMessage('plugin_activated', $context);
1654
  }
1655
 
1656
- if (! $db_data_exists) {
1657
  $welcome_message_1 = __(
1658
  '
1659
  Welcome to Simple History!
@@ -1665,18 +1662,18 @@ This is the main history feed. It will contain events that this plugin has logge
1665
 
1666
  $welcome_message_2 = __(
1667
  '
1668
- Because Simple History was just recently installed, this feed does not contain much events yet. But keep the plugin activated and soon you will see detailed information about page edits, plugin updates, user logins, and much more.
1669
  ',
1670
  'simple-history'
1671
  );
1672
 
1673
- SimpleLogger()->info($welcome_message_2, array(
1674
- '_initiator' => SimpleLoggerLogInitiators::WORDPRESS
1675
- ));
1676
 
1677
- SimpleLogger()->info($welcome_message_1, array(
1678
- '_initiator' => SimpleLoggerLogInitiators::WORDPRESS
1679
- ));
1680
  }
1681
  }
1682
 
@@ -1718,26 +1715,26 @@ Because Simple History was just recently installed, this feed does not contain m
1718
  $one_tab['name'], // 1
1719
  $tab_slug, // 2
1720
  esc_url(add_query_arg('selected-tab', $tab_slug, $settings_base_url)), // 3
1721
- $active_tab == $tab_slug ? 'nav-tab-active' : ''// 4
1722
  );
1723
  } ?>
1724
  </h2>
1725
 
1726
  <?php
1727
  // Output contents for selected tab
1728
- $arr_active_tab = wp_filter_object_list($arr_settings_tabs, array(
1729
- 'slug' => $active_tab
1730
- ));
1731
  $arr_active_tab = current($arr_active_tab);
1732
 
1733
  // We must have found an active tab and it must have a callable function
1734
- if (! $arr_active_tab || ! is_callable($arr_active_tab['function'])) {
1735
  wp_die(__('No valid callback found', 'simple-history'));
1736
  }
1737
 
1738
- $args = array(
1739
- 'arr_active_tab' => $arr_active_tab
1740
- );
1741
 
1742
  call_user_func_array($arr_active_tab['function'], $args);?>
1743
 
@@ -1791,7 +1788,7 @@ Because Simple History was just recently installed, this feed does not contain m
1791
  _x('Simple History', 'dashboard menu name', 'simple-history'),
1792
  $this->get_view_history_capability(),
1793
  'simple_history_page',
1794
- array( $this, 'history_page_output' )
1795
  );
1796
  }
1797
  }
@@ -1807,7 +1804,7 @@ Because Simple History was just recently installed, this feed does not contain m
1807
  _x('Simple History', 'Options page menu title', 'simple-history'),
1808
  $this->get_view_settings_capability(),
1809
  SimpleHistory::SETTINGS_MENU_SLUG,
1810
- array( $this, 'settings_page_output' )
1811
  );
1812
  }
1813
  }
@@ -1820,7 +1817,8 @@ Because Simple History was just recently installed, this feed does not contain m
1820
  {
1821
  // Clear the log if clear button was clicked in settings
1822
  // and redirect user to show message.
1823
- if (isset($_GET['simple_history_clear_log_nonce']) &&
 
1824
  wp_verify_nonce($_GET['simple_history_clear_log_nonce'], 'simple_history_clear_log')
1825
  ) {
1826
  if ($this->user_can_clear_log()) {
@@ -1849,7 +1847,7 @@ Because Simple History was just recently installed, this feed does not contain m
1849
  add_settings_section(
1850
  $settings_section_general_id,
1851
  '',
1852
- array( $this, 'settings_section_output' ),
1853
  SimpleHistory::SETTINGS_MENU_SLUG // Same slug as for options menu page.
1854
  );
1855
 
@@ -1860,7 +1858,7 @@ Because Simple History was just recently installed, this feed does not contain m
1860
  add_settings_field(
1861
  'simple_history_show_where',
1862
  __('Show history', 'simple-history'),
1863
- array( $this, 'settings_field_where_to_show' ),
1864
  SimpleHistory::SETTINGS_MENU_SLUG,
1865
  $settings_section_general_id
1866
  );
@@ -1873,7 +1871,7 @@ Because Simple History was just recently installed, this feed does not contain m
1873
  add_settings_field(
1874
  'simple_history_number_of_items',
1875
  __('Number of items per page on the log page', 'simple-history'),
1876
- array( $this, 'settings_field_number_of_items' ),
1877
  SimpleHistory::SETTINGS_MENU_SLUG,
1878
  $settings_section_general_id
1879
  );
@@ -1885,7 +1883,7 @@ Because Simple History was just recently installed, this feed does not contain m
1885
  add_settings_field(
1886
  'simple_history_number_of_items_dashboard',
1887
  __('Number of items per page on the dashboard', 'simple-history'),
1888
- array( $this, 'settings_field_number_of_items_dashboard' ),
1889
  SimpleHistory::SETTINGS_MENU_SLUG,
1890
  $settings_section_general_id
1891
  );
@@ -1898,7 +1896,7 @@ Because Simple History was just recently installed, this feed does not contain m
1898
  add_settings_field(
1899
  'simple_history_clear_log',
1900
  __('Clear log', 'simple-history'),
1901
- array( $this, 'settings_field_clear_log' ),
1902
  SimpleHistory::SETTINGS_MENU_SLUG,
1903
  $settings_section_general_id
1904
  );
@@ -1932,7 +1930,7 @@ Because Simple History was just recently installed, this feed does not contain m
1932
  <div class="dashicons dashicons-backup SimpleHistoryPageHeadline__icon"></div>
1933
  <?php echo _x('Simple History', 'history page headline', 'simple-history'); ?>
1934
  </h1>
1935
-
1936
  <?php /**
1937
  * Fires before the gui div
1938
  *
@@ -1947,20 +1945,16 @@ Because Simple History was just recently installed, this feed does not contain m
1947
  <div class="SimpleHistoryGui"
1948
  data-pager-size='<?php echo $pager_size; ?>'
1949
  ></div>
1950
-
1951
- <?php /**
1952
- * Fires after the gui div
1953
- *
1954
- * @since 2.0
1955
- *
1956
- * @param SimpleHistory $SimpleHistory This class.
1957
- */
1958
- do_action('simple_history/history_page/after_gui', $this); ?>
1959
-
1960
  </div>
1961
-
1962
  </div>
1963
-
1964
  <?php
1965
  }
1966
 
@@ -2053,12 +2047,7 @@ Because Simple History was just recently installed, this feed does not contain m
2053
  ? "checked='checked'"
2054
  : ''; ?> type="checkbox" value="1" name="simple_history_show_as_page" id="simple_history_show_as_page" class="simple_history_show_as_page" />
2055
  <label for="simple_history_show_as_page">
2056
- <?php
2057
- _e(
2058
- 'as a page under the dashboard menu',
2059
- 'simple-history'
2060
- );
2061
- ?>
2062
  </label>
2063
 
2064
  <?php
@@ -2069,7 +2058,6 @@ Because Simple History was just recently installed, this feed does not contain m
2069
  */
2070
  public function settings_field_clear_log()
2071
  {
2072
-
2073
  // Get base URL to current page.
2074
  // Will be like "/wordpress/wp-admin/options-general.php?page=simple_history_settings_menu_slug&"
2075
  $clear_link = add_query_arg('', '');
@@ -2078,7 +2066,7 @@ Because Simple History was just recently installed, this feed does not contain m
2078
  $clear_link = wp_nonce_url($clear_link, 'simple_history_clear_log', 'simple_history_clear_log_nonce');
2079
 
2080
  $clear_days = $this->get_clear_history_interval();
2081
-
2082
  echo '<p>';
2083
 
2084
  if ($clear_days > 0) {
@@ -2147,9 +2135,9 @@ Because Simple History was just recently installed, this feed does not contain m
2147
  // Zero state sucks
2148
  SimpleLogger()->info(
2149
  __('The log for Simple History was cleared ({num_rows} rows were removed).', 'simple-history'),
2150
- array(
2151
- 'num_rows' => $num_rows
2152
- )
2153
  );
2154
 
2155
  $this->get_cache_incrementor(true);
@@ -2183,7 +2171,7 @@ Because Simple History was just recently installed, this feed does not contain m
2183
  $do_purge_history = apply_filters('simple_history_allow_db_purge', $do_purge_history);
2184
  $do_purge_history = apply_filters('simple_history/allow_db_purge', $do_purge_history);
2185
 
2186
- if (! $do_purge_history) {
2187
  return;
2188
  }
2189
 
@@ -2235,10 +2223,10 @@ Because Simple History was just recently installed, this feed does not contain m
2235
  'simple-history'
2236
  );
2237
 
2238
- SimpleLogger()->info($message, array(
2239
- 'days' => $days,
2240
- 'num_rows' => count($ids_to_delete)
2241
- ));
2242
 
2243
  $this->get_cache_incrementor(true);
2244
  }
@@ -2256,18 +2244,18 @@ Because Simple History was just recently installed, this feed does not contain m
2256
  {
2257
  $row_logger = $row->logger;
2258
  $logger = null;
2259
- $row->context = isset($row->context) && is_array($row->context) ? $row->context : array();
2260
 
2261
- if (! isset($row->context['_message_key'])) {
2262
  $row->context['_message_key'] = null;
2263
  }
2264
 
2265
  // Fallback to SimpleLogger if no logger exists for row
2266
- if (! isset($this->instantiatedLoggers[ $row_logger ])) {
2267
  $row_logger = 'SimpleLogger';
2268
  }
2269
 
2270
- $logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
2271
 
2272
  return $logger->getLogRowPlainTextOutput($row);
2273
  }
@@ -2287,14 +2275,14 @@ Because Simple History was just recently installed, this feed does not contain m
2287
  {
2288
  $row_logger = $row->logger;
2289
  $logger = null;
2290
- $row->context = isset($row->context) && is_array($row->context) ? $row->context : array();
2291
 
2292
  // Fallback to SimpleLogger if no logger exists for row
2293
- if (! isset($this->instantiatedLoggers[ $row_logger ])) {
2294
  $row_logger = 'SimpleLogger';
2295
  }
2296
 
2297
- $logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
2298
 
2299
  return $logger->getLogRowHeaderOutput($row);
2300
  }
@@ -2309,14 +2297,14 @@ Because Simple History was just recently installed, this feed does not contain m
2309
  {
2310
  $row_logger = $row->logger;
2311
  $logger = null;
2312
- $row->context = isset($row->context) && is_array($row->context) ? $row->context : array();
2313
 
2314
  // Fallback to SimpleLogger if no logger exists for row
2315
- if (! isset($this->instantiatedLoggers[ $row_logger ])) {
2316
  $row_logger = 'SimpleLogger';
2317
  }
2318
 
2319
- $logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
2320
 
2321
  return $logger->getLogRowSenderImageOutput($row);
2322
  }
@@ -2325,14 +2313,14 @@ Because Simple History was just recently installed, this feed does not contain m
2325
  {
2326
  $row_logger = $row->logger;
2327
  $logger = null;
2328
- $row->context = isset($row->context) && is_array($row->context) ? $row->context : array();
2329
 
2330
  // Fallback to SimpleLogger if no logger exists for row
2331
- if (! isset($this->instantiatedLoggers[ $row_logger ])) {
2332
  $row_logger = 'SimpleLogger';
2333
  }
2334
 
2335
- $logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
2336
 
2337
  return $logger->getLogRowDetailsOutput($row);
2338
  }
@@ -2369,9 +2357,9 @@ Because Simple History was just recently installed, this feed does not contain m
2369
  */
2370
  public function getLogRowHTMLOutput($oneLogRow, $args)
2371
  {
2372
- $defaults = array(
2373
- 'type' => 'overview' // or "single" to include more stuff
2374
- );
2375
 
2376
  $args = wp_parse_args($args, $defaults);
2377
 
@@ -2468,13 +2456,13 @@ Because Simple History was just recently installed, this feed does not contain m
2468
  *
2469
  * Array is in format
2470
  *
2471
- * Array
2472
- * (
2473
- * [id] => 1
2474
- * [logger] => 1
2475
- * [level] => 1
2476
- * ...
2477
- * )
2478
  *
2479
  * @since 2.0.29
2480
  *
@@ -2500,7 +2488,7 @@ Because Simple History was just recently installed, this feed does not contain m
2500
 
2501
  foreach ($oneLogRow as $rowKey => $rowVal) {
2502
  // Only columns from oneLogRow that exist in logRowKeysToShow will be outputed
2503
- if (! array_key_exists($rowKey, $logRowKeysToShow) || ! $logRowKeysToShow[ $rowKey ]) {
2504
  continue;
2505
  }
2506
 
@@ -2534,8 +2522,8 @@ Because Simple History was just recently installed, this feed does not contain m
2534
  * [plugin_description] => 1
2535
  * [plugin_author] => 1
2536
  * [plugin_version] => 1
2537
- * ...
2538
- * )
2539
  *
2540
  * @since 2.0.29
2541
  *
@@ -2550,7 +2538,8 @@ Because Simple History was just recently installed, this feed does not contain m
2550
 
2551
  foreach ($oneLogRow->context as $contextKey => $contextVal) {
2552
  // Only columns from context that exist in logRowContextKeysToShow will be outputed
2553
- if (!array_key_exists($contextKey, $logRowContextKeysToShow) ||
 
2554
  !$logRowContextKeysToShow[$contextKey]
2555
  ) {
2556
  continue;
@@ -2578,16 +2567,16 @@ Because Simple History was just recently installed, this feed does not contain m
2578
  '<div class="SimpleHistoryLogitem__moreDetails">%1$s</div>',
2579
  $more_details_html
2580
  );
2581
- }// End if().
2582
 
2583
  // Classes to add to log item li element
2584
- $classes = array(
2585
  'SimpleHistoryLogitem',
2586
  "SimpleHistoryLogitem--loglevel-{$oneLogRow->level}",
2587
- "SimpleHistoryLogitem--logger-{$oneLogRow->logger}"
2588
- );
2589
 
2590
- if (isset($oneLogRow->initiator) && ! empty($oneLogRow->initiator)) {
2591
  $classes[] = 'SimpleHistoryLogitem--initiator-' . $oneLogRow->initiator;
2592
  }
2593
 
@@ -2731,7 +2720,7 @@ Because Simple History was just recently installed, this feed does not contain m
2731
 
2732
  default:
2733
  $str_translated = $loglevel;
2734
- }// End switch().
2735
 
2736
  return $str_translated;
2737
  }
@@ -2775,9 +2764,9 @@ Because Simple History was just recently installed, this feed does not contain m
2775
  */
2776
  public function getLoggersThatUserCanRead($user_id = '', $format = 'array')
2777
  {
2778
- $arr_loggers_user_can_view = array();
2779
 
2780
- if (! is_numeric($user_id)) {
2781
  $user_id = get_current_user_id();
2782
  }
2783
 
@@ -2864,7 +2853,7 @@ Because Simple History was just recently installed, this feed does not contain m
2864
  $safe_alt = esc_attr($alt);
2865
  }
2866
 
2867
- if (! is_numeric($size)) {
2868
  $size = '96';
2869
  }
2870
 
@@ -2877,14 +2866,14 @@ Because Simple History was just recently installed, this feed does not contain m
2877
  }
2878
  }
2879
 
2880
- if (! empty($email)) {
2881
  $email_hash = md5(strtolower(trim($email)));
2882
  }
2883
 
2884
  if (is_ssl()) {
2885
  $host = 'https://secure.gravatar.com';
2886
  } else {
2887
- if (! empty($email)) {
2888
  $host = sprintf('http://%d.gravatar.com', hexdec($email_hash[0]) % 2);
2889
  } else {
2890
  $host = 'http://0.gravatar.com';
@@ -2895,7 +2884,7 @@ Because Simple History was just recently installed, this feed does not contain m
2895
  $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}";
2896
  } elseif ('blank' == $default) {
2897
  $default = $email ? 'blank' : includes_url('images/blank.gif');
2898
- } elseif (! empty($email) && 'gravatar_default' == $default) {
2899
  $default = '';
2900
  } elseif ('gravatar_default' == $default) {
2901
  $default = "$host/avatar/?s={$size}";
@@ -2905,14 +2894,14 @@ Because Simple History was just recently installed, this feed does not contain m
2905
  $default = add_query_arg('s', $size, $default);
2906
  }
2907
 
2908
- if (! empty($email)) {
2909
  $out = "$host/avatar/";
2910
  $out .= $email_hash;
2911
  $out .= '?s=' . $size;
2912
  $out .= '&amp;d=' . urlencode($default);
2913
 
2914
  $rating = get_option('avatar_rating');
2915
- if (! empty($rating)) {
2916
  $out .= "&amp;r={$rating}";
2917
  }
2918
 
@@ -2951,10 +2940,10 @@ Because Simple History was just recently installed, this feed does not contain m
2951
 
2952
  // Get number of events today
2953
  $logQuery = new SimpleHistoryLogQuery();
2954
- $logResults = $logQuery->query(array(
2955
- 'posts_per_page' => 1,
2956
- 'date_from' => strtotime('today')
2957
- ));
2958
 
2959
  $total_row_count = (int) $logResults['total_row_count'];
2960
 
@@ -3031,7 +3020,6 @@ Because Simple History was just recently installed, this feed does not contain m
3031
  }
3032
 
3033
  $count_other_sources = sizeof($results_other_sources_today);
3034
-
3035
  // sf_d($logResults, '$logResults');
3036
  // sf_d($results_users_today, '$sql_users_today');
3037
  // sf_d($results_other_sources_today, '$results_other_sources_today');
@@ -3065,13 +3053,13 @@ Because Simple History was just recently installed, this feed does not contain m
3065
 
3066
  // A single event existed and was from another source
3067
  // 1 event today from 1 source.
3068
- if ($total_row_count == 1 && ! $count_users_today) {
3069
  $msg_tmpl .= __('One event today from one source.', 'simple-history');
3070
  }
3071
 
3072
  // Multiple events from a single user
3073
  // 3 events today from one user.
3074
- if ($total_row_count > 1 && $count_users_today == 1 && ! $count_other_sources) {
3075
  $msg_tmpl .= __('%1$d events today from one user.', 'simple-history');
3076
  }
3077
 
@@ -3104,7 +3092,7 @@ Because Simple History was just recently installed, this feed does not contain m
3104
  if ($total_row_count > 1 && $count_users_today > 1 && $count_other_sources > 1) {
3105
  $msg_tmpl .= __('%1$s events today from %2$d users and %3$d other sources.', 'simple-history');
3106
  }
3107
- }// End if().
3108
 
3109
  // only show stats if we have something to output
3110
  if ($msg_tmpl) {
@@ -3262,13 +3250,11 @@ Because Simple History was just recently installed, this feed does not contain m
3262
  ?>
3263
  <div class="error notice">
3264
  <p>
3265
- <?php
3266
- echo esc_html__(
3267
  'The slug for a logger in Simple History can be max 30 chars long.',
3268
  'simple-history'
3269
- );
3270
- ?></p>
3271
  </div>
3272
  <?php
3273
  }
3274
- } // class
50
  * Required to automagically determine orginal text and text domain
51
  * for calls like this `SimpleLogger()->log( __("My translated message") );`
52
  */
53
+ public $gettextLatestTranslations = [];
54
 
55
  /**
56
  * All registered settings tabs
57
  */
58
+ private $arr_settings_tabs = [];
59
 
60
  const DBTABLE = 'simple_history';
61
  const DBTABLE_CONTEXTS = 'simple_history_contexts';
91
  $this->setup_variables();
92
 
93
  // Actions and filters, ordered by order specified in codex: http://codex.wordpress.org/Plugin_API/Action_Reference
94
+ add_action('after_setup_theme', [$this, 'load_plugin_textdomain']);
95
+ add_action('after_setup_theme', [$this, 'add_default_settings_tabs']);
96
 
97
  // Plugins and dropins are loaded using the "after_setup_theme" filter so
98
  // themes can use filters to modify the loading of them.
99
  // The drawback with this is that for example logouts done when plugins like
100
  // iThemes Security is installed is not logged, because those plugins fire wp_logout()
101
  // using filter "plugins_loaded", i.e. before simple history has loaded its filters.
102
+ add_action('after_setup_theme', [$this, 'load_loggers']);
103
+ add_action('after_setup_theme', [$this, 'load_dropins']);
104
 
105
  // Run before loading of loggers and before menu items are added.
106
+ add_action('after_setup_theme', [$this, 'check_for_upgrade'], 5);
107
 
108
+ add_action('after_setup_theme', [$this, 'setup_cron']);
109
 
110
  // Filters and actions not called during regular boot.
111
+ add_filter('gettext', [$this, 'filter_gettext'], 20, 3);
112
+ add_filter('gettext_with_context', [$this, 'filter_gettext_with_context'], 20, 4);
113
 
114
+ add_filter('gettext', [$this, 'filter_gettext_storeLatestTranslations'], 10, 3);
115
 
116
+ add_action('admin_bar_menu', [$this, 'add_admin_bar_network_menu_item'], 40);
117
+ add_action('admin_bar_menu', [$this, 'add_admin_bar_menu_item'], 40);
118
 
119
  /**
120
  * Filter that is used to log things, without the need to check that simple history is available
129
  *
130
  * @since 2.13
131
  */
132
+ add_filter('simple_history_log', [$this, 'on_filter_simple_history_log'], 10, 3);
133
 
134
  /**
135
  * Filter to log with specific log level, for example:
138
  *
139
  * @since 2.17
140
  */
141
+ add_filter('simple_history_log_emergency', [$this, 'on_filter_simple_history_log_emergency'], 10, 3);
142
+ add_filter('simple_history_log_alert', [$this, 'on_filter_simple_history_log_alert'], 10, 2);
143
+ add_filter('simple_history_log_critical', [$this, 'on_filter_simple_history_log_critical'], 10, 2);
144
+ add_filter('simple_history_log_error', [$this, 'on_filter_simple_history_log_error'], 10, 2);
145
+ add_filter('simple_history_log_warning', [$this, 'on_filter_simple_history_log_warning'], 10, 2);
146
+ add_filter('simple_history_log_notice', [$this, 'on_filter_simple_history_log_notice'], 10, 2);
147
+ add_filter('simple_history_log_info', [$this, 'on_filter_simple_history_log_info'], 10, 2);
148
+ add_filter('simple_history_log_debug', [$this, 'on_filter_simple_history_log_debug'], 10, 2);
149
 
150
  if (is_admin()) {
151
  $this->add_admin_actions();
269
  */
270
  private function add_admin_actions()
271
  {
272
+ add_action('admin_menu', [$this, 'add_admin_pages']);
273
+ add_action('admin_menu', [$this, 'add_settings']);
274
 
275
+ add_action('admin_footer', [$this, 'add_js_templates']);
276
 
277
+ add_action('wp_dashboard_setup', [$this, 'add_dashboard_widget']);
278
 
279
+ add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']);
280
 
281
+ add_action('admin_head', [$this, 'onAdminHead']);
282
+ add_action('admin_footer', [$this, 'onAdminFooter']);
283
 
284
+ add_action('simple_history/history_page/before_gui', [$this, 'output_quick_stats']);
285
+ add_action('simple_history/dashboard/before_gui', [$this, 'output_quick_stats']);
286
 
287
+ add_action('wp_ajax_simple_history_api', [$this, 'api']);
288
 
289
+ add_filter('plugin_action_links_simple-history/index.php', [$this, 'plugin_action_links'], 10, 4);
290
  }
291
 
292
  /**
307
  */
308
  $add_items = apply_filters('simple_history/add_admin_bar_network_menu_item', true);
309
 
310
+ if (!$add_items) {
311
  return;
312
  }
313
 
314
  // Don't show for logged out users or single site mode.
315
+ if (!is_user_logged_in() || !is_multisite()) {
316
  return;
317
  }
318
 
319
  // Show only when the user has at least one site, or they're a super admin.
320
+ if (count($wp_admin_bar->user->blogs) < 1 && !is_super_admin()) {
321
  return;
322
  }
323
 
324
  // Setting to show as page must be true
325
+ if (!$this->setting_show_as_page()) {
326
  return;
327
  }
328
 
329
  // User must have capability to view the history page
330
+ if (!current_user_can($this->get_view_history_capability())) {
331
  return;
332
  }
333
 
341
 
342
  if (is_plugin_active(SIMPLE_HISTORY_BASENAME)) {
343
  $menu_id = 'simple-history-blog-' . $blog->userblog_id;
344
+ $parent_menu_id = 'blog-' . $blog->userblog_id;
345
+ $url = admin_url(
346
+ apply_filters('simple_history/admin_location', 'index') . '.php?page=simple_history_page'
347
+ );
348
 
349
  // Each network site is added by WP core with id "blog-1", "blog-2" ... "blog-n"
350
  // https://codex.wordpress.org/Function_Reference/add_node
351
+ $args = [
352
+ 'id' => $menu_id,
353
  'parent' => $parent_menu_id,
354
  'title' => _x('View History', 'Admin bar network name', 'simple-history'),
355
+ 'href' => $url,
356
+ 'meta' => [
357
+ 'class' => 'ab-item--simplehistory',
358
+ ],
359
+ ];
360
 
361
  $wp_admin_bar->add_node($args);
362
  } // End if().
383
  */
384
  $add_item = apply_filters('simple_history/add_admin_bar_menu_item', true);
385
 
386
+ if (!$add_item) {
387
  return;
388
  }
389
 
390
  // Don't show for logged out users
391
+ if (!is_user_logged_in()) {
392
  return;
393
  }
394
 
395
  // Setting to show as page must be true
396
+ if (!$this->setting_show_as_page()) {
397
  return;
398
  }
399
 
400
  // User must have capability to view the history page
401
+ if (!current_user_can($this->get_view_history_capability())) {
402
  return;
403
  }
404
 
406
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
407
 
408
  $menu_id = 'simple-history-view-history';
409
+ $parent_menu_id = 'site-name';
410
  $url = admin_url(apply_filters('simple_history/admin_location', 'index') . '.php?page=simple_history_page');
411
 
412
+ $args = [
413
+ 'id' => $menu_id,
414
  'parent' => $parent_menu_id,
415
  'title' => _x('Simple History', 'Admin bar name', 'simple-history'),
416
+ 'href' => $url,
417
+ 'meta' => [
418
+ 'class' => 'ab-item--simplehistory',
419
+ ],
420
+ ];
421
 
422
  $wp_admin_bar->add_node($args);
423
  } // func
429
  */
430
  public static function get_instance()
431
  {
432
+ if (!isset(self::$instance)) {
433
  self::$instance = new SimpleHistory();
434
  }
435
 
439
  public function filter_gettext_storeLatestTranslations($translation, $text, $domain)
440
  {
441
  // Check that translation is a string or integer, i.ex. the valid values for an array key
442
+ if (!is_string($translation) || !is_integer($translation)) {
443
  return $translation;
444
  }
445
 
451
  // global $sh_latest_translations;
452
  $sh_latest_translations = $this->gettextLatestTranslations;
453
 
454
+ $sh_latest_translations[$translation] = [
455
  'translation' => $translation,
456
  'text' => $text,
457
+ 'domain' => $domain,
458
+ ];
459
 
460
  $arr_length = sizeof($sh_latest_translations);
461
  if ($arr_length > $array_max_size) {
469
 
470
  public function setup_cron()
471
  {
472
+ add_filter('simple_history/maybe_purge_db', [$this, 'maybe_purge_db']);
473
 
474
+ if (!wp_next_scheduled('simple_history/maybe_purge_db')) {
475
  wp_schedule_event(time(), 'daily', 'simple_history/maybe_purge_db');
476
  } else {
477
  }
572
  <div class="SimpleHistory-modal__background"></div>
573
  <div class="SimpleHistory-modal__content">
574
  <div class="SimpleHistory-modal__contentInner">
575
+ <img class="SimpleHistory-modal__contentSpinner" src="<?php echo esc_url(
576
+ admin_url('/images/spinner.gif')
577
+ ); ?>" alt="">
578
  </div>
579
  <div class="SimpleHistory-modal__contentClose">
580
  <button class="button">✕</button>
594
  <div class="SimpleHistoryLogitem__secondcol">
595
  <div class="SimpleHistoryLogitem__text">
596
  <?php _e('Sorry, but there are too many similar events to show.', 'simple-history'); ?>
 
 
 
 
 
 
 
 
 
597
  </div>
598
  </div>
599
  </li>
600
  </script>
601
 
602
+ <?php // Call plugins so they can add their js.
603
  foreach ($this->instantiatedLoggers as $one_logger) {
604
  if (method_exists($one_logger['instance'], 'adminJS')) {
605
  $one_logger['instance']->adminJS();
606
  }
607
+ }}
 
608
  }
609
 
610
  /**
627
  // Type = overview | ...
628
  $type = isset($_GET['type']) ? $_GET['type'] : null;
629
 
630
+ if (empty($args) || !$type) {
631
+ wp_send_json_error([
632
+ _x('Not enough args specified', 'API: not enought arguments passed', 'simple-history'),
633
+ ]);
634
  }
635
 
636
  // User must have capability to view the history page
637
+ if (!current_user_can($this->get_view_history_capability())) {
638
+ wp_send_json_error([
639
+ 'error' => 'CAPABILITY_ERROR',
640
+ ]);
641
  }
642
 
643
  if (isset($args['id'])) {
644
+ $args['post__in'] = [$args['id']];
645
  }
646
 
647
+ $data = [];
648
 
649
  switch ($type) {
650
  case 'overview':
658
 
659
  // Output can be array or HMTL
660
  if (isset($args['format']) && 'html' === $args['format']) {
661
+ $data['log_rows_raw'] = [];
662
 
663
  foreach ($data['log_rows'] as $key => $oneLogRow) {
664
+ $args = [];
665
  if ($type == 'single') {
666
  $args['type'] = 'single';
667
  }
668
 
669
+ $data['log_rows'][$key] = $this->getLogRowHTMLOutput($oneLogRow, $args);
670
  $data['num_queries'] = get_num_queries();
671
  }
672
  } else {
677
 
678
  default:
679
  $data[] = 'Nah.';
680
+ } // End switch().
681
 
682
  wp_send_json_success($data);
683
  }
690
  public function filter_gettext($translated_text, $untranslated_text, $domain)
691
  {
692
  if (isset($this->doFilterGettext) && $this->doFilterGettext) {
693
+ $this->doFilterGettext_currentLogger->messages[] = [
694
  'untranslated_text' => $untranslated_text,
695
  'translated_text' => $translated_text,
696
  'domain' => $domain,
697
+ 'context' => null,
698
+ ];
699
  }
700
 
701
  return $translated_text;
707
  public function filter_gettext_with_context($translated_text, $untranslated_text, $context, $domain)
708
  {
709
  if (isset($this->doFilterGettext) && $this->doFilterGettext) {
710
+ $this->doFilterGettext_currentLogger->messages[] = [
711
  'untranslated_text' => $untranslated_text,
712
  'translated_text' => $translated_text,
713
  'domain' => $domain,
714
+ 'context' => $context,
715
+ ];
716
  }
717
 
718
  return $translated_text;
740
  */
741
  public function setup_variables()
742
  {
743
+ $this->externalLoggers = [];
744
+ $this->externalDropins = [];
745
+ $this->instantiatedLoggers = [];
746
+ $this->instantiatedDropins = [];
747
 
748
  $this->plugin_basename = SIMPLE_HISTORY_BASENAME;
749
  }
797
  public function add_default_settings_tabs()
798
  {
799
  // Add default settings tabs
800
+ $this->arr_settings_tabs = [
801
+ [
802
  'slug' => 'settings',
803
  'name' => __('Settings', 'simple-history'),
804
+ 'function' => [$this, 'settings_output_general'],
805
+ ],
806
+ ];
807
 
808
  if (defined('SIMPLE_HISTORY_DEV') && SIMPLE_HISTORY_DEV) {
809
+ $arr_dev_tabs = [
810
+ [
811
  'slug' => 'log',
812
  'name' => __('Log (debug)', 'simple-history'),
813
+ 'function' => [$this, 'settings_output_log'],
814
+ ],
815
+ [
816
  'slug' => 'styles-example',
817
  'name' => __('Styles example (debug)', 'simple-history'),
818
+ 'function' => [$this, 'settings_output_styles_example'],
819
+ ],
820
+ ];
821
 
822
  $this->arr_settings_tabs = array_merge($this->arr_settings_tabs, $arr_dev_tabs);
823
  }
857
  {
858
  $loggersDir = SIMPLE_HISTORY_PATH . 'loggers/';
859
 
860
+ $loggersFiles = [
861
  // Main loggers.
862
  $loggersDir . 'SimpleCommentsLogger.php',
863
  $loggersDir . 'SimpleCoreUpdatesLogger.php',
886
  $loggersDir . 'Plugin_Redirection.php',
887
  $loggersDir . 'Plugin_DuplicatePost.php',
888
  $loggersDir . 'Plugin_ACF.php',
889
+ $loggersDir . 'Plugin_BeaverBuilder.php',
890
+ ];
891
 
892
  // SimpleLogger.php must be loaded first and always since the other loggers extend it.
893
  // Include it manually so no risk of anyone using filters or similar disables it.
907
 
908
  // Array with slug of loggers to instantiate.
909
  // Slug of logger must also be the name of the logger class.
910
+ $arr_loggers_to_instantiate = [];
911
 
912
  // $one_logger_file = "SimpleCommentsLogger.php", "class-privacy-logger.php", and so on.
913
  foreach ($loggersFiles as $one_logger_file) {
933
  $load_logger = true;
934
  }
935
 
936
+ if (!$load_logger) {
937
  continue;
938
  }
939
 
961
  * (
962
  * [0] => SimpleCommentsLogger
963
  * [1] => SimpleCoreUpdatesLogger
964
+ * ...
965
+ * )
966
  *
967
  * @since 2.0
968
  *
994
  }
995
 
996
  // Continue to load next logger if no valid logger class found.
997
+ if (!$logger_class_name) {
998
  continue;
999
  }
1000
 
1001
  // Init found logger class.
1002
  $logger_instance = new $logger_class_name($this);
1003
 
1004
+ if (!is_subclass_of($logger_instance, 'SimpleLogger') && !is_a($logger_instance, 'SimpleLogger')) {
1005
  continue;
1006
  }
1007
 
1016
  // Check so no logger has a logger slug with more than 30 chars,
1017
  // because db column is only 30 chars.
1018
  if (strlen($logger_instance->slug) > 30) {
1019
+ add_action('admin_notices', [$this, 'admin_notice_logger_slug_to_long']);
1020
  }
1021
 
1022
  // Un-tell gettext filter.
1027
  // Add messages to the loggerInstance.
1028
  $loopNum = 0;
1029
 
1030
+ $arr_messages_by_message_key = [];
1031
 
1032
  if (isset($logger_info['messages']) && is_array($logger_info['messages'])) {
1033
  foreach ((array) $logger_info['messages'] as $message_key => $message_translated) {
1034
  // Find message in array with both translated and non translated strings.
1035
  foreach ($logger_instance->messages as $one_message_with_translation_info) {
1036
  if ($message_translated == $one_message_with_translation_info['translated_text']) {
1037
+ $arr_messages_by_message_key[$message_key] = $one_message_with_translation_info;
1038
  continue;
1039
  }
1040
  }
1044
  $logger_instance->messages = $arr_messages_by_message_key;
1045
 
1046
  // Add logger to array of loggers.
1047
+ $this->instantiatedLoggers[$logger_instance->slug] = [
1048
  'name' => $logger_info['name'],
1049
+ 'instance' => $logger_instance,
1050
+ ];
1051
+ } // End foreach().
1052
 
1053
  do_action('simple_history/loggers_loaded');
1054
  }
1061
  {
1062
  $dropinsDir = SIMPLE_HISTORY_PATH . 'dropins/';
1063
 
1064
+ $dropinsFiles = [
1065
  $dropinsDir . 'SimpleHistoryPluginPatchesDropin.php',
1066
  $dropinsDir . 'SimpleHistoryDonateDropin.php',
1067
  $dropinsDir . 'SimpleHistoryExportDropin.php',
1077
  $dropinsDir . 'SimpleHistorySidebarSettings.php',
1078
  $dropinsDir . 'SimpleHistoryWPCLIDropin.php',
1079
  $dropinsDir . 'SimpleHistoryDebugDropin.php',
1080
+ ];
1081
 
1082
  /**
1083
  * Filter the array with absolute paths to files as returned by glob function.
1090
  */
1091
  $dropinsFiles = apply_filters('simple_history/dropins_files', $dropinsFiles);
1092
 
1093
+ $arrDropinsToInstantiate = [];
1094
 
1095
  foreach ($dropinsFiles as $oneDropinFile) {
1096
  // path/path/simplehistory/dropins/SimpleHistoryDonateDropin.php => SimpleHistoryDonateDropin
1119
  */
1120
  $load_dropin = apply_filters('simple_history/dropin/load_dropin', $load_dropin, $oneDropinFileBasename);
1121
 
1122
+ if (!$load_dropin) {
1123
  continue;
1124
  }
1125
 
1126
  include_once $oneDropinFile;
1127
 
1128
  $arrDropinsToInstantiate[] = $oneDropinFileBasename;
1129
+ } // End foreach().
1130
 
1131
  /**
1132
  * Action that dropins can use to add their custom loggers.
1151
 
1152
  // Instantiate each dropin
1153
  foreach ($arrDropinsToInstantiate as $oneDropinName) {
1154
+ if (!class_exists($oneDropinName)) {
1155
  continue;
1156
  }
1157
 
1158
+ $this->instantiatedDropins[$oneDropinName] = [
1159
  'name' => $oneDropinName,
1160
+ 'instance' => new $oneDropinName($this),
1161
+ ];
1162
  }
1163
  }
1164
 
1213
  public function plugin_action_links($actions, $b, $c, $d)
1214
  {
1215
  // Only add link if user has the right to view the settings page
1216
+ if (!current_user_can($this->get_view_settings_capability())) {
1217
  return $actions;
1218
  }
1219
 
1221
 
1222
  if (empty($actions)) {
1223
  // Create array if actions is empty (and therefore is assumed to be a string by PHP & results in PHP 7.1+ fatal error due to trying to make array modifications on what's assumed to be a string)
1224
+ $actions = [];
1225
  } elseif (is_string($actions)) {
1226
  // Convert the string (which it might've been retrieved as) to an array for future use as an array
1227
+ $actions = [$actions];
1228
  }
1229
  $actions[] = "<a href='$settings_page_url'>" . __('Settings', 'simple-history') . '</a>';
1230
 
1249
  $show_dashboard_widget = apply_filters('simple_history/show_dashboard_widget', true);
1250
 
1251
  if ($show_dashboard_widget) {
1252
+ wp_add_dashboard_widget('simple_history_dashboard_widget', __('Simple History', 'simple-history'), [
1253
+ $this,
1254
+ 'dashboard_widget_output',
1255
+ ]);
 
1256
  }
1257
  }
1258
  }
1286
  $current_screen = get_current_screen();
1287
 
1288
  $basePrefix = apply_filters('simple_history/admin_location', 'index');
1289
+ $basePrefix = $basePrefix === 'index' ? 'dashboard' : $basePrefix;
1290
 
1291
  if ($current_screen && $current_screen->base == 'settings_page_' . SimpleHistory::SETTINGS_MENU_SLUG) {
1292
  return true;
1293
+ } elseif ($current_screen && $current_screen->base == $basePrefix . '_page_simple_history_page') {
1294
  return true;
1295
+ } elseif (
1296
+ $hook == 'settings_page_' . SimpleHistory::SETTINGS_MENU_SLUG ||
1297
+ ($this->setting_show_on_dashboard() && $hook == 'index.php') ||
1298
+ ($this->setting_show_as_page() && $hook == $basePrefix . '_page_simple_history_page')
1299
+ ) {
1300
  return true;
1301
  } elseif ($current_screen && $current_screen->base == 'dashboard' && $this->setting_show_on_dashboard()) {
1302
  return true;
1324
  wp_enqueue_script(
1325
  'simple_history_script',
1326
  SIMPLE_HISTORY_DIR_URL . 'js/scripts.js',
1327
+ ['jquery', 'backbone', 'wp-util'],
1328
  SIMPLE_HISTORY_VERSION,
1329
  true
1330
  );
1331
 
1332
+ wp_enqueue_script('select2', SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.full.min.js', ['jquery']);
1333
  wp_enqueue_style('select2', SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.min.css');
1334
 
1335
  // Translations that we use in JavaScript
1336
+ wp_localize_script('simple_history_script', 'simple_history_script_vars', [
1337
+ 'settingsConfirmClearLog' => __('Remove all log items?', 'simple-history'),
1338
+ 'pagination' => [
1339
+ 'goToTheFirstPage' => __('Go to the first page', 'simple-history'),
1340
+ 'goToThePrevPage' => __('Go to the previous page', 'simple-history'),
1341
+ 'goToTheNextPage' => __('Go to the next page', 'simple-history'),
1342
+ 'goToTheLastPage' => __('Go to the last page', 'simple-history'),
1343
+ 'currentPage' => __('Current page', 'simple-history'),
1344
+ ],
1345
+ 'loadLogAPIError' => __('Oups, the log could not be loaded right now.', 'simple-history'),
1346
  'ajaxLoadError' => __(
1347
  'Hm, the log could not be loaded right now. Perhaps another plugin is giving some errors. Anyway, below is the output I got from the server.',
1348
  'simple-history'
1349
  ),
1350
+ 'logNoHits' => __('Your search did not match any history events.', 'simple-history'),
1351
+ ]);
1352
 
1353
  // Call plugins adminCSS-method, so they can add their CSS
1354
  foreach ($this->instantiatedLoggers as $one_logger) {
1361
  wp_enqueue_script(
1362
  'timeago',
1363
  SIMPLE_HISTORY_DIR_URL . 'js/timeago/jquery.timeago.js',
1364
+ ['jquery'],
1365
  '1.5.2',
1366
  true
1367
  );
1368
 
1369
  // Determine current locale to load timeago locale
1370
+ $locale = strtolower(substr(get_locale(), 0, 2));
1371
  $locale_url_path = SIMPLE_HISTORY_DIR_URL . 'js/timeago/locales/jquery.timeago.%s.js';
1372
  $locale_dir_path = SIMPLE_HISTORY_PATH . 'js/timeago/locales/jquery.timeago.%s.js';
1373
 
1374
  // Only enqueue if locale-file exists on file system
1375
  if (file_exists(sprintf($locale_dir_path, $locale))) {
1376
+ wp_enqueue_script('timeago-locale', sprintf($locale_url_path, $locale), ['jquery'], '1.5.2', true);
1377
  } else {
1378
+ wp_enqueue_script('timeago-locale', sprintf($locale_url_path, 'en'), ['jquery'], '1.5.2', true);
1379
  }
1380
  // end add timeago
1381
  // Load Select2 locale
1383
  $locale_dir_path = SIMPLE_HISTORY_PATH . 'js/select2/i18n/%s.js';
1384
 
1385
  if (file_exists(sprintf($locale_dir_path, $locale))) {
1386
+ wp_enqueue_script('select2-locale', sprintf($locale_url_path, $locale), ['jquery'], '3.5.1', true);
1387
  }
1388
 
1389
  /**
1395
  * @param SimpleHistory $SimpleHistory This class.
1396
  */
1397
  do_action('simple_history/enqueue_admin_scripts', $this);
1398
+ } // End if().
1399
  }
1400
 
1401
  public function filter_option_page_capability($capability)
1464
 
1465
  // Check that all options we use are set to their defaults, if they miss value
1466
  // Each option that is missing a value will make a sql call otherwise = unnecessary
1467
+ $arr_options = [
1468
+ [
1469
  'name' => 'simple_history_show_as_page',
1470
+ 'default_value' => 1,
1471
+ ],
1472
+ [
1473
  'name' => 'simple_history_show_on_dashboard',
1474
+ 'default_value' => 1,
1475
+ ],
1476
+ ];
1477
 
1478
  foreach ($arr_options as $one_option) {
1479
+ if (false === ($option_value = get_option($one_option['name']))) {
1480
  // Value is not set in db, so set it to a default
1481
  update_option($one_option['name'], $one_option['default_value']);
1482
  }
1544
 
1545
  // Say welcome, however loggers are not added this early so we need to
1546
  // use a filter to load it later
1547
+ add_action('simple_history/loggers_loaded', [$this, 'addWelcomeLogMessage']);
1548
  } // End if().
1549
 
1550
  /**
1587
  // Some installs on 2.2.2 got failed installs
1588
  // We detect these by checking for db_version and then running the install stuff again
1589
  if (4 == intval($db_version)) {
1590
+ if (!$this->does_database_have_data()) {
1591
  // not ok, decrease db number so installs will run again and hopefully fix things
1592
  $db_version = 0;
1593
  } else {
1632
  $pluginLogger = $this->getInstantiatedLoggerBySlug('SimplePluginLogger');
1633
  if ($pluginLogger) {
1634
  // Add plugin installed message
1635
+ $context = [
1636
  'plugin_name' => 'Simple History',
1637
  'plugin_description' =>
1638
  'Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.',
1639
+ 'plugin_url' => 'https://simple-history.com',
1640
  'plugin_version' => SIMPLE_HISTORY_VERSION,
1641
+ 'plugin_author' => 'Pär Thernström',
1642
+ ];
1643
 
1644
  $pluginLogger->infoMessage('plugin_installed', $context);
1645
 
1646
  // Add plugin activated message
1647
  $context['plugin_slug'] = 'simple-history';
1648
+ $context['plugin_title'] = '<a href="https://simple-history.com/">Simple History</a>';
1649
 
1650
  $pluginLogger->infoMessage('plugin_activated', $context);
1651
  }
1652
 
1653
+ if (!$db_data_exists) {
1654
  $welcome_message_1 = __(
1655
  '
1656
  Welcome to Simple History!
1662
 
1663
  $welcome_message_2 = __(
1664
  '
1665
+ Because Simple History was only recently installed, this feed does not display many events yet. As long as the plugin remains activated you will soon see detailed information about page edits, plugin updates, users logging in, and much more.
1666
  ',
1667
  'simple-history'
1668
  );
1669
 
1670
+ SimpleLogger()->info($welcome_message_2, [
1671
+ '_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
1672
+ ]);
1673
 
1674
+ SimpleLogger()->info($welcome_message_1, [
1675
+ '_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
1676
+ ]);
1677
  }
1678
  }
1679
 
1715
  $one_tab['name'], // 1
1716
  $tab_slug, // 2
1717
  esc_url(add_query_arg('selected-tab', $tab_slug, $settings_base_url)), // 3
1718
+ $active_tab == $tab_slug ? 'nav-tab-active' : '' // 4
1719
  );
1720
  } ?>
1721
  </h2>
1722
 
1723
  <?php
1724
  // Output contents for selected tab
1725
+ $arr_active_tab = wp_filter_object_list($arr_settings_tabs, [
1726
+ 'slug' => $active_tab,
1727
+ ]);
1728
  $arr_active_tab = current($arr_active_tab);
1729
 
1730
  // We must have found an active tab and it must have a callable function
1731
+ if (!$arr_active_tab || !is_callable($arr_active_tab['function'])) {
1732
  wp_die(__('No valid callback found', 'simple-history'));
1733
  }
1734
 
1735
+ $args = [
1736
+ 'arr_active_tab' => $arr_active_tab,
1737
+ ];
1738
 
1739
  call_user_func_array($arr_active_tab['function'], $args);?>
1740
 
1788
  _x('Simple History', 'dashboard menu name', 'simple-history'),
1789
  $this->get_view_history_capability(),
1790
  'simple_history_page',
1791
+ [$this, 'history_page_output']
1792
  );
1793
  }
1794
  }
1804
  _x('Simple History', 'Options page menu title', 'simple-history'),
1805
  $this->get_view_settings_capability(),
1806
  SimpleHistory::SETTINGS_MENU_SLUG,
1807
+ [$this, 'settings_page_output']
1808
  );
1809
  }
1810
  }
1817
  {
1818
  // Clear the log if clear button was clicked in settings
1819
  // and redirect user to show message.
1820
+ if (
1821
+ isset($_GET['simple_history_clear_log_nonce']) &&
1822
  wp_verify_nonce($_GET['simple_history_clear_log_nonce'], 'simple_history_clear_log')
1823
  ) {
1824
  if ($this->user_can_clear_log()) {
1847
  add_settings_section(
1848
  $settings_section_general_id,
1849
  '',
1850
+ [$this, 'settings_section_output'],
1851
  SimpleHistory::SETTINGS_MENU_SLUG // Same slug as for options menu page.
1852
  );
1853
 
1858
  add_settings_field(
1859
  'simple_history_show_where',
1860
  __('Show history', 'simple-history'),
1861
+ [$this, 'settings_field_where_to_show'],
1862
  SimpleHistory::SETTINGS_MENU_SLUG,
1863
  $settings_section_general_id
1864
  );
1871
  add_settings_field(
1872
  'simple_history_number_of_items',
1873
  __('Number of items per page on the log page', 'simple-history'),
1874
+ [$this, 'settings_field_number_of_items'],
1875
  SimpleHistory::SETTINGS_MENU_SLUG,
1876
  $settings_section_general_id
1877
  );
1883
  add_settings_field(
1884
  'simple_history_number_of_items_dashboard',
1885
  __('Number of items per page on the dashboard', 'simple-history'),
1886
+ [$this, 'settings_field_number_of_items_dashboard'],
1887
  SimpleHistory::SETTINGS_MENU_SLUG,
1888
  $settings_section_general_id
1889
  );
1896
  add_settings_field(
1897
  'simple_history_clear_log',
1898
  __('Clear log', 'simple-history'),
1899
+ [$this, 'settings_field_clear_log'],
1900
  SimpleHistory::SETTINGS_MENU_SLUG,
1901
  $settings_section_general_id
1902
  );
1930
  <div class="dashicons dashicons-backup SimpleHistoryPageHeadline__icon"></div>
1931
  <?php echo _x('Simple History', 'history page headline', 'simple-history'); ?>
1932
  </h1>
1933
+
1934
  <?php /**
1935
  * Fires before the gui div
1936
  *
1945
  <div class="SimpleHistoryGui"
1946
  data-pager-size='<?php echo $pager_size; ?>'
1947
  ></div>
1948
+ <?php /**
1949
+ * Fires after the gui div
1950
+ *
1951
+ * @since 2.0
1952
+ *
1953
+ * @param SimpleHistory $SimpleHistory This class.
1954
+ */
1955
+ do_action('simple_history/history_page/after_gui', $this); ?>
 
 
1956
  </div>
 
1957
  </div>
 
1958
  <?php
1959
  }
1960
 
2047
  ? "checked='checked'"
2048
  : ''; ?> type="checkbox" value="1" name="simple_history_show_as_page" id="simple_history_show_as_page" class="simple_history_show_as_page" />
2049
  <label for="simple_history_show_as_page">
2050
+ <?php _e('as a page under the dashboard menu', 'simple-history'); ?>
 
 
 
 
 
2051
  </label>
2052
 
2053
  <?php
2058
  */
2059
  public function settings_field_clear_log()
2060
  {
 
2061
  // Get base URL to current page.
2062
  // Will be like "/wordpress/wp-admin/options-general.php?page=simple_history_settings_menu_slug&"
2063
  $clear_link = add_query_arg('', '');
2066
  $clear_link = wp_nonce_url($clear_link, 'simple_history_clear_log', 'simple_history_clear_log_nonce');
2067
 
2068
  $clear_days = $this->get_clear_history_interval();
2069
+
2070
  echo '<p>';
2071
 
2072
  if ($clear_days > 0) {
2135
  // Zero state sucks
2136
  SimpleLogger()->info(
2137
  __('The log for Simple History was cleared ({num_rows} rows were removed).', 'simple-history'),
2138
+ [
2139
+ 'num_rows' => $num_rows,
2140
+ ]
2141
  );
2142
 
2143
  $this->get_cache_incrementor(true);
2171
  $do_purge_history = apply_filters('simple_history_allow_db_purge', $do_purge_history);
2172
  $do_purge_history = apply_filters('simple_history/allow_db_purge', $do_purge_history);
2173
 
2174
+ if (!$do_purge_history) {
2175
  return;
2176
  }
2177
 
2223
  'simple-history'
2224
  );
2225
 
2226
+ SimpleLogger()->info($message, [
2227
+ 'days' => $days,
2228
+ 'num_rows' => count($ids_to_delete),
2229
+ ]);
2230
 
2231
  $this->get_cache_incrementor(true);
2232
  }
2244
  {
2245
  $row_logger = $row->logger;
2246
  $logger = null;
2247
+ $row->context = isset($row->context) && is_array($row->context) ? $row->context : [];
2248
 
2249
+ if (!isset($row->context['_message_key'])) {
2250
  $row->context['_message_key'] = null;
2251
  }
2252
 
2253
  // Fallback to SimpleLogger if no logger exists for row
2254
+ if (!isset($this->instantiatedLoggers[$row_logger])) {
2255
  $row_logger = 'SimpleLogger';
2256
  }
2257
 
2258
+ $logger = $this->instantiatedLoggers[$row_logger]['instance'];
2259
 
2260
  return $logger->getLogRowPlainTextOutput($row);
2261
  }
2275
  {
2276
  $row_logger = $row->logger;
2277
  $logger = null;
2278
+ $row->context = isset($row->context) && is_array($row->context) ? $row->context : [];
2279
 
2280
  // Fallback to SimpleLogger if no logger exists for row
2281
+ if (!isset($this->instantiatedLoggers[$row_logger])) {
2282
  $row_logger = 'SimpleLogger';
2283
  }
2284
 
2285
+ $logger = $this->instantiatedLoggers[$row_logger]['instance'];
2286
 
2287
  return $logger->getLogRowHeaderOutput($row);
2288
  }
2297
  {
2298
  $row_logger = $row->logger;
2299
  $logger = null;
2300
+ $row->context = isset($row->context) && is_array($row->context) ? $row->context : [];
2301
 
2302
  // Fallback to SimpleLogger if no logger exists for row
2303
+ if (!isset($this->instantiatedLoggers[$row_logger])) {
2304
  $row_logger = 'SimpleLogger';
2305
  }
2306
 
2307
+ $logger = $this->instantiatedLoggers[$row_logger]['instance'];
2308
 
2309
  return $logger->getLogRowSenderImageOutput($row);
2310
  }
2313
  {
2314
  $row_logger = $row->logger;
2315
  $logger = null;
2316
+ $row->context = isset($row->context) && is_array($row->context) ? $row->context : [];
2317
 
2318
  // Fallback to SimpleLogger if no logger exists for row
2319
+ if (!isset($this->instantiatedLoggers[$row_logger])) {
2320
  $row_logger = 'SimpleLogger';
2321
  }
2322
 
2323
+ $logger = $this->instantiatedLoggers[$row_logger]['instance'];
2324
 
2325
  return $logger->getLogRowDetailsOutput($row);
2326
  }
2357
  */
2358
  public function getLogRowHTMLOutput($oneLogRow, $args)
2359
  {
2360
+ $defaults = [
2361
+ 'type' => 'overview', // or "single" to include more stuff
2362
+ ];
2363
 
2364
  $args = wp_parse_args($args, $defaults);
2365
 
2456
  *
2457
  * Array is in format
2458
  *
2459
+ * Array
2460
+ * (
2461
+ * [id] => 1
2462
+ * [logger] => 1
2463
+ * [level] => 1
2464
+ * ...
2465
+ * )
2466
  *
2467
  * @since 2.0.29
2468
  *
2488
 
2489
  foreach ($oneLogRow as $rowKey => $rowVal) {
2490
  // Only columns from oneLogRow that exist in logRowKeysToShow will be outputed
2491
+ if (!array_key_exists($rowKey, $logRowKeysToShow) || !$logRowKeysToShow[$rowKey]) {
2492
  continue;
2493
  }
2494
 
2522
  * [plugin_description] => 1
2523
  * [plugin_author] => 1
2524
  * [plugin_version] => 1
2525
+ * ...
2526
+ * )
2527
  *
2528
  * @since 2.0.29
2529
  *
2538
 
2539
  foreach ($oneLogRow->context as $contextKey => $contextVal) {
2540
  // Only columns from context that exist in logRowContextKeysToShow will be outputed
2541
+ if (
2542
+ !array_key_exists($contextKey, $logRowContextKeysToShow) ||
2543
  !$logRowContextKeysToShow[$contextKey]
2544
  ) {
2545
  continue;
2567
  '<div class="SimpleHistoryLogitem__moreDetails">%1$s</div>',
2568
  $more_details_html
2569
  );
2570
+ } // End if().
2571
 
2572
  // Classes to add to log item li element
2573
+ $classes = [
2574
  'SimpleHistoryLogitem',
2575
  "SimpleHistoryLogitem--loglevel-{$oneLogRow->level}",
2576
+ "SimpleHistoryLogitem--logger-{$oneLogRow->logger}",
2577
+ ];
2578
 
2579
+ if (isset($oneLogRow->initiator) && !empty($oneLogRow->initiator)) {
2580
  $classes[] = 'SimpleHistoryLogitem--initiator-' . $oneLogRow->initiator;
2581
  }
2582
 
2720
 
2721
  default:
2722
  $str_translated = $loglevel;
2723
+ } // End switch().
2724
 
2725
  return $str_translated;
2726
  }
2764
  */
2765
  public function getLoggersThatUserCanRead($user_id = '', $format = 'array')
2766
  {
2767
+ $arr_loggers_user_can_view = [];
2768
 
2769
+ if (!is_numeric($user_id)) {
2770
  $user_id = get_current_user_id();
2771
  }
2772
 
2853
  $safe_alt = esc_attr($alt);
2854
  }
2855
 
2856
+ if (!is_numeric($size)) {
2857
  $size = '96';
2858
  }
2859
 
2866
  }
2867
  }
2868
 
2869
+ if (!empty($email)) {
2870
  $email_hash = md5(strtolower(trim($email)));
2871
  }
2872
 
2873
  if (is_ssl()) {
2874
  $host = 'https://secure.gravatar.com';
2875
  } else {
2876
+ if (!empty($email)) {
2877
  $host = sprintf('http://%d.gravatar.com', hexdec($email_hash[0]) % 2);
2878
  } else {
2879
  $host = 'http://0.gravatar.com';
2884
  $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}";
2885
  } elseif ('blank' == $default) {
2886
  $default = $email ? 'blank' : includes_url('images/blank.gif');
2887
+ } elseif (!empty($email) && 'gravatar_default' == $default) {
2888
  $default = '';
2889
  } elseif ('gravatar_default' == $default) {
2890
  $default = "$host/avatar/?s={$size}";
2894
  $default = add_query_arg('s', $size, $default);
2895
  }
2896
 
2897
+ if (!empty($email)) {
2898
  $out = "$host/avatar/";
2899
  $out .= $email_hash;
2900
  $out .= '?s=' . $size;
2901
  $out .= '&amp;d=' . urlencode($default);
2902
 
2903
  $rating = get_option('avatar_rating');
2904
+ if (!empty($rating)) {
2905
  $out .= "&amp;r={$rating}";
2906
  }
2907
 
2940
 
2941
  // Get number of events today
2942
  $logQuery = new SimpleHistoryLogQuery();
2943
+ $logResults = $logQuery->query([
2944
+ 'posts_per_page' => 1,
2945
+ 'date_from' => strtotime('today'),
2946
+ ]);
2947
 
2948
  $total_row_count = (int) $logResults['total_row_count'];
2949
 
3020
  }
3021
 
3022
  $count_other_sources = sizeof($results_other_sources_today);
 
3023
  // sf_d($logResults, '$logResults');
3024
  // sf_d($results_users_today, '$sql_users_today');
3025
  // sf_d($results_other_sources_today, '$results_other_sources_today');
3053
 
3054
  // A single event existed and was from another source
3055
  // 1 event today from 1 source.
3056
+ if ($total_row_count == 1 && !$count_users_today) {
3057
  $msg_tmpl .= __('One event today from one source.', 'simple-history');
3058
  }
3059
 
3060
  // Multiple events from a single user
3061
  // 3 events today from one user.
3062
+ if ($total_row_count > 1 && $count_users_today == 1 && !$count_other_sources) {
3063
  $msg_tmpl .= __('%1$d events today from one user.', 'simple-history');
3064
  }
3065
 
3092
  if ($total_row_count > 1 && $count_users_today > 1 && $count_other_sources > 1) {
3093
  $msg_tmpl .= __('%1$s events today from %2$d users and %3$d other sources.', 'simple-history');
3094
  }
3095
+ } // End if().
3096
 
3097
  // only show stats if we have something to output
3098
  if ($msg_tmpl) {
3250
  ?>
3251
  <div class="error notice">
3252
  <p>
3253
+ <?php echo esc_html__(
 
3254
  'The slug for a logger in Simple History can be max 30 chars long.',
3255
  'simple-history'
3256
+ ); ?></p>
 
3257
  </div>
3258
  <?php
3259
  }
3260
+ }
index.php CHANGED
@@ -5,7 +5,7 @@
5
  * Text Domain: simple-history
6
  * Domain Path: /languages
7
  * Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
8
- * Version: 2.34.0
9
  * Author: Pär Thernström
10
  * Author URI: http://simple-history.com/
11
  * License: GPL2
@@ -46,7 +46,7 @@ if ($ok_php_version && $ok_wp_version) {
46
  */
47
 
48
  if (!defined('SIMPLE_HISTORY_VERSION')) {
49
- define('SIMPLE_HISTORY_VERSION', '2.34.0');
50
  }
51
 
52
  if (!defined('SIMPLE_HISTORY_PATH')) {
5
  * Text Domain: simple-history
6
  * Domain Path: /languages
7
  * Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
8
+ * Version: 2.35.0
9
  * Author: Pär Thernström
10
  * Author URI: http://simple-history.com/
11
  * License: GPL2
46
  */
47
 
48
  if (!defined('SIMPLE_HISTORY_VERSION')) {
49
+ define('SIMPLE_HISTORY_VERSION', '2.35.0');
50
  }
51
 
52
  if (!defined('SIMPLE_HISTORY_PATH')) {
loggers/Plugin_Redirection.php CHANGED
@@ -129,9 +129,11 @@ if (! class_exists('Plugin_Redirection')) {
129
  $this->log_redirection_edit($request);
130
  } elseif ('Redirection_Api_Redirect::route_bulk' === $callable_name) {
131
  $bulk_action = $request->get_param('bulk');
132
-
133
  $bulk_items = $request->get_param('items');
134
- $bulk_items = explode(',', $bulk_items);
 
 
 
135
 
136
  if (is_array($bulk_items)) {
137
  $bulk_items = array_map('intval', $bulk_items);
129
  $this->log_redirection_edit($request);
130
  } elseif ('Redirection_Api_Redirect::route_bulk' === $callable_name) {
131
  $bulk_action = $request->get_param('bulk');
 
132
  $bulk_items = $request->get_param('items');
133
+
134
+ if (!is_array($bulk_items)) {
135
+ $bulk_items = explode(',', $bulk_items);
136
+ }
137
 
138
  if (is_array($bulk_items)) {
139
  $bulk_items = array_map('intval', $bulk_items);
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: eskapism
3
  Donate link: https://www.paypal.me/eskapism
4
  Tags: history, log, changes, changelog, audit, audit log, event log, user tracking, trail, pages, attachments, users, dashboard, admin, syslog, feed, activity, stream, audit trail, brute-force
5
  Requires at least: 5.2
6
- Tested up to: 5.4
7
  Requires PHP: 5.6
8
- Stable tag: 2.34.0
9
 
10
  View changes made by users within WordPress. See who created a page, uploaded an attachment or approved an comment, and more.
11
 
@@ -189,11 +189,19 @@ Events in the log are stored for 60 days by default. Events older than this will
189
 
190
  == Changelog ==
191
 
192
- ## Changelog
193
 
194
- ### [Unreleased]
195
 
196
- = 2.34 (January 2020) =
 
 
 
 
 
 
 
 
197
 
198
  **Changed**
199
 
3
  Donate link: https://www.paypal.me/eskapism
4
  Tags: history, log, changes, changelog, audit, audit log, event log, user tracking, trail, pages, attachments, users, dashboard, admin, syslog, feed, activity, stream, audit trail, brute-force
5
  Requires at least: 5.2
6
+ Tested up to: 5.5
7
  Requires PHP: 5.6
8
+ Stable tag: 2.35.0
9
 
10
  View changes made by users within WordPress. See who created a page, uploaded an attachment or approved an comment, and more.
11
 
189
 
190
  == Changelog ==
191
 
192
+ = unreleased =
193
 
194
+ You can now [sponsor the developer of this plugin at GitHub](https://github.com/sponsors/bonny/).
195
 
196
+ **Fixed**
197
+
198
+ - Fix PHP Warning when bulk editing items in the Redirection plugin. Fixes https://github.com/bonny/WordPress-Simple-History/issues/207, https://wordpress.org/support/topic/crashes-with-redirection-plugin/. (https://github.com/bonny/WordPress-Simple-History/commit/e8be051c4d95e598275a7ba17a01f76008eb7a5b)
199
+
200
+ **Changed**
201
+
202
+ - Welcome text updated to be more correct. (https://github.com/bonny/WordPress-Simple-History/pull/211)
203
+
204
+ = 2.34 (June 2020) =
205
 
206
  **Changed**
207