Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Calculator Bundle Laravel Package

denismitr/calculator-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:
    composer require denismitr/calculator-bundle
    
  2. Configure the bundle by creating config/packages/denismitr_calculator.yaml (Symfony 5+) or config/denismitr_calculator.yaml (older versions):
    denismitr_calculator:
      algorithm: denismitr_calculator.dijkstra_two_stack_algorithm
    
  3. First Use Case: Inject the CalculatorService into a controller or service:
    use Denismitr\CalculatorBundle\Service\CalculatorService;
    
    class ExampleController extends AbstractController
    {
        public function __construct(private CalculatorService $calculator)
        {
        }
    
        public function calculate(Expression $expression)
        {
            $result = $this->calculator->calculate($expression->getValue());
            return new Response($result);
        }
    }
    
    • Note: The package assumes a Expression DTO (not included). You’ll need to create a simple class like:
      class Expression
      {
          public function __construct(private string $value) {}
          public function getValue(): string { return $this->value; }
      }
      

Implementation Patterns

Core Workflow

  1. Expression Handling:

    • Parse user input (e.g., "3 + 5 * (2 - 1)") into a structured format (e.g., Abstract Syntax Tree).
    • Use the CalculatorService to evaluate the expression:
      $result = $this->calculator->calculate("3 + 5 * (2 - 1)"); // Returns 18
      
    • Tip: Validate input with regex or a parser (e.g., Symfony\Component\ExpressionLanguage).
  2. Algorithm Customization:

    • The bundle supports swapping algorithms via configuration (e.g., dijkstra_two_stack_algorithm).
    • To add a new algorithm:
      1. Create a service tagged as denismitr_calculator.algorithm:
        services:
          app.custom_calculator:
            class: App\Service\CustomCalculator
            tags:
              - { name: denismitr_calculator.algorithm, algorithm: 'app.custom_algorithm' }
        
      2. Implement Denismitr\CalculatorBundle\Algorithm\AlgorithmInterface.
  3. Integration with Forms:

    • Use in Symfony forms for dynamic calculations:
      $builder->add('expression', TextType::class, [
          'attr' => ['placeholder' => 'e.g., 2 + 3 * (4 - 1)'],
      ]);
      $builder->add('result', HiddenType::class, [
          'mapped' => false,
          'data' => $this->calculator->calculate($builder->getData()['expression']),
      ]);
      
  4. Command-Line Usage:

    • Create a console command to expose calculations:
      class CalculateCommand extends Command
      {
          protected function execute(InputInterface $input, OutputInterface $output): int
          {
              $expression = $input->getArgument('expression');
              $result = $this->calculator->calculate($expression);
              $output->writeln("Result: {$result}");
              return Command::SUCCESS;
          }
      }
      
      Register in config/services.yaml:
      commands:
        App\Command\CalculateCommand::class
      

Gotchas and Tips

Pitfalls

  1. No Built-in Parser:

    • The bundle expects valid mathematical expressions as strings (e.g., "2 + 3"). You must handle:
      • Syntax errors: Wrap calls in a try-catch for Denismitr\CalculatorBundle\Exception\CalculationException.
      • Malformed input: Sanitize/user input (e.g., reject "2 +" or "abc").
    • Workaround: Use a library like symfony/expression-language for parsing.
  2. Algorithm Limitations:

    • The default dijkstra_two_stack_algorithm supports basic arithmetic (+, -, *, /, parentheses).
    • Missing features:
      • Functions (e.g., sin(), log()).
      • Variables (e.g., x + 2 where x is dynamic).
    • Solution: Extend the bundle by implementing AlgorithmInterface or patch the core logic.
  3. Configuration Overrides:

    • The algorithm key in denismitr_calculator.yaml is case-sensitive and must match the service ID exactly.
    • Debugging tip: Dump the loaded services to verify the algorithm is registered:
      $this->container->get('denismitr_calculator.algorithm_resolver')->getAlgorithms();
      
  4. Performance:

    • The two-stack algorithm (Shunting-yard) has O(n) complexity but may be slow for deeply nested expressions.
    • Optimization: For high-frequency use, cache results (e.g., with Symfony\Contracts\Cache\CacheInterface).

Debugging Tips

  1. Enable Debug Mode:

    • Add this to config/packages/dev/denismitr_calculator.yaml to log intermediate steps:
      denismitr_calculator:
        debug: true
        algorithm: denismitr_calculator.dijkstra_two_stack_algorithm
      
    • Check logs for stack traces during evaluation.
  2. Unit Testing:

    • Mock the CalculatorService to test controllers:
      $mockCalculator = $this->createMock(CalculatorService::class);
      $mockCalculator->method('calculate')->willReturn(42);
      $this->container->set(CalculatorService::class, $mockCalculator);
      
  3. Extension Points:

    • Pre/Post-Processing: Subscribe to events (if the bundle supports them) or wrap the service:
      $this->calculator->calculate($expression); // Original
      $this->customCalculator->calculate($expression); // Your wrapper
      

Configuration Quirks

  • No Default Algorithm: The bundle fails silently if no algorithm is configured. Always validate:
    if (!$this->calculator->supportsAlgorithm()) {
        throw new \RuntimeException('Calculator algorithm not configured.');
    }
    
  • Service Autowiring: The bundle does not auto-register services. Ensure your custom algorithms are loaded via services.yaml or autoconfigure: true.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle