baks-dev/reference-caps
Russian PHP library for headwear sizing from baks-dev, providing cap size references for Laravel applications. Requires PHP 8.4+ and installs via Composer.
Install and sanity-check
composer require baks-dev/reference-caps
composer show baks-dev/reference-caps # confirm version 7.4.3 and PHP constraint
php -v # must be 8.4+
The README is a one-liner in Russian ("Библиотека размеров головных уборов" = headwear sizing library) with no usage examples. Treat the package source as the documentation and read it before writing integration code.
Where to look first
vendor/baks-dev/reference-caps/composer.json — the require block tells you what you actually pulled in. BaksDev packages are typically part of a wider Symfony/Doctrine ecosystem (baks-dev/core, attributes, Type/Id value objects), so verify whether this is a pure data library or drags in framework coupling.vendor/baks-dev/reference-caps/src/ — find the primary reference class. Look for a Type, Reference, or Enum-style class exposing constants and a cases() / getCases() method; that is the dictionary you will actually consume.*.orm.xml, attributes) or Resources/config/ directory — determines whether the sizes are plain PHP values or persistable entities.First use case (30-minute spike)
Don't design anything yet. Dump the data and look at it:
// tinker / a throwaway route
$ref = new \BaksDev\ReferenceCaps\...\Type(); // fill in after reading src/
dump($ref->cases()); // or ::cases(), getCases(), etc.
Once you can see the shape of the data, your first real ticket is almost always one of two things:
Both are 20-line jobs if you put a thin adapter in front of the package (see below) instead of calling vendor classes from controllers.
Adoption gate. This package has 0 stars, 0 dependents, no issues, no tests, and a future-dated release (2026-08-14). That's fine for what it is — a small static lookup table — but decide up front that it is vendored data, not infrastructure. Budget an hour to read the source and write your own 10-line wrapper. If the wrapper is trivial, the risk is trivial.
1. Wrap it, never call it directly. One class in your app (App\Support\CapSizes or App\Domain\Sizing\CapSizeReference) is the only place that imports the vendor namespace. Everything else — controllers, Blade/Vue components, API resources, validation rules — talks to your wrapper. This is what makes the "abandoned package" failure mode a half-day fix instead of a refactor.
final class CapSizes
{
public static function all(): array // ['56' => '56 см', ...]
public static function has(string $code): bool
public static function label(string $code): ?string
}
2. Form selects and validation rules. Generate the options from CapSizes::all() and validate with Rule::in(array_keys(CapSizes::all())). Never hand-type the size list into a config/ file or a Blade template — that duplication is the #1 source of drift when the package updates.
$request->validate([
'cap_size' => ['required', 'string', Rule::in(array_keys(CapSizes::all()))],
]);
3. Persist the size code, not an object. Store the reference code in your products table as a string (or smallint if purely numeric). Do not attempt to store package objects or IDs unless the package ships a stable identifier — you'd be coupling your schema to undocumented internals. Keep the FK relationship logical, enforced in your app layer.
4. Numeric range support for filters. "Fits 56–58 cm" is a range, not a point, and range queries don't work on enum constants. If your catalogue needs "show me all caps that fit a 57 cm head", denormalize the bounds once:
// migration: products.min_circumference, products.max_circumference
// populate from CapSizes in an observer/import command
$query->where('min_circumference', '<=', $cm)
->where('max_circumference', '>=', $cm);
This is the pattern that unlocks sizing filters, "does this fit me?" widgets, and compatibility checks — the actual product features. The package supplies the data; the range columns supply the queryability.
5. Seed/import command rather than per-request reads. For anything beyond a dropdown, import the reference into a cap_sizes table via an Artisan command. You gain joins, ordering, admin editing, per-locale labels, and the ability to cache it with Cache::rememberForever() without thinking about object serialization.
6. Presentation layer for size charts. Package labels will be Russian and metric. Build a presenter that outputs what your storefront needs:
['code' => '58', 'label' => '58 cm', 'label_ru' => '58 см', 'fits' => '56–60 cm']
Translate/label at the edge, not by mutating the reference data.
7. API responses. Emit a normalized DTO array, not the vendor object. It pins your public contract and prevents a package upgrade from silently changing your JSON shape.
8. Test against the wrapper, not the package. Your feature tests should assert on CapSizes::all() output shape; one small integration test asserts the vendor class loads and returns a non-empty set. That way a package bump fails one test, not fifty.
composer require fails outright. Confirm before adding it to a shared monorepo — a single dependency can block the whole workspace.grep -rn "public function\|case \|const " vendor/baks-dev/reference-caps/src and read the actual source first. Half a day can be lost to calling a CapSize::find() that never existed.2026-08-14) plus 0 stars is a smell. Pin the exact version ("baks-dev/reference-caps": "7.4.3") and commit composer.lock. Don't use ^7.4 if you can't review diffs.composer.json require for baks-dev/core, symfony/*, or doctrine/* before installing — you may be adopting more than a data table. If the transitive weight is high, the pragmatic move is to copy the size data into your own config and skip the dependency entirely (MIT allows it, keep the license notice).trim, strip "см"/"cm", normalize decimal separators).int in one place and string in another; in_array($x, $keys) without strict comparison then fails silently.Type-style class requiring constructor arguments (some BaksDev references take an Id/Reference value object). If new Foo() throws, look for a static from()/cases() factory or a container binding instead.config/ is a morning's work — provided you followed the wrapper pattern. Build accordingly: thin adapter, no schema coupling, one integration test.How can I help you explore Laravel packages today?