WP Security Audit Log - Version 0.3

Version Description

  • New WordPress Security Alerts

    • Alert 6001: Anyone can Register option in WordPress settings was changed
    • Alert 6002: Default use role in WordPress settings was changed
    • Alert 6003: Administrator notification email in WordPress settings was changed
    • Alert 2025: Visibility of a blog post was changed
    • Alert 2026: Visibility of a page was changed
    • Alert 2027: Date of a blog post was changed
    • Alert 2028: Date of a page was changed
  • Plugin Improvements

    • Links to the Audit Log Viewer and Settings in the plugin summary page
    • Time of Failed Login alerts now reflects the time of last failed login attempt
  • Bug Fixes

    • Fixed: Incorrect alerts generated when author of page was changed from quick edit mode
    • Fixed: Conflict with WP Mandrill and other plugins using pluggable.php
    • Fixed: Incorrect alerts generated when plugin is installed via a zip file / upload method
Download this release

Release Info

Developer WPWhiteSecurity
Plugin Icon 128x128 WP Security Audit Log
Version 0.3
Comparing to
See all releases

Code changes from version 0.2 to 0.3

inc/WPPH.php CHANGED
@@ -109,25 +109,33 @@ class WPPH
109
 
110
  public static function onPluginActivate()
111
  {
 
 
112
  $optErrorData = array();
113
  $canContinue = true;
114
- // Check: MySQL, PHP - without these there's not much left for this plugin to do
115
- if(! self::__checkMySQL()){
 
116
  $optErrorData = self::__addError($optErrorData, 'e400');
 
117
  $canContinue = false;
118
  }
119
- if(! self::__checkPHP()){
120
  $optErrorData = self::__addError($optErrorData, 'e300');
 
121
  $canContinue = false;
122
  }
123
- // no need for further checks, the plugin cannot run on this server...
124
  if(! $canContinue){
125
  $optErrorData = self::__addError($optErrorData, 'e500');
126
  update_option(WPPH_PLUGIN_ERROR_OPTION_NAME, $optErrorData);
 
127
  return false;
128
  }
129
 
130
- // check to see whether or not an upgrade is necessary
 
 
131
  $v = get_option(WPPH_PLUGIN_VERSION_OPTION_NAME,false);
132
  if($v != false)
133
  {
@@ -135,31 +143,50 @@ class WPPH
135
  $cv = (float)WPPH_PLUGIN_VERSION;
136
  //#! no need for upgrade
137
  if($v == $cv){
 
138
  update_option(WPPH_PLUGIN_VERSION_OPTION_NAME, WPPH_PLUGIN_VERSION);
139
  WPPHEvent::hookWatchPluginActivity(); //#! log self installation
140
  return true;
141
  }
142
  }
143
-
144
- if(! WPPHDatabase::v2Cleanup()){
145
- $optErrorData = self::__addError($optErrorData, 'e600');
146
- update_option(WPPH_PLUGIN_ERROR_OPTION_NAME, $optErrorData);
147
- return false;
 
 
 
 
 
 
 
 
 
148
  }
149
 
150
  //#! run the upgrade / update
151
- if(($result = WPPHDatabase::handleTables()) !== true)
152
- {
153
  $optErrorData = self::__addError($optErrorData, 'e'.$result);
154
  }
155
 
156
  if(empty($optErrorData)){
 
157
  update_option(WPPH_PLUGIN_VERSION_OPTION_NAME, WPPH_PLUGIN_VERSION);
 
 
 
 
 
 
 
 
158
  WPPHEvent::hookWatchPluginActivity(); //#! log self installation
159
  return true;
160
  }
161
 
162
  update_option(WPPH_PLUGIN_ERROR_OPTION_NAME, $optErrorData);
 
163
  return false;
164
  }
165
 
@@ -168,10 +195,10 @@ class WPPH
168
  */
169
  public static function onPluginDeactivate()
170
  {
 
171
  if(self::optionExists(WPPH_PLUGIN_ERROR_OPTION_NAME)){ delete_option(WPPH_PLUGIN_ERROR_OPTION_NAME); }
172
  if(self::optionExists(WPPH_PLUGIN_SETTING_NAME)){ delete_option(WPPH_PLUGIN_SETTING_NAME); }
173
- wp_clear_scheduled_hook(WPPH_PLUGIN_DEL_EVENTS_CRON_TASK_NAME);
174
- wpphLog('Plugin deactivated.');
175
  }
176
 
177
 
@@ -203,7 +230,17 @@ class WPPH
203
 
204
  public static function getPluginErrors() { return get_option(WPPH_PLUGIN_ERROR_OPTION_NAME,null); }
205
 
206
- private static function __checkMySQL(){
 
 
 
 
 
 
 
 
 
 
207
  global $wpdb;
208
  $v = $wpdb->get_var("SELECT VERSION();");
209
  if(empty($v)){ return false; }
@@ -211,7 +248,7 @@ class WPPH
211
  if(intval($v[0]) < 5){ return false; }
212
  return true;
213
  }
214
- private static function __checkPHP(){ return (version_compare(phpversion(), '5.0.0', '>')); }
215
  }
216
 
217
 
109
 
110
  public static function onPluginActivate()
111
  {
112
+ wpphLog(__FUNCTION__.'() triggered. Checking if the plugin needs to be updated.');
113
+
114
  $optErrorData = array();
115
  $canContinue = true;
116
+
117
+ // Check: MySQL, PHP - without these there's not much left for this plugin to do
118
+ if(! self::checkMySQL()){
119
  $optErrorData = self::__addError($optErrorData, 'e400');
120
+ update_option(WPPH_PLUGIN_ERROR_OPTION_NAME, $optErrorData);
121
  $canContinue = false;
122
  }
123
+ if(! self::checkPHP()){
124
  $optErrorData = self::__addError($optErrorData, 'e300');
125
+ update_option(WPPH_PLUGIN_ERROR_OPTION_NAME, $optErrorData);
126
  $canContinue = false;
127
  }
128
+ // no need for further checks, the plugin cannot run on this server...
129
  if(! $canContinue){
130
  $optErrorData = self::__addError($optErrorData, 'e500');
131
  update_option(WPPH_PLUGIN_ERROR_OPTION_NAME, $optErrorData);
132
+ $GLOBALS['WPPH_CAN_RUN'] = false;
133
  return false;
134
  }
135
 
136
+ $triggerInstall = false;
137
+
138
+ // check to see whether or not an upgrade is necessary
139
  $v = get_option(WPPH_PLUGIN_VERSION_OPTION_NAME,false);
140
  if($v != false)
141
  {
143
  $cv = (float)WPPH_PLUGIN_VERSION;
144
  //#! no need for upgrade
145
  if($v == $cv){
146
+ delete_option(WPPH_PLUGIN_ERROR_OPTION_NAME);
147
  update_option(WPPH_PLUGIN_VERSION_OPTION_NAME, WPPH_PLUGIN_VERSION);
148
  WPPHEvent::hookWatchPluginActivity(); //#! log self installation
149
  return true;
150
  }
151
  }
152
+ else { $triggerInstall = true; }
153
+
154
+ // check to see whether or not the tables exist - if true, it means the installed version is 0.1
155
+ // and we need to clear the tables before upgrading them
156
+ if(WPPHDatabase::tablesExist()){
157
+ $triggerInstall = false;
158
+ if(!empty($v) && version_compare($v, '0.2', '<')){
159
+ wpphLog('Version 0.1 detected. Cleaning out the tables.');
160
+ if(! WPPHDatabase::v2Cleanup()){
161
+ $optErrorData = self::__addError($optErrorData, 'e600');
162
+ update_option(WPPH_PLUGIN_ERROR_OPTION_NAME, $optErrorData);
163
+ return false;
164
+ }
165
+ }
166
  }
167
 
168
  //#! run the upgrade / update
169
+ if(($result = self::wpphDoUpdate()) != true){
 
170
  $optErrorData = self::__addError($optErrorData, 'e'.$result);
171
  }
172
 
173
  if(empty($optErrorData)){
174
+ delete_option(WPPH_PLUGIN_ERROR_OPTION_NAME);
175
  update_option(WPPH_PLUGIN_VERSION_OPTION_NAME, WPPH_PLUGIN_VERSION);
176
+
177
+ if($triggerInstall){
178
+ define('WPPH_PLUGIN_INSTALLED_OK',true);
179
+ $current_user = wp_get_current_user();
180
+ WPPHEvent::_addLogEvent(5000,$current_user->ID, WPPHUtil::getIP(), array(WPPH_PLUGIN_NAME));
181
+ wpphLog('Plugin installed.', array('plugin'=>WPPH_PLUGIN_NAME));
182
+ }
183
+
184
  WPPHEvent::hookWatchPluginActivity(); //#! log self installation
185
  return true;
186
  }
187
 
188
  update_option(WPPH_PLUGIN_ERROR_OPTION_NAME, $optErrorData);
189
+ $GLOBALS['WPPH_CAN_RUN'] = false;
190
  return false;
191
  }
192
 
195
  */
196
  public static function onPluginDeactivate()
197
  {
198
+ wp_clear_scheduled_hook(WPPH_PLUGIN_DEL_EVENTS_CRON_TASK_NAME);
199
  if(self::optionExists(WPPH_PLUGIN_ERROR_OPTION_NAME)){ delete_option(WPPH_PLUGIN_ERROR_OPTION_NAME); }
200
  if(self::optionExists(WPPH_PLUGIN_SETTING_NAME)){ delete_option(WPPH_PLUGIN_SETTING_NAME); }
201
+ wpphLog('__FUNCTION__.() triggered.');
 
202
  }
203
 
204
 
230
 
231
  public static function getPluginErrors() { return get_option(WPPH_PLUGIN_ERROR_OPTION_NAME,null); }
232
 
233
+ public static function wpphDoUpdate()
234
+ {
235
+ wpphLog(__FUNCTION__.'() triggered. Running the update.');
236
+ if(($result = WPPHDatabase::handleTables()) !== true)
237
+ {
238
+ return $result;
239
+ }
240
+ return true;
241
+ }
242
+
243
+ public static function checkMySQL(){
244
  global $wpdb;
245
  $v = $wpdb->get_var("SELECT VERSION();");
246
  if(empty($v)){ return false; }
248
  if(intval($v[0]) < 5){ return false; }
249
  return true;
250
  }
251
+ public static function checkPHP(){ return (version_compare(phpversion(), '5.0.0', '>=')); }
252
  }
253
 
254
 
inc/WPPHDatabase.php CHANGED
@@ -36,16 +36,14 @@ class WPPHDatabase
36
  //================================================================================================================
37
 
38
  /**
39
- * @temp
40
  * @internal
41
- * Prepares the tables for v0.2 upgrade as there are some differencies between old & new events
42
  */
43
  public static function v2Cleanup()
44
  {
45
  global $wpdb;
46
 
47
  // empty table 1
48
-
49
  if(self::_eventLogsTableExists())
50
  {
51
  $query = "TRUNCATE ".$wpdb->prefix.self::$_eventsLogTableBaseName;
@@ -75,10 +73,6 @@ class WPPHDatabase
75
 
76
  public static function handleTables()
77
  {
78
- if(! self::$_canUpgrade){
79
- return 6;
80
- }
81
-
82
  if(! self::tablesExist())
83
  {
84
  $result = WPPHDatabase::createTables();
@@ -136,8 +130,10 @@ class WPPHDatabase
136
 
137
  public static function upgradeTables()
138
  {
 
139
  $optData = get_option(WPPH_PLUGIN_DB_UPDATED);
140
  if($optData !== false){
 
141
  if($optData == 1){ return true; }
142
  }
143
 
@@ -153,11 +149,6 @@ class WPPHDatabase
153
 
154
  public static function updateTables()
155
  {
156
- $optData = get_option(WPPH_PLUGIN_DB_UPDATED);
157
- if($optData !== false){
158
- if($optData == 1){ return true; }
159
- }
160
-
161
  if(! @self::_updateEventsDetailsTable()){
162
  return 1;
163
  }
@@ -297,10 +288,6 @@ class WPPHDatabase
297
  private static function _upgradeEventDetailsTable()
298
  {
299
  //EXECUTE THE QUERY FROM self::getUpgradeQueryEventsDetailsTable();
300
- $optData = get_option(WPPH_PLUGIN_DB_UPDATED);
301
- if($optData !== false){
302
- if($optData == 1){ return true; }
303
- }
304
  $queries = self::getUpgradeQueryEventsDetailsTable();
305
  if(empty($queries)){ return true; }
306
 
@@ -330,10 +317,6 @@ class WPPHDatabase
330
  private static function _upgradeEventLogsTable()
331
  {
332
  //EXECUTE THE QUERY FROM self::getUpgradeQueryLogsTable();
333
- $optData = get_option(WPPH_PLUGIN_DB_UPDATED);
334
- if($optData !== false){
335
- if($optData == 1){ return true; }
336
- }
337
  $queries = self::getUpgradeQueryLogsTable();
338
  if(empty($queries)){ return true;}
339
  global $wpdb;
36
  //================================================================================================================
37
 
38
  /**
 
39
  * @internal
40
+ * Prepares the tables for future upgrades from v0.1
41
  */
42
  public static function v2Cleanup()
43
  {
44
  global $wpdb;
45
 
46
  // empty table 1
 
47
  if(self::_eventLogsTableExists())
48
  {
49
  $query = "TRUNCATE ".$wpdb->prefix.self::$_eventsLogTableBaseName;
73
 
74
  public static function handleTables()
75
  {
 
 
 
 
76
  if(! self::tablesExist())
77
  {
78
  $result = WPPHDatabase::createTables();
130
 
131
  public static function upgradeTables()
132
  {
133
+ wpphLog(__FUNCTION__.'() triggered.');
134
  $optData = get_option(WPPH_PLUGIN_DB_UPDATED);
135
  if($optData !== false){
136
+ wpphLog('Database is already updated.');
137
  if($optData == 1){ return true; }
138
  }
139
 
149
 
150
  public static function updateTables()
151
  {
 
 
 
 
 
152
  if(! @self::_updateEventsDetailsTable()){
153
  return 1;
154
  }
288
  private static function _upgradeEventDetailsTable()
289
  {
290
  //EXECUTE THE QUERY FROM self::getUpgradeQueryEventsDetailsTable();
 
 
 
 
291
  $queries = self::getUpgradeQueryEventsDetailsTable();
292
  if(empty($queries)){ return true; }
293
 
317
  private static function _upgradeEventLogsTable()
318
  {
319
  //EXECUTE THE QUERY FROM self::getUpgradeQueryLogsTable();
 
 
 
 
320
  $queries = self::getUpgradeQueryLogsTable();
321
  if(empty($queries)){ return true;}
322
  global $wpdb;
inc/WPPHEvent.php CHANGED
@@ -69,6 +69,14 @@ class WPPHEvent
69
  array( 'id' => 2023, 'category' => 'NOTICE', 'text' => __('Created a new category called <strong>%s</strong>.') ),
70
  // 2024 - deleted category
71
  array( 'id' => 2024, 'category' => 'WARNING', 'text' => __('Deleted the <strong>%s</strong> category.') ),
 
 
 
 
 
 
 
 
72
 
73
  // 3xxx - Themes management
74
  // Activated the theme %themeName%
@@ -100,8 +108,14 @@ class WPPHEvent
100
  array( 'id' => 5004, 'category' => 'WARNING', 'text' => __('Upgraded the plugin <strong>%s</strong> installed in /<strong>%s</strong>.') ),
101
 
102
  // 6xxx - System events
103
- //
104
  array( 'id' => 6000, 'category' => 'NOTICE', 'text' => __('Events automatically deleted by system.') ),
 
 
 
 
 
 
105
  );
106
  }
107
 
@@ -147,12 +161,15 @@ class WPPHEvent
147
  // 2016, 2017
148
  public static function hookWatchPostStateBefore()
149
  {
 
 
150
  if(isset($_POST['action']) && $_POST['action'] == 'autosave') { return; }
151
 
152
  if(isset($GLOBALS['WPPH_DEFAULT_EDITOR_ENABLED']) || isset($GLOBALS['WPPH_SCREEN_EDITOR_ENABLED']))
153
  {
154
  wpphLog(__METHOD__.'() triggered by hook.');
155
 
 
156
  $pid = $_POST['post_ID'];
157
 
158
  /*
@@ -162,26 +179,42 @@ class WPPHEvent
162
  */
163
  if(! empty($_POST['post_author']))
164
  {
165
- $GLOBALS['WPPH_POST_AUTHOR_UPDATED'] = intval($_POST['post_author']);
166
  if(isset($GLOBALS['WPPH_SCREEN_EDITOR_ENABLED'])){
167
  // trigger hook manually
168
  add_filter( 'wp_insert_post_data', 'wpph_managePostAuthorUpdateQuickEditForm', '1', 2 );
 
 
169
  }
170
  }
171
 
 
 
 
 
 
 
 
 
172
  // if blog post
173
  if($_POST['post_type'] == 'post')
174
  {
175
  // before further checks, we have to make sure this post isn't new
176
- global $wpdb;
177
- $postExists = (bool)$wpdb->get_var("SELECT ID FROM ".$wpdb->posts." WHERE ID = ".$pid);
178
- if(! $postExists){
179
  return;
180
  }
181
 
182
- /*
183
- * CHECK IF POST CATEGORY UPDATED; 2016
184
- */
 
 
 
 
 
 
 
 
185
  $GLOBALS['WPPH_POST_OLD_CATEGORIES'] = wp_get_post_categories($pid);
186
 
187
  /*
@@ -194,11 +227,23 @@ class WPPHEvent
194
  // if page
195
  elseif($_POST['post_type'] == 'page')
196
  {
 
 
 
 
 
 
 
 
 
 
 
 
197
  /*
198
- * CHECK IF PAGE URL UPDATED; 2018
199
- * ## step 1: this is where we retrieve the new URL
200
- * ## step 2: @see WPPHEventWatcher::watchBlogActivity()
201
- */
202
  $GLOBALS['WPPH_POST_NEW_URL'] = get_permalink($pid);
203
  }
204
  }
@@ -209,7 +254,6 @@ class WPPHEvent
209
  // 2024
210
  public static function hookWatchCategoryDelete() { WPPHEventWatcher::watchCategoryDelete($_POST); }
211
 
212
-
213
  // 3xxx - Themes management
214
 
215
  // 3000
@@ -257,6 +301,60 @@ class WPPHEvent
257
  // 6000
258
  public static function hookEventsDeletion() { add_action('init', array('WPPHEventWatcher', 'watchDeleteEvents')); }
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
 
261
  /**
262
  * Add log event. Internal function. Don not use outside class scope.
@@ -705,7 +803,7 @@ class WPPHEventWatcher extends WPPHEvent
705
  $current_user = wp_get_current_user();
706
 
707
  // activate one by link
708
- if(! empty($_GET['action']) && ($_GET['action']=='activate') || !empty($_GET['action2']) && ($_GET['action2']=='activate'))
709
  {
710
  $pluginFile = $_GET['plugin'];
711
  $pluginData = get_plugin_data(WP_PLUGIN_DIR.'/'.$pluginFile,false,false);
@@ -787,6 +885,7 @@ class WPPHEventWatcher extends WPPHEvent
787
  // # 5000
788
  public static function watchPluginInstall()
789
  {
 
790
  if(empty($_GET)) { return; }
791
 
792
  /**
@@ -840,47 +939,60 @@ class WPPHEventWatcher extends WPPHEvent
840
  // # 5004
841
  public static function watchPluginUpgrade()
842
  {
843
- // single update/upgrade
844
- if(! empty($_GET['action']))
 
 
 
 
 
 
 
 
 
845
  {
846
- $action = '';
847
- if(! empty($_GET['action'])){ $action = $_GET['action'];}
848
- elseif(! empty($_GET['action2'])){ $action = $_GET['action2'];}
849
- if(empty($action) || $action != 'upgrade-plugin') {
 
 
 
 
 
 
 
 
 
 
 
850
  return;
851
  }
852
- wpphLog(__METHOD__.'() triggered by hook.');
853
-
854
- // get info for the currently logged in user
855
- $current_user = wp_get_current_user();
856
- $pluginFile = $_GET['plugin'];
857
- $pluginData = get_plugin_data(WP_PLUGIN_DIR.'/'.$pluginFile,false,false);
858
- $pluginName = $pluginData['Name'];
859
- // Upgraded the plugin <strong>%s</strong> installed in /<strong>%s</strong>
860
- self::_addLogEvent(5004,$current_user->ID, WPPHUtil::getIP(), array($pluginName,$pluginFile));
861
- wpphLog('Plugin upgraded.', array('plugin file'=>$pluginFile));
862
  }
863
- // multi-update/upgrade
864
- elseif(! empty($_POST))
865
  {
866
  $action = '';
867
- if(! empty($_POST['action'])){ $action = $_POST['action'];}
868
- elseif(! empty($_POST['action2'])){ $action = $_POST['action2'];}
869
- if(empty($action) || $action != 'update-selected') { return; }
870
- if(empty($_POST['checked'])){ return; }
871
- if(empty($_POST['_wp_http_referer'])){ return; }
872
- $referrer = $_POST['_wp_http_referer'];
873
- if(false === ($pos = stripos($referrer, 'plugins.php'))){
874
- return;
 
 
 
875
  }
876
- wpphLog(__METHOD__.'() triggered by hook.');
877
 
878
- // get info for the currently logged in user
879
- $current_user = wp_get_current_user();
880
- foreach($_POST['checked'] as $pluginFile){
 
881
  $pluginData = get_plugin_data(WP_PLUGIN_DIR.'/'.$pluginFile,false,false);
882
  $pluginName = $pluginData['Name'];
883
- self::_addLogEvent(5004,$current_user->ID, WPPHUtil::getIP(), array($pluginName,$pluginFile));
884
  wpphLog('Plugin upgraded.', array('plugin file'=>$pluginFile));
885
  }
886
  }
@@ -889,20 +1001,19 @@ class WPPHEventWatcher extends WPPHEvent
889
 
890
  public static function watchBlogActivity($newStatus, $oldStatus, $post)
891
  {
892
- wpphLog(__FUNCTION__.'. POST DATA', array(
893
- '$newStatus' => $newStatus,
 
 
894
  '$oldStatus' => $oldStatus,
 
895
  '$post' => $post
896
  ));
897
 
898
- // IGNORE STATES
899
- if($newStatus == 'auto-draft' || $post->post_status == 'auto-draft')
900
- {
901
- return;
902
- }
903
-
904
- // so we skip generating multiple events
905
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; }
 
 
906
 
907
  $postID = $post->ID;
908
  $postTitle = $post->post_title;
@@ -915,13 +1026,6 @@ class WPPHEventWatcher extends WPPHEvent
915
  $userID = $currentUserID;
916
  }
917
 
918
- if($post->post_type == 'revision'){
919
- return;
920
- }
921
-
922
- wpphLog(__FUNCTION__.' triggered by hook.');
923
-
924
-
925
  // CHECK TO SEE IF THIS UPDATE IS FROM THE QUICK EDIT FORM or the default wp post editor
926
  if(isset($_POST['original_post_status']))
927
  {
@@ -929,212 +1033,166 @@ class WPPHEventWatcher extends WPPHEvent
929
  }
930
  else{
931
  // quick edit form
932
- $originalPostStatus = $_POST['_status'];
933
  }
934
 
 
 
 
 
935
 
936
- // We're dealing with posts
937
- if($post->post_type == 'post')
938
- {
939
- /**
940
- * @@ 2016
941
- * Check for category change
942
- */
943
- if(isset($GLOBALS['WPPH_POST_OLD_CATEGORIES']))
944
- {
945
- $originalCats = $GLOBALS['WPPH_POST_OLD_CATEGORIES'];
946
- $categories_1 = array();
947
- foreach($originalCats as $catID){
948
- $cat = get_category($catID);
949
- array_push($categories_1, $cat->name);
950
- }
951
- $categories_2 = array();
952
- $newCats = $post->post_category;
953
- if(empty($newCats[0])){
954
- unset($newCats[0]);
955
- }
956
- foreach($newCats as $catID){
957
- $cat = get_category($catID);
958
- array_push($categories_2, $cat->name);
959
- }
960
 
961
- sort($categories_1);
962
- sort($categories_2);
963
 
964
- // categories updated
965
- if($categories_1 <> $categories_2)
966
- {
967
- $c1 = implode(', ', $categories_1);
968
- $c2 = implode(', ', $categories_2);
969
- wpph_postCategoriesUpdated(wp_get_current_user()->ID, $postTitle, $c1, $c2);
970
- $GLOBALS['WPPH_EVENT_2016'] = true;
971
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
972
  }
 
973
 
974
- // 2019
975
- // check to see whether or not the post author was changed
976
- if(isset($GLOBALS['WPPH_POST_AUTHOR_UPDATED'])){
977
- $newAuthorID = (int)$GLOBALS['WPPH_POST_AUTHOR_UPDATED'];
978
- if(wpph_postAuthorUpdated($newAuthorID, $postID, $userID, $postTitle)){
979
- unset($GLOBALS['WPPH_POST_AUTHOR_UPDATED']);
980
- $GLOBALS['WPPH_EVENT_2019'] = true;
981
- }
982
  }
 
 
 
 
 
983
 
984
- // # 2000 - NEW POST AS DRAFT
985
- // # 2003 - DRAFT UPDATED
986
- if(($oldStatus == 'draft' || $oldStatus == 'auto-draft') && $newStatus == 'draft' && $postStatus == 'draft')
 
987
  {
988
- // # 2000 - NEW POST AS DRAFT
989
- if($originalPostStatus == 'auto-draft')
990
- {
991
- // New blog post saved as draft
992
- wpph_newPostAsDraft($userID, $postID, $postTitle);
993
- }
994
- // # 2003 - DRAFT UPDATED
995
- elseif($originalPostStatus == 'draft')
996
- {
997
  // only if 2016 || 2017 || 2019 were not triggered
998
- if(isset($GLOBALS['WPPH_EVENT_2016']) || isset($GLOBALS['WPPH_EVENT_2017']) || isset($GLOBALS['WPPH_EVENT_2019'])){
999
- return;
 
 
1000
  }
1001
- // Modified the draft blog post %post_title%. Blog post ID is %ID%
1002
- wpph_draftPostUpdated($userID, $postID, $postTitle);
1003
  }
1004
- }
1005
- // # 2001 - DRAFT TO PUBLISHED
1006
- elseif($oldStatus == 'draft' && $newStatus == 'publish' && $postStatus == 'publish'){
1007
- // Published a blog post called %Post_Title%. Blog post URL is %Post_URL%
1008
- wpph_newPostPublished($userID, $postTitle, $postUrl);
1009
- }
1010
- // # 2001 - NEW POST PUBLISHED
1011
- elseif($oldStatus == 'auto-draft' && $newStatus == 'publish' && $postStatus == 'publish'){
1012
- // Published a blog post called %Post_Title%. Blog post URL is %Post_URL%
1013
- wpph_newPostPublished($userID, $postTitle, $postUrl);
1014
- }
1015
- // # 2001 - PENDING TO PUBLISHED
1016
- elseif($oldStatus == 'pending' && $newStatus == 'publish' && $postStatus == 'publish'){
1017
- // Published a blog post called %Post_Title%. Blog post URL is %Post_URL%
1018
- wpph_newPostPublished($userID, $postTitle, $postUrl);
1019
- }
1020
- // # 2002 - PUBLISHED POST UPDATED
1021
- elseif($oldStatus == 'publish' && $newStatus == 'publish' && $postStatus == 'publish')
1022
- {
1023
- // CHECK IF POST URL MODIFIED
1024
- // ## step 1: see self::hookWatchPostStateBefore()
1025
- // ## step 2: trigger event
1026
- // trigger: 2017 - Changed the URL of the post %post_name% from %old_url% to %new_url%
1027
- if(isset($GLOBALS['WPPH_POST_NEW_URL']))
1028
- {
1029
- if(wpph_postUrlUpdated($GLOBALS['WPPH_POST_NEW_URL'], get_permalink($postID), $userID, $postTitle)){
1030
- unset($GLOBALS['WPPH_POST_NEW_URL']);
1031
- $GLOBALS['WPPH_EVENT_2017'] = true;
1032
  }
1033
  }
1034
- // only if 2016 || 2017 || 2019 were not triggered
1035
- if(isset($GLOBALS['WPPH_EVENT_2016']) || isset($GLOBALS['WPPH_EVENT_2017']) || isset($GLOBALS['WPPH_EVENT_2019'])){
1036
- return;
1037
- }
1038
- // Modified the published blog post %post_title%. Blog post URL is %post_URL%
1039
- wpph_publishedPostUpdated($userID, $postTitle, $postUrl);
1040
- }
1041
- // # 2021 - PUBLISHED TO PENDING
1042
- elseif($oldStatus == 'publish' && $newStatus == 'pending' && $postStatus == 'pending'){
1043
- wpph_postStatusUpdated('Published', 'Pending Review', $userID, $postTitle);
1044
- }
1045
- // # 2021 - PENDING TO DRAFT
1046
- elseif($oldStatus == 'pending' && $newStatus == 'draft' && $postStatus == 'draft'){
1047
- wpph_postStatusUpdated('Pending Review', 'Draft', $userID, $postTitle);
1048
- }
1049
- // # 2021 - DRAFT TO PENDING
1050
- elseif($oldStatus == 'draft' && $newStatus == 'pending' && $postStatus == 'pending'){
1051
- wpph_postStatusUpdated('Draft', 'Pending Review', $userID, $postTitle);
1052
- }
1053
- // # 2021 - PUBLISHED TO DRAFT
1054
- elseif($oldStatus == 'publish' && $newStatus == 'draft' && $postStatus == 'draft'){
1055
- wpph_postStatusUpdated('Published', 'Draft', $userID, $postTitle);
1056
  }
1057
  }
1058
- // We're dealing with pages
1059
- elseif($post->post_type == 'page')
 
1060
  {
1061
- // 2020
1062
- // check to see whether or not the page author was changed
1063
- if(isset($GLOBALS['WPPH_POST_AUTHOR_UPDATED'])){
1064
- $newAuthorID = (int)$GLOBALS['WPPH_POST_AUTHOR_UPDATED'];
1065
- if(wpph_pageAuthorUpdated($newAuthorID, $postID, $userID, $postTitle)){
1066
- unset($GLOBALS['WPPH_POST_AUTHOR_UPDATED']);
1067
- $GLOBALS['WPPH_EVENT_2020'] = true;
1068
- }
1069
- }
1070
 
1071
- // # 2004 - NEW PAGE AS DRAFT
1072
- // # 2007 - DRAFT UPDATED
1073
- if(($oldStatus == 'draft' || $oldStatus == 'auto-draft') && $newStatus == 'draft' && $postStatus == 'draft')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1074
  {
1075
- // # 2004 - NEW PAGE AS DRAFT
1076
- if($originalPostStatus == 'auto-draft'){
1077
- wpph_newPageAsDraft($userID, $postID, $postTitle);
 
 
1078
  }
1079
- // # 2007 - DRAFT UPDATED
1080
- elseif($originalPostStatus == 'draft'){
1081
- // only if 2018 || 2020 were not triggered
1082
- if(isset($GLOBALS['WPPH_EVENT_2018']) || isset($GLOBALS['WPPH_EVENT_2020'])){
1083
- return;
 
 
 
 
 
1084
  }
1085
- wpph_draftPageUpdated($userID, $postID, $postTitle);
1086
  }
1087
  }
1088
- // # 2005 - DRAFT TO PUBLISHED
1089
- elseif($oldStatus == 'draft' && $newStatus == 'publish' && $postStatus == 'publish'){
1090
- wpph_newPagePublished($userID, $postTitle, $postUrl);
1091
- }
1092
- // # 2005 - NEW PAGE PUBLISHED
1093
- elseif(($oldStatus == 'draft' || $oldStatus == 'auto-draft') && $newStatus == 'publish' && $postStatus == 'publish'){
1094
- // Published a page called %page_title%. Page URL is %URL%
1095
- wpph_newPagePublished($userID, $postTitle, $postUrl);
1096
- }
1097
- // # 2005 - PENDING TO PUBLISHED
1098
- elseif($oldStatus == 'pending' && $newStatus == 'publish' && $postStatus == 'publish'){
1099
- // Published a page called %page_title%. Page URL is %URL%
1100
- wpph_newPagePublished($userID, $postTitle, $postUrl);
1101
- }
1102
- // # 2006 - PUBLISHED PAGE UPDATED | 2018, 2020
1103
- elseif($oldStatus == 'publish' && $newStatus == 'publish' && $postStatus == 'publish')
1104
  {
1105
- // CHECK IF PAGE URL MODIFIED
1106
- // ## step 1: see self::hookWatchPostStateBefore()
1107
- // ## step 2: trigger event
1108
- // trigger: 2018 - Changed the URL of the page %post_name% from %old_url% to %new_url%
1109
- if(isset($GLOBALS['WPPH_POST_NEW_URL']))
1110
- {
1111
- if(wpph_pageUrlUpdated($GLOBALS['WPPH_POST_NEW_URL'], get_permalink($postID), $userID, $postTitle)){
1112
- unset($GLOBALS['WPPH_POST_NEW_URL']);
1113
- $GLOBALS['WPPH_EVENT_2018'] = true;
1114
  }
1115
  }
1116
- // only if 2018 || 2020 were not triggered
1117
- if(isset($GLOBALS['WPPH_EVENT_2018']) || isset($GLOBALS['WPPH_EVENT_2020'])){
1118
- return;
1119
- }
1120
- // Modified the published page %page_title%. Page URL is %URL%
1121
- wpph_publishedPageUpdated($userID, $postTitle, $postUrl);
1122
- }
1123
- // # 2022 - PUBLISHED TO PENDING
1124
- elseif($oldStatus == 'publish' && $newStatus == 'pending' && $postStatus == 'pending'){
1125
- wpph_pageStatusUpdated('Published', 'Pending Review', $userID, $postTitle);
1126
- }
1127
- // # 2022 - PENDING TO DRAFT
1128
- elseif($oldStatus == 'pending' && $newStatus == 'draft' && $postStatus == 'draft'){
1129
- wpph_pageStatusUpdated('Pending Review', 'Draft', $userID, $postTitle);
1130
- }
1131
- // # 2022 - DRAFT TO PENDING
1132
- elseif($oldStatus == 'draft' && $newStatus == 'pending' && $postStatus == 'pending'){
1133
- wpph_pageStatusUpdated('Draft', 'Pending Review', $userID, $postTitle);
1134
  }
1135
- // # 2022 - PUBLISHED TO DRAFT
1136
- elseif($oldStatus == 'publish' && $newStatus == 'draft' && $postStatus == 'draft'){
1137
- wpph_pageStatusUpdated('Published', 'Draft', $userID, $postTitle);
 
 
 
 
 
 
1138
  }
1139
  }
1140
  }
@@ -1175,10 +1233,16 @@ class WPPHEventWatcher extends WPPHEvent
1175
  // Uploaded the file %file name$ in %file location%
1176
  self::_addLogEvent(2010, $current_user->ID, WPPHUtil::getIP(), array($fileName, $dirName));
1177
  wpphLog('File uploaded.', array('title'=>$fileName, 'url'=>$dirName));
 
1178
  }
1179
  // 2011
1180
  public static function watchFileUploadedDeleted($attachmentID)
1181
  {
 
 
 
 
 
1182
  global $wpdb;
1183
  // get info for the currently logged in user
1184
  $current_user = wp_get_current_user();
@@ -1311,4 +1375,184 @@ class WPPHEventWatcher extends WPPHEvent
1311
  }
1312
  }
1313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1314
  }
69
  array( 'id' => 2023, 'category' => 'NOTICE', 'text' => __('Created a new category called <strong>%s</strong>.') ),
70
  // 2024 - deleted category
71
  array( 'id' => 2024, 'category' => 'WARNING', 'text' => __('Deleted the <strong>%s</strong> category.') ),
72
+ // 2025 - Changed the visibility of %post_name% blog post from %old_visibility% to %new_visibility%
73
+ array( 'id' => 2025, 'category' => 'WARNING', 'text' => __('Changed the visibility of <strong>%s</strong> blog post from <strong>%s</strong> to <strong>%s</strong>.') ),
74
+ // 2026 - Changed the visibility of %page_name% page from %old_visibility% to %new_visibility%
75
+ array( 'id' => 2026, 'category' => 'WARNING', 'text' => __('Changed the visibility of <strong>%s</strong> page from <strong>%s</strong> to <strong>%s</strong>.') ),
76
+ // 2027 - Changed the date of %post_name% blog post from %old_date% to %new_date%
77
+ array( 'id' => 2027, 'category' => 'NOTICE', 'text' => __('Changed the date of <strong>%s</strong> blog post from <strong>%s</strong> to <strong>%s</strong>.') ),
78
+ // 2028 - Changed the date of %post_name% page from %old_date% to %new_date%
79
+ array( 'id' => 2028, 'category' => 'NOTICE', 'text' => __('Changed the date of <strong>%s</strong> page from <strong>%s</strong> to <strong>%s</strong>.') ),
80
 
81
  // 3xxx - Themes management
82
  // Activated the theme %themeName%
108
  array( 'id' => 5004, 'category' => 'WARNING', 'text' => __('Upgraded the plugin <strong>%s</strong> installed in /<strong>%s</strong>.') ),
109
 
110
  // 6xxx - System events
111
+ // #6000 Events automatically deleted by system.
112
  array( 'id' => 6000, 'category' => 'NOTICE', 'text' => __('Events automatically deleted by system.') ),
113
+ // #6001 - <strong>%s</strong> the option Anyone can register
114
+ array( 'id' => 6001, 'category' => 'HIGH', 'text' => __('<strong>%s</strong> the option Anyone can register') ),
115
+ // #6002 - Changed the New User Default Role from <strong>%s</strong> to <strong>%s</strong>
116
+ array( 'id' => 6002, 'category' => 'HIGH', 'text' => __('Changed the New User Default Role from <strong>%s</strong> to <strong>%s</strong>') ),
117
+ // #6003 - Changed the WordPress administrator notifications email address from %old_email% to %new_mail%
118
+ array( 'id' => 6003, 'category' => 'HIGH', 'text' => __('Changed the WordPress administrator notifications email address from <strong>%s</strong> to <strong>%s</strong>') ),
119
  );
120
  }
121
 
161
  // 2016, 2017
162
  public static function hookWatchPostStateBefore()
163
  {
164
+ if(! isset($_POST)){ return; }
165
+ if(! is_admin()){ return; }
166
  if(isset($_POST['action']) && $_POST['action'] == 'autosave') { return; }
167
 
168
  if(isset($GLOBALS['WPPH_DEFAULT_EDITOR_ENABLED']) || isset($GLOBALS['WPPH_SCREEN_EDITOR_ENABLED']))
169
  {
170
  wpphLog(__METHOD__.'() triggered by hook.');
171
 
172
+ global $wpdb;
173
  $pid = $_POST['post_ID'];
174
 
175
  /*
179
  */
180
  if(! empty($_POST['post_author']))
181
  {
182
+ $GLOBALS['WPPH_POST_AUTHOR_UPDATED_ID'] = intval($_POST['post_author']);
183
  if(isset($GLOBALS['WPPH_SCREEN_EDITOR_ENABLED'])){
184
  // trigger hook manually
185
  add_filter( 'wp_insert_post_data', 'wpph_managePostAuthorUpdateQuickEditForm', '1', 2 );
186
+ // $GLOBALS['WPPH_POST_AUTHOR_UPDATED'] = true;
187
+ // $GLOBALS['WPPH_PAGE_AUTHOR_UPDATED'] = true;
188
  }
189
  }
190
 
191
+ // check if post exists
192
+ $query = "SELECT ID FROM ".$wpdb->posts." WHERE ID = ".$pid;
193
+ $postExists = $wpdb->get_var($query);
194
+ $GLOBALS['WPPH_POST_EXISTS'] = (empty($postExists) ? false : true);
195
+
196
+ // get aggregated data
197
+ $result = $wpdb->get_row("SELECT post_name, post_password, post_date FROM ".$wpdb->posts." WHERE ID = $pid");
198
+
199
  // if blog post
200
  if($_POST['post_type'] == 'post')
201
  {
202
  // before further checks, we have to make sure this post isn't new
203
+ if(empty($GLOBALS['WPPH_POST_EXISTS'])){
 
 
204
  return;
205
  }
206
 
207
+ if(! is_null($result))
208
+ {
209
+ // retrieve the old post pwd to help us detect the posts' visibility transition state
210
+ $GLOBALS['WPPH_OLD_POST_PASSWORD'] = $result->post_password;
211
+ // check if post date has been changed
212
+ $GLOBALS['WPPH_POST_OLD_DATE'] = $result->post_date;
213
+ // Get the post name so we'll know if URL was updated
214
+ $GLOBALS['WPPH_POST_OLD_NAME'] = $result->post_name;
215
+ }
216
+
217
+ // CHECK IF POST CATEGORY UPDATED; 2016
218
  $GLOBALS['WPPH_POST_OLD_CATEGORIES'] = wp_get_post_categories($pid);
219
 
220
  /*
227
  // if page
228
  elseif($_POST['post_type'] == 'page')
229
  {
230
+ if(! is_null($result))
231
+ {
232
+ // get the page's password if any (to trigger the 2026 event)
233
+ // retrieve the old post pwd to help us detect the posts' visibility transition state
234
+ $GLOBALS['WPPH_OLD_POST_PASSWORD'] = $result->post_password;
235
+ // check if post date has been changed
236
+ $GLOBALS['WPPH_POST_OLD_DATE'] = $result->post_date;
237
+ // Get the post name so we'll know if URL was updated
238
+ $GLOBALS['WPPH_POST_OLD_NAME'] = $result->post_name;
239
+ }
240
+
241
+
242
  /*
243
+ * CHECK IF PAGE URL UPDATED; 2018
244
+ * ## step 1: this is where we retrieve the new URL
245
+ * ## step 2: @see WPPHEventWatcher::watchBlogActivity()
246
+ */
247
  $GLOBALS['WPPH_POST_NEW_URL'] = get_permalink($pid);
248
  }
249
  }
254
  // 2024
255
  public static function hookWatchCategoryDelete() { WPPHEventWatcher::watchCategoryDelete($_POST); }
256
 
 
257
  // 3xxx - Themes management
258
 
259
  // 3000
301
  // 6000
302
  public static function hookEventsDeletion() { add_action('init', array('WPPHEventWatcher', 'watchDeleteEvents')); }
303
 
304
+ // 6001, 6002
305
+ public static function hookCheckWpGeneralSettings(){
306
+ if(isset($_POST))
307
+ {
308
+ $wpphOptData = get_option(WPPH_USERS_CAN_REGISTER_OPT_NAME);
309
+
310
+ // 6001
311
+ if(!empty($_POST['option_page']) && $_POST['option_page'] == 'general')
312
+ {
313
+ if(isset($_POST['users_can_register'])){
314
+ // on
315
+ if(false === $wpphOptData || 0 == $wpphOptData){
316
+ self::_addLogEvent(6001, wp_get_current_user()->ID, WPPHUtil::getIP(), array('Enabled'));
317
+ update_option(WPPH_USERS_CAN_REGISTER_OPT_NAME,1);
318
+ }
319
+ }
320
+ else {
321
+ // off
322
+ if(false === $wpphOptData || 1 == $wpphOptData){
323
+ self::_addLogEvent(6001, wp_get_current_user()->ID, WPPHUtil::getIP(), array('Disabled'));
324
+ update_option('wpph_users_can_register',0);
325
+ }
326
+ }
327
+
328
+ // 6002
329
+ if(! empty($_POST['default_role'])){
330
+ $from = get_option('default_role');
331
+ $to = trim($_POST['default_role']);
332
+ if(strcasecmp($from,$to)!=0){
333
+ wpphLog('Default user role changed',array(
334
+ 'from' => $from,
335
+ 'to' => $to
336
+ ));
337
+ self::_addLogEvent(6002, wp_get_current_user()->ID, WPPHUtil::getIP(), array($from, $to));
338
+ }
339
+ }
340
+
341
+ // 6003
342
+ if(! empty($_POST['admin_email'])){
343
+ $from = get_option('admin_email');
344
+ $to = trim($_POST['admin_email']);
345
+ if(strcasecmp($from,$to)!=0){
346
+ wpphLog('Admin email changed',array(
347
+ 'from' => $from,
348
+ 'to' => $to
349
+ ));
350
+ self::_addLogEvent(6003, wp_get_current_user()->ID, WPPHUtil::getIP(), array($from, $to));
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+
357
+
358
 
359
  /**
360
  * Add log event. Internal function. Don not use outside class scope.
803
  $current_user = wp_get_current_user();
804
 
805
  // activate one by link
806
+ if(!empty($_GET['action']) && ($_GET['action']=='activate') || !empty($_GET['action2']) && ($_GET['action2']=='activate'))
807
  {
808
  $pluginFile = $_GET['plugin'];
809
  $pluginData = get_plugin_data(WP_PLUGIN_DIR.'/'.$pluginFile,false,false);
885
  // # 5000
886
  public static function watchPluginInstall()
887
  {
888
+ if(defined('WPPH_PLUGIN_INSTALLED_OK')){ return; }
889
  if(empty($_GET)) { return; }
890
 
891
  /**
939
  // # 5004
940
  public static function watchPluginUpgrade()
941
  {
942
+ wpphLog(__METHOD__.'() triggered by hook.',array(
943
+ 'get' => $_GET,
944
+ 'post' => $_POST
945
+ ));
946
+
947
+ $current_user = wp_get_current_user();
948
+ $userID = $current_user->ID;
949
+ $ip = WPPHUtil::getIP();
950
+
951
+ //#! One by link
952
+ if(!empty($_GET))
953
  {
954
+ if(isset($_GET['action']) && !empty($_GET['action']))
955
+ {
956
+ $action = $_GET['action'];
957
+ if(! in_array($action, array('upgrade-plugin', 'update-selected'))){
958
+ return;
959
+ }
960
+ if(! empty($_GET['plugin'])){ $pluginFile = $_GET['plugin']; }
961
+ if(empty($pluginFile)){
962
+ return;
963
+ }
964
+ $pluginData = get_plugin_data(WP_PLUGIN_DIR.'/'.$pluginFile,false,false);
965
+ $pluginName = $pluginData['Name'];
966
+ // Upgraded the plugin <strong>%s</strong> installed in /<strong>%s</strong>
967
+ self::_addLogEvent(5004,$current_user->ID, WPPHUtil::getIP(), array($pluginName,$pluginFile));
968
+ wpphLog('Plugin upgraded.', array('plugin file'=>$pluginFile));
969
  return;
970
  }
 
 
 
 
 
 
 
 
 
 
971
  }
972
+ elseif(isset($_POST))
 
973
  {
974
  $action = '';
975
+ if(isset($_POST['action']) && !empty($_POST['action'])){
976
+ $action = $_POST['action'];
977
+ if(! in_array($action, array('upgrade-plugin', 'update-selected'))){
978
+ $action = '';
979
+ if(isset($_POST['action2']) && !empty($_POST['action2'])){
980
+ $action = $_POST['action2'];
981
+ if(! in_array($action, array('upgrade-plugin', 'update-selected'))){
982
+ return;
983
+ }
984
+ }
985
+ }
986
  }
987
+ if(empty($action)) { return; }
988
 
989
+ if(! isset($_POST['checked']) || empty($_POST['checked'])){
990
+ return;
991
+ }
992
+ foreach($_POST['checked'] as $i=>$pluginFile){
993
  $pluginData = get_plugin_data(WP_PLUGIN_DIR.'/'.$pluginFile,false,false);
994
  $pluginName = $pluginData['Name'];
995
+ self::_addLogEvent(5004,$userID, $ip, array($pluginName,$pluginFile));
996
  wpphLog('Plugin upgraded.', array('plugin file'=>$pluginFile));
997
  }
998
  }
1001
 
1002
  public static function watchBlogActivity($newStatus, $oldStatus, $post)
1003
  {
1004
+ wpphLog(__FUNCTION__.'() triggered.');
1005
+
1006
+
1007
+ wpphLog(__FUNCTION__.'. POST STATUS DATA', array(
1008
  '$oldStatus' => $oldStatus,
1009
+ '$newStatus' => $newStatus,
1010
  '$post' => $post
1011
  ));
1012
 
1013
+ // IGNORE STATES - so we skip generating multiple events
 
 
 
 
 
 
1014
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; }
1015
+ if($post->post_type == 'revision') {return;}
1016
+ if($newStatus == 'auto-draft' || ($oldStatus == 'new' && $newStatus=='auto-draft')) { return; }
1017
 
1018
  $postID = $post->ID;
1019
  $postTitle = $post->post_title;
1026
  $userID = $currentUserID;
1027
  }
1028
 
 
 
 
 
 
 
 
1029
  // CHECK TO SEE IF THIS UPDATE IS FROM THE QUICK EDIT FORM or the default wp post editor
1030
  if(isset($_POST['original_post_status']))
1031
  {
1033
  }
1034
  else{
1035
  // quick edit form
1036
+ $originalPostStatus = (isset($_POST['_status']) ? $_POST['_status'] : null);
1037
  }
1038
 
1039
+ if(empty($originalPostStatus)){
1040
+ wpphLog('$_POST["_status"] not found. $originalPostStatus is EMPTY - nothing to do here.');
1041
+ return;
1042
+ }
1043
 
1044
+ $postTypePost = $postTypePage = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1045
 
1046
+ if($post->post_type == 'post'){ $postTypePost = true;}
1047
+ elseif($post->post_type == 'page'){ $postTypePage = true;}
1048
 
1049
+ if(!$postTypePost && !$postTypePage){
1050
+ wpphLog('Ignored. Invalid post type');
1051
+ return;
1052
+ }
1053
+
1054
+ global $wpdb;
1055
+ //===============================================
1056
+
1057
+ //## 2025 & 2026
1058
+ self::watchPostVisibilityChange($oldStatus, $newStatus, $userID, $postTitle, $post, ($postTypePost) ? 2025 : 2026);
1059
+
1060
+ //## 2027 & 2028
1061
+ if(! in_array($oldStatus, array('new', 'auto-draft'))){
1062
+ self::watchPostDateChange($userID, $postTitle, $post->post_date, ($postTypePost) ? 2027 : 2028);
1063
+ }
1064
+
1065
+ //## 2016
1066
+ if($postTypePost){ self::watchPostCategoriesChange($post, $wpdb, $postTitle); }
1067
+
1068
+ //## 2019 & 2020
1069
+ $authorChanged = false;
1070
+ if(isset($GLOBALS['WPPH_POST_AUTHOR_UPDATED_ID']))
1071
+ {
1072
+ if(wpph_postAuthorChanged((int)$GLOBALS['WPPH_POST_AUTHOR_UPDATED_ID'], $postID, $userID, $postTitle, ($postTypePost) ? 2019 : 2020)){
1073
+ unset($GLOBALS['WPPH_POST_AUTHOR_UPDATED_ID']);
1074
+ $GLOBALS['WPPH_POST_AUTHOR_UPDATED'] = true;
1075
+ $authorChanged = true;
1076
  }
1077
+ }
1078
 
1079
+ if($newStatus != 'publish'){
1080
+ if($originalPostStatus == 'auto-draft' || ($oldStatus=='new' && $newStatus=='inherit' && $postStatus=='inherit'))
1081
+ {
1082
+ wpph_newPostAsDraft($userID, $postID, $postTitle, ($postTypePost) ? 2000 : 2004);
 
 
 
 
1083
  }
1084
+ }
1085
+
1086
+ // check if post/page modified
1087
+ $postModified = self::watchPostChanged($wpdb, $postID);
1088
+ wpphLog('POST MODIFIED',array('modified'=> $postModified ? 'true' : 'false'));
1089
 
1090
+ //## 2000 & 2003 & 2004 & 2007
1091
+ if(($oldStatus == 'draft') && ($newStatus == 'draft' && $postStatus == 'draft'))
1092
+ {
1093
+ if($originalPostStatus == 'draft')
1094
  {
1095
+ //## 2003 - draft post updated
1096
+ if($postTypePost){
 
 
 
 
 
 
 
1097
  // only if 2016 || 2017 || 2019 were not triggered
1098
+ if(isset($GLOBALS['WPPH_POST_CATEGORIES_UPDATED']) || isset($GLOBALS['WPPH_POST_URL_UPDATED']) || isset($GLOBALS['WPPH_POST_AUTHOR_UPDATED'])){}
1099
+ else {
1100
+ wpph_draftPostUpdated($userID, $postID, $postTitle, 2003);
1101
+ $postModified = false;
1102
  }
 
 
1103
  }
1104
+ //## 2007 - draft page updated
1105
+ else {
1106
+ // only if 2018 || 2020 were not triggered
1107
+ if(isset($GLOBALS['WPPH_PAGE_URL_UPDATED']) || isset($GLOBALS['WPPH_PAGE_AUTHOR_UPDATED'])){}
1108
+ else {
1109
+ wpph_draftPostUpdated($userID, $postID, $postTitle, 2007);
1110
+ $postModified = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1111
  }
1112
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1113
  }
1114
  }
1115
+
1116
+ //## 2001 & 2005 - new post/page published
1117
+ elseif(in_array($oldStatus, array('draft','auto-draft','pending')) && $newStatus == 'publish' && $postStatus == 'publish')
1118
  {
1119
+ wpph_newPostPublished($userID, $postTitle, $postUrl, ($postTypePost) ? 2001 : 2005);
1120
+ return; // no need to process further
1121
+ }
 
 
 
 
 
 
1122
 
1123
+ //## 2021 & 2022 : published -> pending
1124
+ elseif($oldStatus == 'publish' && $newStatus == 'pending' && $postStatus == 'pending')
1125
+ {
1126
+ wpph_postStatusChanged($postTitle, 'Published', 'Pending Review', $userID, ($postTypePost) ? 2021 : 2022);
1127
+ }
1128
+
1129
+ //## 2021 & 2022 : pending -> draft
1130
+ elseif($oldStatus == 'pending' && $newStatus == 'draft' && $postStatus == 'draft')
1131
+ {
1132
+ wpph_postStatusChanged($postTitle, 'Pending Review', 'Draft', $userID, ($postTypePost) ? 2021 : 2022);
1133
+ }
1134
+
1135
+ //## 2021 & 2022 : draft -> pending
1136
+ elseif($oldStatus == 'draft' && $newStatus == 'pending' && $postStatus == 'pending')
1137
+ {
1138
+ wpph_postStatusChanged($postTitle, 'Draft', 'Pending Review', $userID, ($postTypePost) ? 2021 : 2022);
1139
+ }
1140
+
1141
+ //## 2021 & 2022 : published -> draft
1142
+ elseif($oldStatus == 'publish' && $newStatus == 'draft' && $postStatus == 'draft')
1143
+ {
1144
+ wpph_postStatusChanged($postTitle, 'Published', 'Draft', $userID, ($postTypePost) ? 2021 : 2022);
1145
+ }
1146
+
1147
+ //## 2002 & 2006 : published post/page updated
1148
+ elseif($oldStatus == 'publish' && $newStatus == 'publish' && $postStatus == 'publish')
1149
+ {
1150
+ // CHECK IF POST URL MODIFIED
1151
+ // ## step 1: see self::hookWatchPostStateBefore()
1152
+ // ## step 2: trigger event
1153
+ // trigger: 2017 - Changed the URL of the post %post_name% from %old_url% to %new_url%
1154
+ if(isset($GLOBALS['WPPH_POST_NEW_URL']) || $postModified)
1155
  {
1156
+ if(wpph_postUrlUpdated($GLOBALS['WPPH_POST_NEW_URL'], get_permalink($postID), $userID, $postTitle, ($postTypePost) ? 2017 : 2018))
1157
+ {
1158
+ unset($GLOBALS['WPPH_POST_NEW_URL']);
1159
+ $GLOBALS['WPPH_POST_URL_UPDATED'] = $postTypePost;
1160
+ $GLOBALS['WPPH_PAGE_URL_UPDATED'] = $postTypePage;
1161
  }
1162
+ }
1163
+ if($postTypePost)
1164
+ {
1165
+ if(isset($GLOBALS['WPPH_POST_CATEGORIES_UPDATED']) || isset($GLOBALS['WPPH_POST_URL_UPDATED'])
1166
+ || isset($GLOBALS['WPPH_POST_AUTHOR_UPDATED']) || isset($GLOBALS['WPPH_POST_PROTECTED_TRANSITION'])
1167
+ || isset($GLOBALS['WPPH_POST_DATE_CHANGED']) || isset($GLOBALS['WPPH_PREVENT_BUBBLE'])){}
1168
+ // Modified the published blog post %post_title%. Blog post URL is %post_URL%
1169
+ else {
1170
+ if(! $authorChanged){
1171
+ wpph_publishedPostUpdated($userID, $postTitle, $postUrl, 2002);
1172
  }
 
1173
  }
1174
  }
1175
+ else
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1176
  {
1177
+ if(isset($GLOBALS['WPPH_PAGE_URL_UPDATED']) || isset($GLOBALS['WPPH_PAGE_AUTHOR_UPDATED'])
1178
+ || isset($GLOBALS['WPPH_PAGE_PROTECTED_TRANSITION']) || isset($GLOBALS['WPPH_POST_DATE_CHANGED'])
1179
+ || isset($GLOBALS['WPPH_PREVENT_BUBBLE'])){}
1180
+ // Modified the published page %page_title%. Page URL is %URL%
1181
+ else {
1182
+ if(! $authorChanged){
1183
+ wpph_publishedPostUpdated($userID, $postTitle, $postUrl, 2006);
 
 
1184
  }
1185
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1186
  }
1187
+ return;
1188
+ }
1189
+
1190
+ // if post name changed - we probably have a URL change here
1191
+ if($postModified){
1192
+ if( isset($GLOBALS['WPPH_PAGE_AUTHOR_UPDATED']) || isset($GLOBALS['WPPH_PAGE_AUTHOR_UPDATED'])
1193
+ || isset($GLOBALS['WPPH_POST_CATEGORIES_UPDATED'])|| isset($GLOBALS['WPPH_POST_DATE_CHANGED'])){}
1194
+ else {
1195
+ wpph_draftPostUpdated($userID, $postID, $postTitle, ($postTypePost) ? 2003 : 2007);
1196
  }
1197
  }
1198
  }
1233
  // Uploaded the file %file name$ in %file location%
1234
  self::_addLogEvent(2010, $current_user->ID, WPPHUtil::getIP(), array($fileName, $dirName));
1235
  wpphLog('File uploaded.', array('title'=>$fileName, 'url'=>$dirName));
1236
+ $GLOBALS['WPPH_PLUGIN_FILE_UPLOADED_IGNORE_DELETE'] = true;
1237
  }
1238
  // 2011
1239
  public static function watchFileUploadedDeleted($attachmentID)
1240
  {
1241
+ if(isset($GLOBALS['WPPH_PLUGIN_FILE_UPLOADED_IGNORE_DELETE'])){
1242
+ // return, because if this variable is set this means this action is
1243
+ // triggered inside WP after uploading a plugin and there's no reason to log this event.
1244
+ return;
1245
+ }
1246
  global $wpdb;
1247
  // get info for the currently logged in user
1248
  $current_user = wp_get_current_user();
1375
  }
1376
  }
1377
 
1378
+ // #! 2025, 2026
1379
+ public static function watchPostVisibilityChange($oldStatus, $newStatus, $userID, $postTitle, $post, $event)
1380
+ {
1381
+ wpphLog(__FUNCTION__.'() triggered.');
1382
+
1383
+ global $wpdb;
1384
+
1385
+ $crtPostPassword = $wpdb->get_var("SELECT post_password FROM ".$wpdb->posts." WHERE ID = ".$post->ID);
1386
+ $oldPostPassword = (isset($GLOBALS['WPPH_OLD_POST_PASSWORD']) ? $GLOBALS['WPPH_OLD_POST_PASSWORD'] : null);
1387
+
1388
+ $from = $to = '';
1389
+
1390
+ // public -> pwd protected
1391
+ // pwd protected -> public
1392
+ if($oldStatus == 'publish' && $newStatus == 'publish')
1393
+ {
1394
+ // pwd protected -> public
1395
+ if(empty($crtPostPassword) && !empty($oldPostPassword)){
1396
+ $from = 'Password Protected';
1397
+ $to = 'Public';
1398
+ }
1399
+ // public -> pwd protected
1400
+ else {
1401
+ if(! empty($crtPostPassword)){
1402
+ $from = 'Public';
1403
+ $to = 'Password Protected';
1404
+ }
1405
+ }
1406
+ }
1407
+ // public -> private
1408
+ // pwd protected -> private
1409
+ elseif($oldStatus == 'publish' && $newStatus == 'private')
1410
+ {
1411
+ // public -> private
1412
+ if(empty($crtPostPassword) && empty($oldPostPassword)){
1413
+ $from = 'Public';
1414
+ $to = 'Private';
1415
+ }
1416
+ // pwd protected -> private
1417
+ else {
1418
+ if(!empty($oldPostPassword)){
1419
+ $from = 'Password Protected';
1420
+ $to = 'Private';
1421
+ }
1422
+ }
1423
+ }
1424
+ // private -> public
1425
+ // private -> pwd protected
1426
+ elseif($oldStatus == 'private' && $newStatus == 'publish')
1427
+ {
1428
+ // private -> public
1429
+ if(empty($oldPostPassword) && empty($crtPostPassword)){
1430
+ $from = 'Private';
1431
+ $to = 'Public';
1432
+ }
1433
+ // private -> pwd protected
1434
+ else {
1435
+ if(empty($oldPostPassword) && !empty($crtPostPassword)){
1436
+ $from = 'Private';
1437
+ $to = 'Password Protected';
1438
+ }
1439
+ }
1440
+ }
1441
+
1442
+ if(empty($from) || empty($to)){
1443
+ return;
1444
+ }
1445
+
1446
+ $GLOBALS['WPPH_PREVENT_BUBBLE'] = true;
1447
+ wpph_postVisibilityChanged($userID, $postTitle, $from, $to, $event);
1448
+ }
1449
+
1450
+ //#! 2027 & 2028
1451
+ public static function watchPostDateChange($userID, $postTitle, $postCurrentDate, $event)
1452
+ {
1453
+ wpphLog(__FUNCTION__.'() triggered.');
1454
+
1455
+ if($GLOBALS['WPPH_POST_IS_NEW']){
1456
+ wpphLog('Nothing to do. The post is brand new.');
1457
+ return;
1458
+ }
1459
+
1460
+ $t1 = strtotime($GLOBALS['WPPH_POST_OLD_DATE']);
1461
+ $t2 = strtotime($postCurrentDate);
1462
+
1463
+ if($t1 == $t2){
1464
+ wpphLog('No change.');
1465
+ return;
1466
+ }
1467
+
1468
+ $format = get_option('date_format');
1469
+ $from = date($format, $t1);
1470
+ $to = date($format, $t2);
1471
+ if($from == $to){
1472
+ wpphLog('No date change.');
1473
+ return;
1474
+ }
1475
+ wpphLog('POST DATE CHANGED',array(
1476
+ 'from' => $from . '('.$t1.')',
1477
+ 'to' => $to . '('.$t2.')'
1478
+ ));
1479
+ wpph_postDateChanged($userID, $postTitle, $from, $to, $event);
1480
+ }
1481
+
1482
+ public static function watchPostCategoriesChange($post, $wpdb, $postTitle)
1483
+ {
1484
+ wpphLog(__FUNCTION__.'() triggered.');
1485
+
1486
+ if(isset($GLOBALS['WPPH_POST_OLD_CATEGORIES']))
1487
+ {
1488
+ $originalCats = $GLOBALS['WPPH_POST_OLD_CATEGORIES'];
1489
+ $categories_1 = array();
1490
+ foreach($originalCats as $catID){
1491
+ $cat = get_category($catID);
1492
+ array_push($categories_1, $cat->name);
1493
+ }
1494
+ $categories_2 = array();
1495
+ $newCats = $post->post_category;
1496
+ if(empty($newCats[0])){
1497
+ unset($newCats[0]);
1498
+ }
1499
+ foreach($newCats as $catID){
1500
+ $cat = get_category($catID);
1501
+ array_push($categories_2, $cat->name);
1502
+ }
1503
+
1504
+ sort($categories_1);
1505
+ sort($categories_2);
1506
+
1507
+ // categories updated
1508
+ if($categories_1 <> $categories_2)
1509
+ {
1510
+ if(empty($categories_1)){
1511
+ // get the name of the default category
1512
+ $optID = get_option('default_category');
1513
+ $query = $wpdb->prepare("SELECT wpt.name FROM ".$wpdb->terms." AS wpt
1514
+ INNER JOIN ".$wpdb->options." AS wpo
1515
+ WHERE wpo.option_id = %d
1516
+ AND wpt.term_id = %d;", $optID, $optID);
1517
+ $defaultCategoryName = $wpdb->get_var($query);
1518
+
1519
+ // if categories-2 contains only the name of the default category...
1520
+ if(count($categories_2) == 1){
1521
+ if(strcasecmp($categories_2[0], $defaultCategoryName) == 0){
1522
+ // nothing to do here...
1523
+ $GLOBALS['WPPH_POST_CATEGORIES_UPDATED'] = true;
1524
+ }
1525
+ }
1526
+ else {
1527
+ $c1 = implode(', ', $categories_1);
1528
+ $c2 = implode(', ', $categories_2);
1529
+ wpph_postCategoriesUpdated(wp_get_current_user()->ID, $postTitle, $c1, $c2);
1530
+ $GLOBALS['WPPH_POST_CATEGORIES_UPDATED'] = true;
1531
+ }
1532
+ }
1533
+ else {
1534
+ $c1 = implode(', ', $categories_1);
1535
+ $c2 = implode(', ', $categories_2);
1536
+ wpph_postCategoriesUpdated(wp_get_current_user()->ID, $postTitle, $c1, $c2);
1537
+ $GLOBALS['WPPH_POST_CATEGORIES_UPDATED'] = true;
1538
+ }
1539
+ }
1540
+ }
1541
+ }
1542
+
1543
+ // 2017 & 2018 - Post/page modified
1544
+ // convenience method to trigger a post/page modified event
1545
+ public static function watchPostChanged($wpdb, $postID)
1546
+ {
1547
+ wpphLog(__FUNCTION__.'() triggered.');
1548
+
1549
+ if(isset($GLOBALS['WPPH_POST_OLD_NAME'])){
1550
+ // get the current post name and compare
1551
+ $post_name = $wpdb->get_var("SELECT post_name, post_password, post_date FROM ".$wpdb->posts." WHERE ID = $postID");
1552
+ if($GLOBALS['WPPH_POST_OLD_NAME'] != $post_name){
1553
+ return true;
1554
+ }
1555
+ }
1556
+ return false;
1557
+ }
1558
  }
inc/WPPHLogger.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  // custom function
3
- function wpphLog($message, $data=null,$function=null,$line=null){ WPPHLogger::write($message,$data,$function,$line); }
4
  /*
5
  * @internal
6
  * Debug class
@@ -15,9 +15,14 @@ class WPPHLogger
15
  public static function enableDebugLogging(){ self::$_debugLoggingEnabled = true; }
16
  public static function enableErrorLogging(){ ini_set('error_log', WPPH_PLUGIN_DIR.'error.log'); }
17
 
18
- public static function write($message, $data=null,$function=null,$line=null)
19
  {
 
 
 
 
20
  if(!self::$_debugLoggingEnabled) { return; }
 
21
  $m = '['.@date("D, M d, Y @H:i:s").'] Debug: '.$message;
22
  if(!empty($function)){
23
  $m .= PHP_EOL.'Function: '.$function;
@@ -29,6 +34,7 @@ class WPPHLogger
29
  $m .= ' Data: '.var_export($data, true);
30
  }
31
  $m .= PHP_EOL;
 
32
  @file_put_contents(WPPH_PLUGIN_DIR.self::$_fileName,$m,FILE_APPEND);
33
  }
34
  }
1
  <?php
2
  // custom function
3
+ function wpphLog($message, $data=null, $function=null,$line=null){ WPPHLogger::write($message,$data,$function,$line); }
4
  /*
5
  * @internal
6
  * Debug class
15
  public static function enableDebugLogging(){ self::$_debugLoggingEnabled = true; }
16
  public static function enableErrorLogging(){ ini_set('error_log', WPPH_PLUGIN_DIR.'error.log'); }
17
 
18
+ public static function write($message, $data=null, $function=null, $line=null)
19
  {
20
+ if(!empty($_POST)){
21
+ if(isset($_POST['action']) && $_POST['action'] == 'heartbeat'){ return;}
22
+ }
23
+
24
  if(!self::$_debugLoggingEnabled) { return; }
25
+
26
  $m = '['.@date("D, M d, Y @H:i:s").'] Debug: '.$message;
27
  if(!empty($function)){
28
  $m .= PHP_EOL.'Function: '.$function;
34
  $m .= ' Data: '.var_export($data, true);
35
  }
36
  $m .= PHP_EOL;
37
+
38
  @file_put_contents(WPPH_PLUGIN_DIR.self::$_fileName,$m,FILE_APPEND);
39
  }
40
  }
inc/WPPHUtil.php CHANGED
@@ -1,6 +1,12 @@
1
  <?php
2
  class WPPHUtil
3
  {
 
 
 
 
 
 
4
  public static function getIP() { return(!empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'); }
5
 
6
  /**
1
  <?php
2
  class WPPHUtil
3
  {
4
+ public static function loadPluggable(){
5
+ if(! function_exists('user_can')){
6
+ @include_once(ABSPATH.'wp-includes/pluggable.php');
7
+ }
8
+ }
9
+
10
  public static function getIP() { return(!empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'); }
11
 
12
  /**
inc/wpphFunctions.php CHANGED
@@ -1,97 +1,82 @@
1
  <?php
2
- // #!-- BEGIN PAGE
3
- //======================================================================================================================
4
 
5
- // 2018
6
- function wpph_pageUrlUpdated($oldUrl, $newUrl, $userID, $postTitle)
7
  {
8
- if($oldUrl == $newUrl) { return false; }
9
-
10
- WPPHEvent::_addLogEvent(2018, $userID, WPPHUtil::getIP(), array($postTitle, $oldUrl, $newUrl));
11
- wpphLog('Page URL updated.', array('from' => $oldUrl,'to' => $newUrl));
12
- return true;
13
  }
14
 
15
- // 2020
16
- function wpph_pageAuthorUpdated($newAuthorID, $postID, $userID, $postTitle, $quickFormEnabled = false)
17
  {
18
- global $wpdb;
19
- $oldAuthorID = $wpdb->get_var("SELECT post_author FROM ".$wpdb->posts." WHERE ID = ".$postID);
20
- if($newAuthorID <> $oldAuthorID){
21
- $n = $wpdb->get_var("SELECT user_login FROM ".$wpdb->users." WHERE ID = ".$newAuthorID);
22
- $o = $wpdb->get_var("SELECT user_login FROM ".$wpdb->users." WHERE ID = ".$oldAuthorID);
23
-
24
- if($quickFormEnabled){
25
- // in quick edit form the authors get switched whereas in the default post editor they don't :/
26
- $t = $n;
27
- $n = $o;
28
- $o = $t;
29
- }
30
-
31
- WPPHEvent::_addLogEvent(2020, $userID, WPPHUtil::getIP(), array($postTitle,$n,$o));
32
- wpphLog(__FUNCTION__.' : Page author updated.', array('from'=>$o, 'to'=>$n));
33
- return true;
34
- }
35
- return false;
36
  }
37
 
38
- // 2004
39
- function wpph_newPageAsDraft($userID, $postID, $postTitle)
40
  {
41
- WPPHEvent::_addLogEvent(2004, $userID, WPPHUtil::getIP(), array($postTitle,$postID));
42
- wpphLog(__FUNCTION__.' : New page saved as draft.', array('title'=>$postTitle));
43
  }
44
 
45
- // 2005
46
- function wpph_newPagePublished($userID, $postTitle, $postUrl)
47
  {
48
- WPPHEvent::_addLogEvent(2005, $userID, WPPHUtil::getIP(), array($postTitle,$postUrl));
49
- wpphLog(__FUNCTION__.' : Page published.', array('title'=>$postTitle));
 
 
 
50
  }
51
 
52
- // 2007
53
- function wpph_draftPageUpdated($userID, $postID, $postTitle)
54
  {
55
- WPPHEvent::_addLogEvent(2007, $userID, WPPHUtil::getIP(), array($postTitle,$postID));
56
- wpphLog(__FUNCTION__.' : Draft page updated.', array('title'=>$postTitle));
57
  }
58
 
59
- // 2006
60
- function wpph_publishedPageUpdated($userID, $postTitle, $postUrl)
61
  {
62
- WPPHEvent::_addLogEvent(2006, $userID, WPPHUtil::getIP(), array($postTitle,$postUrl));
63
- wpphLog(__FUNCTION__.' : Published page updated.', array('title'=>$postTitle));
 
64
  }
65
 
66
- // 2022
67
- function wpph_pageStatusUpdated($fromStatus, $toStatus, $userID, $postTitle)
68
  {
69
- WPPHEvent::_addLogEvent(2022, $userID, WPPHUtil::getIP(), array($postTitle, $fromStatus, $toStatus));
70
- wpphLog(__FUNCTION__.' : Page status updated.', array('title'=>$postTitle, 'from' => $fromStatus, 'to' => $toStatus));
 
 
71
  }
72
 
73
- // #!-- END PAGE
74
- //======================================================================================================================
75
-
76
-
77
- // #!-- BEGIN POSTS
78
- //======================================================================================================================
79
-
80
- // 2017
81
- function wpph_postUrlUpdated($oldUrl, $newUrl, $userID, $postTitle)
82
  {
83
- if($oldUrl == $newUrl) { return false; }
 
 
84
 
85
- WPPHEvent::_addLogEvent(2017, $userID, WPPHUtil::getIP(), array($postTitle, $oldUrl, $newUrl));
86
- wpphLog(__FUNCTION__.' : Blog post URL updated.', array('from' => $oldUrl,'to' => $newUrl));
87
- return true;
 
 
88
  }
89
 
90
- // 2019
91
- function wpph_postAuthorUpdated($newAuthorID, $postID, $userID, $postTitle, $quickFormEnabled = false)
92
  {
93
  global $wpdb;
94
  $oldAuthorID = $wpdb->get_var("SELECT post_author FROM ".$wpdb->posts." WHERE ID = ".$postID);
 
 
 
 
 
 
95
  if($newAuthorID <> $oldAuthorID){
96
  $n = $wpdb->get_var("SELECT user_login FROM ".$wpdb->users." WHERE ID = ".$newAuthorID);
97
  $o = $wpdb->get_var("SELECT user_login FROM ".$wpdb->users." WHERE ID = ".$oldAuthorID);
@@ -103,66 +88,25 @@ function wpph_postAuthorUpdated($newAuthorID, $postID, $userID, $postTitle, $qui
103
  $o = $t;
104
  }
105
 
106
- WPPHEvent::_addLogEvent(2019, $userID, WPPHUtil::getIP(), array($postTitle,$n,$o));
107
- wpphLog(__FUNCTION__.' : Blog post author updated.', array('from'=>$o, 'to'=>$n));
108
  return true;
109
  }
110
  return false;
111
  }
112
 
113
- // 2016
114
- function wpph_postCategoriesUpdated($userID, $postTitle, $fromCategories, $toCategories)
115
- {
116
- WPPHEvent::_addLogEvent(2016, $userID, WPPHUtil::getIP(), array($postTitle, $fromCategories, $toCategories));
117
- wpphLog(__FUNCTION__.' : Blog post categories updated.', array('from'=>$fromCategories, 'to'=>$toCategories));
118
- }
119
-
120
- // 2000
121
- function wpph_newPostAsDraft($userID, $postID, $postTitle)
122
- {
123
- WPPHEvent::_addLogEvent(2000, $userID, WPPHUtil::getIP(), array($postTitle,$postID));
124
- wpphLog(__FUNCTION__.' : New blog post saved as draft.', array('title'=>$postTitle));
125
- }
126
-
127
- // 2003
128
- function wpph_draftPostUpdated($userID, $postID, $postTitle)
129
- {
130
- WPPHEvent::_addLogEvent(2003, $userID, WPPHUtil::getIP(), array($postTitle,$postID));
131
- wpphLog(__FUNCTION__.' : Draft blog post updated.', array('title'=>$postTitle));
132
- }
133
-
134
- // 2001
135
- function wpph_newPostPublished($userID, $postTitle, $postUrl)
136
- {
137
- WPPHEvent::_addLogEvent(2001, $userID, WPPHUtil::getIP(), array($postTitle,$postUrl));
138
- wpphLog(__FUNCTION__.' : Blog post published.', array('title'=>$postTitle));
139
- }
140
-
141
- // 2002
142
- function wpph_publishedPostUpdated($userID, $postTitle, $postUrl)
143
- {
144
- WPPHEvent::_addLogEvent(2002, $userID, WPPHUtil::getIP(), array($postTitle,$postUrl));
145
- wpphLog(__FUNCTION__.' : Published blog post updated.', array('title'=>$postTitle));
146
- }
147
-
148
- // 2021
149
- function wpph_postStatusUpdated($fromStatus, $toStatus, $userID, $postTitle)
150
- {
151
- WPPHEvent::_addLogEvent(2021, $userID, WPPHUtil::getIP(), array($postTitle, $fromStatus, $toStatus));
152
- wpphLog(__FUNCTION__.' : Post status updated.', array('title'=>$postTitle, 'from' => $fromStatus, 'to' => $toStatus));
153
- }
154
-
155
- // #!-- END POSTS
156
- //======================================================================================================================
157
-
158
  // handle author change in quick edit form
159
  function wpph_managePostAuthorUpdateQuickEditForm($data, $postArray)
160
  {
161
  if($data['post_type'] == 'post'){
162
- wpph_postAuthorUpdated($GLOBALS['WPPH_POST_AUTHOR_UPDATED'], $postArray['ID'], wp_get_current_user()->ID, $data['post_title'], true);
 
 
163
  }
164
  elseif($data['post_type'] == 'page'){
165
- wpph_pageAuthorUpdated($GLOBALS['WPPH_POST_AUTHOR_UPDATED'], $postArray['ID'], wp_get_current_user()->ID, $data['post_title'], true);
 
 
166
  }
167
  return $data;
168
- }
1
  <?php
 
 
2
 
3
+ //#! 2001 & 2005
4
+ function wpph_newPostPublished($userID, $postTitle, $postUrl, $event)
5
  {
6
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle,$postUrl));
7
+ wpphLog(__FUNCTION__.'() : Post/Page published.', array('title'=>$postTitle));
 
 
 
8
  }
9
 
10
+ // 2003 & 2007
11
+ function wpph_draftPostUpdated($userID, $postID, $postTitle, $event)
12
  {
13
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle,$postID));
14
+ wpphLog(__FUNCTION__.'() : Draft post/page updated.', array('title'=>$postTitle));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  }
16
 
17
+ // 2000 & 2004
18
+ function wpph_newPostAsDraft($userID, $postID, $postTitle, $event)
19
  {
20
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle,$postID));
21
+ wpphLog(__FUNCTION__.'() : New post/page saved as draft.', array('title'=>$postTitle));
22
  }
23
 
24
+ // 2017 & 2018
25
+ function wpph_postUrlUpdated($oldUrl, $newUrl, $userID, $postTitle, $event)
26
  {
27
+ if($oldUrl == $newUrl) { return false; }
28
+
29
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle, $oldUrl, $newUrl));
30
+ wpphLog(__FUNCTION__.'() : Post/Page URL updated.', array('from' => $oldUrl,'to' => $newUrl));
31
+ return true;
32
  }
33
 
34
+ // 2002 & 2006
35
+ function wpph_publishedPostUpdated($userID, $postTitle, $postUrl, $event)
36
  {
37
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle,$postUrl));
38
+ wpphLog(__FUNCTION__.'() : Published post/page updated.', array('title'=>$postTitle));
39
  }
40
 
41
+ function wpph_postVisibilityChanged($userID, $postTitle, $fromVisibility, $toVisibility, $event)
 
42
  {
43
+ wpphLog(__FUNCTION__.'() triggered.');
44
+ wpphLog('Post visibility changed.', array('from' => $fromVisibility, 'to' => $toVisibility));
45
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle,$fromVisibility,$toVisibility));
46
  }
47
 
48
+ function wpph_postDateChanged($userID, $postTitle, $fromDate, $toDate, $event)
 
49
  {
50
+ wpphLog(__FUNCTION__.'() triggered.');
51
+ wpphLog('Post date changed.', array('from' => $fromDate . ' ('.strtotime($fromDate).')', 'to' => $toDate . ' ('.strtotime($toDate).')'));
52
+ $GLOBALS['WPPH_POST_DATE_CHANGED'] = true; // so we won't trigger the "modified post/page" event alongside the current event
53
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle,$fromDate,$toDate));
54
  }
55
 
56
+ function wpph_postStatusChanged($postTitle, $fromStatus, $toStatus, $userID, $event)
 
 
 
 
 
 
 
 
57
  {
58
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle, $fromStatus, $toStatus));
59
+ wpphLog(__FUNCTION__.'() : Post status updated.', array('title'=>$postTitle, 'from' => $fromStatus, 'to' => $toStatus));
60
+ }
61
 
62
+ // 2016
63
+ function wpph_postCategoriesUpdated($userID, $postTitle, $fromCategories, $toCategories)
64
+ {
65
+ WPPHEvent::_addLogEvent(2016, $userID, WPPHUtil::getIP(), array($postTitle, $fromCategories, $toCategories));
66
+ wpphLog(__FUNCTION__.' : Blog post categories updated.', array('from'=>$fromCategories, 'to'=>$toCategories));
67
  }
68
 
69
+ // 2019 & 2020
70
+ function wpph_postAuthorChanged($newAuthorID, $postID, $userID, $postTitle, $event, $quickFormEnabled = false)
71
  {
72
  global $wpdb;
73
  $oldAuthorID = $wpdb->get_var("SELECT post_author FROM ".$wpdb->posts." WHERE ID = ".$postID);
74
+
75
+ wpphLog(__FUNCTION__.'() ',array(
76
+ 'oldAuthorID' => $oldAuthorID,
77
+ 'newAuthorID' => $newAuthorID
78
+ ));
79
+
80
  if($newAuthorID <> $oldAuthorID){
81
  $n = $wpdb->get_var("SELECT user_login FROM ".$wpdb->users." WHERE ID = ".$newAuthorID);
82
  $o = $wpdb->get_var("SELECT user_login FROM ".$wpdb->users." WHERE ID = ".$oldAuthorID);
88
  $o = $t;
89
  }
90
 
91
+ WPPHEvent::_addLogEvent($event, $userID, WPPHUtil::getIP(), array($postTitle,$n,$o));
92
+ wpphLog(__FUNCTION__.' : Post/Page author updated.', array('from'=>$o, 'to'=>$n));
93
  return true;
94
  }
95
  return false;
96
  }
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  // handle author change in quick edit form
99
  function wpph_managePostAuthorUpdateQuickEditForm($data, $postArray)
100
  {
101
  if($data['post_type'] == 'post'){
102
+ if(wpph_postAuthorChanged($GLOBALS['WPPH_POST_AUTHOR_UPDATED_ID'], $postArray['ID'], wp_get_current_user()->ID, $data['post_title'], 2019, true)){
103
+ $GLOBALS['WPPH_POST_AUTHOR_UPDATED'] = true;
104
+ }
105
  }
106
  elseif($data['post_type'] == 'page'){
107
+ if(wpph_postAuthorChanged($GLOBALS['WPPH_POST_AUTHOR_UPDATED_ID'], $postArray['ID'], wp_get_current_user()->ID, $data['post_title'], 2020, true)){
108
+ $GLOBALS['WPPH_PAGE_AUTHOR_UPDATED'] = true;
109
+ }
110
  }
111
  return $data;
112
+ }
readme.txt CHANGED
@@ -1,27 +1,29 @@
1
  === WP Security Audit Log ===
2
- Contributors: WPProHelp, WPWhiteSecurity
3
  License: GPLv3
4
  License URI: http://www.gnu.org/licenses/gpl.html
5
- Tags: wordpress security plugin, wordpress security audit log, audit log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail
6
  Requires at least: 3.0
7
- Tested up to: 3.6
8
- Stable tag: 0.2
9
 
10
- Identify WordPress security issues before they become a problem. Keep an audit log of everything that happens on WordPress
11
 
12
  == Description ==
13
- Identify WordPress security issues before they become a problem by keeping an audit log of what is happening under the hood of your WordPress blog or website. This plugin is developed by WordPress Security Consultants and Specialists [WP White Security](http://www.wpwhitesecurity.com/wordpress-security-services/).
14
 
15
  = Keep A WordPress Security Audit Log & Identify WordPress Security Issues =
16
- WP Security Audit Log keeps track of everything that is happening on your WordPress blog or website. By using this WordPress security plugin it is very easy to track suspicious user activity before it becomes a problem. A security event is generated in each of the below cases:
17
 
18
  * New user is created via registration or created by another user
19
  * Existing user changes the role or password of another user
20
  * User uploads a file, changes a password or email
 
 
21
  * Failed login attempt
22
  * and much more...
23
 
24
- Refer to the complete list of [WordPress Security Audit Events](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-event-logs/) for more information.
25
 
26
  = Monitor WordPress Users Activity & Productivity =
27
  If you own a multi user WordPress blog or website you can use the WP Security Audit Log plugin to monitor your users' activity and productivity. With this WordPress security plugin you can monitor:
@@ -34,7 +36,7 @@ If you own a multi user WordPress blog or website you can use the WP Security Au
34
  * Users who modified published WordPress content such as a page or a blog post
35
  * and much more...
36
 
37
- Refer to the complete list of [WordPress Security Audit Events](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-event-logs/) for more information.
38
 
39
  = WordPress Audit Log in your Language! =
40
  We need help translating the plugin and the WordPress Security Events. If you're good at translating, please drop us an email on plugins@wpwhitesecurity.com.
@@ -47,7 +49,7 @@ Even if WordPress security is not your cup of tea, the security of your WordPres
47
  For more information and to get started with WordPress Security, check out the following:
48
 
49
  * [Official WP Security Audit Log Page](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/)
50
- * [List of all WP Security Audit Log Events](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-event-logs/)
51
  * [Recipe for ultimate WordPress Security](http://www.wpwhitesecurity.com/wordpress-security/recipe-ultimate-diy-wordpress-security/)
52
 
53
  == Installation ==
@@ -62,8 +64,8 @@ For more information and to get started with WordPress Security, check out the f
62
 
63
  By default the plugin will keep up to 10,000 events. When this limit is reached, older events are deleted to make place for the new ones. You can configure the plugin to keep more events from the settings page. You can also configure the plugin to delete events which are older than a number of days.
64
 
65
- = Is there a complete list of all WordPress security audit events? =
66
- Yes. A complete list can be found [here](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-event-logs/)
67
 
68
  == Screenshots ==
69
 
@@ -72,6 +74,26 @@ Yes. A complete list can be found [here](http://www.wpwhitesecurity.com/wordpres
72
 
73
  == Changelog ==
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  = 0.2 =
76
 
77
  * Restricted plugin options and WordPress Audit Log Event Viewer only to WordPress administrators
1
  === WP Security Audit Log ===
2
+ Contributors: WPWhiteSecurity
3
  License: GPLv3
4
  License URI: http://www.gnu.org/licenses/gpl.html
5
+ Tags: wordpress security plugin, wordpress security audit log, audit log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor
6
  Requires at least: 3.0
7
+ Tested up to: 3.6.1
8
+ Stable tag: 0.3
9
 
10
+ Identify WordPress security issues before they become a problem. Keep an audit log of everything that happens on WordPress including WordPress user activity.
11
 
12
  == Description ==
13
+ Identify WordPress security issues before they become a problem by keeping an audit log of what is happening under the hood of your WordPress blog or website. WP Security Audit Log plugin is developed by WordPress Security Consultants and Professionals [WP White Security](http://www.wpwhitesecurity.com/wordpress-security-services/).
14
 
15
  = Keep A WordPress Security Audit Log & Identify WordPress Security Issues =
16
+ WP Security Audit Log keeps a log of everything happening on your WordPress blog or website. By using WP Security Audit Log security plugin it is very easy to track suspicious user activity before it becomes a problem or a security issue. A security alert is generated by the plugin when:
17
 
18
  * New user is created via registration or created by another user
19
  * Existing user changes the role or password of another user
20
  * User uploads a file, changes a password or email
21
+ * User installs, activates, deactivates, upgrades or uninstalls a plugin
22
+ * WordPress settings are changed
23
  * Failed login attempt
24
  * and much more...
25
 
26
+ Refer to the complete list of [WordPress Security Audit Alerts](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-alerts-logs/) for more information.
27
 
28
  = Monitor WordPress Users Activity & Productivity =
29
  If you own a multi user WordPress blog or website you can use the WP Security Audit Log plugin to monitor your users' activity and productivity. With this WordPress security plugin you can monitor:
36
  * Users who modified published WordPress content such as a page or a blog post
37
  * and much more...
38
 
39
+ Refer to the complete list of [WordPress Security Audit Alerts](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-alerts-logs/) for more information.
40
 
41
  = WordPress Audit Log in your Language! =
42
  We need help translating the plugin and the WordPress Security Events. If you're good at translating, please drop us an email on plugins@wpwhitesecurity.com.
49
  For more information and to get started with WordPress Security, check out the following:
50
 
51
  * [Official WP Security Audit Log Page](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/)
52
+ * [List of all WP Security Audit Log Alerts](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-alerts-logs/)
53
  * [Recipe for ultimate WordPress Security](http://www.wpwhitesecurity.com/wordpress-security/recipe-ultimate-diy-wordpress-security/)
54
 
55
  == Installation ==
64
 
65
  By default the plugin will keep up to 10,000 events. When this limit is reached, older events are deleted to make place for the new ones. You can configure the plugin to keep more events from the settings page. You can also configure the plugin to delete events which are older than a number of days.
66
 
67
+ = Is there a complete list of all WordPress security audit events? =
68
+ Yes. A complete list can be found [here](http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/security-audit-event-logs/)
69
 
70
  == Screenshots ==
71
 
74
 
75
  == Changelog ==
76
 
77
+ = 0.3 =
78
+
79
+ * New WordPress Security Alerts
80
+ * Alert 6001: Anyone can Register option in WordPress settings was changed
81
+ * Alert 6002: Default use role in WordPress settings was changed
82
+ * Alert 6003: Administrator notification email in WordPress settings was changed
83
+ * Alert 2025: Visibility of a blog post was changed
84
+ * Alert 2026: Visibility of a page was changed
85
+ * Alert 2027: Date of a blog post was changed
86
+ * Alert 2028: Date of a page was changed
87
+
88
+ * Plugin Improvements
89
+ * Links to the Audit Log Viewer and Settings in the plugin summary page
90
+ * Time of Failed Login alerts now reflects the time of last failed login attempt
91
+
92
+ * Bug Fixes
93
+ * Fixed: Incorrect alerts generated when author of page was changed from quick edit mode
94
+ * Fixed: Conflict with WP Mandrill and other plugins using pluggable.php
95
+ * Fixed: Incorrect alerts generated when plugin is installed via a zip file / upload method
96
+
97
  = 0.2 =
98
 
99
  * Restricted plugin options and WordPress Audit Log Event Viewer only to WordPress administrators
wp-security-audit-log.php CHANGED
@@ -2,14 +2,14 @@
2
  /*
3
  Plugin Name: WP Security Audit Log
4
  Plugin URI: http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/
5
- Description: Identify WordPress security issues before they become a problem and keep track of everything happening on your WordPress, including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log will generate an event for every action it logs. Use the Audit Log Viewer to see all the events.
6
  Author: WP White Security
7
- Version: 0.2
8
  Author URI: http://www.wpwhitesecurity.com/
9
  License: GPL2
10
 
11
  WP Security Audit Log
12
- Copyright(c) 2013 Robert Abela (email : robert@wpprohelp.com)
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License, version 2, as
@@ -25,7 +25,7 @@ License: GPL2
25
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
  */
27
  //#! Holds the plugin option name
28
- define('WPPH_PLUGIN_VERSION','0.2');
29
  define('WPPH_PLUGIN_VERSION_OPTION_NAME','WPPH_PLUGIN_VERSION');
30
  define('WPPH_PLUGIN_ERROR_OPTION_NAME','WPPH_PLUGIN_ERROR');
31
  define('WPPH_PLUGIN_SETTING_NAME', 'wpph_plugin_settings');
@@ -37,9 +37,16 @@ if(defined('__DIR__')) { define('WPPH_PLUGIN_BASE_NAME', basename(__DIR__)); }
37
  else { define('WPPH_PLUGIN_BASE_NAME', basename(dirname(__FILE__))); }
38
  define('WPPH_PLUGIN_DB_UPDATED', 'WPPH_PLUGIN_DB_UPDATED');
39
  define('WPPH_PLUGIN_DEL_EVENTS_CRON_TASK_NAME', 'wpph_plugin_delete_events_cron');
 
 
 
 
 
 
 
 
40
 
41
  //#! Load required files
42
- @include_once(ABSPATH.'wp-includes/pluggable.php');
43
  require('inc/WPPHLogger.php');
44
  require('inc/WPPHUtil.php');
45
  require('inc/WPPHAdminNotices.php');
@@ -48,6 +55,18 @@ require('inc/WPPHEvent.php');
48
  require('inc/WPPH.php');
49
  require('inc/wpphFunctions.php');
50
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * triggered when the plugin is uninstalled (with option files delete: true)
53
  */
@@ -55,6 +74,7 @@ function onPluginUninstall()
55
  {
56
  if(WPPH::optionExists(WPPH_PLUGIN_DB_UPDATED)){ delete_option(WPPH_PLUGIN_DB_UPDATED); }
57
  if(WPPH::optionExists(WPPH_PLUGIN_VERSION_OPTION_NAME)){ delete_option(WPPH_PLUGIN_VERSION_OPTION_NAME); }
 
58
  global $wpdb;
59
  $wpdb->query("DROP TABLE IF EXISTS ".WPPHDatabase::getFullTableName('main'));
60
  $wpdb->query("DROP TABLE IF EXISTS ".WPPHDatabase::getFullTableName('events'));
@@ -64,50 +84,63 @@ register_activation_hook( __FILE__, array('WPPH', 'onPluginActivate') );
64
  register_deactivation_hook( __FILE__, array('WPPH', 'onPluginDeactivate') );
65
  register_uninstall_hook( __FILE__, 'onPluginUninstall' );
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  //#! Load resources
68
- add_action('admin_init', array('WPPH', 'loadBaseResources'));
69
 
70
  //#! Add the sidebar menu
71
- add_action('admin_menu', array('WPPH', 'createPluginWpSidebar'));
72
 
73
  //#! Plugin init
74
- add_action('init', 'wpphPluginInit');
75
- function wpphPluginInit()
76
- {
77
- if(is_admin())
78
  {
79
- // WPPHEvent::hookWatchPostStateBefore:
80
- // # 2016 - post category updated
81
- // # 2017 - post url updated
82
- // # 2018 - page url updated
83
- // # 2019 - post author changed
84
- if(! empty($_POST['action']) && $_POST['action'] == 'editpost'){ $GLOBALS['WPPH_DEFAULT_EDITOR_ENABLED'] = true; }
85
- elseif(! empty($_POST['screen']) && $_POST['screen'] == 'edit-post'){ $GLOBALS['WPPH_SCREEN_EDITOR_ENABLED'] = true; }
86
- elseif(! empty($_POST['screen']) && $_POST['screen'] == 'edit-page'){ $GLOBALS['WPPH_SCREEN_EDITOR_ENABLED'] = true; }
87
- WPPHEvent::hookWatchPostStateBefore();
88
- WPPHEvent::hookWatchCategoryAdd();
89
- WPPHEvent::hookWatchCategoryDelete();
90
- WPPHEvent::hookFileDeletion();
91
- WPPHEvent::hookFileUploaded();
92
- WPPHEvent::hookFileUploadedDeleted();
93
- WPPHEvent::hookTrashPost();
94
- WPPHEvent::hookTrashPage();
95
- WPPHEvent::hookUntrashedPosts();
96
- WPPHEvent::hookUntrashedPages();
97
- WPPHEvent::hookThemeChange();
98
- WPPHEvent::hookUserRoleUpdated();
99
- WPPHEvent::hookUserPasswordUpdated();
100
- WPPHEvent::hookUserEmailUpdated();
101
- WPPHEvent::hookUserDeletion();
102
- WPPHEvent::hookEventsDeletion();
103
- WPPHEvent::hookWatchBlogActivity();
104
- WPPHEvent::hookWatchPluginActivity();
105
- /* Enable ajax functionality in the dashboard page */
106
- add_action('wp_ajax_wpph_get_events', array('WPPHUtil','get_events_html'));
 
 
 
 
 
107
  }
108
- WPPHEvent::hookLoginEvent();
109
- WPPHEvent::hookLogoutEvent();
110
- WPPHEvent::hookLoginFailure();
111
- WPPHEvent::hookUserRegisterEvent();
112
  }
113
  //#! End wp-security-audit-log
2
  /*
3
  Plugin Name: WP Security Audit Log
4
  Plugin URI: http://www.wpwhitesecurity.com/wordpress-security-plugins/wp-security-audit-log/
5
+ Description: Identify WordPress security issues before they become a problem and keep track of everything happening on your WordPress, including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log will generate a security alert for everything that happens on your WordPress blog or website. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  Author: WP White Security
7
+ Version: 0.3
8
  Author URI: http://www.wpwhitesecurity.com/
9
  License: GPL2
10
 
11
  WP Security Audit Log
12
+ Copyright(c) 2013 Robert Abela (email : robert@wpwhitesecurity.com)
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License, version 2, as
25
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
  */
27
  //#! Holds the plugin option name
28
+ define('WPPH_PLUGIN_VERSION','0.3');
29
  define('WPPH_PLUGIN_VERSION_OPTION_NAME','WPPH_PLUGIN_VERSION');
30
  define('WPPH_PLUGIN_ERROR_OPTION_NAME','WPPH_PLUGIN_ERROR');
31
  define('WPPH_PLUGIN_SETTING_NAME', 'wpph_plugin_settings');
37
  else { define('WPPH_PLUGIN_BASE_NAME', basename(dirname(__FILE__))); }
38
  define('WPPH_PLUGIN_DB_UPDATED', 'WPPH_PLUGIN_DB_UPDATED');
39
  define('WPPH_PLUGIN_DEL_EVENTS_CRON_TASK_NAME', 'wpph_plugin_delete_events_cron');
40
+ /** @since v0.3 */
41
+ define('WPPH_USERS_CAN_REGISTER_OPT_NAME', 'wpph_users_can_register');
42
+ /**
43
+ * @since v0.3
44
+ * @see WPPH::onPluginActivate()
45
+ */
46
+ $GLOBALS['WPPH_CAN_RUN'] = true;
47
+
48
 
49
  //#! Load required files
 
50
  require('inc/WPPHLogger.php');
51
  require('inc/WPPHUtil.php');
52
  require('inc/WPPHAdminNotices.php');
55
  require('inc/WPPH.php');
56
  require('inc/wpphFunctions.php');
57
 
58
+
59
+ //#! 2000
60
+ $GLOBALS['WPPH_POST_IS_NEW'] = false;
61
+ add_action('wp_insert_post', 'wpphPostDetectNew', 1, 2);
62
+ function wpphPostDetectNew($post, $wp_error = false){
63
+ wpphLog(__FUNCTION__.' triggered by hook: WP_INSERT_POST');
64
+ if(isset($_POST['post_id'])){
65
+ $GLOBALS['WPPH_POST_IS_NEW'] = true;
66
+ wpphLog('POST IS NEW');
67
+ }
68
+ }
69
+
70
  /**
71
  * triggered when the plugin is uninstalled (with option files delete: true)
72
  */
74
  {
75
  if(WPPH::optionExists(WPPH_PLUGIN_DB_UPDATED)){ delete_option(WPPH_PLUGIN_DB_UPDATED); }
76
  if(WPPH::optionExists(WPPH_PLUGIN_VERSION_OPTION_NAME)){ delete_option(WPPH_PLUGIN_VERSION_OPTION_NAME); }
77
+ if(WPPH::optionExists(WPPH_USERS_CAN_REGISTER_OPT_NAME)){ delete_option(WPPH_USERS_CAN_REGISTER_OPT_NAME); }
78
  global $wpdb;
79
  $wpdb->query("DROP TABLE IF EXISTS ".WPPHDatabase::getFullTableName('main'));
80
  $wpdb->query("DROP TABLE IF EXISTS ".WPPHDatabase::getFullTableName('events'));
84
  register_deactivation_hook( __FILE__, array('WPPH', 'onPluginDeactivate') );
85
  register_uninstall_hook( __FILE__, 'onPluginUninstall' );
86
 
87
+ // Add custom links on plugins page
88
+ function wpphCustomLinks($links) {
89
+ return array_merge(array('<a href="admin.php?page=wpph_">Audit Log Viewer </a>', '<a href="admin.php?page=wpph_settings">'.__('Settings').'</a>'), $links);
90
+ }
91
+ add_filter("plugin_action_links_".plugin_basename(__FILE__), 'wpphCustomLinks' );
92
+
93
+ // $GLOBALS['WPPH_CAN_RUN']
94
+ // @since v0.3
95
+ // @see WPPH::onPluginActivate()
96
+ if($GLOBALS['WPPH_CAN_RUN'])
97
+ {
98
+ //#! Load the pluggable.php file if needed
99
+ add_action('admin_init', array('WPPHUtil','loadPluggable'));
100
+
101
  //#! Load resources
102
+ add_action('admin_init', array('WPPH', 'loadBaseResources'));
103
 
104
  //#! Add the sidebar menu
105
+ add_action('admin_menu', array('WPPH', 'createPluginWpSidebar'));
106
 
107
  //#! Plugin init
108
+ add_action('init', 'wpphPluginInit');
109
+ function wpphPluginInit()
 
 
110
  {
111
+ if(is_admin())
112
+ {
113
+ if(isset($_POST)){
114
+ //# 6001, 6002, 6003
115
+ WPPHEvent::hookCheckWpGeneralSettings();
116
+ if(isset($_POST['action']) && $_POST['action'] == 'editpost'){ $GLOBALS['WPPH_DEFAULT_EDITOR_ENABLED'] = true; }
117
+ elseif(isset($_POST['screen']) && ($_POST['screen'] == 'edit-post' || $_POST['screen'] == 'edit-page') ){ $GLOBALS['WPPH_SCREEN_EDITOR_ENABLED'] = true; wpphLog('WPPH_SCREEN_EDITOR_ENABLED');}
118
+ }
119
+ WPPHEvent::hookWatchPostStateBefore();
120
+ WPPHEvent::hookWatchBlogActivity();
121
+ WPPHEvent::hookWatchCategoryAdd();
122
+ WPPHEvent::hookWatchCategoryDelete();
123
+ WPPHEvent::hookFileDeletion();
124
+ WPPHEvent::hookFileUploaded();
125
+ WPPHEvent::hookFileUploadedDeleted();
126
+ WPPHEvent::hookTrashPost();
127
+ WPPHEvent::hookTrashPage();
128
+ WPPHEvent::hookUntrashedPosts();
129
+ WPPHEvent::hookUntrashedPages();
130
+ WPPHEvent::hookThemeChange();
131
+ WPPHEvent::hookUserRoleUpdated();
132
+ WPPHEvent::hookUserPasswordUpdated();
133
+ WPPHEvent::hookUserEmailUpdated();
134
+ WPPHEvent::hookUserDeletion();
135
+ WPPHEvent::hookEventsDeletion();
136
+ WPPHEvent::hookWatchPluginActivity();
137
+ /* Enable ajax functionality in the dashboard page */
138
+ add_action('wp_ajax_wpph_get_events', array('WPPHUtil','get_events_html'));
139
+ }
140
+ WPPHEvent::hookLoginEvent();
141
+ WPPHEvent::hookLogoutEvent();
142
+ WPPHEvent::hookLoginFailure();
143
+ WPPHEvent::hookUserRegisterEvent();
144
  }
 
 
 
 
145
  }
146
  //#! End wp-security-audit-log