teltek/pumukit-external-api-bundle
Symfony bundle that adds an external API layer to Pumukit, enabling third-party applications and services to authenticate and interact with multimedia content programmatically through standardized endpoints for smoother integrations.
Know what you're installing. This is a Symfony bundle for Pumukit (Teltek's video management platform), not a Laravel package. There is no Laravel service provider, no facade, no config publish. You will either:
If consuming from Laravel, you don't install it at all. You talk to a running Pumukit instance that has this bundle enabled. Add to config/services.php:
'pumukit' => [
'base_url' => env('PUMUKIT_URL'),
'token' => env('PUMUKIT_API_TOKEN'),
'timeout' => 15,
],
First smoke test:
curl -H "Authorization: Bearer $PUMUKIT_TOKEN" https://pumukit.example.com/api/multimedia
If you must work on the bundle itself, look here first, in order:
composer.json — Symfony/PHP version constraints (this ecosystem skews old; expect Symfony 2.8–4.x and PHP 7.x).Resources/config/routing.yml (or routing/) — the actual endpoint surface. Grep for api prefixes.Controller/ — the API controllers; FOSRestBundle style, actions named getMultimediaAction, cgetSeriesAction, etc.DependencyInjection/ + Resources/config/services.yml — services and the config key (typically pumukit_external_api).security.yml — auth lives there, not in the bundle.First use case: read-only catalog sync. Fetch series/multimedia lists on a schedule, store IDs locally, and render in your Laravel UI. Get that working before attempting writes.
Wrap the API in a single client class. Resist scattering Http:: calls:
class PumukitClient
{
public function __construct(private array $config) {}
public function multimedia(array $query = []): array
{
return Http::baseUrl($this->config['base_url'].'/api')
->withToken($this->config['token'])
->timeout($this->config['timeout'])
->retry(3, 200, throw: false)
->get('/multimedia', $query)
->throw()
->json();
}
}
Config-driven base URL and auth. Auth is usually a token/API key header or HTTP Basic defined in the host's security.yml firewall for /api. Confirm which by inspecting a working request before writing code.
Mirror pagination, don't invent it. Pumukit-style APIs typically return an envelope like { total, page, limit, resources: [...] } with page/limit query params. Map it onto a Laravel LengthAwarePaginator once, in an adapter, so controllers and Blade stay clean.
Store external IDs explicitly. Add pumukit_id (indexed, unique) to your local models. Every sync should be an upsert keyed on it — this is what makes retries and replays safe.
Queue the writes. Creating a multimedia object is often two-step: create the object, then upload a track file (multipart) referencing it. Do both inside one job, mark success only when the track exists:
class PublishVideoToPumukit implements ShouldQueue
{
public function handle(PumukitClient $client): void
{
$object = $client->createMultimedia($this->payload);
$client->uploadTrack($object['id'], $this->filePath);
$this->video->update(['pumukit_id' => $object['id'], 'synced_at' => now()]);
}
}
Webhooks via Symfony events (host-side). If you control Pumukit, register an event subscriber listening to the multimedia/series events and POST to a Laravel webhook endpoint. This beats polling and is the cleanest integration point. Guard the webhook with an HMAC header.
Cache read-heavy catalog data with Cache::remember keyed on the query, and invalidate on your own writes. There is no ETag/Last-Modified convention to lean on.
Add your own endpoints by extending, not forking. In a Pumukit host you can add a small bundle with its own controller/routing, or decorate existing services via services.yml. Bundle inheritance (overriding templates/controllers by name) still works in the older Symfony versions this targets, but is brittle.
Test the client boundary, not the network. Http::fake([...]) in Laravel feature tests; assert the request shape (path, headers, query params) and your upsert behavior. For the bundle itself, use Symfony KernelBrowser functional tests against real fixtures.
This is effectively unmaintained. 0 stars, 0 dependents, low overall score. Vendor/pin it to a commit SHA, expect no upstream fixes, and budget for a fork. Do not build a critical write path without a fallback plan.
Laravel auto-discovery does not apply. composer require teltek/pumukit-external-api-bundle into a Laravel app will do nothing useful and may drag in Symfony conflicts. Consume over HTTP instead.
401 vs 403 is a security.yml problem, not a bundle problem. Check the firewall for /api in the host app. access_control rules match top-down — the first match wins, so a broad ^/ rule can shadow your API rule.
Route loading differs by Symfony version. On 4+/Flex, the bundle's routes are not auto-imported; check config/routes.yaml. Debug with:
bin/console debug:router | grep api
PHP/Symfony constraints will fight you. Trying to install on PHP 8 with a modern Symfony will produce unsatisfiable dependency graphs. Use --ignore-platform-reqs only as a last resort, and expect runtime failures if you do.
Absolute URLs in responses break behind proxies. If API payloads embed host-derived URLs, ensure trusted proxies and X-Forwarded-Proto/Host are configured, or you'll get http:// links to internal hostnames.
Query params can silently 400. Endpoints often accept a criteria/json filter blob rather than flat params. If a filtered request 400s, log the full response body — FOSRestBundle tends to give a terse error.
Track upload is the fragile step. Verify mimetype/profile values against what the host expects, and confirm the response actually contains a track. A "successful" object creation with a failed track upload is the most common silent data bug.
Deletes are often soft. Status flags (-1 or similar) may hide objects while leaving them in lists filtered by status. Check status in every list query, or you'll "resurrect" deleted items.
Log the raw exchange when debugging. Temporarily add ->beforeSending(fn($r) => logger()->debug(...)) and log status + body, not just exceptions — this API's error messages are not always descriptive.
Extension points worth knowing: Symfony event subscribers (for outbound sync), service decoration (to override behavior without forking), and bundle inheritance (last resort). Prefer the first two.
How can I help you explore Laravel packages today?