freema / ga4-analytics-data-bundle
Google Analytics 4 Data API Bundle for Symfony applications
Installs: 10
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: >=8.1
- ext-bcmath: *
- ext-json: *
- google/analytics-data: ^0.20.0
- psr/cache: ^1.0|^2.0|^3.0
- psr/log: ^1.0|^2.0|^3.0
- symfony/config: ^5.4|^6.4|^7.1
- symfony/dependency-injection: ^5.4|^6.4|^7.1
- symfony/framework-bundle: ^5.4|^6.4|^7.1
- symfony/http-kernel: ^5.4|^6.4|^7.1
Requires (Dev)
- doctrine/annotations: ^1.13|^2.0
- friendsofphp/php-cs-fixer: ^3.14
- nyholm/psr7: ^1.5
- php-http/discovery: ^1.14
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.5|^10.0
- psr/http-client: ^1.0
- symfony/browser-kit: ^5.4|^6.4|^7.1
- symfony/css-selector: ^5.4|^6.4|^7.1
- symfony/debug-bundle: ^5.4|^6.4|^7.1
- symfony/dotenv: ^5.4|^6.4|^7.1
- symfony/http-client: ^5.4|^6.4|^7.1
- symfony/http-client-contracts: ^2.5|^3.0
- symfony/monolog-bundle: ^3.8
- symfony/phpunit-bridge: ^5.4|^6.4|^7.1
- symfony/routing: ^5.4|^6.4|^7.1
- symfony/web-profiler-bundle: ^5.4|^6.4|^7.1
- symfony/yaml: ^5.4|^6.4|^7.1
Suggests
- nyholm/psr7: For PSR-7 HTTP message implementation
- php-http/discovery: For HTTP client auto-discovery
- psr/http-client: Needed for HTTP client implementations
- symfony/http-client: To use Symfony HTTP client for API requests
README
A Symfony bundle for working with the Google Analytics 4 Data API. This bundle supports multiple Google Analytics properties, cache configuration, and provides a clean API to query analytics data.
Installation
Install the bundle using Composer:
composer require freema/ga4-analytics-data-bundle
The bundle uses Symfony Flex, so it will automatically:
- Enable the bundle in
config/bundles.php
- Create the configuration file
config/packages/ga4_analytics_data.yaml
- Add environment variables to your
.env
file - Add the credentials file path to your
.gitignore
Manual Installation (Without Flex)
If you're not using Symfony Flex, you need to:
- Register the bundle in your
config/bundles.php
:
return [ // ... Freema\GA4AnalyticsDataBundle\GA4AnalyticsDataBundle::class => ['all' => true], ];
- Create the configuration file at
config/packages/ga4_analytics_data.yaml
:
ga4_analytics_data: clients: default: property_id: '%env(ANALYTICS_PROPERTY_ID)%' service_account_credentials_json: '%env(ANALYTICS_CREDENTIALS_PATH)%' cache: enabled: true # Enable/disable caching lifetime_in_minutes: 1440 # 24 hours cache lifetime # Optional proxy configuration proxy: '%env(default::ANALYTICS_PROXY)%' no_proxy: [] # You can define multiple clients with different properties # another_property: # property_id: '%env(ANOTHER_ANALYTICS_PROPERTY_ID)%' # service_account_credentials_json: '%env(ANOTHER_ANALYTICS_CREDENTIALS_PATH)%' # The default client to use when none is specified default_client: 'default' # Enable/disable the Symfony profiler integration profiler: '%kernel.debug%'
- Add the required environment variables to your
.env
file:
###> freema/ga4-analytics-data-bundle ###
ANALYTICS_PROPERTY_ID=123456789
ANALYTICS_CREDENTIALS_PATH=%kernel.project_dir%/config/analytics-credentials.json
# ANALYTICS_PROXY=http://proxy.example.com:8080
###< freema/ga4-analytics-data-bundle ###
Requirements
- PHP 8.1+
- Symfony 5.4|6.4|7.1
- Google Analytics 4 Property
- Service Account credentials with access to the GA4 property
Usage
Basic Usage
use Freema\GA4AnalyticsDataBundle\Analytics\AnalyticsClientInterface; use Freema\GA4AnalyticsDataBundle\Domain\Period; class ReportingController { public function dashboard(AnalyticsClientInterface $analyticsClient) { // Get statistics for the last 30 days $period = Period::days(30); // Get most viewed pages $topPages = $analyticsClient->getMostViewedPages($period, 10); // Get visitors and pageviews by date $visitorsData = $analyticsClient->getVisitorsAndPageViews($period); // Get total visitors and pageviews $totals = $analyticsClient->getTotalVisitorsAndPageViews($period); return $this->render('dashboard.html.twig', [ 'topPages' => $topPages, 'visitorsData' => $visitorsData, 'totals' => $totals, ]); } }
Using Multiple Clients
use Freema\GA4AnalyticsDataBundle\Client\AnalyticsRegistryInterface; class MultiPropertyReportingController { private $analyticsRegistry; public function __construct(AnalyticsRegistryInterface $analyticsRegistry) { $this->analyticsRegistry = $analyticsRegistry; } public function compareProperties() { $period = Period::days(30); // Get data from first property $defaultClient = $this->analyticsRegistry->getClient('default'); $defaultData = $defaultClient->getTotalVisitorsAndPageViews($period); // Get data from second property $anotherClient = $this->analyticsRegistry->getClient('another_property'); $anotherData = $anotherClient->getTotalVisitorsAndPageViews($period); return $this->render('compare.html.twig', [ 'defaultData' => $defaultData, 'anotherData' => $anotherData, ]); } }
Custom Queries
// Run a custom report $results = $analyticsClient->runReport( // Dimensions ['date', 'deviceCategory', 'browser'], // Metrics ['totalUsers', 'newUsers', 'sessions'], // Period Period::months(3), // Options [ 'orderBy' => [ OrderBy::dimension('date', OrderBy::ASCENDING), ], 'limit' => 100, ] );
Period Helper
The bundle includes a Period
class to easily define date ranges:
// Last 30 days $period = Period::days(30); // Last 6 months $period = Period::months(6); // Last year $period = Period::years(1); // Custom period $period = Period::create( new \DateTime('2023-01-01'), new \DateTime('2023-12-31') );
Caching
The bundle provides flexible caching options:
- Enable/Disable: Set
enabled: true/false
in the cache config section - Lifetime: Configure with
lifetime_in_minutes
(defaults to 1440 = 24 hours) - Custom Cache: The bundle uses Symfony's cache system, so you can configure any PSR-6 cache adapter
Symfony Web Profiler Integration
The bundle includes a data collector for the Symfony Web Profiler that shows:
- Configured Analytics clients
- Property IDs
- Cache settings
- Proxy configuration
This can be disabled by setting profiler: false
in the bundle config.
Getting Google Analytics 4 Credentials
Creating Service Account Credentials
- Go to the Google Cloud Console
- Create a new project or select an existing one
- Enable the "Google Analytics Data API" for your project
- Go to "APIs & Services" > "Credentials"
- Create a new "Service Account"
- Download the JSON key file for the service account
- In Google Analytics, go to Admin > Property > Property Access Management
- Add the service account email with "Viewer" permissions
Credentials File Format
The service account credentials file should be a JSON file with the following structure:
{ "type": "service_account", "project_id": "your-project-id", "private_key_id": "key-id", "private_key": "-----BEGIN PRIVATE KEY-----\nPrivate key content\n-----END PRIVATE KEY-----\n", "client_email": "your-service-account@your-project.iam.gserviceaccount.com", "client_id": "client-id", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/your-service-account%40your-project.iam.gserviceaccount.com" }
Security Best Practices
- Store credentials securely: Keep the JSON file in a secure location, outside of your web root
- Use environment variables: Reference the path to the credentials file using environment variables
- Restrict permissions: Set appropriate file permissions to limit access to the credentials file
- Environment-specific paths: Use different paths for different environments (dev, staging, prod)
# config/packages/ga4_analytics_data.yaml ga4_analytics_data: clients: default: service_account_credentials_json: '%env(ANALYTICS_CREDENTIALS_PATH)%'
# .env
ANALYTICS_CREDENTIALS_PATH=/secure/path/to/credentials.json
# .env.local (development)
ANALYTICS_CREDENTIALS_PATH=config/credentials/analytics-dev.json
Error Handling
The bundle validates the credentials file and provides clear error messages for common issues:
- File not found or unreadable
- Invalid JSON format
- Missing required fields
- Incorrect service account format
If you encounter credential errors, check:
- That the file exists at the specified path
- That the file has proper read permissions
- That the file contains valid JSON with all required fields
- That the service account has access to the Google Analytics property
License
This bundle is released under the MIT License. See the included LICENSE file.
Contributing
See CONTRIBUTING.md for information on how to contribute to this project.