PHPackages                             xterr/php-cpvcodes - 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. [Localization &amp; i18n](/categories/localization)
4. /
5. xterr/php-cpvcodes

ActiveLibrary[Localization &amp; i18n](/categories/localization)

xterr/php-cpvcodes
==================

CPV Codes with framework-agnostic translation support

2.0.0(6mo ago)082MITPHPPHP &gt;=7.1 || ^8.0CI passing

Since Jun 12Pushed 6mo ago1 watchersCompare

[ Source](https://github.com/xterr/php-cpvcodes)[ Packagist](https://packagist.org/packages/xterr/php-cpvcodes)[ RSS](/packages/xterr-php-cpvcodes/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (5)Dependencies (6)Versions (6)Used By (0)

PHP CPV Codes
=============

[](#php-cpv-codes)

[![PHP Version](https://camo.githubusercontent.com/a36ed93e60420b5782989c6c5834d9b2085aab7c1a99bc36751792706a2f0b83/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344372e312d3838393242462e737667)](https://php.net/)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![Latest Version](https://camo.githubusercontent.com/d15a1220217a59c57809f0d91b4026a491bdda5acb1986640751215acd5f1603/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f78746572722f7068702d637076636f6465732e737667)](https://packagist.org/packages/xterr/php-cpvcodes)

A framework-agnostic PHP library for working with CPV (Common Procurement Vocabulary) codes, including built-in translation support for 23 EU languages.

Overview
--------

[](#overview)

CPV codes are a standardized classification system for public procurement in the European Union. This library provides:

- Complete CPV code database (all divisions, groups, classes, and categories)
- Support for CPV code versions 1 and 2
- Framework-agnostic translation system with 23 language support
- Adapters for Symfony, Laravel, and native PHP
- Zero runtime dependencies for the core library

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

[](#installation)

```
composer require xterr/php-cpvcodes
```

Quick Start
-----------

[](#quick-start)

### Basic Usage (No Translation)

[](#basic-usage-no-translation)

```
use Xterr\CpvCodes\CpvCodesFactory;
use Xterr\CpvCodes\CpvCode;

$factory = new CpvCodesFactory();
$codes = $factory->getCodes();

// Find a specific CPV code
$cpvCode = $codes->getByCodeAndVersion('31532700-1', CpvCode::VERSION_2);

echo $cpvCode->getCode();        // "31532700-1"
echo $cpvCode->getName();        // "Lamp covers" (English)
echo $cpvCode->getLocalName();   // "Lamp covers" (falls back to English)
echo $cpvCode->getDivision();    // "31"
echo $cpvCode->getType();        // CpvCode::TYPE_SUPPLY
```

### With Translation Support

[](#with-translation-support)

```
use Xterr\CpvCodes\CpvCodesFactory;
use Xterr\CpvCodes\Translation\Adapter\ArrayTranslator;

// Use the built-in ArrayTranslator for zero-dependency translations
$translator = new ArrayTranslator(null, 'de');
$factory = new CpvCodesFactory(null, $translator);

$cpvCode = $factory->getCodes()->getByCodeAndVersion('31532700-1');

echo $cpvCode->getName();        // "Lamp covers" (always English)
echo $cpvCode->getLocalName();   // "Lampenabdeckungen" (German translation)
```

Translation Adapters
--------------------

[](#translation-adapters)

The library provides a framework-agnostic `TranslatorInterface` with multiple adapter implementations.

### ArrayTranslator (Native PHP - Zero Dependencies)

[](#arraytranslator-native-php---zero-dependencies)

Best for standalone PHP applications or when you don't want any framework dependencies.

```
use Xterr\CpvCodes\CpvCodesFactory;
use Xterr\CpvCodes\Translation\Adapter\ArrayTranslator;

// Simple usage with locale
$translator = new ArrayTranslator(null, 'fr');
$factory = new CpvCodesFactory(null, $translator);

// With fallback locale
$translator = new ArrayTranslator(null, 'fr', 'en');

// Change locale at runtime
$translator->setLocale('de');

// Get available locales
$locales = $translator->getAvailableLocales();
// ['bg', 'cs', 'da', 'de', 'el', 'es', 'et', 'fi', 'fr', 'ga', 'hr', 'hu', 'it', 'lt', 'lv', 'mt', 'nl', 'pl', 'pt', 'ro', 'sk', 'sl', 'sv']
```

### SymfonyTranslatorAdapter

[](#symfonytranslatoradapter)

For Symfony applications. Requires `symfony/translation-contracts`.

```
composer require symfony/translation-contracts
```

```
use Xterr\CpvCodes\CpvCodesFactory;
use Xterr\CpvCodes\Translation\Adapter\SymfonyTranslatorAdapter;
use Symfony\Contracts\Translation\TranslatorInterface;

// In a Symfony controller or service
public function __construct(
    TranslatorInterface $symfonyTranslator
) {
    $adapter = new SymfonyTranslatorAdapter($symfonyTranslator);
    $this->cpvCodesFactory = new CpvCodesFactory(null, $adapter);
}

// Usage
$codes = $this->cpvCodesFactory->getCodes();
$cpvCode = $codes->getByCodeAndVersion('31532700-1');

// Uses the locale from Symfony's translator (auto-detected from request)
echo $cpvCode->getLocalName();
```

#### Symfony Configuration

[](#symfony-configuration)

Copy or generate translation files to your Symfony translations directory:

```
# Generate YAML files for Symfony
composer translations:yaml

# Copy to your Symfony project
cp Resources/translations/cpvCodes.*.yaml /path/to/symfony/translations/
```

Or configure as a translation resource in `config/packages/translation.yaml`:

```
framework:
  translator:
    paths:
      - '%kernel.project_dir%/vendor/xterr/php-cpvcodes/Resources/translations'
```

### LaravelTranslatorAdapter

[](#laraveltranslatoradapter)

For Laravel applications. Requires `illuminate/contracts`.

```
composer require illuminate/contracts
```

```
use Xterr\CpvCodes\CpvCodesFactory;
use Xterr\CpvCodes\Translation\Adapter\LaravelTranslatorAdapter;
use Illuminate\Contracts\Translation\Translator;

// In a Laravel service provider
public function register()
{
    $this->app->singleton(CpvCodesFactory::class, function ($app) {
        $adapter = new LaravelTranslatorAdapter($app->make(Translator::class));
        return new CpvCodesFactory(null, $adapter);
    });
}

// Usage in controller
public function show(CpvCodesFactory $factory, string $code)
{
    $cpvCode = $factory->getCodes()->getByCodeAndVersion($code);

    // Uses Laravel's current locale
    return response()->json([
        'code' => $cpvCode->getCode(),
        'name' => $cpvCode->getName(),
        'localName' => $cpvCode->getLocalName(),
    ]);
}
```

#### Laravel Configuration

[](#laravel-configuration)

Generate and publish Laravel translation files:

```
# Generate Laravel PHP files
composer translations:laravel

# Copy to your Laravel project
cp -r Resources/translations/laravel/cpvcodes /path/to/laravel/lang/vendor/
```

### NullTranslator (Default)

[](#nulltranslator-default)

Returns the original English text. Used internally as the default when no translator is provided.

```
use Xterr\CpvCodes\Translation\Adapter\NullTranslator;

$translator = new NullTranslator();
echo $translator->translate('Lamp covers'); // "Lamp covers"
```

### Custom Translator

[](#custom-translator)

Implement the `TranslatorInterface` for custom translation sources:

```
use Xterr\CpvCodes\Translation\TranslatorInterface;

class DatabaseTranslator implements TranslatorInterface
{
    public function translate(string $id, ?string $locale = null, string $domain = 'cpvCodes'): string
    {
        // Your custom translation logic
        return $this->repository->findTranslation($id, $locale) ?? $id;
    }
}
```

Supported Languages
-------------------

[](#supported-languages)

The library includes translations for 23 EU languages:

CodeLanguageCodeLanguagebgBulgarianitItaliancsCzechltLithuaniandaDanishlvLatviandeGermanmtMalteseelGreeknlDutchesSpanishplPolishetEstonianptPortuguesefiFinnishroRomanianfrFrenchskSlovakgaIrishslSlovenianhrCroatiansvSwedishhuHungarianCpvCode Properties
------------------

[](#cpvcode-properties)

MethodReturn TypeDescription`getCode()``string`Full CPV code (e.g., "31532700-1")`getName()``string`English name`getLocalName()``string`Translated name (falls back to English)`getType()``int`Type constant (SUPPLY, WORKS, SERVICES)`getVersion()``int`CPV version (1 or 2)`getNumericCode()``int`Numeric code without check digit`getParentCode()``?string`Parent CPV code`getDivision()``string`First 2 digits`getGroup()``string`First 3 digits`getClass()``string`First 4 digits`getCategory()``string`First 5 digits`getShortCode()``string`Code without trailing zerosCPV Code Types
--------------

[](#cpv-code-types)

```
CpvCode::TYPE_SUPPLY   // 1 - Goods and supplies
CpvCode::TYPE_WORKS    // 2 - Construction works
CpvCode::TYPE_SERVICES // 3 - Services
```

CPV Versions
------------

[](#cpv-versions)

```
CpvCode::VERSION_1 // 1 - Original CPV codes
CpvCode::VERSION_2 // 2 - Updated CPV codes (2008)
```

Iterating Over Codes
--------------------

[](#iterating-over-codes)

```
$factory = new CpvCodesFactory();
$codes = $factory->getCodes();

// Iterate all codes
foreach ($codes as $cpvCode) {
    echo $cpvCode->getCode() . ': ' . $cpvCode->getLocalName() . "\n";
}

// Count total codes
echo count($codes); // ~9,454 codes

// Convert to array
$array = $codes->toArray();
```

Building Translation Files
--------------------------

[](#building-translation-files)

The library includes a console command to build translation files in different formats.

```
# Build all formats
composer translations:build

# Build specific formats
composer translations:php      # PHP arrays (source of truth)
composer translations:yaml     # Symfony YAML format
composer translations:laravel  # Laravel PHP format
```

Or use the console directly:

```
./bin/console build:translations all
./bin/console build:translations php:from-yaml
./bin/console build:translations yaml:generate
./bin/console build:translations laravel:generate
```

API Platform Integration
------------------------

[](#api-platform-integration)

For Symfony API Platform, expose `CpvCode` with the `localName` property:

```
# config/api_platform/cpv_code.yaml
Xterr\CpvCodes\CpvCode:
  attributes:
    normalization_context:
      groups: [ 'cpv_code:read' ]
  properties:
    code:
      groups: [ 'cpv_code:read' ]
    name:
      groups: [ 'cpv_code:read' ]
    localName:
      groups: [ 'cpv_code:read' ]
    type:
      groups: [ 'cpv_code:read' ]
    division:
      groups: [ 'cpv_code:read' ]
```

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

[](#requirements)

- PHP &gt;= 7.1
- ext-json

### Optional Dependencies

[](#optional-dependencies)

- `symfony/translation-contracts` - For Symfony integration
- `illuminate/contracts` - For Laravel integration
- `symfony/console` - For CLI translation builder (dev only)

License
-------

[](#license)

This library is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

Credits
-------

[](#credits)

- [Razvan Ceana](https://github.com/xterr) - Author
- CPV code data sourced from the [Official EU CPV](https://ted.europa.eu/en/simap/cpv)

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance66

Regular maintenance activity

Popularity9

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity57

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 ~320 days

Total

5

Last Release

200d ago

Major Versions

1.1.2 → 2.0.02025-12-15

PHP version history (2 changes)1.0.0PHP &gt;=7.1

1.1.2PHP &gt;=7.1 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/d9526b453abaa7d569fdacdf58cb0f55aa8d889f68f5b622344a28b37eb6c17d?d=identicon)[razvanceana](/maintainers/razvanceana)

---

Top Contributors

[![xterr](https://avatars.githubusercontent.com/u/619509?v=4)](https://github.com/xterr "xterr (8 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/xterr-php-cpvcodes/health.svg)

```
[![Health](https://phpackages.com/badges/xterr-php-cpvcodes/health.svg)](https://phpackages.com/packages/xterr-php-cpvcodes)
```

###  Alternatives

[smmoosavi/php-gettext

Wrapper for php-gettext by danilo segan. This library provides PHP functions to read MO files even when gettext is not compiled in or when appropriate locale is not present on the system.

1927.0k1](/packages/smmoosavi-php-gettext)

PHPackages © 2026

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