-
Notifications
You must be signed in to change notification settings - Fork 25
/
audit-trail.php
204 lines (174 loc) · 5.49 KB
/
audit-trail.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php
/**
Plugin Name: WP Document Revisions - Audit Trail Code Sample
Plugin URI: https://github.com/wp-document-revisions/WP-Document-Revisions-Code-Cookbook
Description: Code sample to demonstrate check-in/check-out audit trail functionality
Version: 1.0
Author: Benjamin J. Balter
Author URI: http://ben.balter.com
License: GPL2
*
* @package WP Document Revisions Code Cookbook
*/
/**
* Helper function to return audit trail as an array
* array has elements array( 'timestamp' = YYYY-MM-DD H:i:s, 'user' => {userID}, 'action' => {Check in|Check Out}
*
* @param integer $post_ID The post ID.
*/
function wpdr_get_audit_trail( $post_ID ) {
$downloads = wpdr_get_downloads( $post_ID );
$uploads = wpdr_get_uploads( $post_ID );
// merge uploads and downloads into a single trail.
$trail = array_merge( $downloads, $uploads );
// sort by timestamp.
wpdr_sort( $trail, 'timestamp' );
return $trail;
}
/**
* Returns array of downloads from post meta
*
* @param integer $post_ID The post ID.
*/
function wpdr_get_downloads( $post_ID ) {
$downloads = get_post_meta( $post_ID, 'document_audit', false );
// get_post_meta returns false if there are no results, but we use array_merge later, so force array.
if ( ! is_array( $downloads ) ) {
return array();
}
// sort by timestamp.
wpdr_sort( $downloads, 'timestamp' );
return $downloads;
}
/**
* Revisions normally in uploads - but not if past limit, so store in downloads.
*
* @param int $revision_id Post revision ID.
* @param object|array $revision Post revision object or array.
*/
function wpdr_delete_revision( $revision_id, $revision ) {
// ensure WP Document Revisions is loaded.
if ( ! class_exists( 'WP_Document_Revisions' ) ) {
return;
}
// identify parent.
$post_ID = $revision->parent;
// check that it is a document revision.
$wpdr = WP_Document_Revisions::$instance;
if ( ! $wpdr->verify_post_type( $post_ID ) ) {
return;
}
// format data array.
$data = array(
'timestamp' => $revision->post_date_gmt,
'user' => $revision->post_author,
'action' => 'Check In',
);
// store the meta.
add_post_meta( $post_ID, 'document_audit', $data );
}
add_action( 'wp_delete_post_revision', 'wpdr_delete_revision', 10, 2 );
/**
* Parses standard WP revision history into an array for the audit trail
*
* @param integer $post_ID The post ID.
*/
function wpdr_get_uploads( $post_ID ) {
$uploads = array();
// get revisions using our internal function.
$wpdr = WP_Document_Revisions::$instance;
$revisions = $wpdr->get_revisions( $post_ID );
// loop through and build an array.
foreach ( $revisions as $revision ) {
$uploads[] = array(
'timestamp' => $revision->post_date_gmt,
'user' => $revision->post_author,
'action' => __( 'Check In', 'wp-document-revisions' ),
);
}
// sort by timestamp.
wpdr_sort( $uploads, 'timestamp' );
return $uploads;
}
/**
* Logs file downloads by user and time
*
* @param integer $post_ID The post ID.
*/
function wpdr_log_download( $post_ID ) {
// make sure we have the post parent not the revision.
$parent = wp_is_post_revision( $post_ID );
if ( false !== $parent ) {
$post_ID = $parent;
}
// format data array.
$data = array(
'timestamp' => gmdate( 'Y-m-d H:i:s' ),
'user' => get_current_user_id(),
'action' => __( 'Check Out', 'wp-document-revisions' ),
);
// store the meta.
add_post_meta( $post_ID, 'document_audit', $data );
}
add_action( 'serve_document', 'wpdr_log_download', 10, 1 );
/**
* Sorts an array of arrays by a specific key
* From: http://stackoverflow.com/questions/2699086/php-sort-multidimensional-array-by-value
*
* @param array $arr The array to be sorted.
* @param string $col The column of the array to be the sort key.
* @param integer $dir Direction of sort SORT_ASC or SORT_DESC.
*/
function wpdr_sort( &$arr, $col, $dir = SORT_ASC ) {
$sort_col = array();
foreach ( $arr as $key => $row ) {
$sort_col[ $key ] = $row[ $col ];
}
array_multisort( $sort_col, $dir, $arr );
}
/**
* Formats and outputs audit trail metabox
*
* Convert title to local time
*
* @param WP_Post $post The post object.
*/
function wpdr_audit_metabox( $post ) {
// get the trail.
$trail = wpdr_get_audit_trail( $post->ID );
// if there is no trail, kick.
if ( 0 === count( $trail ) ) {
return;
}
?>
<table width="100%">
<tr>
<th style="text-align: left;"><?php esc_html_e( 'Time', 'wp-document-revisions' ); ?></th>
<th style="text-align: left;"><?php esc_html_e( 'User', 'wp-document-revisions' ); ?></th>
<th style="text-align: left;"><?php esc_html_e( 'Event', 'wp-document-revisions' ); ?></th>
</tr>
<?php
foreach ( $trail as $event ) {
$user = get_user_by( 'id', $event['user'] );
if ( is_object( $user ) ) {
$user_name = $user->display_name;
} else {
$user_name = 'Deleted - ' . $event['user'];
}
?>
<tr>
<td><abbr class="timestamp" title="<?php echo esc_html( get_date_from_gmt( $event['timestamp'] ) ); ?>" id="<?php echo esc_html( strtotime( $event['timestamp'] ) ); ?>"><?php echo esc_html( human_time_diff( strtotime( $event['timestamp'] ) ) ); ?></abbr> ago</td>
<td><?php echo esc_html( $user_name ); ?></td>
<td><?php echo esc_html( $event['action'] ); ?></td>
</tr>
<?php } ?>
</table>
<?php
}
/**
* Registers the audit trail metabox with the WordPress metabox API
*/
function wpdr_add_audit_metabox() {
add_meta_box( 'document_audit_trail', 'Audit Trail', 'wpdr_audit_metabox', 'document', 'normal', 'low' );
}
add_action( 'add_meta_boxes_document', 'wpdr_add_audit_metabox' );