PHPackages                             arraypress/edd-register-recount-tools - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Admin Panels](/categories/admin)
4. /
5. arraypress/edd-register-recount-tools

ActiveLibrary[Admin Panels](/categories/admin)

arraypress/edd-register-recount-tools
=====================================

A library for registering custom recount tools in Easy Digital Downloads admin area

03PHP

Since Dec 10Pushed 5mo agoCompare

[ Source](https://github.com/arraypress/edd-register-recount-tools)[ Packagist](https://packagist.org/packages/arraypress/edd-register-recount-tools)[ RSS](/packages/arraypress-edd-register-recount-tools/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

EDD Recount Tools - Register Custom Recount Tools
=================================================

[](#edd-recount-tools---register-custom-recount-tools)

Add custom recount/batch processing tools to Easy Digital Downloads admin Tools page.

Installation
------------

[](#installation)

```
composer require arraypress/edd-register-recount-tools
```

Basic Usage (Simple Callbacks)
------------------------------

[](#basic-usage-simple-callbacks)

```
// Register callback-based recount tools (recommended)
edd_register_recount_tools( [
    'recount-customer-downloads' => [
        'label'          => 'Customer Download Counts',
        'description'    => 'Recalculates the total number of file downloads for each customer.',
        'batch_size'     => 20,
        'count_callback' => function() {
            return edd_count_customers();
        },
        'callback'       => function( $offset, $batch_size ) {
            $customers = edd_get_customers( [
                'number' => $batch_size,
                'offset' => $offset,
                'fields' => 'id'
            ] );

            foreach ( $customers as $customer_id ) {
                $customer = new EDD_Customer( $customer_id );

                // Count file downloads for this customer
                $download_count = edd_count_file_downloads_of_customer( $customer->id );

                // Update customer meta
                edd_update_customer_meta( $customer->id, 'total_downloads', $download_count );

                edd_debug_log( sprintf( 'Updated download count for customer #%d: %d downloads', $customer->id, $download_count ) );
            }

            return $customers; // Return the processed items
        }
    ],
    'recount-product-reviews' => [
        'label'          => 'Product Review Counts',
        'description'    => 'Updates the review count and average rating for all downloads.',
        'batch_size'     => 10,
        'count_callback' => function() {
            return wp_count_posts( 'download' )->publish;
        },
        'callback'       => function( $offset, $batch_size ) {
            $downloads = get_posts( [
                'post_type'      => 'download',
                'posts_per_page' => $batch_size,
                'offset'         => $offset,
                'fields'         => 'ids'
            ] );

            foreach ( $downloads as $download_id ) {
                // Count reviews
                $review_count = get_comments_number( $download_id );

                // Calculate average rating
                $reviews = get_comments( [
                    'post_id'      => $download_id,
                    'meta_key'     => 'rating',
                    'meta_compare' => 'EXISTS'
                ] );

                $total_rating = 0;
                $rating_count = 0;

                foreach ( $reviews as $review ) {
                    $rating = get_comment_meta( $review->comment_ID, 'rating', true );
                    if ( $rating ) {
                        $total_rating += (int) $rating;
                        $rating_count++;
                    }
                }

                $average_rating = $rating_count > 0 ? round( $total_rating / $rating_count, 2 ) : 0;

                // Update post meta
                update_post_meta( $download_id, '_edd_review_count', $review_count );
                update_post_meta( $download_id, '_edd_average_rating', $average_rating );
            }

            return $downloads;
        }
    ]
] );
```

Real Examples
-------------

[](#real-examples)

### Sync Customer Data with CRM

[](#sync-customer-data-with-crm)

```
edd_register_recount_tools( [
    'sync-crm-data' => [
        'label'          => 'Sync CRM Data',
        'description'    => 'Synchronizes customer purchase data with external CRM system.',
        'batch_size'     => 5, // Smaller batches for API calls
        'count_callback' => function() {
            return edd_count_customers();
        },
        'callback'       => function( $offset, $batch_size ) {
            $customers = edd_get_customers( [
                'number' => $batch_size,
                'offset' => $offset
            ] );

            foreach ( $customers as $customer ) {
                // Prepare customer data for CRM
                $crm_data = [
                    'email'         => $customer->email,
                    'name'          => $customer->name,
                    'total_spent'   => $customer->purchase_value,
                    'order_count'   => $customer->purchase_count,
                    'last_purchase' => $customer->date_created
                ];

                // Send to CRM
                $response = wp_remote_post( 'https://your-crm.com/api/customers', [
                    'body' => json_encode( $crm_data ),
                    'headers' => [
                        'Content-Type' => 'application/json',
                        'Authorization' => 'Bearer ' . get_option( 'crm_api_key' )
                    ]
                ] );

                if ( is_wp_error( $response ) ) {
                    edd_debug_log( sprintf( 'CRM sync failed for customer #%d: %s', $customer->id, $response->get_error_message() ), true );
                } else {
                    // Mark as synced
                    edd_update_customer_meta( $customer->id, 'crm_synced', current_time( 'timestamp' ) );
                }

                // Rate limiting
                sleep( 1 );
            }

            return array_column( $customers, 'id' );
        }
    ]
] );
```

### Update Custom Fields

[](#update-custom-fields)

```
edd_register_recount_tools( [
    'update-lifetime-value' => [
        'label'          => 'Calculate Lifetime Value',
        'description'    => 'Calculates and updates customer lifetime value predictions.',
        'batch_size'     => 15,
        'count_callback' => function() {
            return edd_count_customers();
        },
        'callback'       => function( $offset, $batch_size ) {
            $customers = edd_get_customers( [
                'number' => $batch_size,
                'offset' => $offset
            ] );

            foreach ( $customers as $customer ) {
                if ( $customer->purchase_count < 2 ) {
                    $ltv = $customer->purchase_value;
                } else {
                    // Complex LTV calculation
                    $payments = edd_get_payments( [
                        'customer' => $customer->id,
                        'status'   => 'publish',
                        'number'   => -1
                    ] );

                    $purchase_dates = array_map( function( $payment ) {
                        return strtotime( $payment->date );
                    }, $payments );

                    sort( $purchase_dates );

                    // Calculate average time between purchases
                    $intervals = [];
                    for ( $i = 1; $i < count( $purchase_dates ); $i++ ) {
                        $intervals[] = $purchase_dates[$i] - $purchase_dates[$i-1];
                    }

                    $avg_interval = array_sum( $intervals ) / count( $intervals );
                    $avg_days = $avg_interval / DAY_IN_SECONDS;

                    // Predict 2 years of purchases
                    $predicted_purchases = (365 * 2) / $avg_days;
                    $avg_order_value = $customer->purchase_value / $customer->purchase_count;

                    $ltv = round( $predicted_purchases * $avg_order_value, 2 );
                }

                // Update customer meta
                edd_update_customer_meta( $customer->id, 'predicted_ltv', $ltv );
            }

            return array_column( $customers, 'id' );
        }
    ]
] );
```

Advanced Usage (Custom Classes)
-------------------------------

[](#advanced-usage-custom-classes)

For complex processing, you can still use custom classes:

```
edd_register_recount_tools( [
    'complex-recount' => [
        'class'       => 'EDD_Batch_Complex_Recount',
        'file'        => __DIR__ . '/includes/class-complex-recount.php',
        'label'       => 'Complex Data Processing',
        'description' => 'Performs complex multi-step data processing.'
    ]
] );
```

Configuration Options
---------------------

[](#configuration-options)

### Callback-Based Tools

[](#callback-based-tools)

OptionRequiredDescription`callback`**Yes**Function that processes items (`function($offset, $batch_size)`)`count_callback`**Yes**Function that returns total item count`label`NoDisplay name (auto-generated from key if not provided)`description`NoDescription shown in admin interface`batch_size`NoItems per batch (default: 20)### Class-Based Tools

[](#class-based-tools)

OptionRequiredDescription`class`**Yes**PHP class name that extends `EDD_Batch_Export``file`**Yes**Full path to file containing the class`label`NoDisplay name (auto-generated from key if not provided)`description`NoDescription shown in admin interfaceCallback Guidelines
-------------------

[](#callback-guidelines)

1. **Return processed items** - Your callback should return the items it processed
2. **Handle pagination** - Use `$offset` and `$batch_size` parameters
3. **Keep batches small** - 10-50 items per batch to avoid timeouts
4. **Include logging** - Use `edd_debug_log()` for progress tracking
5. **Handle errors gracefully** - Use try/catch blocks
6. **Rate limiting** - Add delays for external API calls

Requirements
------------

[](#requirements)

- PHP 7.4+
- WordPress 5.0+
- Easy Digital Downloads 3.0+

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

License
-------

[](#license)

This project is licensed under the GPL-2.0-or-later License.

Support
-------

[](#support)

- [Documentation](https://github.com/arraypress/edd-register-custom-stats)
- [Issue Tracker](https://github.com/arraypress/edd-register-custom-stats/issues)

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance49

Moderate activity, may be stable

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/cd6eb8aff0903d87eb674d1ba3c5f3653899c0d7661504eb0deb7798ed86b643?d=identicon)[arraypress](/maintainers/arraypress)

---

Top Contributors

[![arraypress](https://avatars.githubusercontent.com/u/22668877?v=4)](https://github.com/arraypress "arraypress (4 commits)")

### Embed Badge

![Health badge](/badges/arraypress-edd-register-recount-tools/health.svg)

```
[![Health](https://phpackages.com/badges/arraypress-edd-register-recount-tools/health.svg)](https://phpackages.com/packages/arraypress-edd-register-recount-tools)
```

###  Alternatives

[jeroennoten/laravel-adminlte

Easy AdminLTE integration with Laravel

4.0k4.8M43](/packages/jeroennoten-laravel-adminlte)[dmstr/yii2-adminlte-asset

AdminLTE backend theme asset bundle for Yii 2.0 Framework

1.1k1.8M67](/packages/dmstr-yii2-adminlte-asset)[dwij/laraadmin

LaraAdmin is a Open source Laravel Admin Panel / CMS which can be used as Admin Backend, Data Management Tool or CRM boilerplate for Laravel with features like CRUD Generation, Module Manager, Media, Menus, Backups and much more

1.6k68.7k](/packages/dwij-laraadmin)[filament/spatie-laravel-media-library-plugin

Filament support for `spatie/laravel-medialibrary`.

1764.8M125](/packages/filament-spatie-laravel-media-library-plugin)[bezhansalleh/filament-exceptions

A Simple &amp; Beautiful Pluggable Exception Viewer for FilamentPHP's Admin Panel

193195.9k13](/packages/bezhansalleh-filament-exceptions)[filament/infolists

Easily add beautiful read-only infolists to any Livewire component.

1220.8M36](/packages/filament-infolists)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
