endroid/tile-bundle
EndroidTileBundle is a Symfony bundle that adds tile handling to your application, offering a simple way to define, render, and serve tiles. Consult the package documentation for setup, configuration, and usage details.
endroid/tile-bundle is an archived Symfony bundle with a README that is effectively empty. There is no documented API, no usage example, zero stars and zero dependents. Treat the README as non-existent and the source as the only specification. This is not a package you introduce into a new project; it is something you inherit in a legacy codebase and need to keep running, or extract yourself from.
What it almost certainly is. Following Endroid's naming convention, this is a thin Symfony DI wrapper around a standalone endroid/tile library: a bundle class, a DependencyInjection/ extension with a config tree, and a services.yaml that registers the library's main class as a service. Your day-to-day work will therefore be 80% learning the underlying library and 20% Symfony wiring.
Minimal steps to get oriented:
composer require endroid/tile-bundle
composer show endroid/tile-bundle # version + require constraints
ls vendor/endroid/tile-bundle/src # the real documentation
cat vendor/endroid/tile-bundle/composer.json
Check the bundle's PHP and Symfony constraints in composer.json first. If it caps at symfony/framework-bundle: ^4.4 or similar, stop — it will not boot on a modern kernel, and that is your real blocker, not the missing docs.
Register the bundle (name it from the class you find in src/; the convention would be Endroid\TileBundle\EndroidTileBundle):
// config/bundles.php
return [
// ...
Endroid\TileBundle\EndroidTileBundle::class => ['all' => true],
];
There is no Flex recipe for this, so nothing will be auto-registered in config/packages/.
php bin/console debug:container --show-private | grep -i tile
php bin/console config:dump-reference endroid_tile # confirm the root key from Configuration.php
php bin/console about
debug:container is your README here. Read DependencyInjection/Configuration.php to learn the exact config root and available keys — that file is the contract.
// src/Command/TileProbeCommand.php
$tile = $this->container->get('endroid.tile'); // confirm ID via debug:container
$result = $tile->/* method from src/ */;
dump($result); // learn the return type before designing around it
Facade everything. The single most important pattern with an archived dependency: never let the bundle's classes leak across your codebase. Write one adapter of your own that wraps the library, and inject that everywhere.
namespace App\Tile;
use Endroid\Tile\Tile; // the underlying library class
final class TileGenerator
{
public function __construct(private Tile $tile) {}
public function generate(/* your domain args */): string
{
// all bundle/library coupling lives here and nowhere else
}
}
When the day comes to replace the bundle (it will), you rewrite this class and nothing else. This is also how you write tests today: mock TileGenerator, not the untyped vendor service.
Configuration-driven setup. Put settings in config/packages/endroid_tile.yaml (verify the root key with config:dump-reference) and keep it environment-aware. Endroid bundles typically take scalars and paths, so:
# config/packages/endroid_tile.yaml
endroid_tile:
# keys taken verbatim from DependencyInjection/Configuration.php
Because the config tree is undocumented, prefer constructor arguments from YAML over hardcoding values, so a cache/tmp path can differ between dev and prod without code changes.
Generation vs. serving. Decide early whether the bundle produces files or streams responses. In practice with this kind of package you will usually:
%kernel.cache_dir%/tiles or a public dir),#[Route('/tile/{key}', name: 'tile_show')]
public function tile(string $key, TileGenerator $generator): Response
{
$path = $generator->pathFor($key); // deterministic, cacheable
return $this->file($path);
}
Batch work belongs in a command, not a controller. Whatever the bundle does, run it from a console command with progress output so you can warm caches during deploy and debug in isolation:
$output->writeln('Generating tiles...');
// loop, call generator, $io->progressAdvance()
Decoration over forking. If you need to change one behaviour, use Symfony's service decoration rather than editing vendor code:
App\Tile\CachingTileGenerator:
decorates: endroid.tile # confirm the decorated ID first
This survives composer update and documents your intent.
composer.json constraints before planning anything; if the bundle pins an old symfony/http-kernel, your adoption decision is already made.autowire: true. Symptoms: "Cannot autowire argument $tile... none of the candidates exist". Fix by injecting the service ID explicitly in services.yaml:App\Tile\TileGenerator:
arguments: ['@endroid.tile']
endroid.tile, Endroid\TileBundle\Service\Tile, endroid_tile.tile are all plausible. debug:container | grep -i tile is the only source of truth.config:dump-reference returns nothing? That means the extension has no configuration tree (or a different alias). Read DependencyInjection/*Extension.php — the getAlias() return value is the key.tests/ and a phpunit.xml. If there are none, your probe command is your test suite; keep it in the repo as a smoke test.vendor/endroid/tile*/src. Read the actual file at the throw site — the exception messages in an undocumented package are usually the best documentation available.php bin/console cache:clear, and stale var/cache is the most common reason "the bundle isn't there".decorates: for behaviour changes. Don't look for hooks that don't exist.src/ of your app is often cheaper than carrying a dead dependency. If you do, keep the LICENSE file and attribution.How can I help you explore Laravel packages today?