{"id":35024031,"url":"https://github.com/carstingaxion/gatherpress-statistics","last_synced_at":"2026-04-24T00:35:20.315Z","repository":{"id":328558287,"uuid":"1115984471","full_name":"carstingaxion/gatherpress-statistics","owner":"carstingaxion","description":"Display dynamically calculated statistics about your GatherPress events with beautiful, cached counters.","archived":false,"fork":false,"pushed_at":"2025-12-28T15:17:45.000Z","size":2112,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-31T04:12:00.558Z","etag":null,"topics":["block","gatherpress","statistics","wordpress"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/carstingaxion.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-14T00:29:51.000Z","updated_at":"2025-12-16T22:44:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/carstingaxion/gatherpress-statistics","commit_stats":null,"previous_names":["figuren-theater/gatherpress-statistics"],"tags_count":0,"template":false,"template_full_name":"figuren-theater/new-ft-module","purl":"pkg:github/carstingaxion/gatherpress-statistics","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carstingaxion%2Fgatherpress-statistics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carstingaxion%2Fgatherpress-statistics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carstingaxion%2Fgatherpress-statistics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carstingaxion%2Fgatherpress-statistics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/carstingaxion","download_url":"https://codeload.github.com/carstingaxion/gatherpress-statistics/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carstingaxion%2Fgatherpress-statistics/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32204710,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T00:06:41.111Z","status":"ssl_error","status_checked_at":"2026-04-24T00:06:35.224Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["block","gatherpress","statistics","wordpress"],"created_at":"2025-12-27T06:10:24.941Z","updated_at":"2026-04-24T00:35:20.265Z","avatar_url":"https://github.com/carstingaxion.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GatherPress Statistics\n\nStable tag: 0.1.0  \nTested up to: 6.8  \nLicense: GPL v2 or later  \nTags: block, gatherpress, events, statistics  \nContributors: carstenbach, WordPress Telex  \n\nDisplay dynamically calculated statistics about your GatherPress events with beautiful, cached counters.\n\n[![Playground Demo Link](https://img.shields.io/badge/WordPress_Playground-blue?logo=wordpress\u0026logoColor=%23fff\u0026labelColor=%233858e9\u0026color=%233858e9)](https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/carstingaxion/gatherpress-statistics/main/.wordpress-org/blueprints/blueprint.json)\n\n## Description\n\nThe GatherPress Statistics block is a powerful tool  to provide statistics about your GatherPress events, venues, and topics with intelligent caching for optimal performance and a modular architecture that lets you control exactly which statistics are available.\n\n### Key Features:\n\n* **Modular Statistics System:** Enable or disable individual statistic types via post type supports\n* **Multiple Statistic Types:** Total events, events per taxonomy, multi-taxonomy filtering, attendee counts, and more\n* **Smart Caching System:** All statistics are calculated on data change using WordPress hooks and cached as transients for lightning-fast performance\n* **Dynamic Taxonomy Support:** Automatically works with all taxonomies registered to supported post types\n* **Multiple Block Styles:** Choose from Counter, Card, Minimal, or Confetti display styles\n* **Theme.json Integration:** Fully compatible with theme.json spacing, typography, and color settings\n* **Conditional Formatting:** Show different prefix/suffix based on count thresholds\n* **Event Time Filtering:** Separate statistics for upcoming and past events\n* **Semantic HTML:** Uses proper HTML5 elements (`\u003cfigure\u003e`, `\u003cdata\u003e`, `\u003cfigcaption\u003e`) for better accessibility\n\n### Perfect For:\n\n* Event organizers tracking attendance and engagement\n* Community managers analyzing event distribution\n* Website owners showcasing event statistics\n* Marketing teams highlighting venue utilization\n\n### How It Works:\n\nThe block uses WordPress hooks to monitor when GatherPress events, venues, or topics are created, updated, or deleted. When changes occur, statistics are recalculated in the background and stored as transients. The frontend simply displays the cached values, ensuring your site remains fast even with thousands of events.\n\n### Behind the Scenes:\n\nWhen you save an event, update attendee counts, or modify taxonomy terms, the plugin:\n1. Clears all cached statistics (instant)\n2. Schedules a background job to regenerate cache (60 seconds later)\n3. Pre-generates ~50-60 common statistics (0.3-1.2 seconds, background)\n4. Stores results as WordPress transients (default 12-hour expiration, customizable via filter)\n5. Frontend blocks retrieve cached values (0.001 seconds)\n\n== Installation ==\n\n1. Upload the plugin files to the `/wp-content/plugins/gatherpress-statistics` directory\n2. Activate the plugin through the 'Plugins' screen in WordPress\n3. Ensure GatherPress plugin is installed and activated\n4. Add the \"GatherPress Statistics\" block to any post or page\n5. Configure your desired statistic type and filters in the block settings\n\n## Frequently Asked Questions\n\n### Does this require GatherPress to be installed?\n\nYes, this block is designed to work with the GatherPress event management plugin. It queries GatherPress custom post types and taxonomies.\n\n### How often are statistics updated?\n\nStatistics are updated immediately when events, venues, or topics are created, modified, or deleted. The caching system ensures changes are reflected instantly while maintaining performance.\n\n### Can I display multiple statistics on one page?\n\nAbsolutely! Add multiple instances of the block, each configured to show different statistics.\n\n### How long are statistics cached?\n\nBy default, statistics are cached for 12 hours. However, the cache is automatically cleared and regenerated whenever relevant data changes. You can customize the cache duration using the `gatherpress_statistics_cache_expiration` filter.\n\n### Can I customize the appearance?\n\nYes! The block supports four built-in styles (Counter, Card, Minimal, Confetti) and fully respects your theme's color, typography, and spacing settings via theme.json. You can also use conditional prefix/suffix formatting based on count thresholds.\n\n### Will this slow down my site?\n\nNo! The block is designed with performance as a top priority. All heavy calculations happen in the background when data changes, not during page loads. Frontend rendering is nearly instant using cached values.\n\n### What happens with custom GatherPress taxonomies?\n\nThe block automatically detects and works with any taxonomies registered to the `gatherpress_event` post type. You don't need to modify any code when adding new taxonomies.\n\n### Can I show statistics for all events (upcoming and past combined)?\n\nNo. The plugin requires you to choose either upcoming or past events. This is by design to ensure accurate and meaningful statistics.\n\n### How do I style the number and label differently?\n\nSee the \"Styling with theme.json\" section below for detailed examples of targeting specific elements.\n\n## Screenshots\n\n1. ![Block editor interface showing statistic type selection and filtering options](assets/screenshot-1.png)\n2. ![Counter style displaying total events with custom colors](assets/screenshot-2.png)\n3. Card style showing events per topic with elegant design\n4. Minimal style integrated seamlessly into content\n5. ![Confetti style with interactive hover animation](assets/screenshot-5.png)\n6. Inspector controls for configuring statistics and filters\n7. Multiple taxonomy filter panel for complex queries\n8. ![Conditional prefix/suffix settings for dynamic formatting](assets/screenshot-8.png)\n\n## Block Usage\n\n### Basic Usage\n\n1. Add the \"GatherPress Statistics\" block to your post or page\n2. Select a statistic type from the sidebar\n3. Choose between upcoming or past events (where applicable)\n4. Configure labels and formatting options\n5. Apply filters if needed (taxonomy, terms, etc.)\n\n### Event Time Filtering\n\nMost statistics support filtering by event time:\n\n- **Upcoming Events**: Events scheduled in the future\n- **Past Events**: Events that have already occurred\n\nNote: This filter is not available for taxonomy term counts.\n\n### Single Taxonomy Filtering\n\nFor \"Events per Taxonomy Term\" and \"Total Attendees\" statistics:\n\n1. Select a taxonomy (e.g., \"Topics\")\n2. Choose a specific term (e.g., \"WordPress\")\n3. Statistics will show only events with that term\n\n### Multiple Taxonomy Filtering\n\nFor \"Events (Multiple Taxonomies)\" statistics:\n\n1. Expand each taxonomy panel in the sidebar\n2. Select multiple terms from each taxonomy\n3. Events must match ALL selected terms (AND relationship)\n\nExample: Select \"WordPress\" from Topics AND \"Beginner\" from Skill Level\n\n### Conditional Formatting\n\nCustomize the display based on count thresholds:\n\n1. Set a threshold number (e.g., 10)\n2. Define default prefix/suffix (e.g., \"Total\" / \"events\")\n3. Define conditional prefix/suffix (e.g., \"Over\" / \"and counting!\")\n4. When count exceeds threshold, conditional values are used\n\n### Block Styles\n\n- **Counter** (default): Large number with label below\n- **Card**: Elevated card design with shadow\n- **Minimal**: Compact display with smaller text\n- **Confetti**: Gradient background with hover animation\n\n== Styling with theme.json ==\n\n### HTML Structure\n\nThe block uses semantic HTML for better accessibility and styling:\n\n```html\n\u003cfigure class=\"wp-block-gatherpress-statistics\"\u003e\n  \u003cdata class=\"gatherpress-stats-value\" value=\"42\"\u003e\n    \u003cspan class=\"gatherpress-stats-prefix\"\u003eOver\u003c/span\u003e\n    \u003cspan class=\"gatherpress-stats-number\"\u003e42\u003c/span\u003e\n    \u003cspan class=\"gatherpress-stats-suffix\"\u003eand counting\u003c/span\u003e\n  \u003c/data\u003e\n  \u003cfigcaption class=\"gatherpress-stats-label\"\u003eEvents\u003c/figcaption\u003e\n\u003c/figure\u003e\n```\n\n### Key Elements:\n\n- **`\u003cfigure\u003e`**: Container with block classes and styles\n- **`\u003cdata\u003e`**: Holds the numeric value with machine-readable `value` attribute\n- **`\u003cspan class=\"gatherpress-stats-number\"\u003e`**: The actual statistic number\n- **`\u003cspan class=\"gatherpress-stats-prefix\"\u003e`**: Optional prefix text (e.g., \"Over\", \"+\")\n- **`\u003cspan class=\"gatherpress-stats-suffix\"\u003e`**: Optional suffix text (e.g., \"total\", \"and counting\")\n- **`\u003cfigcaption\u003e`**: The descriptive label\n\n### Styling the Number Separately\n\nTarget the `.gatherpress-stats-number` class to style just the number:\n\n```json\n{\n  \"version\": 2,\n  \"styles\": {\n    \"blocks\": {\n      \"gatherpress/statistics\": {\n        \"elements\": {\n          \".gatherpress-stats-number\": {\n            \"typography\": {\n              \"fontSize\": \"4rem\",\n              \"fontWeight\": \"900\",\n              \"lineHeight\": \"1\"\n            },\n            \"color\": {\n              \"text\": \"var(--wp--preset--color--primary)\"\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Styling the Label Separately\n\nTarget the `.gatherpress-stats-label` class:\n\n```json\n{\n  \"version\": 2,\n  \"styles\": {\n    \"blocks\": {\n      \"gatherpress/statistics\": {\n        \"elements\": {\n          \".gatherpress-stats-label\": {\n            \"typography\": {\n              \"fontSize\": \"0.875rem\",\n              \"fontWeight\": \"600\",\n              \"textTransform\": \"uppercase\",\n              \"letterSpacing\": \"0.05em\"\n            },\n            \"color\": {\n              \"text\": \"var(--wp--preset--color--contrast)\"\n            },\n            \"spacing\": {\n              \"margin\": {\n                \"top\": \"0.5rem\"\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Styling Prefix and Suffix\n\n```json\n{\n  \"version\": 2,\n  \"styles\": {\n    \"blocks\": {\n      \"gatherpress/statistics\": {\n        \"elements\": {\n          \".gatherpress-stats-prefix, .gatherpress-stats-suffix\": {\n            \"typography\": {\n              \"fontSize\": \"0.75em\",\n              \"fontWeight\": \"600\"\n            },\n            \"color\": {\n              \"text\": \"var(--wp--preset--color--secondary)\"\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Complete Styling Example\n\n```json\n{\n  \"version\": 2,\n  \"styles\": {\n    \"blocks\": {\n      \"gatherpress/statistics\": {\n        \"spacing\": {\n          \"padding\": \"2rem\"\n        },\n        \"border\": {\n          \"radius\": \"8px\"\n        },\n        \"color\": {\n          \"background\": \"var(--wp--preset--color--base)\",\n          \"text\": \"var(--wp--preset--color--contrast)\"\n        },\n        \"elements\": {\n          \".gatherpress-stats-value\": {\n            \"spacing\": {\n              \"margin\": {\n                \"bottom\": \"1rem\"\n              }\n            }\n          },\n          \".gatherpress-stats-number\": {\n            \"typography\": {\n              \"fontSize\": \"clamp(3rem, 8vw, 5rem)\",\n              \"fontWeight\": \"900\",\n              \"lineHeight\": \"1\"\n            },\n            \"color\": {\n              \"text\": \"var(--wp--preset--color--primary)\"\n            }\n          },\n          \".gatherpress-stats-prefix, .gatherpress-stats-suffix\": {\n            \"typography\": {\n              \"fontSize\": \"1rem\",\n              \"fontWeight\": \"600\"\n            },\n            \"color\": {\n              \"text\": \"var(--wp--preset--color--secondary)\"\n            }\n          },\n          \".gatherpress-stats-label\": {\n            \"typography\": {\n              \"fontSize\": \"1.25rem\",\n              \"fontWeight\": \"500\",\n              \"textTransform\": \"uppercase\",\n              \"letterSpacing\": \"0.1em\"\n            },\n            \"color\": {\n              \"text\": \"var(--wp--preset--color--contrast)\"\n            }\n          }\n        },\n        \"variations\": {\n          \"card\": {\n            \"shadow\": \"0 4px 6px -1px rgb(0 0 0 / 0.1)\",\n            \"elements\": {\n              \".gatherpress-stats-number\": {\n                \"typography\": {\n                  \"fontSize\": \"4.5rem\"\n                }\n              }\n            }\n          },\n          \"minimal\": {\n            \"spacing\": {\n              \"padding\": \"1rem\"\n            },\n            \"elements\": {\n              \".gatherpress-stats-number\": {\n                \"typography\": {\n                  \"fontSize\": \"2rem\"\n                }\n              },\n              \".gatherpress-stats-label\": {\n                \"typography\": {\n                  \"fontSize\": \"0.875rem\"\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Responsive Typography\n\nUse `clamp()` for fluid typography:\n\n```json\n{\n  \"elements\": {\n    \".gatherpress-stats-number\": {\n      \"typography\": {\n        \"fontSize\": \"clamp(2.5rem, 6vw + 1rem, 5rem)\"\n      }\n    },\n    \".gatherpress-stats-label\": {\n      \"typography\": {\n        \"fontSize\": \"clamp(0.875rem, 2vw + 0.5rem, 1.25rem)\"\n      }\n    }\n  }\n}\n```\n\n== Developer Documentation ==\n\n### Architecture Overview:\n\nThe plugin uses a layered architecture for optimal performance:\n1. **Post Type Support Layer:** Controls which statistics are available\n2. **Data Layer:** WordPress hooks monitor all relevant data changes\n3. **Scheduling Layer:** Changes trigger scheduled cache regeneration (60s delay)\n4. **Calculation Layer:** Efficient WP_Query-based calculations\n5. **Cache Layer:** WordPress transients store results\n6. **Presentation Layer:** Block renders cached data\n\n### Example Data Structure (15 events, 3 topics, 3 venues):\n\nSetup:\n- Events: E1-E15 (8 upcoming, 7 past)\n- Topics: Technology (ID: 1), Workshop (ID: 2), Networking (ID: 3)\n- Venues: Downtown Hall (ID: 4), Tech Center (ID: 5), Community Space (ID: 6)\n- Attendees: Varying from 10-50 per event\n\nEvent Distribution:\n- E1, E2, E6, E9: Technology, Downtown Hall (upcoming, 100 attendees)\n- E3, E7, E10: Technology, Tech Center (past, 75 attendees)\n- E4, E8: Workshop, Tech Center (upcoming, 45 attendees)\n- E5, E11, E14: Workshop, Community Space (past, 80 attendees)\n- E12: Technology, Downtown Hall (past, 25 attendees)\n- E13: Workshop, Tech Center (past, 15 attendees)\n- E15: Networking, Community Space (upcoming, 40 attendees)\n\nCached Statistics Examples:\n\n```php\n// Total counts by event query\nget_transient( 'gatherpress_stats_total_events_upcoming_abc123' ); // Returns: 8\nget_transient( 'gatherpress_stats_total_events_past_def456' );     // Returns: 7\nget_transient( 'gatherpress_stats_total_attendees_past_jkl012' );  // Returns: 195\n\n// Per taxonomy\nget_transient( 'gatherpress_stats_total_taxonomy_terms_mno345' ); // 3 topics\nget_transient( 'gatherpress_stats_total_taxonomy_terms_pqr678' ); // 3 venues\n\n// Per term with event query\nget_transient( 'gatherpress_stats_events_per_taxonomy_upcoming_stu901' ); // 4 (upcoming Technology events)\nget_transient( 'gatherpress_stats_events_per_taxonomy_past_vwx234' );    // 3 (past Technology events)\nget_transient( 'gatherpress_stats_total_attendees_past_bcd890' );        // 100 (past Technology attendees)\n\n// Cross-taxonomy\nget_transient( 'gatherpress_stats_taxonomy_terms_by_taxonomy_efg123' ); // 2 (venues with Tech events)\n```\n\n### Configuration Guide\n\n**Post Type Support System**\n\nThe plugin uses WordPress post type supports to provide granular control over functionality. By default, it registers support for `gatherpress_event` with all statistic types enabled:\n\n```php\nadd_post_type_support( 'gatherpress_event', 'gatherpress_statistics', array(\n    'total_events' =\u003e true,                // Total event counts\n    'events_per_taxonomy' =\u003e true,         // Events filtered by single taxonomy\n    'events_multi_taxonomy' =\u003e false,      // Events filtered by multiple taxonomies\n    'total_taxonomy_terms' =\u003e false,       // Count of taxonomy terms\n    'taxonomy_terms_by_taxonomy' =\u003e false, // Cross-taxonomy term counts\n    'total_attendees' =\u003e true,             // Attendee counts\n) );\n```\n\n**Available Statistic Types**\n\n1. **total_events** - Count all events (with optional filters)\n2. **events_per_taxonomy** - Count events in a specific taxonomy term\n3. **events_multi_taxonomy** - Count events matching multiple taxonomy terms (AND relationship)\n4. **total_taxonomy_terms** - Count total terms in a taxonomy\n5. **taxonomy_terms_by_taxonomy** - Count terms from one taxonomy that have events in another\n6. **total_attendees** - Sum of attendees across events (with optional filters)\n\n**Modifying Default Configuration**\n\nUse the `gatherpress_statistics_support_config` filter to customize which statistic types are enabled:\n\n```php\nadd_filter( 'gatherpress_statistics_support_config', function( $config ) {\n    // Disable complex statistics for better performance\n    $config['events_multi_taxonomy'] = false;\n    $config['taxonomy_terms_by_taxonomy'] = false;\n    \n    // Enable all basic statistics\n    $config['total_events'] = true;\n    $config['total_attendees'] = true;\n    $config['events_per_taxonomy'] = true;\n    \n    return $config;\n} );\n```\n\n**Adding Support to Custom Post Types**\n\nExtend the plugin to work with your custom event post types:\n\n```php\nadd_action( 'init', function() {\n    add_post_type_support( 'my_event_cpt', 'gatherpress_statistics', array(\n        'total_events' =\u003e true,\n        'events_per_taxonomy' =\u003e true,\n        'total_attendees' =\u003e false,  // Don't track attendees for this type\n    ) );\n}, 20 );\n```\n\n\n```php\n/**\n * Exclude specific taxonomies from statistics.\n *\n * This filter allows developers to exclude taxonomies from both\n * statistics generation and block editor selection.\n *\n * Note: `_gatherpress_venue` is excluded by default.\n *\n * @since 0.1.0\n *\n * @param array $excluded_taxonomies Array of taxonomy slugs to exclude.\n * @param bool  $for_editor         Whether this is for editor selection.\n * @return array Modified array of excluded taxonomy slugs.\n */\nadd_filter( 'gatherpress_statistics_excluded_taxonomies', function( $excluded, $for_editor ) {\n    // Exclude custom taxonomies from statistics\n    $excluded[] = 'post_tag';\n    $excluded[] = 'custom_event_type';\n    return $excluded;\n}, 10, 2 );\n```\n\n\n```php\n/**\n * Modify cache expiration time.\n *\n * Default is 12 hours (43200 seconds). Change this to adjust how long\n * statistics remain cached before automatic expiration.\n *\n * @since 0.1.0\n *\n * @param int $expiration Cache expiration time in seconds.\n * @return int Modified expiration time.\n */\nadd_filter( 'gatherpress_statistics_cache_expiration', function( $expiration ) {\n    // Cache for 6 hours instead of 12\n    return 6 * HOUR_IN_SECONDS;\n} );\n\n// Example: Cache for 1 hour\nadd_filter( 'gatherpress_statistics_cache_expiration', function( $expiration ) {\n    return HOUR_IN_SECONDS;\n} );\n\n// Example: Cache for 24 hours\nadd_filter( 'gatherpress_statistics_cache_expiration', function( $expiration ) {\n    return DAY_IN_SECONDS;\n} );\n```\n\n\n```php\n/**\n * Filter calculated statistics before caching.\n *\n * Available filters for each statistic type:\n * - gatherpress_stats_calculate_total_events\n * - gatherpress_stats_calculate_events_per_taxonomy\n * - gatherpress_stats_calculate_events_multi_taxonomy\n * - gatherpress_stats_calculate_total_taxonomy_terms\n * - gatherpress_stats_calculate_taxonomy_terms_by_taxonomy\n * - gatherpress_stats_calculate_total_attendees\n *\n * @since 0.1.0\n *\n * @param int   $count   The calculated statistic value.\n * @param array $filters The filters applied to this statistic.\n * @return int Modified statistic value.\n */\n\n// Example: Round counts to nearest 10 when over 50\nadd_filter( 'gatherpress_stats_calculate_total_events', function( $count, $filters ) {\n    if ( $count \u003e 50 ) {\n        return round( $count / 10 ) * 10;\n    }\n    return $count;\n}, 10, 2 );\n\n// Example: Round based on value ranges\nadd_filter( 'gatherpress_stats_calculate_total_attendees', function( $count, $filters ) {\n    // Round to nearest 5 if between 10-50\n    if ( $count \u003e= 10 \u0026\u0026 $count \u003c= 50 ) {\n        return round( $count / 5 ) * 5;\n    }\n    // Round to nearest 10 if between 50-100\n    if ( $count \u003e 50 \u0026\u0026 $count \u003c= 100 ) {\n        return round( $count / 10 ) * 10;\n    }\n    // Round to nearest 50 if over 100\n    if ( $count \u003e 100 ) {\n        return round( $count / 50 ) * 50;\n    }\n    return $count;\n}, 10, 2 );\n\n// Example: Apply a custom multiplier\nadd_filter( 'gatherpress_stats_calculate_total_events', function( $count, $filters ) {\n    // Apply a 1.5x multiplier to all event counts\n    return round( $count * 1.5 );\n}, 10, 2 );\n```\n\n### Performance Metrics:\n\n- Cache hit: ~0.001 seconds\n- Cache miss + calculation: ~0.005-0.02 seconds per statistic\n- Full cache regeneration (50-60 stats): ~0.3-1.2 seconds (background)\n- Database impact: Minimal (uses transients, cleared automatically)\n\n### Cache Invalidation Triggers:\n\nThe plugin uses a smart cache invalidation system that balances freshness with performance:\n\n#### Trigger Events:\n\n1. Event post status changes to/from 'publish' (`transition_post_status`)\n2. Attendee count meta field updated (`updated_post_meta`, `added_post_meta`, `deleted_post_meta`)\n3. GatherPress taxonomy terms created, edited, or deleted (`create_term`, `edit_term`, `delete_term`)\n4. Taxonomy term relationships change (`set_object_terms`)\n\n#### Cache Clearing Process:\n\n1. Trigger event occurs (e.g., event published)\n2. All statistics transients deleted immediately from database\n3. Single cron job scheduled to run in 60 seconds\n4. Additional triggers within 60s don't schedule duplicate jobs\n5. After 60s, background regeneration creates ~50-60 common statistics\n6. Each statistic cached with configured expiration (default 12 hours)\n\n#### Why 60-second delay?\n\n- Prevents multiple regenerations during bulk operations\n- Avoids resource exhaustion during large imports\n- Allows all related changes to complete first\n- Doesn't block or slow down admin operations\n\n#### Manual Cache Clearing:\n\n```php\n// Clear cache programmatically\n\\GatherPressStatistics\\clear_cache();\n\n// Force immediate regeneration (use sparingly)\n\\GatherPressStatistics\\clear_cache();\n\\GatherPressStatistics\\pregenerate_cache();\n```\n\n\n## Changelog\n\n###  0.1.0\n* Initial release\n* Support GatherPress post types \u0026 with any taxonomies\n* Filtering for upcoming or past events\n* Smart caching system with automatic invalidation\n* Scheduled cache regeneration system\n* Four display style variations including animated Confetti style\n* Full theme.json integration\n* Comprehensive taxonomy filtering\n* Attendee count statistics\n* Conditional prefix/suffix formatting\n* Comprehensive documentation and developer hooks\n* Semantic HTML structure with `\u003cfigure\u003e`, `\u003cdata\u003e`, and `\u003cfigcaption\u003e` elements\n\n\n## Privacy \u0026 Data\n\nThis plugin does not collect, store, or transmit any personal data. It only queries and caches statistics about your events and taxonomies. All data is stored locally in your WordPress database using the transients API.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarstingaxion%2Fgatherpress-statistics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarstingaxion%2Fgatherpress-statistics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarstingaxion%2Fgatherpress-statistics/lists"}