Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alex-georgiou/29ec4dd91b33e29e152de3cbeca2d48e to your computer and use it in GitHub Desktop.
Save alex-georgiou/29ec4dd91b33e29e152de3cbeca2d48e to your computer and use it in GitHub Desktop.
Bitcoin and Altcoin Wallets airdrops aggregation script. The script will aggregate airdrop transactions older than 1 month into one.
<?php
/**
* Bitcoin and Altcoin Wallets airdrops aggregation script
*
* The script will aggregate airdrop transactions older than 1 month into one.
* Use it if the Airdrop extension has created too many transactions and
* your site is now slowing down because of this.
*
* It will create one aggregate transaction for each combination of:
* - blog (for multisite installations)
* - user
* - currency
*
* USAGE INSTRUCTIONS - please read carefully!!!
*
* DO NOT RUN THIS SCRIPT UNLESS YOU KNOW WHAT IT IS FOR!
* TAKE A BACKUP OF YOUR WORDPRESS SITE BEFORE RUNNING THIS SCRIPT.
*
* 1. Enter the full path to your WordPress installation into the `$wppath` variable below.
*
* 2. Take a backup of your WordPress site.
*
* 3. Run this script with the following command:
* php ./wallets-balances-airdrops-aggregation-script.php
*
* 4. Please note the script's output. If you encounter any problems, email me the script's output.
*
* The script attempts to create MySQL atomic transactions for extra safety.
* IF atomic transactions slow down the script too much, you can set $safe_execution to false below.
* As long as you have a full backup of your site, it is OK to run this script without atomic transactions.
*
* If you have any questions, contact me at info@dashed-slug.net
*
* @author Alex Georgiou <info@dashed-slug.net>
* @copyright 2024
* @license GPL-2.0-or-later
* @version 1.0.0
* @link https://www.dashed-slug.net/bitcoin-altcoin-wallets-wordpress-plugin/airdrop-extension/
*/
// SET THIS TO THE PATH OF YOUR WORDPRESS INSTALLATION
$wppath = '/var/www/wordpress';
// SET THIS TO HOW OLD TRANSACTIONS YOU WANT TO AGGREGATE. "-1 month" MEANS THAT ONLY TXS OLDER THAN A MONTH WILL BE AGGREGATED.
$before_text = '-1 month';
// SET THIS TO FALSE ONLY IF USING TRANSACTIONS SLOWS DOWN THE SCRIPT SO MUCH THAT IT BECOMES UNUSABLE. KEEP A BACKUP OF YOUR SITE BEFORE RUNNING!
$safe_execution = true;
// DO NOT EDIT BELOW THIS LINE
global $wpdb;
$wppath = rtrim( $wppath, '/ \n\r\t\v\x00' );
if ( ! file_exists( "$wppath/wp-load.php" ) ) {
echo "Invalid WordPress dir!\n";
die;
}
require_once "$wppath/wp-load.php";
echo "Bitcoin and Altcoin Wallets airdrops aggregation\n";
echo "DB NAME: " . DB_NAME ."\n";
echo "DB USER: " . DB_USER ."\n";
echo "DB_HOST: " . DB_HOST ."\n";
echo "ABSPATH: " . ABSPATH ."\n";
if ( ! function_exists( 'DSWallets\get_first_currency_by_symbol' ) ) {
echo "Wallets plugin is not installed!\n";
die;
}
require_once ABSPATH . WPINC . '/class-wp-site-query.php';
require_once ABSPATH . WPINC . '/class-wp-network-query.php';
require_once ABSPATH . WPINC . '/ms-blogs.php';
if( !function_exists('get_plugin_data') ){
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$version = get_plugin_data( ABSPATH . 'wp-content/plugins/wallets/wallets.php' )['Version'];
echo "Version $version found\n";
if ( version_compare( $version, '6.0.0' ) < 0 ) {
echo "You must install and activate wallets version 6.0.0 or later\n";
die;
}
if ( ! is_plugin_active( 'wallets/wallets.php' ) ) {
echo "You must activate the wallets plugin\n";
die;
}
if ( ! function_exists( 'get_option' ) ) {
echo ABSPATH . 'wp-includes/option.php';
require_once ABSPATH . 'wp-includes/option.php';
}
function get_all_user_ids(): array {
return get_users( [ 'fields' => 'ids' ] );
}
function get_old_airdrops_txs( int $user_id, int $currency_id, string $before ):array {
$query_args = [
'fields' => 'ids',
'post_type' => 'wallets_tx',
'post_status' => 'publish',
'orderby' => 'ID',
'order' => 'DESC',
'nopaging' => true,
'posts_per_page' => -1,
'meta_query' => [
'relation' => 'AND',
[
'key' => 'wallets_user',
'value' => $user_id,
'type' => 'numeric',
],
[
'key' => 'wallets_category',
'value' => 'move',
],
[
'key' => 'wallets_currency_id',
'value' => $currency_id,
],
],
'tax_query' => [
[
'taxonomy' => 'wallets_tx_tags',
'field' => 'slug',
'terms' => 'airdrop',
]
],
'date_query' => [
[
'before' => $before,
'inclusive' => false,
],
],
];
$query = new \WP_Query( $query_args );
return array_values( $query->posts );
}
function get_all_blog_ids(): array {
if ( is_multisite() ) {
$blogs = wp_get_sites();
$blog_ids = array();
foreach ( $blogs as $blog ) {
$blog_ids[] = $blog->blog_id;
}
return $blog_ids;
} else {
return [ get_current_blog_id() ];
}
}
$stats_txcount = 0;
$stats_agtxcount = 0;
foreach ( get_all_blog_ids() as $blog_id ) {
switch_to_blog( $blog_id );
printf( "\n\nProcessing airdrop transactions for blog %d\n", $blog_id );
foreach ( get_all_user_ids() as $user_id ) {
$before_stamp = strtotime( $before_text, strtotime( current_time( 'mysql' ) ) );
$before = date( 'Y-m-d H:i:s', $before_stamp );
$user = new \WP_User( $user_id );
printf( "\n\tProcessing airdrop transactions for user %d (%s)\n", $user_id, $user->user_login );
foreach ( DSWallets\get_currency_ids() as $currency_id ) {
printf( "\t\tProcessing airdrop transactions for currency %d\n", $currency_id );
try {
$currency = DSWallets\Currency::load( $currency_id );
$tx_ids = get_old_airdrops_txs( $user_id, $currency_id, $before );
if ( count( $tx_ids ) > 1 ) {
printf(
"\t\t\tProcessing %d airdrop transactions for user %d and currency %s\n",
count($tx_ids),
$user_id,
$currency
);
} else {
continue;
}
if ( $safe_execution ) {
$wpdb->query( 'START TRANSACTION' );
}
$sum_amount = 0;
$sum_fee = 0;
foreach ( $tx_ids as $txid ) {
$tx = DSWallets\Transaction::load( $txid );
echo "\t\t\t\tProcessing transaction: $tx\n";
$sum_amount += $tx->amount;
$sum_fee += $tx->fee;
if ( ! wp_delete_post( $txid, true ) ) {
throw new \Exception( "Failed to delete $tx" );
}
}
$aggregate = new DSWallets\Transaction;
$aggregate->category = 'move';
$aggregate->user = $user;
$aggregate->currency = $currency;
$aggregate->amount = $sum_amount;
$aggregate->comment = sprintf( 'Aggregate airdrop earnings before %s', $before );
$aggregate->timestamp = $before_stamp;
$aggregate->status = 'done';
$aggregate->saveButDontNotify();
$aggregate->tags = ['airdrop-aggregate' ];
echo "\t\t\tCreated aggregate transaction: $aggregate\n\n";
} catch ( \Exception $e ) {
printf(
"\t\t\tFailed to aggregate batch of %d airdrop transactions for user %d (%s) and currency %s, due to: %s",
count( $tx_ids),
$user_id,
$user->user_login,
$currency,
$e->getMessage()
);
if ( $safe_execution ) {
$wpdb->query( 'ROLLBACK' );
print( "Rolled back this batch of transactions.\n" );
continue;
}
}
if ( $safe_execution ) {
$wpdb->query( 'COMMIT' );
}
$stats_txcount += count( $tx_ids );
$stats_agtxcount++;
}
}
restore_current_blog();
}
printf(
"Aggregated %d airdrop transactions into %d transactions in %d blogs and for %d users and %d currencies\n",
$stats_txcount,
$stats_agtxcount,
count(get_all_blog_ids()),
count(get_all_user_ids()),
count(DSWallets\get_currency_ids())
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment