Search by

modular-calculator / calculator-sdk

mohammadumair1244

Public SDK for building plugins for the Modular Calculator.

Package info

github.com/mohammadumair1244/Calculator-SDK

pkg:composer/modular-calculator/calculator-sdk

Statistics

Installs: 7

Dependents: 2

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-09-13 20:47 UTC

This package is auto-updated.

Last update: 2026-09-13 20:48:51 UTC


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 CalculatorPlugin interface
  • Provide operations that do not implement the Operation interface
  • 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:

  1. Push the code to a public repository (GitHub, GitLab, etc.)
  2. Register on Packagist.org
  3. Submit your package
  4. 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.json manifest is valid JSON

License

This SDK is provided under the same license as the Modular Calculator application (MIT).