PHP code example of douglasgreyling / light-service

1. Go to this page and download the library: Download douglasgreyling/light-service library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

douglasgreyling / light-service example snippets


class TaxController extends SomeController {
  public function update {
    $order = Order::find(request('id'));
    $tax_ranges = TaxRange::for_region($order->region);

    if (is_null($tax_ranges)) {
      return ...; // render some view
    }

    $tax_percentage = $tax_ranges->for_total($order->total);

    if (is_null($tax_percentage)) {
      return ...; // render some other view
    }

    $order->tax = round(($order->total * ($tax_percentage/100)), 2);

    if ($order->total_with_tax > 200) {
      $order->provide_free_shipping;
    }

    return ...; // Redirect to some view with a flash message
  }
}

class GreetsSomeoneAction {
  use LightService\Action;

  private $expects  = ['name'];
  private $promises = ['greeting'];

  private function executed($context) {
    $context->greeting = "Hello, {$context->name}. Solved any fun mysteries lately?";
  }
}

$result = GreetsSomeoneAction::execute(['name' => 'Scooby']);

$result = GreetsSomeoneAction::execute(['name' => 'Scooby']);

if ($result->success()) {
  echo $result->greeting;
}

> "Hello, Scooby. Solved any fun mysteries lately?"

class FeedsSomeoneAction {
  use LightService\Action;

  private $expects = ['name'];

  private function executed($context) {
    $snack = Fridge::fetch('Grapes');

    Person::find($context->name)->feed($snack);
  }
}

class GreetsAndFeedsSomeone {
  use LightService\Organizer;

  public static function call($name) {
    return self::with(['name' => $name])->reduce(
      GreetsSomeoneAction::class,
      FeedSomeoneAction::class
    );
  }
}

$result = GreetsAndFeedsSomeone::call(['name' => 'Shaggy']);

$result = GreetsAndFeedsSomeone::call(['name' => 'Shaggy']);

if ($result->success()) {
  echo "Time to stock up on snacks!";
}

> "Time to stock up on snacks!"

class CalculatesTax {
  use LightService\Organizer;

  public static function call($order) {
    return self::with(['order' => $order])->reduce(
      LooksUpTaxPercentageAction::class,
      CalculatesOrderTaxAction::class,
      ProvidesFreeShippingAction::class
    );
  }
}

class LooksUpTaxPercentageAction {
  use LightService\Action;

  private $expects  = ['order'];
  private $promises = ['tax_percentage'];

  private function executed($context) {
    $order      = $context->order;
    $tax_ranges = TaxRange::for_region($order->region);

    $context->tax_percentage = 0;

    if (is_null($tax_ranges)) {
      $context->fail('The tax ranges were not found');
      $this->next_context();
    }

    $tax_percentage = $tax_ranges->for_total($order->total);

    if (is_null($tax_percentage)) {
      $context->fail('The tax percentage were not found');
      $this->next_context();
    }

    $context->tax_percentage = $tax_percentage
  }
}

class CalculatesOrderTaxAction {
  use LightService\Action;

  private $expects = ['order', 'tax_percentage'];

  private function executed($context) {
    $context
      ->order
      ->tax = round($order->total * ($tax_percentage/100), 2);
  }
}

class ProvidesFreeShippingAction {
  use LightService\Action;

  private $expects = ['order'];

  private function executed($context) {
    $total_with_tax = $context->order->total_with_tax;

    if ($total_with_tax > 200)) {
      $context->order->provide_free_shipping;
    }
  }
}

class TaxController extends Controller {
  public function update {
    $order = Order::find(request('id'));

    $service_result = CalculatesTax::call($order);

    if ($service_result->failure()) {
      return ...; // render some view
    } else {
      return ...; // Redirect to some view with a flash message
    }
  }
}

class SubmitsOrderAction {
  use LightService\Action;

  private function executed($context) {
    if (!$context->order->submit_order_successful()) {
      $context->fail_and_return('Failed to submit the order');
    }

    // This won't be executed
    $context->mailer->send_order_notification();
  }
}

class ChecksOrderStatusAction {
  use LightService\Action;

  private function executed($context) {
    if ($context->order->must_send_notification()) {
      $context->skip_remaining("Everything is good, no need to execute the rest of the actions");
    }
  }
}

class SomeOrganizer {
  use LightService\Organizer;

  public static function call($context) {
    return self::with($context)->reduce(...self::actions());
  }

  public static function actions() {
    return [
      OneAction::class,
      TwoAction::class,
      ThreeAction::class
    ];
  }
}

class TwoAction {
  use LightService\Action;

  private function executed($context) {
    if ($context->user->role == 'admin')
      $context->logger->info('admin is doing something');

    $context->user->do_something();
  }
}

class SomeOrganizer {
  use LightService\Organizer;

  public function before_each($context) {
    if ($context->current_action() == TwoAction::class) {
      if ($context->user->role != 'admin')
        return;

      $context->logger->info('admin is doing something');
    }
  }

  public function after_each($context) {
    if ($context->current_action() == TwoAction::class) {
      if ($context->user->role != 'admin')
        return;

      $context->logger->info('admin is doing something');
    }
  }

  public function around_each($context) {
    $context->logger->info('admin is about to do (or already has done) something');
  }

  public static function call($context) {
    return self::with($context)->reduce(...self::actions());
  }

  public static function actions() {
    return [
      OneAction::class,
      TwoAction::class,
      ThreeAction::class
    ];
  }
}

class TwoAction {
  use LightService\Action;

  private function executed($context) {
    $context->user->do_something();
  }
}

class FooAction {
  use LightService\Action;

  private expects  = ['a', 'b'];
  private promises = ['c'];

  private function executed($context) {
    $context->c = $context->a + $context->b;
  }
}

class FooAction {
  use LightService\Action;

  private expects  = 'a';
  private promises = 'b';

  private function executed($context) {
    $context->b = $context->a + 1;
  }
}

$result = GreetsSomeoneAction::execute(['name' => 'Scooby']);

var_dump($result->to_array());

class AnOrganizer {
  use LightService\Organizer;

  private $aliases = ['my_key' => 'key_alias'];

  public static function call($order) {
    return self::with(['order' => $order])->reduce(
      AnAction::class,
      AnotherAction::class,
    );
  }
}

class AnAction {
  use LightService\Action;

  private $promises = 'my_key';

  private function executed($context) {
    $context->my_key = "value";
  }
}

class AnotherAction {
  use LightService\Action;

  private $expects = 'key_alias';

  private function executed($context) {
    $context->key_alias;
  }
}

class SomeAction {
  use LightService\Action;

  private function executed($context) {
    $context->fail("I don't like what happened here.");
  }
}

class SomeAction {
  use LightService\Action;

  private function executed($context) {
    if (95 < $context->teapot->heat())
      $context->fail("The teapot is not hot enough", 1234);

    # Make some tea

    if (2 < $context->sugar->amount())
      $context->fail("There is not enough sugar for the tea", 5678);
  }
}

$result = SomeAction::execute();

echo $result->message();
> "The teapost is not hot enough"

echo $result->error_code();
> 1234

class SaveEntities {
  use LightService\Action;

  private $expects = 'user';

  private function executed($context) {
    $context->user->save();
  }

  private function rolled_back($executed) {
    $context->user->destroy();
  }
}

class CallSomeExternalAPI {
  use LightService\Action;

  private function executed($context) {
    $api_call_result = SomeAPI::save_user($context->user);

    if ($api_call_result->failure)
      $context->fail_with_rollback("Error when calling external API");
  }
}

class ExtractsTransformsLoadsData {
  public static function run($connection) {
    $context = RetrievesConnectionInfo::call($connection);
    $context = PullsDataFromRemoteApi::call($context);

    $retrieved_items = $context->retrieved_items;

    if ($retrieved_items->empty)
      NotifiesEngineeringTeamAction::execute($context);

    foreach($retrieved_items as $item) {
      $context->item = $item;
      TransformsData::call($context);
    }

    $context = LoadsData::call($context);

    return SendsNotifications::call($context);
  }
}

class ExtractsTransformsLoadsData {
  use LightService\Organizer;

  public static function call($connection) {
    return self::with(['connection' => $connection])->reduce(...self::actions());
  }

  public static function actions() {
    return [
      RetrievesConnectionInfo::class,
      PullsDataFromRemoteApi::class,
      self::reduce_if(
        function($context) {
          return array_empty($context->retrieved_items);
        },
        [ NotifiesEngineeringTeamAction::class ]
      ),
      self::iterate('retrieved_items', [ TransformsData::class ]),
      LoadsData::class,
      SendsNotifications::class
    ];
  }
}

class ReduceUntilOrganizer {
  use LightService\Organizer;

  public static function call($number) {
    return self::with(['number' => $number])->reduce(
      AddsOneAction::class,
      self::reduce_until(
        function($context) {
          return 3 < $context->number;
        },
        [ AddsOneAction::class ]
      )
    );
  }
}

class ReduceIfOrganizer {
  use LightService\Organizer;

  public static function call($number) {
    return self::with(['number' => $number])->reduce(
      AddsOneAction::class,
      self::reduce_if(
        function($context) {
          return 1 < $context->number;
        },
        [ AddsOneAction::class ]
      ),
      AddsOneAction::class
    );
  }
}

class IterateOrganizer {
  use LightService\Organizer;

  public static function call($context) {
    return self::with($context)->reduce(
      self::iterate('numbers', [
        IterateAction::class,
      ])
    );
  }
}

class IterateAction {
  use LightService\Action;

  private $expects  = ['number'];
  private $promises = ['number'];

  private function executed($context) {
    $context->sum += $context->number;
  }
}

class ExecuteOrganizer {
  use LightService\Organizer;

  public static function call($number) {
    return self::with(['number' => $number])->reduce(
      AddsOneAction::class,
      self::execute(function($context) { $context->number += 1; })
    );
  }
}

class AddToContextOrganizer {
  use LightService\Organizer;

  public static function call() {
    return self::with([])->reduce(
      self::add_to_context(['number' => 0]),
      AddsOneAction::class
    );
  }
}