Installation
composer require common-gateway/woo-bundle
Add to config/bundles.php:
return [
// ...
CommonGateway\WooBundle\WooBundle::class => ['all' => true],
];
Configuration Publish the default config:
php artisan vendor:publish --provider="CommonGateway\WooBundle\WooBundle" --tag="config"
Edit config/woo.php to define:
open_index_endpoint (API URL)koop_integration (boolean)sync_cron_schedule (e.g., '* * * * *' for every minute)default_publication_categoriesFirst Use Case Sync a single publication manually:
use CommonGateway\WooBundle\Service\PublicationService;
$publicationService = app(PublicationService::class);
$publication = $publicationService->syncFromOpenIndex('woo:publication:123');
Synchronization
app/Console/Kernel.php:
$schedule->command('woo:sync')->everyMinute();
php artisan woo:sync
sync_strategy in woo.php:
'sync_strategy' => 'incremental', // or 'full'
Querying Publications
$publications = $publicationService->search([
'category' => 'wetgeving',
'limit' => 10,
]);
$federatedResults = $publicationService->federatedSearch('wetgeving', ['koophulpje']);
Event-Driven Updates
EventServiceProvider:
protected $listen = [
'CommonGateway\WooBundle\Events\PublicationSynced' => [
'App\Listeners\LogPublicationSync',
],
];
Custom Data Mapping
PublicationTransformer:
use CommonGateway\WooBundle\Transformer\PublicationTransformer;
class CustomPublicationTransformer extends PublicationTransformer
{
public function transform($data)
{
$data = parent::transform($data);
$data['custom_field'] = $this->extractCustomField($data);
return $data;
}
}
WooBundle config:
'transformer' => App\Transformer\CustomPublicationTransformer::class,
Database Schema
Publication, PublicationCategory). Extend them if needed:
class Publication extends \CommonGateway\WooBundle\Entity\Publication
{
protected $casts = [
'metadata' => 'array',
'tags' => 'collection',
];
}
API Clients
OpenIndexClient for custom API logic:
use CommonGateway\WooBundle\Client\OpenIndexClient;
class CustomOpenIndexClient extends OpenIndexClient
{
public function fetchPublications(array $query)
{
// Custom logic
return parent::fetchPublications($query);
}
}
WooBundle config:
'clients' => [
'open_index' => App\Client\CustomOpenIndexClient::class,
],
Caching
'cache' => [
'enabled' => true,
'driver' => 'redis',
'ttl' => 3600, // 1 hour
],
Testing
WooBundleTestCase base class:
use CommonGateway\WooBundle\Tests\WooBundleTestCase;
class PublicationServiceTest extends WooBundleTestCase
{
public function testSyncPublication()
{
// Test logic
}
}
Sync Conflicts
updated_at timestamps are inconsistent.PublicationRepository to handle conflicts:
class CustomPublicationRepository extends \CommonGateway\WooBundle\Repository\PublicationRepository
{
public function findOrCreate(array $attributes)
{
$existing = $this->findByExternalId($attributes['external_id']);
if ($existing && $existing->updated_at > Carbon::parse($attributes['updated_at'])) {
return $existing; // Skip if local version is newer
}
return parent::findOrCreate($attributes);
}
}
WooBundle config:
'repositories' => [
'publication' => App\Repository\CustomPublicationRepository::class,
],
KOOP Integration
koop_client:
'koop_integration' => [
'enabled' => true,
'retry_attempts' => 3,
'retry_delay' => 1000, // ms
],
Category Mapping
CategoryMapper:
use CommonGateway\WooBundle\Mapper\CategoryMapper;
class CustomCategoryMapper extends CategoryMapper
{
protected function getLocalCategory(string $externalCategory): ?string
{
$mapping = [
'wetgeving' => 'wetten-en-regels',
'besluiten' => 'overheidsbesluiten',
];
return $mapping[$externalCategory] ?? null;
}
}
WooBundle config:
'mappers' => [
'category' => App\Mapper\CustomCategoryMapper::class,
],
Performance
sync_strategy:
'sync_strategy' => [
'batch_size' => 50,
'chunk' => true,
],
Enable Logging
Add to config/logging.php:
'channels' => [
'woo' => [
'driver' => 'single',
'path' => storage_path('logs/woo.log'),
'level' => 'debug',
],
],
Then configure in woo.php:
'logging' => [
'channel' => 'woo',
'level' => 'debug',
],
API Debugging
--debug flag for CLI commands:
php artisan woo:sync --debug
$client = app(\CommonGateway\WooBundle\Client\OpenIndexClient::class);
$response = $client->fetchPublications([], true); // $debug = true
Database Debugging
.env:
DB_LOG_QUERIES=true
Custom Fields
Publication model to add custom fields:
class Publication extends \CommonGateway\WooBundle\Entity\Publication
{
protected $fillable = ['custom_field'];
}
public function transform($data)
{
$data['custom_field'] = $data['raw_data']['custom_field'] ?? null;
return parent::transform($data);
}
Webhooks
Route::post('/webhook/woo', function (Request $request) {
$publicationService = app(PublicationService::class);
$publicationService->handleWebhook($request->all());
});
Custom Sync Sources
use CommonGateway\WooBundle\Sync
How can I help you explore Laravel packages today?