composer require devhelp/piwik-bundle
config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):
Devhelp\PiwikBundle\DevhelpPiwikBundle::class => ['all' => true],
config/packages/devhelp_piwik.yaml:
devhelp_piwik:
client: my_piwik.client
api:
reader:
url: "http://your-piwik-instance.com"
default_params:
token_auth: "%env(PIWIK_TOKEN_AUTH)%"
getVisitsSummary):
# config/services.yaml
services:
my_piwik.client:
class: Devhelp\PiwikBundle\Client\Reader
arguments:
- "@devhelp_piwik.client"
- "getVisitsSummary"
Inject the service into a controller or command to fetch Piwik data:
use Devhelp\PiwikBundle\Client\ReaderInterface;
class AnalyticsController extends AbstractController
{
public function showStats(ReaderInterface $piwikReader)
{
$result = $piwikReader->call([
'idSite' => 1,
'period' => 'day',
'date' => 'today',
]);
// Process $result (e.g., render as JSON)
}
}
Service-Based API Calls:
Define reusable services for frequent Piwik API methods (e.g., getVisitsSummary, getActions, getReferrers).
Example:
# config/services.yaml
services:
my_piwik.visits_service:
class: Devhelp\PiwikBundle\Client\Reader
arguments:
- "@devhelp_piwik.client"
- "getVisitsSummary"
Dependency Injection:
Inject ReaderInterface or WriterInterface (for write operations) into controllers, commands, or services.
Example:
public function __construct(
private ReaderInterface $piwikReader,
private WriterInterface $piwikWriter
) {}
Environment Variables:
Store sensitive data (e.g., token_auth) in .env:
PIWIK_TOKEN_AUTH=your_token_here
Reference it in config/packages/devhelp_piwik.yaml:
default_params:
token_auth: "%env(PIWIK_TOKEN_AUTH)%"
Batch Processing:
Use the call() method to fetch large datasets and process them in chunks:
$result = $piwikReader->call([
'idSite' => 1,
'period' => 'month',
'format' => 'JSON',
'token_auth' => $token,
]);
foreach ($result['rows'] as $row) {
// Process each row
}
Custom Clients:
Extend the base Reader or Writer classes to add domain-specific logic:
class CustomPiwikReader extends Reader
{
public function getCustomReport()
{
return $this->call([
'method' => 'API.getCustomReport',
'idSite' => 1,
'columns' => 'nb_visits,nb_actions',
'date' => 'last7',
]);
}
}
Token Authentication:
token_auth is correctly set in default_params or passed per call.try {
$result = $piwikReader->call([...]);
} catch (\RuntimeException $e) {
// Log or handle the error (e.g., invalid token)
}
API Rate Limits:
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
try {
$result = $piwikReader->call([...]);
} catch (ClientExceptionInterface $e) {
if ($e->getResponse()->getStatusCode() === 429) {
sleep(2); // Wait before retrying
return $this->call($params);
}
throw $e;
}
Deprecated Methods:
API.get is deprecated; use API.getVisitsSummary instead.Configuration Overrides:
Caching Responses:
use Symfony\Contracts\Cache\CacheInterface;
public function __construct(
private ReaderInterface $piwikReader,
private CacheInterface $cache
) {}
public function getCachedData(array $params, string $cacheKey, int $ttl = 3600)
{
return $this->cache->get($cacheKey, function () use ($params) {
return $this->piwikReader->call($params);
}, $ttl);
}
Enable Debug Mode:
Set devhelp_piwik.debug: true in config to log raw API responses:
devhelp_piwik:
debug: true
Validate Parameters: Use the Piwik API docs to validate required parameters for each method. Example:
// Invalid: Missing 'idSite'
$piwikReader->call(['period' => 'day']);
// Valid
$piwikReader->call(['idSite' => 1, 'period' => 'day']);
Check HTTP Status Codes:
Wrap calls in a try-catch to handle errors gracefully:
try {
$result = $piwikReader->call([...]);
} catch (HttpException $e) {
$statusCode = $e->getStatusCode();
$response = $e->getResponse()->getContent();
// Log or notify (e.g., Slack/email)
}
Custom Response Handlers: Extend the bundle to transform raw Piwik responses into domain objects:
class PiwikResponseHandler
{
public function handle(array $rawData): array
{
return array_map(function ($row) {
return new VisitSummary(
$row['nb_visits'],
$row['max_actions'],
// ...
);
}, $rawData['rows']);
}
}
Event Listeners: Listen to Piwik API events (e.g., after a successful call) to trigger side effects:
use Devhelp\PiwikBundle\Event\PiwikEvent;
public function onPiwikCall(PiwikEvent $event)
{
if ($event->getMethod() === 'API.getVisitsSummary') {
// Log or process the result
}
}
Multi-Site Configuration: Support multiple Piwik instances by defining separate clients:
devhelp_piwik:
clients:
main:
url: "http://main.piwik.pro"
token: "%env(PIWIK_MAIN_TOKEN)%"
staging:
url: "http://staging.piwik.pro"
token: "%env(PIWIK_STAGING_TOKEN)%"
Then inject the specific client service.
Async Processing: Use Symfony Messenger to process Piwik data asynchronously:
$message = new FetchPiwikDataMessage($params);
$this->messageBus->dispatch($message);
Define a handler to call the Piwik API and store results in a database.
How can I help you explore Laravel packages today?