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

Core Bundle Laravel Package

leapt/core-bundle

LeaptCoreBundle is a Symfony bundle that collects reusable utilities for everyday applications, including pagination, RSS/Atom feed and sitemap generation, Twig extensions, and Doctrine/Form helpers. It reduces boilerplate and offers consistent, configurable building blocks for content-driven Symfon...

View on GitHub
Deep Wiki
Context7

Getting Started

leapt/core-bundle is a Symfony "core" bundle: a grab-bag of small, reusable pieces (base controller helpers, Twig extensions, route/annotation conveniences, form types and validators) rather than a framework of its own. The right mental model is "a library of shortcuts I opt into per-feature", not "an admin generator". That matters because the fastest way to evaluate it is to inventory what's actually in it, not to read docs that don't exist.

Minimal setup

composer require leapt/core-bundle

Flex usually registers it; if not, add it manually:

// config/bundles.php
return [
    // ...
    Leapt\CoreBundle\LeaptCoreBundle::class => ['all' => true],
];

Then create/verify the config file and, crucially, dump the actual config tree:

php bin/console debug:config leapt_core

That command is your documentation. It shows every node the bundle's Configuration class exposes, which is a reliable map of its feature surface for the version you installed.

Where to look first

  1. vendor/leapt/core-bundle/src/ — the bundle is small enough to read in one sitting. Start with the DependencyInjection/Configuration.php and Resources/config/*.yaml files; those two tell you what exists and what service IDs/tags it registers.
  2. php bin/console debug:container 'Leapt\CoreBundle\' to see which services are public/autowirable in your app.
  3. php bin/console debug:twig --filter=leapt (or scan debug:twig output) to see which Twig functions/filters it adds — Twig helpers are usually the highest-value, lowest-risk thing to adopt first.
  4. php bin/console debug:form (or grep src/Form/Type) for the form types, since those are where the newest features land — v6.4.0 added a Google reCAPTCHA v2 form type + validator pair.

First use case

Pick the smallest isolated feature and wire it into one screen, rather than adopting the base controller across the whole app. Two good candidates:

  • Twig extension: add the bundle's formatting/truncation helper to a single template. Zero architectural commitment.
  • reCAPTCHA v2 on one form (new in v6.4.0): if you have a contact/registration form that's getting spam, this is the most self-contained feature the bundle has — a form type plus a constraint, scoped to one DTO. See the pattern below.

Either path proves autoloading, service registration and version compatibility without committing your architecture. If the bundle ships a base Controller with convenience methods, adopt it in one new controller first — retrofitting existing controllers is a mechanical but noisy diff you don't want to do twice.

Implementation Patterns

Extend, don't replace, the base controller

If you adopt the bundle's controller base class, keep your own project-level AbstractController in between:

namespace App\Controller;

use Leapt\CoreBundle\Controller\AbstractController as LeaptController;

abstract class AbstractController extends LeaptController
{
    // project-wide helpers, current-user shortcut, etc.
}

Every app controller extends App\Controller\AbstractController. This gives you one place to swap out the parent if the bundle goes stale, and it avoids scattering use Leapt\CoreBundle\... across hundreds of files.

Treat Twig extensions as the default integration point

Twig helpers are stateless and cheap to trial. Check debug:twig for the exact filter/function names in your installed version, then use them directly; if you need to change behaviour, register your own extension with the same name and let it win, or decorate the bundle's extension service:

# config/services.yaml
services:
    App\Twig\LeaptExtensionDecorator:
        decorates: leapt_core.twig.some_extension
        arguments: ['@.inner']

Decoration beats forking — the bundle is small and unmaintained enough that you do not want a fork to babysit.

Config-driven features over code changes

Anything the bundle gates behind leapt_core.* config should be driven from YAML with env vars, so behaviour differs per environment without code edits:

# config/packages/leapt_core.yaml
leapt_core:
    # keys come straight from `debug:config leapt_core`
    recaptcha:
        # exact node names per `debug:config leapt_core`
        site_key: '%env(LEAPT_RECAPTCHA_SITE_KEY)%'
        secret_key: '%env(LEAPT_RECAPTCHA_SECRET_KEY)%'

Config is validated at container compile time, so a typo surfaces on cache warmup — run php bin/console cache:clear after editing rather than discovering it at runtime.

reCAPTCHA v2: use the form type and the constraint together (v6.4.0+)

This is the pattern to copy for any bundle feature that ships a paired form type + validator. Keep the widget out of your templates and the verification out of your controller:

// App\Form\ContactType.php
use Leapt\CoreBundle\Form\Type\ReCaptchaType; // verify FQCN via src/Form/Type

$builder->add('recaptcha', ReCaptchaType::class);
// App\Dto\ContactDto.php
use Leapt\CoreBundle\Validator\Constraints\ReCaptcha; // verify FQCN via src/Validator

#[ReCaptcha]
private ?string $recaptcha = null;

Then $form->isValid() does the work — the constraint calls Google's siteverify endpoint server-side. Do not call the underlying reCAPTCHA service manually or post the token to your own endpoint: you'll bypass the constraint and lose the config indirection.

Operational rules for reCAPTCHA v2 specifically:

  • v2 checkbox only. Not v3 (score-based, invisible), not Enterprise, not the Android/iOS SDKs. If your security posture needs scoring, this feature does not give it to you.
  • Tokens are single-use and expire in ~2 minutes. Validate exactly once per request in the form; if you find yourself wanting to re-verify (e.g. in both a listener and a controller), you're double-spending the token and will get timeout-or-duplicate.
  • Keys per environment. Use Google's test keys (6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI / 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe) in dev/CI, real keys in prod, and fail loudly if LEAPT_RECAPTCHA_SITE_KEY is unset.
  • Check the version you're on. composer show leapt/core-bundle must be >=6.4.0; composer why-not leapt/core-bundle 6.4.0 tells you what's holding it back.

Template overrides via the standard bundle path

Anything the bundle renders can be overridden without touching vendor:

templates/bundles/LeaptCoreBundle/<path/from/vendor/Resources/views>.html.twig

Copy the vendor template in, then edit. This is the safe way to restyle bundle-provided markup — including the reCAPTCHA widget wrapper if its markup doesn't match your design system.

Integration with sibling Leapt bundles

The leapt/* family (doctrine, feed, sitemap) assumes this core bundle is present for shared utilities. If you adopt more than one, pin the whole family to compatible versions in one composer require invocation so the shared base classes line up.

Gotchas and Tips

Annotations vs. attributes is the big one. Older versions of bundles like this ship route/ORM annotation classes built on doctrine/annotations, which was deprecated in Symfony 6.4 and removed as a hard dependency in Symfony 7. Before adopting, check composer.json constraints in vendor/leapt/core-bundle/composer.json against your symfony/framework-bundle version. If it still requires doctrine/annotations, plan to either stay on an older Symfony minor or import only the non-annotation parts. Never import both Symfony\Component\Routing\Annotation\Route and a Leapt route class in the same file without aliasing — silent routing weirdness follows.

The reCAPTCHA feature adds a transitive dependency. google/recaptcha is a small library that does its own outbound HTTP call — it is not PSR-18 and does not respect Symfony's http_client config or your proxy settings. Consequences: it ignores your configured HTTP client timeouts, it will fail (not throw usefully) in an air-gapped CI box, and you cannot swap in a MockHttpClient. For functional tests, either disable the constraint via config in config/packages/test/leapt_core.yaml or mock the bundle's validator service. Also re-check vendor/composer/installed.json after upgrade if your composer audit policy is strict.

Don't assume "core" means "framework". There's no scaffolding command, no CRUD generator, no admin. Budget an hour to read src/ before writing any integration code; you'll likely find you only want two or three classes and can vendor them.

Bus factor. ~26 stars and near-zero dependents means no community to answer questions and no guarantee of forward compatibility. Recent releases are mostly Dependabot bumps plus one feature per release — that's fine, but it means the maintainer's bandwidth is the roadmap. Pin an exact version ("leapt/core-bundle": "6.4.*"), and prefer decorating/overriding over patching so a future swap is a config change. If you end up using fewer than ~100 lines of it, consider copying those lines into App\ with attribution — the license is MIT, so that's legal and removes an upgrade liability entirely. Copying the reCAPTCHA form type/constraint pair is genuinely viable; it's thin glue over google/recaptcha.

Service IDs are explicit, not autowired guesses. Bundle-internal services are often defined in YAML with string IDs. Use debug:container 'Leapt\CoreBundle\' --show-private to find the real ID before injecting (or before writing a decorates: target); guessing the FQCN will fail at compile time.

debug:config before debug:container. Config node names rarely match class names — the new reCAPTCHA node names in particular are not guessable. Dump the tree first, then trace which service consumes each node in Resources/config/.

Translations live in the bundle's own domain. If you see untranslated strings (the reCAPTCHA widget wrapper/labels are a likely candidate), check vendor/leapt/core-bundle/Resources/translations/ and override the domain in translations/ at project level rather than editing vendor files.

Extension points, in order of preference:

  1. Config (no code).
  2. Template override under templates/bundles/LeaptCoreBundle/.
  3. Service decoration (decorates:).
  4. Subclassing its base classes from your own App\ intermediate class.
  5. Fork — last resort, and only if you're prepared to maintain it.

Debugging a "class not found" on cache warmup almost always means a version mismatch between the bundle's expected Symfony API and yours, not a missing autoload entry. With v6.4.0 specifically, a missing google/recaptcha class after a partial composer update produces this exact symptom. Check composer why-not leapt/core-bundle and read the bundle's composer.json require block before spending time on your own config.

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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core