Skip to content

Instantly share code, notes, and snippets.

@xnau
Last active February 9, 2025 04:02
Show Gist options
  • Save xnau/02cc349916c4fef2aa7b4746ac52c896 to your computer and use it in GitHub Desktop.
Save xnau/02cc349916c4fef2aa7b4746ac52c896 to your computer and use it in GitHub Desktop.
Shows how to set up a running total with the Participants Database Participant Log plugin
<?php
/**
* Plugin Name: PDb Log Running Total
* Description: keeps a running total for each record
* Version: 2.1
*/
/*
* this plugin keeps a cumulative total for each record by subtracting or adding
* a value from a field in the man database every time a log entry is added or updated
*
* INSTRUCTIONS for configuring this plugin:
*
* 1. type in the name of log in the $log_name variable in this plugin
*
* 2. define a cumulative total field in the main database, it should be a numeric,
* currency, or decimal type field, depending on what you're keeping track of.
* This field should be set to "read-only" unless you want the user to be able
* to manage this value. This field serves as the master balance for the record.
*
* 3. type the name of that field in this plugin for the $main_balance_field variable
*
* 4. define a field in the log that will hold the value that is added or subtracted
* from the main total field, this should also be a numeric field of some kind
*
* 5. type the name of that field in this plugin for the $log_add_field variable
*
* 6. in the main database, set the initial value (or the re-up value) for each
* record in the main total field
*
*/
class pdb_log_running_total {
/**
* @var string name of the log that is changing the running total
*/
private $log_name = 'work_log';
/**
* @var string name of the total field in the main database record
*/
private $main_balance_field = 'numeric_value';
/**
* @var string name of the field in the log entry that will be added or
* subtracted from the main total field
*/
private $log_add_field = 'work_log_spend';
/**
* @var int the current record id
*/
private $record_id = 0;
/**
* sets up the action handler
*/
public function __construct()
{
/*
* this method is called when a new log entry is submitted
*/
add_filter( 'pdblog-' . $this->log_name . '_before_insert_log_entry', [$this, 'update_total_new' ] );
/*
* this method is called when a log entry is getting edited
*/
add_filter( 'pdblog-' . $this->log_name . '_before_update_log_entry', [$this, 'update_total_edit' ], 10, 2 );
/*
* this sets the "sum" value as the current balance for the record, which is displayed in the log summary
*/
add_filter( 'pdblog-' . $this->log_name . '_sum', array( $this, 'set_sum_value' ), 10, 2 );
}
/**
* updates the running total for a new entry
*
* @param array $submission_data the newly submitted log entry data
* @return array the submission data
*/
public function update_total_new( $submission_data )
{
// set the record id
$this->record_id = $submission_data['record_id'];
// this is where we perform the calculation and update the log's balance field
$updated_submission_data = $this->process_submission( $submission_data );
return $updated_submission_data;
}
/**
* removes the previously entered value from the total
*
* this is used to reverse the effect of an entry if the value in the entry is getting corrected
*
* @param array $submission_data the newly submitted log entry data
* @param int $entry_id the id of the entry that is getting updated
* @return array the submission data
*/
public function update_total_edit( $submission_data, $entry_id )
{
$this->record_id = $submission_data['record_id'];
$this->correct_balance( $submission_data, $entry_id );
return $this->process_submission( $submission_data );
}
/**
* sets the summary to show the current balance
*
* @param float $sum the sum value
* @param array $entry the entry data
* @return float the sum value
*/
public function set_sum_value( $sum, $entry )
{
if ( count( $entry ) > 0 )
{
$this->record_id = current($entry)->record_id;
$sum = (float) $this->current_total();
}
return $sum;
}
/**
* processes the submission
*
* this updates the main balance and sets the log's balance value
*
* @param array $submission_data
* @return array the processed submission data
*/
private function process_submission( $submission_data )
{
$new_total = $this->get_new_balance( $submission_data );
// update the main record with the new total
$this->update_record_total( $new_total );
return $submission_data;
}
/**
* corrects the balance when an edit is preformed
*
* this reverses the effect of the entry before the new value is calculated
*
* @param array $submission_data
* @param int $entry_id
*/
private function correct_balance( $submission_data, $entry_id )
{
// get the entry values
$entry_values = \pdblog\log\entry_db::values( $this->log_name, $entry_id );
$current_total = $this->current_total();
// use '-' instead of '+' if the entry value is added to the total
$corrected_total = $current_total + $entry_values[ $this->log_add_field ];
$this->update_record_total( $corrected_total );
}
/**
* calculates the new balance
*
* @param array $submission_data
* @return int|float new total
*/
private function get_new_balance( $submission_data )
{
// get the current total value
$current_total = $this->current_total();
// if there is no value that changes the balance, return the balance
if ( ! isset( $submission_data[ $this->log_add_field ] ) || empty( $submission_data[ $this->log_add_field ] ) )
{
return $current_total;
}
// calculate the new total value
// use '+' instead of '-' if the entry value is added to the total
return $current_total - $submission_data[ $this->log_add_field ];
}
/**
* provides the current running total value for a record
*
* @return int|float the current total
*/
private function current_total()
{
$record = Participants_Db::get_participant( $this->record_id );
return $record[ $this->main_balance_field ];
}
/**
* updates the record with the new total
*
* @global \wpdb $wpdb
* @param int|float $new_total
*/
private function update_record_total( $new_total )
{
global $wpdb;
$wpdb->update( Participants_Db::$participants_table, [ $this->main_balance_field => $new_total ], ['id' => $this->record_id] );
PDb_Participant_Cache::is_now_stale( $this->record_id );
}
}
new pdb_log_running_total();
@xnau
Copy link
Author

xnau commented Feb 3, 2025

This is meant to be installed as a WordPress plugin.

Installing a Gist as a WordPress Plugin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment