datinglibre/datinglibre-app-bundle
DatingLibre App Bundle is a Symfony bundle that provides core application functionality for the DatingLibre dating platform, including profiles, matching, messaging, and admin tools, helping developers build and customize a dating site.
Confirm the framework before writing any code. Despite the Laravel framing of this task, the -bundle suffix, DatingLibre lineage, and Symfony conventions mean you should assume this is a Symfony bundle. There is no DatingLibreServiceProvider, no Laravel auto-discovery, and it will not drop into a Laravel app. If you're in a Laravel codebase, treat this as vendored source to port or as a reference implementation — not a dependency.
Minimal steps for a Symfony app:
composer require datinglibre/datinglibre-app-bundle
config/bundles.php:
DatingLibre\AppBundle\DatingLibreAppBundle::class => ['all' => true],
DependencyInjection/Configuration.php first. It's the authoritative map of what you can configure without touching vendor code. Read it before src/.Resources/config/routing.xml or routing.yaml.final, what's abstract, and what's an interface:
src/Entity/ — profiles, photos, preferencessrc/Controller/ — profile, search, messaging, moderationsrc/Form/ — profile editing, preference selectionsrc/Service/ — matching, messaging, moderationResources/views/ — templates you'll overrideFirst use case: extend the bundle's member/profile entity rather than editing vendor code, then override one form type and one template end-to-end. That single path exercises Doctrine inheritance, DI/service overrides, and template overrides — it validates your wiring before you build features on top. Concretely: subclass the profile entity, add one custom field (e.g., displayPronouns), render it in the profile edit form, and confirm it persists.
Entity extension via inheritance. The expected pattern for an "overridable core" bundle is a non-final base entity mapped as @MappedSuperclass or a concrete parent. Your app class extends it, points at the same table, and adds fields. Verify with bin/console doctrine:mapping:info that the inherited mapping resolves — if the bundle ships XML/YAML mappings for the parent, your subclass won't inherit them silently and you'll need @ORM\AttributeOverrides or to re-declare the mapping in PHP attributes.
// src/Entity/Member.php
#[ORM\Entity]
#[ORM\Table(name: 'dl_member')]
class Member extends \DatingLibre\AppBundle\Entity\Member
{
#[ORM\Column(nullable: true)]
private ?string $displayPronouns = null;
}
Service decoration, not replacement. For messaging or matching behavior, decorate rather than swap — you keep the bundle's wiring intact and add your logic at the seam:
# config/services.yaml
App\Service\InstrumentedMatcher:
decorates: datinglibre.matcher
arguments: ['@.inner']
Where you must replace, alias the interface and point it at your class, letting the bundle's container resolve your implementation. This keeps upstream upgrades cheap because you're still using the bundle's tags, event subscriptions, and service graph.
Controller and route overrides. If the bundle lets you override routes, do it in your own config/routes.yaml with the same route name — Symfony's router picks the first match, so your app-level definition wins. Otherwise, import the bundle's routing, then add your own controller extending or wrapping the bundle's and remap individual routes.
Template overrides go in the bundle override path, never in vendor/:
templates/bundles/DatingLibreAppBundle/Profile/edit.html.twig
Copy the original, change the parts you need. This keeps vendor clean and survives composer update.
Form types. Prefer FormTypeExtension over rewriting a form type — extend the profile-edit form by adding your custom field, and the bundle's view layer keeps working:
class ProfileTypeExtension extends AbstractTypeExtension
{
public static function getExtendedTypes(): iterable
{
return [\DatingLibre\AppBundle\Form\ProfileType::class];
}
}
Messaging and moderation integration. Wire your business rules (rate limits, profanity filters, abuse escalation) as event subscribers on the bundle's messaging and reporting events rather than editing the services. This is the extension point that survives upstream changes best — if the bundle dispatches MessageSentEvent, subscribe to it; don't override the message service unless you must.
Schema and migrations. Run the bundle's migrations first, then your own. Keep a strict ordering: bundle migrations in vendor (untouched), your app migrations in migrations/. Never edit an upstream migration — deployment and rebasing both break.
Testing the seams. Add a functional test that boots the kernel and confirms your profile extension persists, and one that confirms a template override renders. These are cheap and catch the highest-frequency regressions after an upstream bump (mapping breaks, template precedence breaks, service decoration ordering breaks).
composer.json, vendor the lockfile, and name an owner for the fork before you ship anything with real user data.services.yaml, run bin/console cache:clear. In dev, container changes occasionally need a full cold boot to take effect.bin/console debug:container datinglibre # what services exist and how they're aliased
bin/console debug:router # what routes the bundle registers
bin/console doctrine:mapping:info # whether your entity subclass is resolved
bin/console debug:twig DatingLibreAppBundle # confirms template override paths
MappedSuperclass parents resolve cleanly; a concrete parent entity mapping the same table needs your subclass to be the mapping root (or use #[ORM\AttributeOverrides]). If a query in the bundle's repository suddenly returns the parent instead of your subclass, that's the symptom — the parent is the mapping root.datinglibre.matcher apply in decoration_priority order. If a rate limit or a logging decorator isn't firing, verify priority — a missing decorator is a silent failure, not an error.DatingLibreAppBundle) in templates/bundles/ — Symfony is case-sensitive here.How can I help you explore Laravel packages today?