Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Face Detect Bundle Laravel Package

tourze/face-detect-bundle

A Symfony bundle that adds face detection capabilities to your application through a configurable service layer. Integrates detection providers with dependency injection and Twig helpers, keeping face-detection logic decoupled from your business code.

View on GitHub
Deep Wiki
Context7

Getting Started

tourze/face-detect-bundle 0.0.1 is the initial tagged release — there is no prior assessment to diff against, so treat everything below as a first-look. The changelog for 0.0.1 contains only a compare link (no feature list, no BC notes), which is itself a signal: this is an early, likely alpha-quality package.

Where to look first, in order:

  1. composer.json — PHP version constraint, tourze/* sibling dependencies, and whether it pulls in a native extension (GD/Imagick) or an HTTP-based detection backend. This determines your deployment story more than anything else.
  2. src/DependencyInjection/*Extension.php + Resources/config/services.yaml (or config/services.php) — the bundle's public surface is whatever services it registers. That list is the API in a Symfony bundle.
  3. The primary detector service class — its detect()/analyze() signature, return type (array of boxes? an object? a result DTO?), and exception behaviour.
  4. README / docs/ if present — often absent at 0.0.x.

Minimal install:

composer require tourze/face-detect-bundle:0.0.1

Pin the exact version (0.0.1, not ^0.0.1) — at this maturity, 0.0.2 can rename anything.

Reality check for a Laravel app: this is a Symfony bundle, not a Laravel package. It will not be auto-discovered, and FaceDetectBundle::class registration in config/bundles.php has no Laravel equivalent. Your first real use case should be narrow: a single-image upload endpoint that returns a face count and bounding boxes, exercised through a thin adapter you own. If you need this in production imminently, evaluate whether the underlying detection engine (whatever the bundle wraps) is usable directly — you may end up depending on that instead and dropping the bundle layer.

Implementation Patterns

Adapter, not direct coupling. The bundle's services are wired through Symfony's container. In Laravel, bind the detector behind your own contract so the rest of the app never imports a Tourze\ class:

// app/Contracts/FaceDetector.php
interface FaceDetector { public function detect(string $absolutePath): array; }

// app/Services/TourzeFaceDetector.php
final class TourzeFaceDetector implements FaceDetector
{
    public function __construct(private object $inner) {}

    public function detect(string $absolutePath): array
    {
        return $this->inner->detect($absolutePath) ?? [];
    }
}

Register it in a FaceDetectionServiceProvider, resolving $inner manually (construct it with its own dependencies, or run the bundle's container in a scoped Symfony ContainerBuilder). This adapter is your escape hatch when 0.0.2 breaks.

Controller → Job → Result row. Keep the request cycle thin:

  • FormRequest validates image (mimes:jpg,jpeg,png, max:8192).
  • Controller stores to a private disk, dispatches DetectFaces job, returns 202 with a job/record id.
  • Job loads via Storage::disk('images')->path($key), runs detection, persists normalized boxes into a face_detections table (boxes as JSON: [{x,y,w,h,score}], plus count, engine_version, duration_ms).
  • Resize/convert before detection (see Gotchas) — do it in the job, not the controller.

Cache by content hash. Detection is CPU-bound; sha1_file() on the resized derivative makes a good cache key. Store the box array, not the image. This single pattern removes most of the cost in read-heavy flows (avatars, repeated uploads, retries).

Deterministic tests. Never call the real detector in feature tests. Bind a fake FaceDetector returning a fixed box array, and keep 2–3 small fixture images (one face, many faces, zero faces) for an integration test that runs only in CI with the extension available.

Decorator for observability. Because you own the contract, wrap the adapter with a logging/timing decorator (Log::info('face_detect', ['ms' => ..., 'count' => ...])) rather than editing vendor code — that's also your extension point if the bundle later adds events.

Config surface. Any bundle configuration (thresholds, model path, backend selection) lives in Symfony bundle config and will not be read by Laravel's config/*.php. Mirror the values you care about into your own config file and pass them explicitly to the adapter; do not rely on the bundle's defaults being loaded.

Gotchas and Tips

  • It's a Symfony bundle in a Laravel app. No service provider, no auto-discovery, no config/bundles.php. Any tutorial or README snippet you find will assume Symfony. Budget for the adapter work up front.
  • 0.0.1 means no compatibility promise. No changelog content, no upgrade guide. Pin exactly, and read src/ before upgrading — assume breaking changes in every patch.
  • Config caching will bite you. php artisan config:cache and optimize do not know about the bundle's configuration; anything you smuggle in via a raw Symfony container will be rebuilt per request or silently stale. Keep configuration in Laravel config and inject it.
  • Native dependencies. Face detection almost always means GD or Imagick, and often a model file. Check extension_loaded('gd') in a health/readiness endpoint, verify the model path resolves from the queue worker's working directory (relative paths break under artisan queue:work), and confirm the file ships with the package rather than being downloaded at runtime.
  • Normalize before you detect. Full-resolution phone photos (12MP+, EXIF-rotated) are the single biggest source of timeouts and "no faces found". Downscale to a fixed long edge, apply exif_read_data orientation, convert to RGB, strip alpha. Do this in your own code — don't assume the bundle handles it.
  • Empty results are normal, not errors. A zero-length array is a valid outcome. Decide explicitly whether "no faces" is a 422, a stored row with count: 0, or a soft pass — and make sure the adapter doesn't coerce null into a false negative.
  • Path handling. Non-ASCII and space-containing filenames routinely break C/native bindings. Use a hashed storage key for the file on disk and keep the original name only in the database.
  • Timeouts and memory. Detection is CPU-bound and unbounded in input size. Set a per-job $timeout, run on a dedicated queue, and cap memory_limit so a bad image fails one job rather than the worker.
  • Debugging blind. With no docs, add temporary logging around the adapter (input dimensions, elapsed ms, raw return) before writing any business logic on top — you need to know the actual shape of the result DTO/array, since 0.0.1 gives you nothing to read.
  • Extension points available to you: decorate your own contract (preferred), subclass the detector service if it isn't final, and override bundle parameters via a manually built ContainerBuilder only as a last resort. Avoid patching vendor files — you'll need that diff to survive the next tag.
  • Supply-chain sanity. tourze/* publishes many small, fast-moving packages. Run composer audit and check the transitive tree; a 0.0.1 bundle can pull a surprisingly deep dependency set for what is conceptually a few calls into an image API.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin