858 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			858 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Class for logging events and errors
 | |
|  *
 | |
|  * @package     EDD
 | |
|  * @subpackage  Logging
 | |
|  * @copyright   Copyright (c) 2018, Easy Digital Downloads, LLC
 | |
|  * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 | |
|  * @since       1.3.1
 | |
|  */
 | |
| 
 | |
| // Exit if accessed directly
 | |
| defined( 'ABSPATH' ) || exit;
 | |
| 
 | |
| /**
 | |
|  * EDD_Logging Class
 | |
|  *
 | |
|  * A general use class for logging events and errors.
 | |
|  *
 | |
|  * @since 1.3.1
 | |
|  * @since 3.0 - Updated to work with the new tables and classes as part of the migration to custom tables.
 | |
|  */
 | |
| class EDD_Logging {
 | |
| 
 | |
| 	/**
 | |
| 	 * Whether the debug log file is writable or not.
 | |
| 	 *
 | |
| 	 * @var bool
 | |
| 	 */
 | |
| 	public $is_writable = true;
 | |
| 
 | |
| 	/**
 | |
| 	 * Filename of the debug log.
 | |
| 	 *
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	private $filename = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * File path to the debug log.
 | |
| 	 *
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	private $file = '';
 | |
| 
 | |
| 	/**
 | |
| 	 * Set up the EDD Logging Class
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 */
 | |
| 	public function __construct() {
 | |
| 		add_action( 'plugins_loaded', array( $this, 'setup_log_file' ), 8 );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Get log types.
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 *
 | |
| 	 * @return array $terms Log types.
 | |
| 	 */
 | |
| 	public function log_types() {
 | |
| 		return apply_filters( 'edd_log_types', array(
 | |
| 			'sale',
 | |
| 			'file_download',
 | |
| 			'gateway_error',
 | |
| 			'api_request'
 | |
| 		) );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Check if a log type is valid
 | |
| 	 *
 | |
| 	 * Checks to see if the specified type is in the registered list of types
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 *
 | |
| 	 * @param string $type Log type.
 | |
| 	 * @return bool True if valid log type, false otherwise.
 | |
| 	 */
 | |
| 	public function valid_type( $type ) {
 | |
| 		return in_array( $type, $this->log_types() );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Create new log entry
 | |
| 	 *
 | |
| 	 * This is just a simple and fast way to log something. Use $this->insert_log()
 | |
| 	 * if you need to store custom meta data
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 *
 | |
| 	 * @param string $title   Log entry title.
 | |
| 	 * @param string $message Log entry message.
 | |
| 	 * @param int    $parent  Download ID.
 | |
| 	 * @param string $type    Log type (default: null).
 | |
| 	 *
 | |
| 	 * @return int ID of the newly created log item.
 | |
| 	 */
 | |
| 	public function add( $title = '', $message = '', $parent = 0, $type = null ) {
 | |
| 		return $this->insert_log( array(
 | |
| 			'post_title'   => $title,
 | |
| 			'post_content' => $message,
 | |
| 			'post_parent'  => $parent,
 | |
| 			'log_type'     => $type
 | |
| 		) );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Easily retrieves log items for a particular object ID.
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 *
 | |
| 	 * @param int    $object_id Object ID (default: 0).
 | |
| 	 * @param string $type      Log type (default: null).
 | |
| 	 * @param int    $paged     Page number (default: null).
 | |
| 	 *
 | |
| 	 * @return array Array of the connected logs.
 | |
| 	*/
 | |
| 	public function get_logs( $object_id = 0, $type = null, $paged = null ) {
 | |
| 		return $this->get_connected_logs( array(
 | |
| 			'post_parent' => $object_id,
 | |
| 			'paged'       => $paged,
 | |
| 			'log_type'    => $type
 | |
| 		) );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Stores a log entry.
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 * @since 3.0 Updated to use the new database classes as part of the migration to custom tables.
 | |
| 	 *
 | |
| 	 * @param array $log_data Log entry data.
 | |
| 	 * @param array $log_meta Log entry meta.
 | |
| 	 * @return int The ID of the newly created log item.
 | |
| 	 */
 | |
| 	public function insert_log( $log_data = array(), $log_meta = array() ) {
 | |
| 
 | |
| 		// Parse args
 | |
| 		$args = wp_parse_args( $log_data, array(
 | |
| 			'post_type'    => 'edd_log',
 | |
| 			'post_status'  => 'publish',
 | |
| 			'post_parent'  => 0,
 | |
| 			'post_content' => '',
 | |
| 			'log_type'     => false,
 | |
| 		) );
 | |
| 
 | |
| 		/**
 | |
| 		 * Triggers just before a log is inserted.
 | |
| 		 *
 | |
| 		 * @param array $args     Log entry data.
 | |
| 		 * @param array $log_meta Log meta data.
 | |
| 		 */
 | |
| 		do_action( 'edd_pre_insert_log', $args, $log_meta );
 | |
| 
 | |
| 		// Used to dynamically dispatch the method call to insert() to the correct class.
 | |
| 		$insert_method = 'edd_add_log';
 | |
| 
 | |
| 		// Set up variables to hold data to go into the logs table by default.
 | |
| 		$data = array(
 | |
| 			'content'     => $args['post_content'],
 | |
| 			'object_id'   => isset( $args['post_parent'] )
 | |
| 				? $args['post_parent']
 | |
| 				: 0,
 | |
| 			'object_type' => isset( $args['log_type'] )
 | |
| 				? $args['log_type']
 | |
| 				: null,
 | |
| 			/*
 | |
| 			 * Fallback user ID is the current user, due to it previously being set to that by WordPress
 | |
| 			 * core when setting post_author on the CPT.
 | |
| 			 */
 | |
| 			'user_id'     => ! empty( $log_meta['user'] ) ? $log_meta['user'] : get_current_user_id()
 | |
| 		);
 | |
| 
 | |
| 		$type = $args['log_type'];
 | |
| 		if ( ! empty( $type ) ) {
 | |
| 			$data['type'] = $type;
 | |
| 		}
 | |
| 
 | |
| 		if ( array_key_exists( 'post_title', $args ) ) {
 | |
| 			$data['title'] = $args['post_title'];
 | |
| 		}
 | |
| 
 | |
| 		$meta_to_unset = array( 'user' );
 | |
| 
 | |
| 		// Override $data and $insert_method based on the log type.
 | |
| 		if ( 'api_request' === $args['log_type'] ) {
 | |
| 			$insert_method = 'edd_add_api_request_log';
 | |
| 
 | |
| 			$data = array(
 | |
| 				'user_id' => ! empty( $log_meta['user'] ) ? $log_meta['user'] : 0,
 | |
| 				'api_key' => ! empty( $log_meta['key'] ) ? $log_meta['key'] : 'public',
 | |
| 				'token'   => ! empty( $log_meta['token'] ) ? $log_meta['token'] : 'public',
 | |
| 				'version' => ! empty( $log_meta['version'] ) ? $log_meta['version'] : '',
 | |
| 				'request' => ! empty( $args['post_excerpt'] ) ? $args['post_excerpt'] : '',
 | |
| 				'error'   => ! empty( $args['post_content'] ) ? $args['post_content'] : '',
 | |
| 				'ip'      => ! empty( $log_meta['request_ip'] ) ? $log_meta['request_ip'] : '',
 | |
| 				'time'    => ! empty( $log_meta['time'] ) ? $log_meta['time'] : '',
 | |
| 			);
 | |
| 
 | |
| 			$meta_to_unset = array( 'user', 'key', 'token', 'version', 'request_ip', 'time' );
 | |
| 		} elseif ( 'file_download' === $args['log_type'] ) {
 | |
| 			$insert_method = 'edd_add_file_download_log';
 | |
| 
 | |
| 			if ( ! class_exists( 'Browser' ) ) {
 | |
| 				require_once EDD_PLUGIN_DIR . 'includes/libraries/browser.php';
 | |
| 			}
 | |
| 
 | |
| 			$browser = new Browser();
 | |
| 
 | |
| 			$user_agent = $browser->getBrowser() . ' ' . $browser->getVersion() . '/' . $browser->getPlatform();
 | |
| 
 | |
| 			$data = array(
 | |
| 				'product_id'  => $args['post_parent'],
 | |
| 				'file_id'     => ! empty( $log_meta['file_id'] ) ? $log_meta['file_id'] : 0,
 | |
| 				'order_id'    => ! empty( $log_meta['payment_id'] ) ? $log_meta['payment_id'] : 0,
 | |
| 				'price_id'    => ! empty( $log_meta['price_id'] ) ? $log_meta['price_id'] : 0,
 | |
| 				'customer_id' => ! empty( $log_meta['customer_id'] ) ? $log_meta['customer_id'] : 0,
 | |
| 				'ip'          => ! empty( $log_meta['ip'] ) ? $log_meta['ip'] : '',
 | |
| 				'user_agent'  => $user_agent,
 | |
| 			);
 | |
| 
 | |
| 			$meta_to_unset = array( 'file_id', 'payment_id', 'price_id', 'customer_id', 'ip', 'user_id' );
 | |
| 		}
 | |
| 
 | |
| 		// Now unset the meta we've used up in the main data array.
 | |
| 		foreach ( $meta_to_unset as $meta_key ) {
 | |
| 			unset( $log_meta[ $meta_key ] );
 | |
| 		}
 | |
| 
 | |
| 		// Get the log ID if method is callable
 | |
| 		$log_id = is_callable( $insert_method )
 | |
| 			? call_user_func( $insert_method, $data )
 | |
| 			: false;
 | |
| 
 | |
| 		// Set log meta, if any
 | |
| 		if ( $log_id && ! empty( $log_meta ) ) {
 | |
| 
 | |
| 			// Use the right log fetching function based on the type of log this is.
 | |
| 			if ( 'edd_add_api_request_log' === $insert_method ) {
 | |
| 				$add_meta_function = 'edd_add_api_request_log_meta';
 | |
| 			} elseif ( 'edd_add_file_download_log' === $insert_method ) {
 | |
| 				$add_meta_function = 'edd_add_file_download_log_meta';
 | |
| 			} else {
 | |
| 				$add_meta_function = 'edd_add_log_meta';
 | |
| 			}
 | |
| 
 | |
| 			if ( is_callable( $add_meta_function ) ) {
 | |
| 				foreach ( (array) $log_meta as $key => $meta ) {
 | |
| 					$add_meta_function( $log_id, sanitize_key( $key ), $meta );
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Triggers after a log has been inserted.
 | |
| 		 *
 | |
| 		 * @param int   $log_id   ID of the new log.
 | |
| 		 * @param array $args     Log data.
 | |
| 		 * @param array $log_meta Log meta data.
 | |
| 		 */
 | |
| 		do_action( 'edd_post_insert_log', $log_id, $args, $log_meta );
 | |
| 
 | |
| 		return $log_id;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Update and existing log item
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 * @since 3.0 - Added $log_id parameter and boolean return type.
 | |
| 	 *
 | |
| 	 * @param array $log_data Log entry data.
 | |
| 	 * @param array $log_meta Log entry meta.
 | |
| 	 * @param int   $log_id   Log ID.
 | |
| 	 * @return bool True on success, false otherwise.
 | |
| 	 */
 | |
| 	public function update_log( $log_data = array(), $log_meta = array(), $log_id = 0 ) {
 | |
| 		// $log_id is at the end because it was introduced in 3.0
 | |
| 		do_action( 'edd_pre_update_log', $log_data, $log_meta, $log_id );
 | |
| 
 | |
| 		$defaults = array(
 | |
| 			'post_content' => '',
 | |
| 			'post_title'   => '',
 | |
| 			'object_id'    => 0,
 | |
| 			'object_type'  => '',
 | |
| 		);
 | |
| 
 | |
| 		$args = wp_parse_args( $log_data, $defaults );
 | |
| 
 | |
| 		if ( isset( $args['ID'] ) && empty( $log_id ) ) {
 | |
| 			$log_id = $args['ID'];
 | |
| 		}
 | |
| 
 | |
| 		// Bail if the log ID is still empty.
 | |
| 		if ( empty( $log_id ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		// Used to dynamically dispatch the method call to insert() to the correct class.
 | |
| 		$update_method        = 'edd_update_log';
 | |
| 		$update_meta_function = 'edd_update_log_meta';
 | |
| 
 | |
| 		$type = $args['log_type'];
 | |
| 		if ( ! empty( $type ) ) {
 | |
| 			$data['type'] = $args['log_type'];
 | |
| 		}
 | |
| 
 | |
| 		$data = array(
 | |
| 			'object_id'   => $args['object_id'],
 | |
| 			'object_type' => $args['object_type'],
 | |
| 			'title'       => $args['title'],
 | |
| 			'message'     => $args['message'],
 | |
| 		);
 | |
| 
 | |
| 		if ( 'api_request' === $data['type'] ) {
 | |
| 			$update_meta_function = 'edd_update_api_request_log_meta';
 | |
| 			$legacy               = array(
 | |
| 				'user'         => 'user_id',
 | |
| 				'key'          => 'api_key',
 | |
| 				'token'        => 'token',
 | |
| 				'version'      => 'version',
 | |
| 				'post_excerpt' => 'request',
 | |
| 				'post_content' => 'error',
 | |
| 				'request_ip'   => 'ip',
 | |
| 				'time'         => 'time',
 | |
| 			);
 | |
| 
 | |
| 			foreach ( $legacy as $old_key => $new_key ) {
 | |
| 				if ( isset( $log_meta[ $old_key ] ) ) {
 | |
| 					$data[ $new_key ] = $log_meta[ $old_key ];
 | |
| 
 | |
| 					unset( $log_meta[ $old_key ] );
 | |
| 				}
 | |
| 			}
 | |
| 		} elseif ( 'file_download' === $data['type'] ) {
 | |
| 			$update_meta_function = 'edd_update_file_download_log_meta';
 | |
| 			$legacy               = array(
 | |
| 				'file_id'    => 'file_id',
 | |
| 				'payment_id' => 'payment_id',
 | |
| 				'price_id'   => 'price_id',
 | |
| 				'user_id'    => 'user_id',
 | |
| 				'ip'         => 'ip',
 | |
| 			);
 | |
| 
 | |
| 			foreach ( $legacy as $old_key => $new_key ) {
 | |
| 				if ( isset( $log_meta[ $old_key ] ) ) {
 | |
| 					$data[ $new_key ] = $log_meta[ $old_key ];
 | |
| 
 | |
| 					unset( $log_meta[ $old_key ] );
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			if ( isset( $args['post_parent'] ) ) {
 | |
| 				$data['download_id'] = $args['post_parent'];
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		unset( $data['type'] );
 | |
| 
 | |
| 		// Bail if not callable
 | |
| 		if ( ! is_callable( $update_method ) ) {
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		call_user_func( $update_method, $data );
 | |
| 
 | |
| 		// Set log meta, if any
 | |
| 		if ( is_callable( $update_meta_function ) ) {
 | |
| 			if ( 'edd_update_log' === $update_method && ! empty( $log_meta ) ) {
 | |
| 				foreach ( (array) $log_meta as $key => $meta ) {
 | |
| 					$update_meta_function( $log_id, sanitize_key( $key ), $meta );
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		do_action( 'edd_post_update_log', $log_id, $log_data, $log_meta );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve all connected logs.
 | |
| 	 *
 | |
| 	 * Used for retrieving logs related to particular items, such as a specific purchase.
 | |
| 	 *
 | |
| 	 * @access public
 | |
| 	 * @since 1.3.1
 | |
| 	 *
 | |
| 	 * @param array $args Query arguments.
 | |
| 	 * @return mixed array Logs fetched, false otherwise.
 | |
| 	 */
 | |
| 	public function get_connected_logs( $args = array() ) {
 | |
| 
 | |
| 		$log_type = isset( $args['log_type'] )
 | |
| 			? $args['log_type']
 | |
| 			: false;
 | |
| 
 | |
| 		// Parse arguments
 | |
| 		$r = $this->parse_args( $args );
 | |
| 
 | |
| 		// Used to dynamically dispatch the call to the correct class.
 | |
| 		$log_type = $this->get_log_table( $log_type );
 | |
| 		$func     = "edd_get_{$log_type}";
 | |
| 		$logs     = is_callable( $func )
 | |
| 			? call_user_func( $func, $r )
 | |
| 			: false;
 | |
| 
 | |
| 		// Return the logs (or false)
 | |
| 		return $logs;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieves number of log entries connected to particular object ID.
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 * @since 1.9 - Added date query support.
 | |
| 	 *
 | |
| 	 * @param int    $object_id  Object ID (default: 0).
 | |
| 	 * @param string $type       Log type (default: null).
 | |
| 	 * @param array  $meta_query Log meta query (default: null).
 | |
| 	 * @param array  $date_query Log date query (default: null) [since 1.9].
 | |
| 	 *
 | |
| 	 * @return int Log count.
 | |
| 	 */
 | |
| 	public function get_log_count( $object_id = 0, $type = null, $meta_query = null, $date_query = null ) {
 | |
| 		$r = array(
 | |
| 			$this->get_object_id_column_name_for_type( $type ) => $object_id,
 | |
| 		);
 | |
| 
 | |
| 		if ( ! empty( $type ) && $this->valid_type( $type ) ) {
 | |
| 			$r['type'] = $type;
 | |
| 		}
 | |
| 
 | |
| 		if ( ! empty( $meta_query ) ) {
 | |
| 			$r['meta_query'] = $meta_query;
 | |
| 		}
 | |
| 
 | |
| 		if ( ! empty( $date_query ) ) {
 | |
| 			$r['date_query'] = $date_query;
 | |
| 		}
 | |
| 
 | |
| 		// Used to dynamically dispatch the call to the correct class.
 | |
| 		$log_type = $this->get_log_table( $type );
 | |
| 
 | |
| 		// Call the func, or not
 | |
| 		$func  = "edd_count_{$log_type}";
 | |
| 		$count = is_callable( $func )
 | |
| 			? call_user_func( $func, $r )
 | |
| 			: 0;
 | |
| 
 | |
| 		return $count;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Delete logs based on parameters passed.
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 *
 | |
| 	 * @param int    $object_id  Object ID (default: 0).
 | |
| 	 * @param string $type       Log type (default: null).
 | |
| 	 * @param array  $meta_query Log meta query (default: null).
 | |
| 	 */
 | |
| 	public function delete_logs( $object_id = 0, $type = null, $meta_query = null ) {
 | |
| 		$r = array(
 | |
| 			$this->get_object_id_column_name_for_type( $type ) => $object_id,
 | |
| 		);
 | |
| 
 | |
| 		if ( ! empty( $type ) && $this->valid_type( $type ) ) {
 | |
| 			$r['type'] = $type;
 | |
| 		}
 | |
| 
 | |
| 		if ( ! empty( $meta_query ) ) {
 | |
| 			$r['meta_query'] = $meta_query;
 | |
| 		}
 | |
| 
 | |
| 		// Used to dynamically dispatch the call to the correct class.
 | |
| 		$log_type = $this->get_log_table( $type );
 | |
| 
 | |
| 		// Call the func, or not.
 | |
| 		$func = "edd_get_{$log_type}";
 | |
| 		$logs = is_callable( $func )
 | |
| 			? call_user_func( $func, $r )
 | |
| 			: array();
 | |
| 
 | |
| 		// Bail if no logs.
 | |
| 		if ( empty( $logs ) ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		// Maybe bail if delete function does not exist.
 | |
| 		$func = rtrim( "edd_delete_{$log_type}", 's' );
 | |
| 		if ( ! is_callable( $func ) ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		// Loop through and delete logs.
 | |
| 		foreach ( $logs as $log ) {
 | |
| 			call_user_func( $func, $log->id );
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the new log type from the old type.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @param string $type
 | |
| 	 *
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	private function get_log_table( $type = '' ) {
 | |
| 		$retval = 'logs';
 | |
| 
 | |
| 		if ( 'api_request' === $type ) {
 | |
| 			$retval = 'api_request_logs';
 | |
| 		} elseif ( 'file_download' === $type ) {
 | |
| 			$retval = 'file_download_logs';
 | |
| 		}
 | |
| 
 | |
| 		return $retval;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Parse arguments. Contains back-compat argument aliasing.
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @param array $args
 | |
| 	 * @return array
 | |
| 	 */
 | |
| 	private function parse_args( $args = array() ) {
 | |
| 
 | |
| 		// Parse args
 | |
| 		$r = wp_parse_args( $args, array(
 | |
| 			'log_type'       => false,
 | |
| 			'post_type'      => 'edd_log',
 | |
| 			'post_status'    => 'publish',
 | |
| 			'post_parent'    => 0,
 | |
| 			'posts_per_page' => 20,
 | |
| 			'paged'          => get_query_var( 'paged' ),
 | |
| 			'orderby'        => 'id',
 | |
| 		) );
 | |
| 
 | |
| 		// Back-compat for ID ordering
 | |
| 		if ( 'ID' === $r['orderby'] ) {
 | |
| 			$r['orderby'] = 'id';
 | |
| 		}
 | |
| 
 | |
| 		// Back-compat for log_type
 | |
| 		if ( ! empty( $r['log_type'] ) ) {
 | |
| 			$r['type'] = $r['log_type'];
 | |
| 		}
 | |
| 
 | |
| 		// Back-compat for post_parent.
 | |
| 		if ( ! empty( $r['post_parent'] ) ) {
 | |
| 			$type                                        = ! empty( $r['log_type'] ) ? $r['log_type'] : '';
 | |
| 			$r[ $this->get_object_id_column_name_for_type( $type ) ] = $r['post_parent'];
 | |
| 		}
 | |
| 
 | |
| 		// Back compat for posts_per_page
 | |
| 		$r['number'] = $r['posts_per_page'];
 | |
| 
 | |
| 		// Unset old keys
 | |
| 		unset(
 | |
| 			$r['posts_per_page'],
 | |
| 			$r['post_parent'],
 | |
| 			$r['post_status'],
 | |
| 			$r['post_type'],
 | |
| 			$r['log_type']
 | |
| 		);
 | |
| 
 | |
| 		if ( ! isset( $r['offset'] ) ) {
 | |
| 			$r['offset'] = $r['paged'] > 1
 | |
| 				? ( ( $r['paged'] - 1 ) * $r['number'] )
 | |
| 				: 0;
 | |
| 			unset( $r['paged'] );
 | |
| 		}
 | |
| 
 | |
| 		// Return parsed args
 | |
| 		return $r;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets the object ID column name based on the log type.
 | |
| 	 *
 | |
| 	 * @since 3.1
 | |
| 	 * @param string $type The log type.
 | |
| 	 * @return string      The column name to query for the object ID.
 | |
| 	 */
 | |
| 	private function get_object_id_column_name_for_type( $type = '' ) {
 | |
| 
 | |
| 		switch ( $type ) {
 | |
| 			case 'file_download':
 | |
| 				$object_id = 'product_id';
 | |
| 				break;
 | |
| 
 | |
| 			case 'api_request':
 | |
| 				$object_id = 'user_id';
 | |
| 				break;
 | |
| 
 | |
| 			default:
 | |
| 				$object_id = 'object_id';
 | |
| 				break;
 | |
| 		}
 | |
| 
 | |
| 		return $object_id;
 | |
| 	}
 | |
| 
 | |
| 	/** File System ***********************************************************/
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets up the log file if it is writable
 | |
| 	 *
 | |
| 	 * @since 2.8.7
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function setup_log_file() {
 | |
| 		$this->init_fs();
 | |
| 
 | |
| 		$upload_dir     = wp_upload_dir();
 | |
| 		$this->filename = wp_hash( home_url( '/' ) ) . '-edd-debug.log';
 | |
| 		$this->file     = trailingslashit( $upload_dir['basedir'] ) . $this->filename;
 | |
| 
 | |
| 		if ( ! $this->get_fs()->is_writable( $upload_dir['basedir'] ) ) {
 | |
| 			$this->is_writable = false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Initialize the WordPress file system
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @global WP_Filesystem_Base $wp_filesystem
 | |
| 	 */
 | |
| 	private function init_fs() {
 | |
| 		global $wp_filesystem;
 | |
| 
 | |
| 		if ( ! empty( $wp_filesystem ) ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		// Include the file-system
 | |
| 		require_once ABSPATH . 'wp-admin/includes/file.php';
 | |
| 
 | |
| 		// Initialize the file system
 | |
| 		WP_Filesystem();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Get the WordPress file-system
 | |
| 	 *
 | |
| 	 * @since 3.0
 | |
| 	 *
 | |
| 	 * @return WP_Filesystem_Base
 | |
| 	 */
 | |
| 	private function get_fs() {
 | |
| 		return ! empty( $GLOBALS['wp_filesystem'] )
 | |
| 			? $GLOBALS['wp_filesystem']
 | |
| 			: false;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Log message to file.
 | |
| 	 *
 | |
| 	 * @access public
 | |
| 	 * @since 2.8.7
 | |
| 	 *
 | |
| 	 * @param string $message Message to insert in the log.
 | |
| 	 */
 | |
| 	public function log_to_file( $message = '' ) {
 | |
| 		$message = date( 'Y-n-d H:i:s' ) . ' - ' . $message . "\r\n";
 | |
| 		$this->write_to_log( $message );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Return the location of the log file that EDD_Logging will use.
 | |
| 	 *
 | |
| 	 * @since 2.9.1
 | |
| 	 *
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function get_log_file_path() {
 | |
| 		return $this->file;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the log data.
 | |
| 	 *
 | |
| 	 * @access public
 | |
| 	 * @since 2.8.7
 | |
| 	 *
 | |
| 	 * @return string Log data.
 | |
| 	 */
 | |
| 	public function get_file_contents() {
 | |
| 		return $this->get_file();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve the file data is written to
 | |
| 	 *
 | |
| 	 * @access protected
 | |
| 	 * @since 2.8.7
 | |
| 	 *
 | |
| 	 * @return string File data.
 | |
| 	 */
 | |
| 	protected function get_file() {
 | |
| 		$file = '';
 | |
| 
 | |
| 		if ( $this->get_fs()->exists( $this->file ) ) {
 | |
| 			if ( ! $this->get_fs()->is_writable( $this->file ) ) {
 | |
| 				$this->is_writable = false;
 | |
| 			}
 | |
| 
 | |
| 			$file = $this->get_fs()->get_contents( $this->file );
 | |
| 		} else {
 | |
| 			$this->get_fs()->put_contents( $this->file, '' );
 | |
| 			$this->get_fs()->chmod( $this->file, 0664 );
 | |
| 		}
 | |
| 
 | |
| 		return $file;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Write the log message.
 | |
| 	 *
 | |
| 	 * @access protected
 | |
| 	 * @since 2.8.7
 | |
| 	 */
 | |
| 	protected function write_to_log( $message = '' ) {
 | |
| 		file_put_contents( $this->file, $message, FILE_APPEND );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Delete the log file or removes all contents in the log file if we cannot delete it.
 | |
| 	 *
 | |
| 	 * @access public
 | |
| 	 * @since 2.8.7
 | |
| 	 *
 | |
| 	 * @return bool True if the log was cleared, false otherwise.
 | |
| 	 */
 | |
| 	public function clear_log_file() {
 | |
| 		$this->get_fs()->delete( $this->file );
 | |
| 
 | |
| 		if ( $this->get_fs()->exists( $this->file ) ) {
 | |
| 
 | |
| 			// It's still there, so maybe server doesn't have delete rights
 | |
| 			$this->get_fs()->chmod( $this->file, 0664 );
 | |
| 			$this->get_fs()->delete( $this->file );
 | |
| 
 | |
| 			// See if it's still there...
 | |
| 			if ( $this->get_fs()->exists( $this->file ) ) {
 | |
| 				$this->get_fs()->put_contents( $this->file, '' );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		$this->file = '';
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	/** Deprecated ************************************************************/
 | |
| 
 | |
| 	/**
 | |
| 	 * Registers the edd_log post type.
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 * @deprecated 3.0 Due to migration to custom tables.
 | |
| 	 */
 | |
| 	public function register_post_type() {
 | |
| 		_edd_deprecated_function( __FUNCTION__, '3.0.0' );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Register the log type taxonomy.
 | |
| 	 *
 | |
| 	 * @since 1.3.1
 | |
| 	 * @deprecated 3.0 Due to migration to custom tables.
 | |
| 	*/
 | |
| 	public function register_taxonomy() {
 | |
| 		_edd_deprecated_function( __FUNCTION__, '3.0.0' );
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Helper method to insert a new log into the database.
 | |
|  *
 | |
|  * @since 1.3.3
 | |
|  *
 | |
|  * @see EDD_Logging::add()
 | |
|  *
 | |
|  * @param string $title   Log title.
 | |
|  * @param string $message Log message.
 | |
|  * @param int    $parent  Download ID.
 | |
|  * @param null   $type    Log type.
 | |
|  *
 | |
|  * @return int ID of the new log.
 | |
|  */
 | |
| function edd_record_log( $title = '', $message = '', $parent = 0, $type = null ) {
 | |
| 	$edd_logs = EDD()->debug_log;
 | |
| 
 | |
| 	return $edd_logs->add( $title, $message, $parent, $type );
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Logs a message to the debug log file.
 | |
|  *
 | |
|  * @since 2.8.7
 | |
|  * @since 2.9.4 Added the 'force' option.
 | |
|  *
 | |
|  * @param string $message Log message.
 | |
|  * @param bool   $force   Whether to force a log entry to be added. Default false.
 | |
|  */
 | |
| function edd_debug_log( $message = '', $force = false ) {
 | |
| 	$edd_logs = EDD()->debug_log;
 | |
| 
 | |
| 	if ( edd_is_debug_mode() || $force ) {
 | |
| 
 | |
| 		if ( function_exists( 'mb_convert_encoding' ) ) {
 | |
| 
 | |
| 			$message = mb_convert_encoding( $message, 'UTF-8' );
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		$edd_logs->log_to_file( $message );
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Logs an exception to the debug log file.
 | |
|  *
 | |
|  * @since 3.0
 | |
|  *
 | |
|  * @param \Exception $exception Exception object.
 | |
|  */
 | |
| function edd_debug_log_exception( $exception ) {
 | |
| 
 | |
| 	$label = get_class( $exception );
 | |
| 
 | |
| 	if ( $exception->getCode() ) {
 | |
| 
 | |
| 		$message = sprintf( '%1$s: %2$s - %3$s',
 | |
| 			$label,
 | |
| 			$exception->getCode(),
 | |
| 			$exception->getMessage()
 | |
| 		);
 | |
| 
 | |
| 	} else {
 | |
| 
 | |
| 		$message = sprintf( '%1$s: %2$s',
 | |
| 			$label,
 | |
| 			$exception->getMessage()
 | |
| 		);
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	edd_debug_log( $message );
 | |
| }
 |