Skip to content

Commit

Permalink
Move some of Ussd functionality to UssdBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
cybersai committed Jan 21, 2024
1 parent fa7f099 commit 4fb58c4
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 150 deletions.
27 changes: 24 additions & 3 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ All notable changes to `laravel Ussd` will be documented in this file.

## [Unreleased]

## [v3.0.0-beta.1] - 2024-01-21
### Removed
- Removed machine in favor of USSD facade.

### Changed
- Changed state interface.
- Changed record implementation and public apis.
- Changed config variables

### Added
- Added `Transition`, `Paginate`, `Truncate` and `Terminate` Attributes.
- Added Custom Exception Handling.
- Added command to create responses, exception handlers and decisions.
- Added decision classes for navigating USSD menus.
- Added testing utility to Ussd Facade.
- Added pagination utility.
- Added resumability of timed-out sessions.
- Added interfaces for decision, exception handler, response, initial state and initial action.
- Added support for dependency injection.
- Added USSD context.

## [v2.5.0] - 2022-06-19
### Added
- Add configuring USSDs using decorator pattern.
Expand All @@ -17,13 +38,11 @@ All notable changes to `laravel Ussd` will be documented in this file.
- Clean up

## [v2.4.0] - 2022-02-22

### Added
- Add Laravel 9 support
- Add PHP 8.1 support

## [v2.3.1] - 2021-10-15

### Fixed
- Coding style

Expand All @@ -50,6 +69,7 @@ All notable changes to `laravel Ussd` will be documented in this file.
- Artisan command to create action class
- increment method to records
- decrement method to records

### Changed
- config file class namespace split to action and state namespace
- Updated changelog
Expand Down Expand Up @@ -82,7 +102,8 @@ All notable changes to `laravel Ussd` will be documented in this file.
- Ussd config to allow developers customize behaviour
- Ussd service Provider class to allow laravel know how to integrate the package

[Unreleased]: ../../compare/v2.5.0...HEAD
[Unreleased]: ../../compare/v3.0.0-beta.1...HEAD
[v3.0.0-beta.1]: ../../compare/v2.5.0...v3.0.0-beta.1
[v2.5.0]: ../../compare/v2.4.2...v2.5.0
[v2.4.2]: ../../compare/v2.4.1...v2.4.2
[v2.4.1]: ../../compare/v2.4.0...v2.4.1
Expand Down
1 change: 0 additions & 1 deletion contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Contributions are accepted via Pull Requests on [Github](https://github.com/spar

# Things you could do
If you want to contribute but do not know where to start, this list provides some starting points.
- Set up TravisCI
- Write a comprehensive ReadMe

## Pull Requests
Expand Down
26 changes: 0 additions & 26 deletions me.md

This file was deleted.

2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class GoodByeState implements State
}
```

Due to some limitation with PHP 8.0, you can not pass class instance to attributes. So to other come this limitation, you can pass an array with the full class path as the first element and the rest should be argument required. eg.
Due to some limitation with PHP 8.0, you can not pass class instance to attributes. So to overcome this limitation, you can pass an array with the full class path as the first element and the rest should be argument required. eg.

``` php
<?php
Expand Down
138 changes: 138 additions & 0 deletions src/Traits/UssdBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?php

namespace Sparors\Ussd\Traits;

use Closure;
use DateInterval;
use DateTimeInterface;
use Illuminate\Support\Facades\App;
use Sparors\Ussd\Context;
use Sparors\Ussd\ContinuingMode;
use Sparors\Ussd\Contracts\Configurator;
use Sparors\Ussd\Contracts\ContinueState;
use Sparors\Ussd\Contracts\ExceptionHandler;
use Sparors\Ussd\Contracts\InitialAction;
use Sparors\Ussd\Contracts\InitialState;
use Sparors\Ussd\Contracts\Response;
use Sparors\Ussd\Exceptions\InvalidConfiguratorException;
use Sparors\Ussd\Exceptions\InvalidContinueStateException;
use Sparors\Ussd\Exceptions\InvalidContinuingModeException;
use Sparors\Ussd\Exceptions\InvalidExceptionHandlerException;
use Sparors\Ussd\Exceptions\InvalidInitialStateException;
use Sparors\Ussd\Exceptions\InvalidResponseException;

trait UssdBuilder
{
public function useContext(Context $context): static
{
$this->context = $context;

return $this;
}

public function useConfigurator(Configurator|string $configurator): static
{
if (is_string($configurator) && class_exists($configurator)) {
$configurator = App::make($configurator);
}

throw_unless(
$configurator instanceof Configurator,
InvalidConfiguratorException::class,
$configurator::class
);

$configurator->configure($this);

return $this;
}

public function useInitialState(InitialAction|InitialState|string $initialState): static
{
if (is_string($initialState) && class_exists($initialState)) {
$initialState = App::make($initialState);
}

throw_unless(
$initialState instanceof InitialState || $initialState instanceof InitialAction,
InvalidInitialStateException::class,
$initialState::class
);

$this->initialState = $initialState;

return $this;
}

public function useContinuingState(
int $continuingMode,
null|DateInterval|DateTimeInterface|int $continuingTtl,
null|ContinueState|string $continuingState = null
): static {
if (is_string($continuingState) && class_exists($continuingState)) {
$continuingState = App::make($continuingState);
}

throw_unless(
in_array($continuingMode, [ContinuingMode::START, ContinuingMode::CONTINUE, ContinuingMode::CONFIRM], true),
InvalidContinuingModeException::class,
$continuingMode
);

$this->continuingMode = $continuingMode;
$this->continuingTtl = $continuingTtl;

if (ContinuingMode::CONFIRM === $continuingMode) {
throw_unless(
$continuingState instanceof ContinueState,
InvalidContinueStateException::class,
isset($continuingState) ? $continuingState::class : null
);
}

$this->continuingState = $continuingState;

return $this;
}

public function useResponse(Closure|Response|string $response): static
{
if (is_string($response) && class_exists($response)) {
$response = App::make($response);
}

throw_unless(
$response instanceof Response || $response instanceof Closure,
InvalidResponseException::class,
$response::class
);

$this->response = $response;

return $this;
}

public function useExceptionHandler(Closure|ExceptionHandler|string $exceptionHandler): static
{
if (is_string($exceptionHandler) && class_exists($exceptionHandler)) {
$exceptionHandler = App::make($exceptionHandler);
}

throw_unless(
$exceptionHandler instanceof ExceptionHandler || $exceptionHandler instanceof Closure,
InvalidExceptionHandlerException::class,
$exceptionHandler::class
);

$this->exceptionHandler = $exceptionHandler;

return $this;
}

public function useStore(string $storeName): static
{
$this->storeName = $storeName;

return $this;
}
}
121 changes: 2 additions & 119 deletions src/Ussd.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,26 @@
use Sparors\Ussd\Attributes\Transition;
use Sparors\Ussd\Attributes\Truncate;
use Sparors\Ussd\Contracts\Action;
use Sparors\Ussd\Contracts\Configurator;
use Sparors\Ussd\Contracts\ContinueState;
use Sparors\Ussd\Contracts\ExceptionHandler;
use Sparors\Ussd\Contracts\InitialAction;
use Sparors\Ussd\Contracts\InitialState;
use Sparors\Ussd\Contracts\Response;
use Sparors\Ussd\Contracts\State;
use Sparors\Ussd\Exceptions\ActiveStateNotFoundException;
use Sparors\Ussd\Exceptions\InvalidConfiguratorException;
use Sparors\Ussd\Exceptions\InvalidContinueStateException;
use Sparors\Ussd\Exceptions\InvalidContinuingModeException;
use Sparors\Ussd\Exceptions\InvalidExceptionHandlerException;
use Sparors\Ussd\Exceptions\InvalidInitialStateException;
use Sparors\Ussd\Exceptions\InvalidResponseException;
use Sparors\Ussd\Exceptions\InvalidStateException;
use Sparors\Ussd\Exceptions\NextStateNotFoundException;
use Sparors\Ussd\Exceptions\NoInitialStateProvided;
use Sparors\Ussd\Tests\PendingTest;
use Sparors\Ussd\Traits\Conditionable;
use Sparors\Ussd\Traits\UssdBuilder;
use Sparors\Ussd\Traits\WithPagination;

class Ussd
{
use Conditionable;
use UssdBuilder;

private const INIT = '__init__';
private const HEAL = '__heal__';
Expand Down Expand Up @@ -87,119 +83,6 @@ public static function test(
return new PendingTest($initialState, $continuingMode, $continuingTtl, $continuingState);
}

public function useContext(Context $context): static
{
$this->context = $context;

return $this;
}

public function useConfigurator(Configurator|string $configurator): static
{
if (is_string($configurator) && class_exists($configurator)) {
$configurator = App::make($configurator);
}

throw_unless(
$configurator instanceof Configurator,
InvalidConfiguratorException::class,
$configurator::class
);

$configurator->configure($this);

return $this;
}

public function useInitialState(InitialAction|InitialState|string $initialState): static
{
if (is_string($initialState) && class_exists($initialState)) {
$initialState = App::make($initialState);
}

throw_unless(
$initialState instanceof InitialState || $initialState instanceof InitialAction,
InvalidInitialStateException::class,
$initialState::class
);

$this->initialState = $initialState;

return $this;
}

public function useContinuingState(
int $continuingMode,
null|DateInterval|DateTimeInterface|int $continuingTtl,
null|ContinueState|string $continuingState = null
): static {
if (is_string($continuingState) && class_exists($continuingState)) {
$continuingState = App::make($continuingState);
}

throw_unless(
in_array($continuingMode, [ContinuingMode::START, ContinuingMode::CONTINUE, ContinuingMode::CONFIRM], true),
InvalidContinuingModeException::class,
$continuingMode
);

$this->continuingMode = $continuingMode;
$this->continuingTtl = $continuingTtl;

if (ContinuingMode::CONFIRM === $continuingMode) {
throw_unless(
$continuingState instanceof ContinueState,
InvalidContinueStateException::class,
isset($continuingState) ? $continuingState::class : null
);
}

$this->continuingState = $continuingState;

return $this;
}

public function useResponse(Closure|Response|string $response): static
{
if (is_string($response) && class_exists($response)) {
$response = App::make($response);
}

throw_unless(
$response instanceof Response || $response instanceof Closure,
InvalidResponseException::class,
$response::class
);

$this->response = $response;

return $this;
}

public function useExceptionHandler(Closure|ExceptionHandler|string $exceptionHandler): static
{
if (is_string($exceptionHandler) && class_exists($exceptionHandler)) {
$exceptionHandler = App::make($exceptionHandler);
}

throw_unless(
$exceptionHandler instanceof ExceptionHandler || $exceptionHandler instanceof Closure,
InvalidExceptionHandlerException::class,
$exceptionHandler::class
);

$this->exceptionHandler = $exceptionHandler;

return $this;
}

public function useStore(string $storeName): static
{
$this->storeName = $storeName;

return $this;
}

public function run(): mixed
{
try {
Expand Down

0 comments on commit 4fb58c4

Please sign in to comment.