PHPackages                             slawe/climbing-grade-conversions - 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. slawe/climbing-grade-conversions

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

slawe/climbing-grade-conversions
================================

Small PHP library for converting rock climbing grades between multiple grading systems.

v0.3.1(5mo ago)05MITPHPPHP &gt;=8.1

Since Nov 10Pushed 5mo agoCompare

[ Source](https://github.com/Slawe/climbing-grade-conversions)[ Packagist](https://packagist.org/packages/slawe/climbing-grade-conversions)[ RSS](/packages/slawe-climbing-grade-conversions/feed)WikiDiscussions master Synced 1mo ago

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

Climbing Grade Conversions
==========================

[](#climbing-grade-conversions)

Small PHP library for converting rock climbing grades between multiple grading systems. It started as a DDD / clean-architecture learning playground and evolved into a reusable package.

Supported Grading Systems
-------------------------

[](#supported-grading-systems)

Currently supported (out of the box):

- French Sport Scale (FR) - "6a", "7c+", etc.
- UIAA Scale (UIAA) - "VI+", "IX-", etc.
- Yosemite Decimal System (YDS) - "5.10a", "5.12d", etc.
- British Technical (UK-tech) - "4a", "6c", etc.
- British Adjectival (UK-adj) - "VS", "E3", etc.
- Saxon Scale (SAXON) - "VIIa", "IXc", etc.
- Australian Ewbank (AU) - "18", "24", etc.
- South African Ewbank (SA) - "19", "25", etc.
- Finnish Scale (FIN) - "6-", "7+", etc.
- Norwegian Scale (NO) - "6", "7+", etc.
- Brazilian Technical (BR) - "VIsup", "8b", etc.
- Polish Kurtyka's Scale (PO) - "VI.1+", "VI.4", etc.
- American Hueco/V-Scale (V) - "V3", "V7", etc.
- French Fontainebleau (FONT) - "7A+", "6C", etc.
- ...*(You can add more by implementing a scale class and registering it.)*

---

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

[](#installation)

```
composer require slawe/climbing-grade-conversions
```

or

```
git clone git@github.com:slawe/climbing-grade-conversions.git
cd climbing-grade-conversions
composer install

```

> The package ships with a CSV-backed repository by default. Configure the CSV path via `Climb\Grades\Infrastructure\Config\GradeConfig::csvPath()`.

---

Basic Usage
-----------

[](#basic-usage)

Convert between any supported grading systems with a simple and fluent API:

```
use Climb\Grades\Infrastructure\Bootstrap\GradeConversion;
use Climb\Grades\Domain\Value\GradeSystem;

// Convert a French 6c+ to YDS
$ydsGrades = GradeConversion::from('6c+', 'fr')->to(GradeSystem::YDS);
echo $ydsGrades[0]->value(); // "5.11b"

// Convert a French 7a to all other systems
$allGrades = GradeConversion::from('7a', 'fr')->toAll();

// Include the source system in the result
$allWithSource = GradeConversion::from('7a', 'fr')->toAll(includeSource: true);

// Get a single result with explicit policies (useful when multiple grade mappings exist)
use Climb\Grades\Domain\Service\PrimaryIndexPolicy;
use Climb\Grades\Domain\Service\TargetVariantPolicy;

$singleGrade = GradeConversion::from('7a', 'fr')
    ->towards(GradeSystem::BR)
    ->single(
        PrimaryIndexPolicy::LOWEST,
        TargetVariantPolicy::LAST
    );
```

---

Advanced Usage
--------------

[](#advanced-usage)

### Using a Different CSV Data Source

[](#using-a-different-csv-data-source)

You can use a different CSV data source by providing your own path:

```
use Climb\Grades\Infrastructure\Config\GradeServices;

// Global configuration (applies to all future conversions)
GradeServices::useCsv('/path/to/your/custom-grades.csv');

// Then use the normal API
$grades = GradeConversion::from('6c+', 'fr')->to(GradeSystem::YDS);
```

### Using a Custom Data Repository

[](#using-a-custom-data-repository)

For advanced use cases, you can implement your own `GradeScaleDataRepository` (e.g., database-backed):

```
use Climb\Grades\Infrastructure\Config\GradeServices;

// Create your custom repository implementing GradeScaleDataRepository
$myRepo = new MyDatabaseRepository($dbConnection);

// Use it globally
GradeServices::useRepository($myRepo);

// Or just for one specific conversion service
$service = GradeServices::conversion($myRepo);
```

---

CLI usage
---------

[](#cli-usage)

A small helper lives at `bin/grades`.

Positional:

- `` - e.g. `6c+`, `7a`
- `` - e.g. `FR`, `UIAA`, `YDS`
- `[targetSystem]` - if omitted, converts to **all** other systems (range)

Options:

- `--single` (or `-1`) - return **one** result (instead of a list)
- `--source-policy=lowest|middle|highest` - how to pick the **source** index if the grade spans multiple (default: `lowest`)
- `--target-policy=first|middle|last` - which **target** variant to pick if the cell has multiple values (default: `first`)
- `--include-source` - when converting to **all** systems, include the source too
- `--help` - show help

Examples:

```
php bin/grades 6c+ fr
php bin/grades 6c+ fr yds
php bin/grades 7a fr br --single --target-policy=last
php bin/grades 6c+ fr --include-source
```

When installed via Composer in another project, the command is also available as:

```
vendor/bin/grades 6c+ fr

```

---

Architecture
------------

[](#architecture)

This library follows DDD and clean architecture principles:

- **Domain layer**: Contains core business logic (grade systems, conversion algorithms)
- **Infrastructure layer**: Provides data access and bootstrap utilities
- **Bootstrap facade**: Offers a convenient entry point for typical usage scenarios

Core components:

- [GradeConversionService](./src/Domain/Service/GradeConversionService.php): Main domain service for converting between systems
- [GradeScale](./src/Domain/Service/GradeScale.php): Interface for specific grading scales
- [GradeScaleDataRepository](./src/Domain/Repository/GradeScaleDataRepository.php): Interface for data access
- [GradeConversion](./src/Infrastructure/Bootstrap/GradeConversion.php) (bootstrap): User-friendly facade for common operations

---

Extending with a new grading system
-----------------------------------

[](#extending-with-a-new-grading-system)

1. **Add a case** to `GradeSystem` enum.
2. **Create a scale class** extending `AbstractGradeScale` and implement `system(): GradeSystem`; its data will come from the repository’s column for that system.
3. **Register** the scale in your composition root (`GradeServices` or your own factory).

No other changes are needed: `GradeConversionService` will pick it up automatically.

---

Development
-----------

[](#development)

Run the test suite:

```
composer test

```

Run CLI locally:

```
php bin/grades 6c+ FR
php bin/grades 6c+ FR YDS

```

---

Changelog
---------

[](#changelog)

See **[CHANGELOG.md](./CHANGELOG.md)** for release notes.

Latest: **v0.3.1** — Release: Architecture refactoring and performance improvements.

---

License
-------

[](#license)

Released under the [MIT License](https://opensource.org/licenses/MIT).

Copyright © 2025 [slawe](https://github.com/slawe)

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance70

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

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

Total

4

Last Release

175d ago

### Community

Maintainers

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

---

Top Contributors

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

---

Tags

phplibraryconversionconverternorwayfrenchGradingclimbinggradessaxongradeclimbboulderinguiaaydsv-scalefontainebleauewbankkurtyka

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/slawe-climbing-grade-conversions/health.svg)

```
[![Health](https://phpackages.com/badges/slawe-climbing-grade-conversions/health.svg)](https://phpackages.com/packages/slawe-climbing-grade-conversions)
```

###  Alternatives

[zman/zman

A Jewish date converter and helper.

186.4k](/packages/zman-zman)

PHPackages © 2026

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