calculates golf handicaps using various methods including WHS rules
longestdrive/laravel-golf-handicap-calculator is a Laravel package for calculates golf handicaps using various methods including whs rules.
It currently has 0 GitHub stars and 87 downloads on Packagist (latest version 2.0.1).
Install it with composer require longestdrive/laravel-golf-handicap-calculator.
Discover more Laravel packages by longestdrive
or browse all Laravel packages to compare alternatives.
Last updated
A Laravel package for calculating golf handicaps using various methods, including the World Handicap System (WHS) rules. This package provides a flexible factory-based approach that allows you to:
The package uses a factory pattern that makes it easy to extend with your own calculation methods while maintaining a consistent interface.
Built using [spatie/laravel-package-skeleton]
You can install the package via composer:
composer require longestdrive/laravel-golf-handicap-calculator
You can publish the config file with:
php artisan vendor:publish --tag="laravel-golf-handicap-calculator-config"
WIP This is the contents of the published config file:
return [
];
use Longestdrive\LaravelGolfHandicapCalculator\Facades\GolfHandicapCalculator;
// Create a calculator instance using the factory (uses WHSHandicapCalculator by default)
$calculator = GolfHandicapCalculator::make('whs');
// Calculate a handicap using the options array
$handicap = $calculator->getHandicap([
'actualHandicap' => 15.4, // Player's actual handicap (float)
'courseSlope' => 125, // Course slope rating (int)
'courseRating' => 72.1, // Course rating (float)
'coursePar' => 72 // Course par (int)
]);
echo "Playing Handicap: " . $handicap;
use Longestdrive\LaravelGolfHandicapCalculator\LaravelGolfHandicapCalculator;
// Create a calculator instance (uses WHSHandicapCalculator by default)
$calculator = new LaravelGolfHandicapCalculator();
// Calculate a handicap using the options array
$handicap = $calculator->getHandicap([
'actualHandicap' => 15.4, // Player's actual handicap (float)
'courseSlope' => 125, // Course slope rating (int)
'courseRating' => 72.1, // Course rating (float)
'coursePar' => 72 // Course par (int)
]);
echo "Playing Handicap: " . $handicap;
Every calculator also supports reverseHandicapIndex(), which works backwards from a known playing handicap to estimate the original handicap index. This is useful when you have a course handicap and want to derive the underlying handicap index.
Note: Because the playing handicap is a rounded integer, the reverse result is an approximation — not a guaranteed exact match of the original handicap index.
use Longestdrive\LaravelGolfHandicapCalculator\Facades\GolfHandicapCalculator;
$calculator = GolfHandicapCalculator::make('whs');
$handicapIndex = $calculator->reverseHandicapIndex([
'playingHandicap' => 8, // Known playing/course handicap (int)
'courseSlope' => 128, // Course slope rating (int|float)
'courseRating' => 70.3, // Course rating (float|int)
'coursePar' => 72, // Course par (int)
]);
// Returns a float (or null if courseSlope is zero)
echo "Estimated Handicap Index: " . $handicapIndex; // e.g. 8.563
The method returns null if courseSlope is zero (to avoid division by zero).
handicapIndex = (playingHandicap - (courseRating - coursePar)) × (113 / courseSlope)
handicapIndex = (playingHandicap - (courseRating - coursePar) / 2) × (100 / courseSlope)
The package is designed with a flexible factory approach that allows you to implement and use different handicap calculation strategies:
use Longestdrive\LaravelGolfHandicapCalculator\Facades\GolfHandicapCalculator;
use App\Services\CustomHandicapCalculator; // Your custom implementation
// Register your custom calculator
GolfHandicapCalculator::register('custom', CustomHandicapCalculator::class);
// Create a calculator instance using the factory
$whsCalculator = GolfHandicapCalculator::make('whs'); // Default WHS calculator
$customCalculator = GolfHandicapCalculator::make('custom'); // Your custom calculator
// Calculate handicap using the selected calculator
$options = [
'actualHandicap' => 15.4,
'courseSlope' => 125,
'courseRating' => 72.1,
'coursePar' => 72
];
$handicap = $whsCalculator->getHandicap($options);
$customHandicap = $customCalculator->getHandicap($options);
The package comes with the following built-in calculator:
whs - World Handicap System calculator (default)The package also includes a SimpleHandicapCalculator class that you can register manually:
use Longestdrive\LaravelGolfHandicapCalculator\Facades\GolfHandicapCalculator;
use Longestdrive\LaravelGolfHandicapCalculator\Calculator\SimpleHandicapCalculator;
// Register the SimpleHandicapCalculator
GolfHandicapCalculator::register('simple', SimpleHandicapCalculator::class);
// Now you can use it
$simpleCalculator = GolfHandicapCalculator::make('simple');
$handicap = $simpleCalculator->getHandicap($options);
You can also use the direct instantiation approach:
use Longestdrive\LaravelGolfHandicapCalculator\LaravelGolfHandicapCalculator;
use Longestdrive\LaravelGolfHandicapCalculator\Calculator\WHSHandicapCalculator;
use App\Services\CustomHandicapCalculator; // Your custom implementation
// Using the default WHS calculator
$calculator = new LaravelGolfHandicapCalculator();
// Explicitly using the WHS calculator
$calculator = new LaravelGolfHandicapCalculator(new WHSHandicapCalculator());
// Using your custom calculator
$calculator = new LaravelGolfHandicapCalculator(new CustomHandicapCalculator());
// Switching calculators at runtime
$calculator = new LaravelGolfHandicapCalculator();
$calculator->setCalculator(new CustomHandicapCalculator());
// All calculators use the same options array format
$options = [
'actualHandicap' => 15.4,
'courseSlope' => 125,
'courseRating' => 72.1,
'coursePar' => 72
];
$handicap = $calculator->getHandicap($options);
You can create your own handicap calculator by implementing the HandicapCalculatorInterface and registering it with the factory:
use Longestdrive\LaravelGolfHandicapCalculator\Calculator\HandicapCalculatorInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CustomHandicapCalculator implements HandicapCalculatorInterface
{
private array $options;
public function getHandicap(array $options): int
{
$this->setCalculationOptions($options);
// Your custom calculation logic here
return (int) round(/* your formula using $this->options */);
}
public function reverseHandicapIndex(array $options): ?float
{
$this->setReverseCalculationOptions($options);
if ($this->options['courseSlope'] == 0) {
return null;
}
// Your custom reverse formula here
return /* derived handicap index as float */;
}
private function setCalculationOptions(array $options): void
{
$resolver = new OptionsResolver();
$resolver->setRequired([
'actualHandicap',
'courseSlope',
'courseRating',
'coursePar',
]);
$resolver->setAllowedTypes('actualHandicap', ['float', 'int']);
$resolver->setAllowedTypes('courseSlope', ['float', 'int']);
$resolver->setAllowedTypes('courseRating', ['float', 'int']);
$resolver->setAllowedTypes('coursePar', 'int');
$this->options = $resolver->resolve($options);
}
private function setReverseCalculationOptions(array $options): void
{
$resolver = new OptionsResolver();
$resolver->setRequired([
'playingHandicap',
'courseSlope',
'courseRating',
'coursePar',
]);
$resolver->setAllowedTypes('playingHandicap', 'int');
$resolver->setAllowedTypes('courseSlope', ['float', 'int']);
$resolver->setAllowedTypes('courseRating', ['float', 'int']);
$resolver->setAllowedTypes('coursePar', 'int');
$this->options = $resolver->resolve($options);
}
}
You can register your calculator in a service provider:
use Longestdrive\LaravelGolfHandicapCalculator\Facades\GolfHandicapCalculator;
use App\Services\CustomHandicapCalculator;
public function boot()
{
// Register your custom calculator
GolfHandicapCalculator::register('custom', CustomHandicapCalculator::class);
}
Or register it directly in your application code:
use Longestdrive\LaravelGolfHandicapCalculator\Facades\GolfHandicapCalculator;
use App\Services\CustomHandicapCalculator;
// Register your custom calculator
GolfHandicapCalculator::register('custom', CustomHandicapCalculator::class);
use Longestdrive\LaravelGolfHandicapCalculator\Facades\GolfHandicapCalculator;
// Create an instance of your custom calculator
$calculator = GolfHandicapCalculator::make('custom');
// Use it to calculate a handicap
$handicap = $calculator->getHandicap([
'actualHandicap' => 15.4,
'courseSlope' => 125,
'courseRating' => 72.1,
'coursePar' => 72
]);
The package registers the HandicapCalculatorFactory in Laravel's service container, allowing you to use dependency injection:
use Longestdrive\LaravelGolfHandicapCalculator\Calculator\HandicapCalculatorFactory;
use Illuminate\Http\Request;
class GolfController extends Controller
{
protected $calculatorFactory;
public function __construct(HandicapCalculatorFactory $calculatorFactory)
{
$this->calculatorFactory = $calculatorFactory;
}
public function calculateHandicap(Request $request, string $calculatorType = 'whs')
{
// Get the requested calculator type or default to 'whs'
$calculator = $this->calculatorFactory->make($calculatorType);
// Create options array from request inputs
$options = [
'actualHandicap' => (float) $request->input('actual_handicap'),
'courseSlope' => (int) $request->input('course_slope'),
'courseRating' => (float) $request->input('course_rating'),
'coursePar' => (int) $request->input('course_par')
];
// Pass the options array to the calculator
$handicap = $calculator->getHandicap($options);
return response()->json(['handicap' => $handicap]);
}
}
use Longestdrive\LaravelGolfHandicapCalculator\Facades\GolfHandicapCalculator;
use Illuminate\Http\Request;
class GolfController extends Controller
{
public function calculateHandicap(Request $request, string $calculatorType = 'whs')
{
// Get the requested calculator type or default to 'whs'
$calculator = GolfHandicapCalculator::make($calculatorType);
// Create options array from request inputs
$options = [
'actualHandicap' => (float) $request->input('actual_handicap'),
'courseSlope' => (int) $request->input('course_slope'),
'courseRating' => (float) $request->input('course_rating'),
'coursePar' => (int) $request->input('course_par')
];
// Pass the options array to the calculator
$handicap = $calculator->getHandicap($options);
return response()->json(['handicap' => $handicap]);
}
}
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.