Last active
December 20, 2015 23:38
-
-
Save lmoffereins/6213466 to your computer and use it in GitHub Desktop.
Proposal for new Simple History main plugin class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* The SH_Event Class | |
* | |
* @package Simple History | |
* @subpackage Event | |
* | |
* @since 2.0 | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) exit; | |
if ( ! class_exists( 'SH_Event' ) ) : | |
/** | |
* SH_Event class | |
* | |
* @since 2.0 | |
*/ | |
final class SH_Event { | |
/** | |
* Event database ID | |
* | |
* @var int | |
*/ | |
public $db_id; | |
/** | |
* Event author ID | |
* | |
* @var int | |
*/ | |
public $event_author = 0; | |
/** | |
* Event date in GMT | |
* | |
* @var string | |
*/ | |
public $event_date_gmt = '0000-00-00 00:00:00'; | |
/** | |
* Event item ID | |
* | |
* @var int | |
*/ | |
public $ID; | |
/** | |
* Event item type | |
* | |
* Holds the type of the event item, like 'post' or 'category' | |
* | |
* @var string | |
*/ | |
public $event_type = ''; | |
/** | |
* Event item meta type | |
* | |
* Holds the type of the event item type, like 'post_type' or 'taxonomy' | |
* | |
* @var string | |
*/ | |
public $event_meta_type = ''; | |
/** | |
* Event item name | |
* | |
* @var string | |
*/ | |
public $event_name = ''; | |
/** | |
* Note on the following event_action and event_action_vars properties: | |
* | |
* Those are both taken from the event_action database column. This column | |
* can hold either just the event action OR an array with the event action | |
* and its action vars array: array( action, array( var1, var2 ) ). In the | |
* latter situation the string and vars array will be separated when the | |
* object is constructed. | |
*/ | |
/** | |
* Event item action ID or action string | |
* | |
* The action can be one of those: | |
* - action identifier, will be searched for in global event translation table | |
* - action string to be filled with vars: 1. type, 2. name, ?. action vars | |
* - action string as verb as seen in previous setup | |
* | |
* NOTE: To get the event action title use {@link SH_Event::get_title()} | |
* | |
* @var string | |
*/ | |
private $event_action = ''; | |
/** | |
* Event action vars | |
* | |
* @var array | |
*/ | |
private $event_action_vars = array(); | |
/** | |
* Event item details | |
* | |
* @var string|array | |
*/ | |
public $event_details = ''; | |
/** | |
* Get an SH_Event by id | |
* | |
* @param int $db_id | |
* @return object SH_Event | |
*/ | |
public static function get_instance( $db_id ) { | |
global $wpdb; | |
// Cast the given id to an integer | |
$db_id = (int) $db_id; | |
if ( ! $db_id ) | |
return false; | |
// Get all data for the given id | |
$_event = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->simple_history WHERE ID = %d LIMIT 1", $db_id ) ); | |
if ( ! $_event ) | |
return false; | |
// Return the event as an SH_Event object | |
return new SH_Event( $_event ); | |
} | |
/** | |
* Constructor | |
* | |
* @param object $event | |
*/ | |
public function __construct( $event ) { | |
foreach ( (array) $event as $key => $value ) { | |
if ( 'ID' == $key ) | |
$this->db_id = $value; | |
elseif ( 'event_id' == $key ) | |
$this->ID = $value; | |
else | |
$this->$key = $value; | |
} | |
// Set the event action | |
$this->parse_event_action(); | |
} | |
/** | |
* Parse the event action | |
* | |
* @param string|array $action | |
*/ | |
public function parse_event_action( $action = '' ) { | |
if ( empty( $action ) ) | |
$action = $this->event_action; | |
if ( empty( $action ) ) | |
return; | |
$action = maybe_unserialize( $action ); | |
// Action is a single string | |
if ( is_string( $action ) ) | |
$this->event_action = $action; | |
// Action contains action vars | |
elseif ( is_array( $action ) && count( $action ) == 2 ) { | |
// Set the first index as the event action | |
$this->event_action = $action[0]; | |
// Set the second index as the event action vars | |
$this->event_action_vars = $action[1]; | |
} | |
} | |
/** | |
* Generate the event title | |
* | |
* @return string | |
*/ | |
public function get_title() { | |
$sh = simple_history(); | |
// Fetch sentence from the actions table | |
if ( array_key_exists( $this->event_action, $sh->actions ) ) | |
$action = $sh->actions[ $this->event_action ]; | |
// Action is an actual sentence containing sprintf vars | |
elseif ( preg_match( "/(%[0-9]*\$?[a-zA-Z])/", $this->event_action ) ) // Search for any %s or %1$s/%2$s/etc. | |
$action = $this->event_action; | |
// Action is text to be prepended with <type> and <name> | |
else | |
$action = '%1$s %2$s ' . $this->event_action; | |
// Allow for overwriting the event action string | |
$action = apply_filters( 'simple_history_event_action', $action, $this ); | |
// Allow filtering for custom action vars line up | |
$action_vars = apply_filters( 'simple_history_event_action_vars', $this->event_action_vars, $this ); | |
// Prepend event type and name when vars aren't modified | |
if ( $action_vars == $this->event_action_vars ) { | |
// Auto-fetch post type or taxonomy label | |
if ( 'post_type' == $this->event_meta_type ) | |
$label = get_post_type_object( $this->event_type )->labels->singular_name; | |
elseif ( 'taxonomy' == $this->event_meta_type ) | |
$label = get_taxonomy( $this->event_type )->labels->singular_name; | |
else | |
$label = apply_filters( 'simple_history_event_type_label', $this->event_type ); | |
$action_vars = array_unshift( $this->event_action_vars, ucfirst( $label ), ucfirst( $this->event_name ) ); | |
} | |
// Fill the action string with the event action vars | |
return vsprintf( $action, $action_vars ); | |
} | |
/** | |
* Return event as database safe array | |
* | |
* @since 2.0 | |
* | |
* @return array Event | |
*/ | |
public function prepare() { | |
$_event = $this->to_array(); | |
// Reorder event IDs | |
$_event['ID'] = $this->db_id; | |
$_event['event_id'] = $this->ID; | |
unset( $_event['db_id'] ); | |
// Merge event action vars with event action | |
if ( ! empty( $_event['event_action_vars'] ) ) | |
$_event['event_action'] = array( $_event['event_action'], (array) $_event['event_action_vars'] ); | |
unset( $_event['event_action_vars'] ); | |
$_event = wp_unslash( $_event ); | |
return $_event; | |
} | |
/** | |
* Get the event as an associative array | |
* | |
* @since 2.0 | |
* | |
* @return array | |
*/ | |
public function to_array() { | |
// Get the object vars | |
$event = get_object_vars( $this ); | |
return $event; | |
} | |
} | |
endif; // class_exists |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Simple History functions | |
* | |
* @package Simple History | |
* @subpackage Functions | |
* | |
* @since 2.0 | |
*/ | |
/** | |
* Register an event | |
* | |
* @since 1.1 | |
* | |
* @uses Simple_History::log_event() | |
* | |
* @param array $args Elements that make up the event to register. | |
* @param boolean $collect Whether to add event to a collection. Default to false. | |
* @return boolean|WP_Error WP_Error on failure. True on succcess. | |
*/ | |
function simple_history_add( $args = array(), $collect = false ) { | |
// Back compat pre-2.0 | |
$depr_message = __('Passing the <code>%s</code> is deprecated. Use <code>%s</code> instead.', 'simple-history'); | |
if ( isset( $args['object_id'] ) ) { | |
_deprecated_argument( __FUNCTION__, '2.0', sprintf( $depr_message, 'object_id', 'ID' ) ); | |
$args['ID'] = (int) $args['object_id']; | |
} | |
if ( isset( $args['object_type'] ) ) { | |
_deprecated_argument( __FUNCTION__, '2.0', sprintf( $depr_message, 'object_type', 'type' ) ); | |
$args['type'] = $args['object_type']; | |
} | |
if ( isset( $args['object_subtype'] ) ) { | |
_deprecated_argument( __FUNCTION__, '2.0', sprintf( $depr_message, 'object_subtype', 'meta_type' ) ); | |
if ( post_type_exists( $args['object_subtype'] ) ) { | |
$args['type'] = $args['object_subtype']; | |
$args['meta_type'] = 'post_type'; | |
} elseif ( taxonomy_exists( $args['object_subtype'] ) ) { | |
$args['type'] = $args['object_subtype']; | |
$args['meta_type'] = 'taxonomy'; | |
} else { | |
$args['meta_type'] = ''; | |
} | |
} | |
if ( isset( $args['object_name'] ) ) { | |
_deprecated_argument( __FUNCTION__, '2.0', sprintf( $depr_message, 'object_name', 'name' ) ); | |
$args['name'] = (int) $args['object_name']; | |
} | |
if ( isset( $args['user_id'] ) ) { | |
_deprecated_argument( __FUNCTION__, '2.0', sprintf( $depr_message, 'user_id', 'author' ) ); | |
$args['author'] = $args['user_id']; | |
} | |
if ( isset( $args['description'] ) ) { | |
_deprecated_argument( __FUNCTION__, '2.0', sprintf( $depr_message, 'description', 'details' ) ); | |
$args['details'] = $args['description']; | |
} | |
return simple_history()->log_event( $args, $collect ); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: __Simple History | |
* Description: A syslog system for WordPress. View all activity/changes on your website. | |
* Plugin URI: http://eskapism.se/code-playground/simple-history/ | |
* Version: 2.0 | |
* Author: Pär Thernström, Laurens Offereins | |
* Author URI: http://eskapism.se | |
* License: GPL2 | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) exit; | |
if ( ! class_exists( 'Simple_History' ) ) : | |
/** | |
* Main Simple History Class | |
* | |
* @since 2.0 | |
*/ | |
final class Simple_History { | |
/** | |
* Holds all events for the current page | |
* @var array | |
*/ | |
public $events = array(); | |
/** | |
* Holds all event action strings | |
* @var array | |
*/ | |
public $actions = array(); | |
/** | |
* Holds all modules | |
* @var array | |
*/ | |
public $modules = array(); | |
/** | |
* The one true Simple History | |
* @var Simple_History | |
*/ | |
private static $instance; | |
/** | |
* Main Simple History instance | |
* | |
* Ensures there's only one instance of Simple_History existing in memory at any | |
* one time. Also prevents defining globals all over the place. | |
* | |
* @since 2.0 | |
* | |
* @staticvar $instance | |
* @uses Simple_History::setup_globals() Setup the globals needed | |
* @uses Simple_History::includes() Include the required files | |
* @uses Simple_History::setup_actions() Setup the hooks and actions | |
* @see simple_history() | |
* @return The one true Simple_History | |
*/ | |
public static function instance() { | |
if ( ! isset( self::$instance ) ) { | |
self::$instance = new Simple_History; | |
self::$instance->setup_globals(); | |
self::$instance->includes(); | |
self::$instance->setup_actions(); | |
} | |
return self::$instance; | |
} | |
/** | |
* Dummy constructor to prevent Simple_History to be loaded more than once. | |
* | |
* @since 2.0 | |
* | |
* @see Simple_History::instance() | |
* @see simple_history() | |
*/ | |
public function __construct() { /* Do nothing here */ } | |
/** | |
* Set class default variables | |
* | |
* @since 2.0 | |
*/ | |
private function setup_globals() { | |
/** Versions **********************************************************/ | |
$this->version = '2.0'; | |
$this->db_version = '200'; | |
/** Paths *************************************************************/ | |
$this->file = __FILE__; | |
$this->basename = plugin_basename( $this->file ); | |
$this->plugin_dir = plugin_dir_path( $this->file ); | |
$this->plugin_url = plugin_dir_url( $this->file ); | |
// Includes | |
$this->includes_dir = trailingslashit( $this->plugin_dir . 'includes' ); | |
$this->includes_url = trailingslashit( $this->plugin_url . 'includes' ); | |
// Languages | |
$this->lang_dir = trailingslashit( $this->plugin_dir . 'languages' ); | |
// Modules | |
$this->modules_dir = trailingslashit( $this->plugin_dir . 'modules' ); | |
$this->modules_url = trailingslashit( $this->plugin_url . 'modules' ); | |
/** Users *************************************************************/ | |
$this->current_user = new stdClass(); // Currently logged in user | |
$this->view_cap = apply_filters( 'simple_history_view_cap', 'edit_pages' ); | |
$this->sett_cap = apply_filters( 'simple_history_sett_cap', 'manage_options' ); | |
/** Misc **************************************************************/ | |
$this->name = 'Simple History'; | |
$this->domain = 'simple-history'; | |
$this->table = 'simple_history'; | |
/** Cache *************************************************************/ | |
// Add Simple History to global cache groups | |
wp_cache_add_global_groups( 'simple-history' ); | |
} | |
/** | |
* Include required files | |
* | |
* @since 2.0 | |
*/ | |
private function includes() { | |
/** Events ************************************************************/ | |
require( $this->includes_dir . 'classes/class.sh-event.php' ); | |
require( $this->includes_dir . 'install.php' ); | |
require( $this->includes_dir . 'functions.php' ); | |
/** Modules ***********************************************************/ | |
require( $this->includes_dir . 'classes/class.sh-module.php' ); | |
require( $this->includes_dir . 'modules.php' ); | |
/** Admin *************************************************************/ | |
if ( is_admin() ) { | |
require( $this->includes_dir . 'admin.php' ); | |
} | |
} | |
/** | |
* Set actions and filters | |
* | |
* @since 2.0 | |
*/ | |
private function setup_actions() { | |
// Add actions to plugin activation and deactivation hooks | |
add_action( 'activate_' . $this->basename, 'simple_history_activation' ); | |
add_action( 'deactivate_' . $this->basename, 'simple_history_deactivation' ); | |
/** Events ************************************************************/ | |
add_action( 'shutdown', array( $this, 'insert_events' ) ); | |
/** Misc **************************************************************/ | |
add_action( 'init', array( $this, 'load_textdomain' ) ); | |
} | |
/** Public Methods ********************************************************/ | |
/** | |
* Register an event | |
* | |
* Stores the event data in the Simple_History::$events array | |
* | |
* @since 2.0 | |
* | |
* @see simple_history_add() | |
* | |
* @param array $args Elements that make up the event to register. | |
* @param boolean $collect Whether to add this event to a collection of other | |
* events belonging to the same event item ID. | |
* @return boolean Whether event registration was successfull. | |
*/ | |
public function log_event( $args = array(), $collect = true ) { | |
$defaults = array( | |
'ID' => 0, | |
'type' => '', | |
'meta_type' => '', | |
'name' => '', | |
'action' => '', | |
'action_vars' => array(), | |
'details' => '', | |
'author' => '', | |
); | |
$args = wp_parse_args( $args, $defaults ); | |
// Require event type, event name and event action | |
if ( empty( $args['type'] ) ) | |
return new WP_Error('sh_no_event_type', __('Missing event type.', 'simple-history')); | |
if ( empty( $args['name'] ) ) | |
return new WP_Error('sh_no_event_name', __('Missing event item name.', 'simple-history')); | |
if ( empty( $args['action'] ) ) | |
return new WP_Error('sh_no_event_action', __('Missing event action.', 'simple-history')); | |
// Set event date GMT | |
$args['date_gmt'] = current_time( 'mysql', 1 ); | |
// Find a place to prepend 'event_' to all args... | |
// Find item of collection | |
if ( $collect // Do collect | |
&& 0 != $args['ID'] // Don't do empty ID's | |
&& $previous = wp_list_filter( $this->events, array( | |
'ID' => $args['ID'], | |
'type' => $args['type'], | |
'meta_type' => $args['meta_type'] | |
) ) // Find matching items on ID, type and meta_type | |
&& ! empty( $previous ) // Matched items found | |
) { | |
// Add event to collection... | |
// Add new item to list | |
} else { | |
$this->events[] = apply_filters( 'simple_history_log_event', $args ); | |
} | |
return true; | |
} | |
/** | |
* Insert an event in the database | |
* | |
* @since 2.0 | |
* | |
* @param SH_Event|array $event The event object or event data. | |
* @return int|WP_Error WP_Error on failure. The event database ID on success. | |
*/ | |
public function insert_event( $event ) { | |
global $wpdb; | |
if ( ! is_a( $event, 'SH_Event' ) ) | |
$event = simple_history_get_event( $event ); | |
if ( ! $event || is_wp_error( $event ) ) | |
return $event; | |
$update = 0 != $event->db_id; | |
$data = $event->prepare(); | |
// Update existing event | |
if ( $update ) { | |
$event_before = simple_history_get_event( $event->db_id ); | |
do_action( 'simple_history_pre_update_event', $event->db_id, $event ); | |
$where = array( 'ID' => $event->db_id ); | |
if ( false === $wpdb->update( $wpdb->simple_history, $data, $where ) ) { | |
return new WP_Error('db_update_error', __('Could not update event in the database', 'simple-history'), $wpdb->last_error ); | |
} | |
// Insert new event | |
} else { | |
if ( false == $wpdb->insert( $wpdb->simple_history, $data ) ) { | |
return new WP_Error('db_insert_error', __('Could not insert event into the database', 'simple-history' ), $wpdb->last_error ); | |
} | |
$event->db_id = (int) $wpdb->insert_id; | |
} | |
if ( $update ) { | |
do_action( 'simple_history_update_event', $event->db_id, $event, $event_before ); | |
} else { | |
do_action( 'simple_history_insert_event', $event->db_id, $event ); | |
} | |
return $event->db_id; | |
} | |
/** | |
* Insert registered events in the database | |
* | |
* @since 2.0 | |
* | |
* @uses Simple_History::insert_event() To insert the events | |
* @return boolean|WP_Error Whether insertion was successfull | |
*/ | |
public function insert_events() { | |
if ( empty( $this->events ) ) | |
return true; | |
foreach ( $this->events as $event ) { | |
$retval = $this->insert_event( $event ); | |
if ( is_wp_error( $retval ) ) | |
return $retval; | |
} | |
return $retval; | |
} | |
/** | |
* Prepare event to be inserted in the database | |
* | |
* @since 2.0 | |
* | |
* @param SH_Event $event Event object | |
* @return array|WP_Error | |
*/ | |
public function prepare_event( $event ) { | |
if ( ! is_a( $event, 'SH_Event' ) ) | |
return new WP_Error('sh_not_an_event', __('Variable to prepare is not an event.', 'simple-history')); | |
$_event = $event->to_array(); | |
$_event['ID'] = $event->db_id; | |
$_event['event_id'] = $event->ID; | |
unset( $_event['db_id'] ); | |
$_event = wp_unslash( $_event ); | |
return apply_filters( 'simple_history_prepare_event', $_event, $event ); | |
} | |
/** | |
* Load the translation file for current language. Checks the languages | |
* folder inside the Simple History plugin first, and then the default | |
* WordPress languages folder. | |
* | |
* Note that custom translation files inside the Simple History plugin | |
* folder will be removed on Simple History updates. If you're creating | |
* custom translation files, please use the global language folder. | |
* | |
* @since 2.0 | |
* | |
* @uses apply_filters() Calls 'plugin_locale' with the {@link get_locale()} value | |
* @uses load_textdomain() To load the textdomain | |
* @return boolean True on success, false on failure | |
*/ | |
public function load_textdomain() { | |
// Traditional WordPress plugin locale filter | |
$locale = apply_filters( 'plugin_locale', get_locale(), $this->domain ); | |
$mofile = sprintf( '%1$s-%2$s.mo', $this->domain, $locale ); | |
// Setup paths to current locale file | |
$mofile_local = $this->lang_dir . $mofile; | |
$mofile_global = WP_LANG_DIR . '/simple-history/' . $mofile; | |
// Look in global /wp-content/languages/simple-history folder | |
if ( file_exists( $mofile_global ) ) { | |
return load_textdomain( $this->domain, $mofile_global ); | |
// Look in local /wp-content/plugins/simple-history/languages/ folder | |
} elseif ( file_exists( $mofile_local ) ) { | |
return load_textdomain( $this->domain, $mofile_local ); | |
} | |
// Nothing found | |
return false; | |
} | |
/** | |
* Setup the currently logged-in user | |
* | |
* @since 2.0 | |
* | |
* @todo Set anonymous user with comment cookies or bbpress user | |
* data when available | |
* | |
* @uses wp_get_current_user() | |
*/ | |
public function setup_current_user() { | |
$this->current_user = &wp_get_current_user(); | |
} | |
} | |
/** | |
* Return the Simple History instance | |
* | |
* @since 2.0 | |
* | |
* @return The one true Simple History instance | |
*/ | |
function simple_history() { | |
return Simple_History::instance(); | |
} | |
// Load this pretty piece of code | |
simple_history(); | |
endif; // class_exists |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment