Repository navigation
Description
Problem
After composer require zammad/zammad-api-client-php, nothing is wired up in a Symfony app. Three manual steps are needed:
- Register
ZammadAPIClient\Bridge\SymfonyBundleinconfig/bundles.php. - Create
config/packages/zammad.yaml. The file is not optional: Symfony calls a bundle's extension only for an alias that has configuration, so without azammad:section the bundle silently registers nothing, and aZammadClienttype-hint fails with a "non-existent service" error that does not point at the missing file. - Add
ZAMMAD_URLandZAMMAD_TOKENto.env.
Laravel users need none of this: the provider is auto-discovered via extra.laravel.providers. In discussion #174 this gap led to the suggestion of moving the bridges into separate packages.
Who is affected: every Symfony user of the bundle, and especially new ones. Step 2 is the easiest to miss and the hardest to diagnose.
Proposed change
Keep the bridges in this package. A separate repository would add a second release cycle without solving anything a recipe cannot. Instead, contribute a Flex recipe to symfony/recipes-contrib. Recipes are keyed by package name, so the library itself stays as it is.
zammad/zammad-api-client-php/3.2/manifest.json:
{
"bundles": {
"ZammadAPIClient\\Bridge\\SymfonyBundle": ["all"]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/"
},
"env": {
"ZAMMAD_URL": "https://zammad.example.com",
"ZAMMAD_TOKEN": ""
},
"post-install-output": [
" * Set <fg=green>ZAMMAD_URL</> and <fg=green>ZAMMAD_TOKEN</> in <fg=green>.env.local</>"
]
}zammad/zammad-api-client-php/3.2/config/packages/zammad.yaml:
zammad:
url: '%env(ZAMMAD_URL)%'
token: '%env(ZAMMAD_TOKEN)%'Why 3.2: before 3.2.0 the bundle registered the client with ContainerBuilder::set() and failed in every compiled container (see the 3.2.0 changelog). A recipe for older versions would install a bundle that does not work.
Empty token: the recipe adds ZAMMAD_TOKEN= without a value. The container still compiles, because the client is a lazy definition. The first use of the client fails with "API token must not be empty." This matches the bundle's documented behaviour, and the post-install message points the user at it.
After the merge:
- README, Symfony section:
composer requirebecomes the setup. Manual registration remains documented as the fallback for apps without Flex or with contrib recipes disabled (Flex asks for confirmation before applying a contrib recipe unlessextra.symfony.allow-contribis set). SymfonyBundledocblock: same change.- Reply in Symfony + Laravel Bridges #174.
Acceptance criteria
In a fresh symfony/skeleton (6.4, 7.4 and 8.1), a plain composer require zammad/zammad-api-client-php:
- registers the bundle in
config/bundles.php, - creates
config/packages/zammad.yaml, - adds
ZAMMAD_URLandZAMMAD_TOKENto.env, - with a token set, lets
ZammadClientandzammad_clientresolve from the container.
Also:
-
composer removetakes all three changes back out. - An app that already defines its own
ZammadAPIClient\ZammadClientservice (as shown in the custom HTTP client guide) keeps its definition. The bundle's definition must not override it. - Projects without Flex are unaffected.
- The install job from
composer requirefails in a fresh Laravel 13 application #181 covers the Symfony path without manual registration. - The recipe is merged in
symfony/recipes-contrib.
Out of scope
- Separate bundle or provider packages (decided against, see above).
- Symfony bundle configuration beyond
urlandtoken, such asConnectionConfigoptions. That would be its own issue.
Verified
With the recipe served from a local Flex endpoint and the published 3.2.0, against fresh symfony/skeleton 6.4.50, 7.4.23 and 8.1.11: a plain composer require registers the bundle, creates config/packages/zammad.yaml, adds both variables to .env, and zammad_client resolves. An app-level ZammadAPIClient\ZammadClient definition in services.yaml takes precedence over the bundle's. composer remove reverts all three changes. A project without Flex gets neither config/ nor .env.
Update: ship the recipe ourselves, recipes-contrib second
Instead of depending on recipes-contrib alone, the recipe lives in this repository and is published with every release:
-
Source:
src/Bridge/Symfony/recipe/3.2/(same layout asrecipes-contrib, excluded from the Composer dist viaexport-ignore). -
Release artifact: a workflow builds a Flex endpoint (
index.jsonplus one recipe file) from that source and attaches it to the GitHub release. Users add it once, beforecomposer require:composer config --json extra.symfony.endpoint \ '["https://github.com/zammad/zammad-api-client-php/releases/latest/download/index.json", "flex://defaults"]'The endpoint declares
is_contrib: false, so noallow-contribsetting or prompt is needed. -
Version
3.2: the recipe ships with the next patch release. Flex compares only major.minor of the client version, so a3.2.1folder would not apply before 3.3.0 (tested);3.2applies to 3.2.0 and later, where the bundle works. -
CI: the install test from
composer requirefails in a fresh Laravel 13 application #181 applies the recipe through a local endpoint built from the same source, and checks thatcomposer removereverts it. -
recipes-contrib: a PR from the same source can follow, so that the extra endpoint line becomes unnecessary for everyone.
Verified: GitHub's releases/latest/download/… chain (two redirects, host change to release-assets.githubusercontent.com, application/octet-stream) is followed by Composer's HttpDownloader. With that chain reproduced locally, Flex fetched both files through it and applied the recipe to a fresh Symfony 8.1 skeleton.
Activity
Symfony: let the Flex recipe apply from 3.2 on (#182)
Symfony: add a Flex recipe for the bundle (#182)
Build a Flex recipe endpoint for release assets (#182)
CI: attach the Flex recipe endpoint to every release (#182)
Test: apply the Flex recipe in the Symfony install test (#182)
Docs: describe the Flex setup for Symfony (#182)
Symfony: let the Flex recipe apply from 3.2 on (#182)
Symfony: add a Flex recipe for the bundle (#182)
Build a Flex recipe endpoint for release assets (#182)
CI: attach the Flex recipe endpoint to every release (#182)
Test: apply the Flex recipe in the Symfony install test (#182)
Docs: describe the Flex setup for Symfony (#182)
Symfony: let the Flex recipe apply from 3.2 on (#182)
derpixler commentedon Nov 9, 2026
Shipped in v3.2.1 (#189): the release carries
index.jsonandzammad.zammad-api-client-php.3.2.json. Verified against the real assets: freshsymfony/skeleton6.4 and 8.1, only the documentedextra.symfony.endpointline, thencomposer requireinstalls v3.2.1, applies the recipe, andzammad_clientresolves. A PR tosymfony/recipes-contribfrom the same source remains optional.