Created
April 3, 2024 11:06
-
-
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.
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 | |
/** | |
* 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