1 <?php
2 /**
3 * Class for logging events and errors
4 *
5 * @package EDD
6 * @subpackage Logging
7 * @copyright Copyright (c) 2013, Pippin Williamson
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 1.3.1
10 */
11
12 // Exit if accessed directly
13 if ( ! defined( 'ABSPATH' ) ) exit;
14
15 /**
16 * EDD_Logging Class
17 *
18 * A general use class for logging events and errors.
19 *
20 * @since 1.3.1
21 */
22 class EDD_Logging {
23 /**
24 * Set up the EDD Logging Class
25 *
26 * @access public
27 * @since 1.3.1
28 * @return void
29 */
30 public function __construct() {
31 // Create the log post type
32 add_action( 'init', array( $this, 'register_post_type' ), -1 );
33
34 // Create types taxonomy and default types
35 add_action( 'init', array( $this, 'register_taxonomy' ), -1 );
36 }
37
38 /**
39 * Registers the edd_log Post Type
40 *
41 * @access public
42 * @since 1.3.1
43 * @return void
44 */
45 public function register_post_type() {
46 /* Logs post type */
47 $log_args = array(
48 'labels' => array( 'name' => __( 'Logs', 'edd' ) ),
49 'public' => false,
50 'query_var' => false,
51 'rewrite' => false,
52 'capability_type' => 'post',
53 'supports' => array( 'title', 'editor' ),
54 'can_export' => true
55 );
56
57 register_post_type( 'edd_log', $log_args );
58 }
59
60 /**
61 * Registers the Type Taxonomy
62 *
63 * The "Type" taxonomy is used to determine the type of log entry
64 *
65 * @access public
66 * @since 1.3.1
67 * @return void
68 */
69 public function register_taxonomy() {
70 register_taxonomy( 'edd_log_type', 'edd_log', array( 'public' => false ) );
71
72 $types = $this->log_types();
73
74 foreach ( $types as $type ) {
75 if ( ! term_exists( $type, 'edd_log_type' ) ) {
76 wp_insert_term( $type, 'edd_log_type' );
77 }
78 }
79 }
80
81 /**
82 * Log types
83 *
84 * Sets up the default log types and allows for new ones to be created
85 *
86 * @access public
87 * @since 1.3.1
88 * @return array $terms
89 */
90 public function log_types() {
91 $terms = array(
92 'sale', 'file_download', 'gateway_error', 'api_request'
93 );
94
95 return apply_filters( 'edd_log_types', $terms );
96 }
97
98 /**
99 * Check if a log type is valid
100 *
101 * Checks to see if the specified type is in the registered list of types
102 *
103 * @access public
104 * @since 1.3.1
105 * @uses EDD_Logging::log_types()
106 * @param string $type Log type
107 * @return bool Whether log type is valid
108 */
109 function valid_type( $type ) {
110 return in_array( $type, $this->log_types() );
111 }
112
113 /**
114 * Create new log entry
115 *
116 * This is just a simple and fast way to log something. Use $this->insert_log()
117 * if you need to store custom meta data
118 *
119 * @access public
120 * @since 1.3.1
121 * @uses EDD_Logging::insert_log()
122 * @param string $title Log entry title
123 * @param string $message Log entry message
124 * @param int $parent Log entry parent
125 * @param string $type Log type (default: null)
126 * @return int Log ID
127 */
128 public function add( $title = '', $message = '', $parent = 0, $type = null ) {
129 $log_data = array(
130 'post_title' => $title,
131 'post_content' => $message,
132 'post_parent' => $parent,
133 'log_type' => $type
134 );
135
136 return $this->insert_log( $log_data );
137 }
138
139 /**
140 * Easily retrieves log items for a particular object ID
141 *
142 * @access public
143 * @since 1.3.1
144 * @uses EDD_Logging::get_connected_logs()
145 * @param int $object_id (default: 0)
146 * @param string $type Log type (default: null)
147 * @param int $paged Page number (default: null)
148 * @return array Array of the connected logs
149 */
150 public function get_logs( $object_id = 0, $type = null, $paged = null ) {
151 return $this->get_connected_logs( array( 'post_parent' => $object_id, 'paged' => $paged, 'log_type' => $type ) );
152 }
153
154 /**
155 * Stores a log entry
156 *
157 * @access public
158 * @since 1.3.1
159 * @uses EDD_Logging::valid_type()
160 * @param array $log_data Log entry data
161 * @param array $log_meta Log entry meta
162 * @return int The ID of the newly created log item
163 */
164 function insert_log( $log_data = array(), $log_meta = array() ) {
165 $defaults = array(
166 'post_type' => 'edd_log',
167 'post_status' => 'publish',
168 'post_parent' => 0,
169 'post_content' => '',
170 'log_type' => false
171 );
172
173 $args = wp_parse_args( $log_data, $defaults );
174
175 do_action( 'edd_pre_insert_log' );
176
177 // Store the log entry
178 $log_id = wp_insert_post( $args );
179
180 // Set the log type, if any
181 if ( $log_data['log_type'] && $this->valid_type( $log_data['log_type'] ) ) {
182 wp_set_object_terms( $log_id, $log_data['log_type'], 'edd_log_type', false );
183 }
184
185 // Set log meta, if any
186 if ( $log_id && ! empty( $log_meta ) ) {
187 foreach ( (array) $log_meta as $key => $meta ) {
188 update_post_meta( $log_id, '_edd_log_' . sanitize_key( $key ), $meta );
189 }
190 }
191
192 do_action( 'edd_post_insert_log', $log_id );
193
194 return $log_id;
195 }
196
197 /**
198 * Update and existing log item
199 *
200 * @access public
201 * @since 1.3.1
202 * @param array $log_data Log entry data
203 * @param array $log_meta Log entry meta
204 * @return bool True if successful, false otherwise
205 */
206 public function update_log( $log_data = array(), $log_meta = array() ) {
207 do_action( 'edd_pre_update_log', $log_id );
208
209 $defaults = array(
210 'post_type' => 'edd_log',
211 'post_status' => 'publish',
212 'post_parent' => 0
213 );
214
215 $args = wp_parse_args( $log_data, $defaults );
216
217 // Store the log entry
218 $log_id = wp_update_post( $args );
219
220 if ( $log_id && ! empty( $log_meta ) ) {
221 foreach ( (array) $log_meta as $key => $meta ) {
222 if ( ! empty( $meta ) )
223 update_post_meta( $log_id, '_edd_log_' . sanitize_key( $key ), $meta );
224 }
225 }
226
227 do_action( 'edd_post_update_log', $log_id );
228 }
229
230 /**
231 * Retrieve all connected logs
232 *
233 * Used for retrieving logs related to particular items, such as a specific purchase.
234 *
235 * @access private
236 * @since 1.3.1
237 * @param array $args Query arguments
238 * @return mixed array if logs were found, false otherwise
239 */
240 public function get_connected_logs( $args = array() ) {
241 $defaults = array(
242 'post_type' => 'edd_log',
243 'posts_per_page' => 20,
244 'post_status' => 'publish',
245 'paged' => get_query_var( 'paged' ),
246 'log_type' => false
247 );
248
249 $query_args = wp_parse_args( $args, $defaults );
250
251 if ( $query_args['log_type'] && $this->valid_type( $query_args['log_type'] ) ) {
252 $query_args['tax_query'] = array(
253 array(
254 'taxonomy' => 'edd_log_type',
255 'field' => 'slug',
256 'terms' => $query_args['log_type']
257 )
258 );
259 }
260
261 $logs = get_posts( $query_args );
262
263 if ( $logs )
264 return $logs;
265
266 // No logs found
267 return false;
268 }
269
270 /**
271 * Retrieves number of log entries connected to particular object ID
272 *
273 * @access public
274 * @since 1.3.1
275 * @param int $object_id (default: 0)
276 * @param string $type Log type (default: null)
277 * @param array $meta_query Log meta query (default: null)
278 * @return int Log count
279 */
280 public function get_log_count( $object_id = 0, $type = null, $meta_query = null ) {
281 $query_args = array(
282 'post_parent' => $object_id,
283 'post_type' => 'edd_log',
284 'posts_per_page'=> -1,
285 'post_status' => 'publish'
286 );
287
288 if ( ! empty( $type ) && $this->valid_type( $type ) ) {
289 $query_args['tax_query'] = array(
290 array(
291 'taxonomy' => 'edd_log_type',
292 'field' => 'slug',
293 'terms' => $type
294 )
295 );
296 }
297
298 if ( ! empty( $meta_query ) ) {
299 $query_args['meta_query'] = $meta_query;
300 }
301
302 $logs = new WP_Query( $query_args );
303
304 return (int) $logs->post_count;
305 }
306
307 /**
308 * Delete a log
309 *
310 * @access public
311 * @since 1.3.1
312 * @uses EDD_Logging::valid_type
313 * @param int $object_id (default: 0)
314 * @param string $type Log type (default: null)
315 * @param array $meta_query Log meta query (default: null)
316 * @return void
317 */
318 public function delete_logs( $object_id = 0, $type = null, $meta_query = null ) {
319 $query_args = array(
320 'post_parent' => $object_id,
321 'post_type' => 'edd_log',
322 'posts_per_page'=> -1,
323 'post_status' => 'publish',
324 'fields' => 'ids'
325 );
326
327 if ( ! empty( $type ) && $this->valid_type( $type ) ) {
328 $query_args['tax_query'] = array(
329 array(
330 'taxonomy' => 'edd_log_type',
331 'field' => 'slug',
332 'terms' => $type,
333 )
334 );
335 }
336
337 if ( ! empty( $meta_query ) ) {
338 $query_args['meta_query'] = $meta_query;
339 }
340
341 $logs = get_posts( $query_args );
342
343 if ( $logs ) {
344 foreach ( $logs as $log ) {
345 wp_delete_post( $log, true );
346 }
347 }
348 }
349 }
350
351 // Initiate the logging system
352 $GLOBALS['edd_logs'] = new EDD_Logging();
353
354 /**
355 * Record a log entry
356 *
357 * This is just a simple wrapper function for the log class add() function
358 *
359 * @since 1.3.3
360 * @global $edd_logs EDD Logs Object
361 * @uses EDD_Logging::add()
362 * @return int $log ID of the new log entry
363 */
364 function edd_record_log( $title = '', $message = '', $parent = 0, $type = null ) {
365 global $edd_logs;
366 $log = $edd_logs->add( $title, $message, $parent, $type );
367 return $log;
368 }