PHPackages                             leads/core - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. leads/core

ActiveSymfony-bundle[Utility &amp; Helpers](/categories/utility)

leads/core
==========

Shared core library for Leads

0.0.16(4w ago)017.1k↓63.3%MITPHPPHP &gt;=8.3

Since May 16Pushed 4d ago1 watchersCompare

[ Source](https://github.com/Maxim-intelico/leads-core)[ Packagist](https://packagist.org/packages/leads/core)[ RSS](/packages/leads-core/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (10)Dependencies (13)Versions (18)Used By (0)

leads/core
==========

[](#leadscore)

Shared core bundle for Leads projects built on the Symfony Framework. It provides DBAL-based pagination, API request validation helpers and base controller utilities.

Requirements
------------

[](#requirements)

- PHP &gt;= 8.3
- Symfony 7.2+ or 8.x (the package resolves to Symfony 8.x on PHP &gt;= 8.4)
- Doctrine DBAL ^4.0 (used by the pagination component)

Installation
------------

[](#installation)

```
composer require leads/core
```

Register the bundle in `config/bundles.php` (done automatically if you use Symfony Flex):

```
return [
    // ...
    Leads\Core\LeadsCoreBundle::class => ['all' => true],
];
```

Pagination
----------

[](#pagination)

Page-based pagination over a Doctrine DBAL `QueryBuilder`. The `Leads\Core\Pagination` namespace is excluded from container autowiring — instantiate the classes manually:

```
use Doctrine\DBAL\Connection;
use Leads\Core\Pagination\DBALPagination;
use Leads\Core\Pagination\DTO\ListResponseDTO;
use Leads\Core\Pagination\Pagination;

final readonly class OrderRepository
{
    public function __construct(
        private Connection $connection,
    ) {
    }

    public function findPaginated(int $page, int $perPage): ListResponseDTO
    {
        $qb = $this->connection->createQueryBuilder()
            ->select('id', 'customer_id', 'amount')
            ->from('orders')
            ->orderBy('id', 'DESC');

        return (new Pagination(
            page: $page,
            perPage: $perPage,
            pagination: new DBALPagination(
                connection: $this->connection,
                qb: $qb,
            ),
        ))->paginate();
    }
}
```

`paginate()` returns a `ListResponseDTO`:

- `items` — the rows for the requested page (`fetchAllAssociative()` result)
- `pagination` — a `PaginationDTO` with `count` (items on this page), `total` (total rows), `page`, `perPage` and `pages` (total page count)

The total is computed by wrapping your query in a `COUNT(*)` subquery (with `ORDER BY` stripped), so it stays correct for queries with `GROUP BY` or `DISTINCT`. `Pagination` throws `\InvalidArgumentException` if `page` or `perPage` is less than 1.

To paginate a different data source, implement `Leads\Core\Pagination\PaginationInterface` (`getItems(int $offset, int $limit): array` and `getTotal(): int`) and pass it instead of `DBALPagination`.

### ClickHouse

[](#clickhouse)

`ClickHousePagination` runs the same DBAL `QueryBuilder`-built query against ClickHouse via the `smi2/phpclickhouse` client. The package is an optional dependency — install it in your project first:

```
composer require smi2/phpclickhouse
```

```
use ClickHouseDB\Client;
use Leads\Core\Pagination\ClickHousePagination;
use Leads\Core\Pagination\Pagination;

return (new Pagination(
    page: $page,
    perPage: $perPage,
    pagination: new ClickHousePagination(
        client: $client, // ClickHouseDB\Client
        qb: $qb,
    ),
))->paginate();
```

Constraints:

- The `QueryBuilder` must use **named parameters** (`:name`) — positional `?` placeholders are not substituted by the ClickHouse client.
- The SQL (including `LIMIT`/`OFFSET` syntax and identifier quoting) is rendered by the DBAL platform of the connection the `QueryBuilder` was created from, so use a connection whose platform produces ClickHouse-compatible SQL (MySQL and PostgreSQL platforms are fine).

API validation and base controller
----------------------------------

[](#api-validation-and-base-controller)

`ApiValidator` wraps the Symfony Validator: it validates an object against its constraint attributes and throws `ApiValidationException` if there are violations. The exception exposes the violations as `getErrors()` — a list of `['property' => ..., 'message' => ...]` pairs, also JSON-encoded into the exception message.

Controllers can extend `BaseAction` to get validation plus JSON response helpers:

```
use Leads\Core\Action\BaseAction;
use Symfony\Component\HttpFoundation\JsonResponse;

final class CreateOrderAction extends BaseAction
{
    public function __invoke(CreateOrderRequest $request): JsonResponse
    {
        $this->validate($request); // throws ApiValidationException on violations

        $id = /* ... */;

        return $this->create201Response($id); // {"id": "..."}
    }
}
```

Available response helpers:

- `create200Response(array $data)` — 200 with a JSON body
- `create201Response(string $id)` — 201 with `{"id": ...}`
- `create201ContentResponse(array $response)` — 201 with a custom body
- `create201EmptyResponse()` — 201 with an empty body
- `create204Response()` — 204
- `create400Response(string $message)` — 400 with a message
- `createCustomResponse(array $data, int $status)` — any status

`ApiValidatorInterface` is autowired to `ApiValidator` by the bundle; you can also inject it directly into your own services.

Exceptions
----------

[](#exceptions)

The `Leads\Core\Exception` namespace provides ready-to-use domain exceptions. All of them extend `\RuntimeException` and carry an HTTP-like status code in `getCode()`, so an exception listener can map them to responses directly. Each constructor accepts an optional custom message, code override and `previous` throwable:

- `Leads\Core\Exception\EntityNotFoundException` — `Entity not found.`, code 404; for missing entities in repositories/handlers
- `Leads\Core\Exception\UserNotFoundException` — `User not found.`, code 404
- `Leads\Core\Exception\AccessDeniedException` — `Access Denied.`, code 403

```
use Leads\Core\Exception\EntityNotFoundException;

$order = $repository->find($id)
    ?? throw new EntityNotFoundException(sprintf('Order "%s" not found.', $id));
```

License
-------

[](#license)

MIT

###  Health Score

48

—

FairBetter than 94% of packages

Maintenance97

Actively maintained with recent releases

Popularity26

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~28 days

Recently: every ~104 days

Total

16

Last Release

29d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ccf9086fb8a19a61b2cedeec5f156244f79933e9a6c661cf4474a330f137fc6b?d=identicon)[Maxim-intelico](/maintainers/Maxim-intelico)

---

Top Contributors

[![Maxim-intelico](https://avatars.githubusercontent.com/u/121932636?v=4)](https://github.com/Maxim-intelico "Maxim-intelico (45 commits)")

### Embed Badge

![Health badge](/badges/leads-core/health.svg)

```
[![Health](https://phpackages.com/badges/leads-core/health.svg)](https://phpackages.com/packages/leads-core)
```

###  Alternatives

[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k18.3M430](/packages/easycorp-easyadmin-bundle)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M236](/packages/sulu-sulu)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.8M674](/packages/shopware-core)[contao/core-bundle

Contao Open Source CMS

1301.7M3.1k](/packages/contao-core-bundle)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k6.0M777](/packages/sylius-sylius)[pimcore/pimcore

Content &amp; Product Management Framework (CMS/PIM/E-Commerce)

3.8k3.9M535](/packages/pimcore-pimcore)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
