modular-calculator / calculator-sdk
Public SDK for building plugins for the Modular Calculator.
Package info
github.com/mohammadumair1244/Calculator-SDK
pkg:composer/modular-calculator/calculator-sdk
Requires
- php: ^8.2
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
The Modular Calculator SDK provides the public interfaces required to develop third-party plugins for the Modular Calculator application.
The SDK is intentionally framework-independent and does not depend on Laravel or any internal calculator implementation.
Requirements
- PHP 8.2 or higher
- Composer
Installation
Install the SDK through Composer:
composer require modular-calculator/calculator-sdk
API Reference
CalculatorPlugin Interface
Every plugin must implement the CalculatorPlugin interface to be discovered and loaded by the calculator application.
namespace CalculatorSdk\Contracts; interface CalculatorPlugin { /** * Get the human-readable name of this plugin. * * @return string The plugin name */ public function name(): string; /** * Get the version of this plugin. * * @return string The plugin version (e.g., "1.0.0") */ public function version(): string; /** * Get all operations provided by this plugin. * * @return array<int, Operation> Array of Operation instances */ public function operations(): array; }
Operation Interface
Each calculator operation must implement the Operation interface.
namespace CalculatorSdk\Contracts; interface Operation { /** * Get the operation identifier. * * Must be unique within the calculator application. * Use lowercase alphanumeric characters and underscores only. * * @return string The operation name (e.g., "percentage", "square_root") */ public function name(): string; /** * Get a human-readable description of this operation. * * @return string Brief description of what the operation does */ public function description(): string; /** * Execute the operation with the given arguments. * * @param array $arguments The input values for this operation * @return float|int The calculation result * @throws InvalidArgumentException If arguments are invalid */ public function execute(array $arguments): float|int; }
Creating a Plugin
Step 1: Project Structure
Create a new directory for your plugin:
my-plugin/
├── src/
│ ├── MyOperation.php
│ └── MyPlugin.php
├── composer.json
└── plugin.json
Step 2: composer.json
Create the composer package configuration:
{
"name": "vendor/my-plugin",
"description": "My custom calculator plugin",
"type": "calculator-plugin",
"license": "MIT",
"require": {
"php": "^8.2",
"modular-calculator/calculator-sdk": "^1.0"
},
"autoload": {
"psr-4": {
"MyPlugin\\": "src/"
}
}
}
Important: Set "type": "calculator-plugin" so the application can discover your plugin.
Step 3: Implement an Operation
Create your operation class implementing the Operation interface:
<?php declare(strict_types=1); namespace MyPlugin; use CalculatorSdk\Contracts\Operation; use InvalidArgumentException; class SquareOperation implements Operation { public function name(): string { return 'square'; } public function description(): string { return 'Calculate the square of a number.'; } public function execute(array $arguments): float|int { if (count($arguments) !== 1) { throw new InvalidArgumentException( 'The square operation requires exactly one argument.' ); } $value = $arguments[0]; if (!is_numeric($value)) { throw new InvalidArgumentException( 'The argument must be numeric.' ); } return $value ** 2; } }
Step 4: Implement the Plugin Class
Create your plugin class implementing the CalculatorPlugin interface:
<?php declare(strict_types=1); namespace MyPlugin; use CalculatorSdk\Contracts\CalculatorPlugin; class MyPlugin implements CalculatorPlugin { public function name(): string { return 'My Custom Plugin'; } public function version(): string { return '1.0.0'; } public function operations(): array { return [ new SquareOperation(), // Add more operations here ]; } }
Step 5: Create plugin.json Manifest
Create a plugin.json file in your plugin root directory:
{
"name": "my-plugin",
"display_name": "My Custom Plugin",
"version": "1.0.0",
"description": "A plugin that adds custom calculator operations.",
"entry": "MyPlugin\\MyPlugin"
}
Step 6: Install the Plugin
To use your plugin locally in the calculator application, add it to the application's composer.json using a path repository:
{
"repositories": [
{
"type": "path",
"url": "plugins/my-plugin"
}
],
"require": {
"vendor/my-plugin": "^1.0"
}
}
Then run:
composer update
For publishing to Packagist or another package registry, follow standard Composer package publishing procedures.
Best Practices
Argument Validation
Always validate operation arguments in the execute() method:
public function execute(array $arguments): float|int { // Validate count if (count($arguments) !== 2) { throw new InvalidArgumentException( 'This operation requires exactly 2 arguments.' ); } // Validate type if (!is_numeric($arguments[0]) || !is_numeric($arguments[1])) { throw new InvalidArgumentException( 'All arguments must be numeric.' ); } return $arguments[0] + $arguments[1]; }
Operation Naming
- Use lowercase alphanumeric characters and underscores for operation names
- Keep names descriptive but concise
- Example good names:
percentage,square_root,unit_convert,power - Example poor names:
op1,calc,do_something
Error Handling
Always throw InvalidArgumentException for invalid arguments. The calculator application handles exceptions and returns appropriate error messages.
Semantic Versioning
Follow Semantic Versioning:
- MAJOR version for breaking changes to your plugin's operations
- MINOR version for new operations or backward-compatible changes
- PATCH version for bug fixes
Example: 1.2.3 = Major 1, Minor 2, Patch 3
Documentation
Include a README.md in your plugin explaining:
- What your plugin does
- Installation instructions
- Usage examples for each operation
- Any dependencies
- License information
Example Plugin
For a complete working example, see the included Percentage or Power plugins in the main repository.
Both implement the SDK interfaces and demonstrate proper error handling and structure.
Compatibility
The calculator application will reject plugins that:
- Do not implement the
CalculatorPlugininterface - Provide operations that do not implement the
Operationinterface - Have empty or missing plugin names
- Have duplicate operation names (within the same plugin or across plugins)
- Declare invalid manifest files
If your plugin fails to load, check the application's plugin error log for details.
Publishing Your Plugin
Once your plugin is ready:
- Push the code to a public repository (GitHub, GitLab, etc.)
- Register on Packagist.org
- Submit your package
- Users can then install it with:
composer require vendor/my-plugin
Make sure your composer.json package name matches what you publish on Packagist.
Support
For questions or issues:
- Check the main calculator application documentation
- Review the example plugins
- Ensure your classes correctly implement the SDK interfaces
- Verify the
plugin.jsonmanifest is valid JSON
License
This SDK is provided under the same license as the Modular Calculator application (MIT).