rizerzero
3/9/2012 - 1:42 AM

Simple CrudEventLogger

Simple CrudEventLogger

<?

// in lib/classes/crudeventlogger.php
class CrudEventLogger {
    protected $event = null;
    protected $table_name = null;
    protected $record_id = null;
    protected $user_id = null;
    protected $before = array();
    protected $after = array();
    protected $db = null;

    // constructor
    public function __construct($event, $table_name, $record_id, $user_id) {
        $this->set_event($event);
        $this->set_table_name($table_name);
        $this->set_record_id($record_id);
        $this->set_user_id($user_id);
        
        // ensure we have a connection to the database
        $this->db = DB();
    }

    // property setters
    public function set_event($event) {
        $this->event = strtolower($event);
    }

    public function set_table_name($table_name) {
        $this->table_name = $table_name;
    }

    public function set_record_id($record_id) {
        $this->record_id = intval($record_id);
    }

    public function set_user_id($user_id) {
        $this->user_id = intval($user_id);
    }

    // property getters
    public function event() {
        return $this->event;
    }

    public function table_name() {
        return $this->table_name;
    }

    public function record_id() {
        return $this->record_id;
    }

    public function user_id() {
        if ($this->user_id === null) {
            return Identity::get('userid');
        }

        return $this->user_id;
    }

    // callbacks
    public function before() {
        if ($this->event() === 'insert') {
            $this->before = array();
        } else {
            // select the record and fill-in the $before array
            $this->before = $this->load_record_details();
        }
    }
    
    public function after() {
        // 1. select the record again, if available
        // 2. compute the changes
        // 3. log the event
        if ($this->event() === 'delete') {
            $this->after = array();
        } else {
            $this->after = $this->load_record_details();
        }
        
        $changes = $this->compute_differences();
        
        $fields_to_log = array(
            'userId'    => $this->user_id(),
            'tableName' => $this->table_name(),
            'event'     => $this->event(),
            'eventDate' => date('Y-m-d H:i:s'),
            'changes'   => json_encode($changes),
        );

        $fields = array();
        foreach ($fields_to_log as $field => $value) {
            $value = mysql_escape_string($value);
            $fields[] = "`$field` = '$value'";
        }
        $fields = join(', ', $fields);

        $db->q("INSERT INTO `Events` SET $fields");
    }

    // helper functions    
    protected function load_record_details() {
        $table_name = $this->table_name();
        $record_id  = $this->record_id();

        foreach ($this->db->q("SELECT * FROM `$table_name` WHERE `id` = $record_id LIMIT 1") as $row) {
            return $row;
        }
        
        return array();
    }
    
    protected function compute_differences() {
        $differences = array('before' => $this->before, 'after' => $this->after);

        foreach ($differences['before'] as $field => $value) {
            if (isset($differences['after'][$field]) && $differences['after'][$field] === $value) {
                unset($differences['before'][$field]);
                unset($differences['after'][$field]);
            }
        }
        
        return $differences;
    }
}