acutex/useful-bundle
Symfony bundle providing handy extras for everyday projects: Ajax autocomplete, dependent entity and date-range form types, plus Doctrine DQL functions (IF, IFNULL, ROUND, DATE_DIFF). Can be used with SonataAdmin as filter types.
Installation
Add the bundle to your composer.json (preferred over deps file for modern Laravel/Symfony projects):
composer require acutex/useful-bundle
Register the bundle in config/bundles.php (Symfony) or manually in AppServiceProvider (Laravel via Symfony bridge):
return [
// ...
Shtumi\UsefulBundle\ShtumiUsefulBundle::class => ['all' => true],
];
First Use Case: Ajax Autocomplete
Use the AjaxAutocompleteType for search-as-you-type fields (e.g., user lookup):
use Shtumi\UsefulBundle\Form\Type\AjaxAutocompleteType;
$builder->add('user', AjaxAutocompleteType::class, [
'route' => 'app_user_autocomplete', // Define this route in `routes.yaml`
'choice_label' => 'fullName', // Property to display
'min_length' => 2, // Min chars to trigger search
'placeholder' => 'Search users...',
]);
Route Example (config/routes.yaml):
app_user_autocomplete:
path: /api/users/autocomplete
controller: App\Controller\UserController::autocompleteAction
methods: GET
First Use Case: DQL Functions
Use custom DQL functions in Doctrine queries (e.g., IF for conditional logic):
$qb = $entityManager->createQueryBuilder();
$qb->select('u')
->from('App\Entity\User', 'u')
->where('IF(u.isActive = 1, 1, 0) = 1'); // Equivalent to CASE WHEN
Ajax Autocomplete
public function autocompleteAction(Request $request): JsonResponse
{
$query = $request->query->get('query');
$users = $this->userRepository->findByName($query, 10); // Custom repo method
return $this->json(array_map(fn($u) => ['id' => $u->id, 'text' => $u->fullName], $users));
}
- **Pagination**: Use `max_results` option to limit results (e.g., `max_results: 10`).
Dependent Filtered Entity
$builder->add('country', EntityType::class, ['class' => Country::class])
->add('region', DependentFilteredEntityType::class, [
'entity_class' => Region::class,
'property' => 'country', // Foreign key
'dependent_property' => 'country', // Field to filter by
]);
getQueryBuilder in your entity repository to filter by parent fields.Date Range
$builder->add('dateRange', DateRangeType::class, [
'widget' => 'single_text', // or 'split'
'start_date_format' => 'yyyy-MM-dd',
'end_date_format' => 'yyyy-MM-dd',
]);
start <= end.symfony/ux-autocomplete) for enhanced frontend behavior.AjaxAutocompleteType as a filter in SonataAdmin:
$filterBuilder->add('user', 'sonata_type_ajax_autocomplete', [
'bundle' => 'AppBundle',
'model' => 'User',
'property' => 'username',
'btn_add' => false,
]);
stof/doctrine-extensions-bundle for advanced DQL functions.DQL Functions in Laravel
$query = DB::select("SELECT IF(is_active = 1, 'Yes', 'No') as status FROM users");
DB::raw():
$users = User::whereRaw('IF(is_active = 1, 1, 0) = 1')->get();
Ajax Autocomplete CORS
NelmioCorsBundle helps):
# config/packages/nelmio_cors.yaml
nelmio_cors:
defaults:
allow_origin: ["*"]
allow_methods: ["GET", "POST"]
allow_headers: ["Content-Type"]
expose_headers: ["Content-Type"]
Dependent Filtered Entity Performance
// In your repository
public function findByCountry(QueryBuilder $qb, $countryId)
{
return $qb->andWhere('r.country = :country')
->setParameter('country', $countryId)
->leftJoin('r.country', 'c')
->addSelect('c');
}
curl or Postman).choice_label property exists in your entity.dql/function mapping (check config/packages/doctrine.yaml):
doctrine:
dql:
string_functions:
IF: Shtumi\UsefulBundle\DQL\IFFunction
IFNULL: Shtumi\UsefulBundle\DQL\IFNULLFunction
Custom DQL Functions
config/packages/shtumi_useful.yaml:
shtumi_useful:
dql_functions:
CONCAT_WS: App\DQL\ConcatWsFunction
Doctrine\ORM\Query\AST\Functions\FunctionNode for new functions.Form Type Overrides
Resources/config/services.yaml:
services:
App\Form\Type\CustomAutocompleteType:
parent: Shtumi\UsefulBundle\Form\Type\AjaxAutocompleteType
tags: [form.type]
Date Range Localization
configureOptions:
$builder->add('dateRange', DateRangeType::class, [
'date_range_options' => [
'start_date_format' => 'd/m/Y', // Override for FR locale
],
]);
Shtumi\UsefulBundle, but Laravel’s autoloader may need adjustment if using acutex/useful-bundle directly. Ensure composer dump-autoload is run post-install.composer.json for constraints.How can I help you explore Laravel packages today?