germania-kg/order-dispatcher

创建和处理订单

1.1.6 2023-01-02 10:34 UTC

This package is auto-updated.

Last update: 2024-08-30 01:23:29 UTC


README

Germania KG · OrderDispatcher

寻找这些材料...

安装

$ composer require germania-kg/order-dispatcher

类和接口

处理订单

OrderInterface

public function getCustomerData() : array;
public function getItems() : iterable;

OrderFactoryInterface

public function createOrder( array $input) : OrderInterface;

public function setItemFactory(ItemFactoryInterface $item_factory);
public function getItemFactory() : ItemFactoryInterface;

OrderFactoryAbstract

这个抽象类实现了在 OrderFactoryInterface 中定义的 Item 工厂拦截器,并使用 ValidatorTrait

public function setItemFactory(ItemFactoryInterface $item_factory);
public function getItemFactory() : ItemFactoryInterface;

ArrayOrderFactory

从数组中创建一个 Order 实例,通常来自用户输入。

ArrayOrderFactory 扩展 OrderFactoryAbstract 并实现了 OrderFactoryInterface

构造函数接受一个 ItemFactoryInterface、订单项目数组键和可选的 PSR-3 LoggerInterface

<?php
use Germania\OrderDispatcher\ArrayOrderFactory;
use Germania\OrderDispatcher\FilterValidator;

$item_factory = ... ;
$logger = ...;

$factory = new ArrayOrderFactory($item_factory, "items");
$factory = new ArrayOrderFactory($item_factory, "items", $logger);

$customer_validation = new FilterValidator(array(
  "email"  =>  FILTER_VALIDATE_EMAIL,
  "company" =>  FILTER_SANITIZE_FULL_SPECIAL_CHARS,
  "retailer_number" =>  [
    	"filter" => FILTER_VALIDATE_REGEXP, 
    	"options" => ['regexp'=>"/^[\d\-]+$/"]
   ],
  "privacyAck"      =>  FILTER_VALIDATE_BOOLEAN
));

// Set customer data validation
$factory->setValidator( $customer_validation );

使用上述设置进行使用

$order = $factory->createOrder([
  'email' => "test@test.com",
  'company' => "ACME Corp.",
  'retailer_number' => "12345",
  'privacyAck' => 1,
  
  'items' => array(
    [ 'sku' => "foo" , "quantity" => 5 ]
  )  
]);

$customer = $order->getCustomerData();
$items = $order->getItems();

OrderHandlerController

这个控制器类接受来自 ServerRequest 身体的用户输入,创建一个正在进行的订单对象并将其委托给给定的处理程序。

其构造函数接受一个 OrderFactoryInterface 实例、一个 OrderHandlerInterface 实例和可选的 PSR-3 LoggerInterface

<?php
use Germania\OrderDispatcher\OrderHandlerController;

$factory = ... ;
$handler = ... ;
$logger = ... ;

$controller = new OrderHandlerController($factory, $handler);
$controller = new OrderHandlerController($factory, $handler, $logger);

给定一个 ServerRequest 和一个 Response 对象,像这样调用控制器

$request = $request->withParsedBody(array(
  'email'           => "test@test.com",
  'company'         => "ACME Corp.",
  'retailer_number' => "12345",
  'privacyAck'      => 1,
  'articles' => array(
    [ 'sku' => 'A1', 'quantity' => 100],
    [ 'sku' => 'B2', 'quantity' => 5]
  )
));

$response = $controller($request, $response);

if ($reponse->getStatusCode != 200) {
	echo $resonse->getHeaderLine('X-Order-Dispatch-Message');
}
响应状态码
响应头

如果发生错误,响应对象将有一个包含抛出的异常类名的 X-Order-Dispatch-Message 头部

if (200 != $reponse->getStatusCode()) {
	echo $resonse->getHeaderLine('X-Order-Dispatch-Message');
  // Germania\OrderDispatcher\Exceptions\OrderHandlerRuntimeException
}

处理订单项

订单项是可以订购的东西。

Item 类和 ItemInterface

ItemInterface 扩展 \ArrayAccess

Item 类扩展 \ArrayObject 并实现 ItemInterface

<?php
use Germania\OrderDispatcher\ItemInterface;
use Germania\OrderDispatcher\Item;

ItemFactoryInterface

public function createItem( array $order_item ) : ItemInterface;

SimpleItemFactory

根据任何数组数据创建一个“订单项”数组。扩展 ItemFactoryAbstract 并实现 ItemFactoryInterface

<?php
use Germania\OrderDispatcher\SimpleItemFactory;

$item_factory = new SimpleItemFactory;

$item = $item_factory->createItem([
  'sku' => 'foobar',
  'quantity' => 100
]);

ContainerItemFactory

使用此功能将订单项限制为仅从 PSR-11 Psr\Container\ContainerInterface 中的项目。需要指定用于检索项目的数组字段名称,构造函数可选地接受一个 PSR-3 Logger。

扩展 ItemFactoryAbstract 并实现 ItemFactoryInterface

当项目不可用时,将抛出 ItemNotAvailableException

<?php
use Germania\OrderDispatcher\ContainerItemFactory;
use Germania\OrderDispatcher\Exceptions\ItemNotAvailableException;

$available = new Psr11Container( ... );

$item_factory = new ContainerItemFactory($available, "sku");
$item_factory = new ContainerItemFactory($available, "sku", $logger);

$sku = 'foobar';

try {
  $item = $item_factory->createItem([
    'sku' => $sku,
    'quantity' => 100
  ]);  
}
catch (ItemNotAvailableException $e) {
  echo "$sku is not available";
}

ValidatorItemFactoryDecorator

此装饰器接受任何 ItemFactoryInterface 和一个 ValidatorInterface 来验证订单项数据。

<?php
use Germania\OrderDispatcher\ValidatorItemFactoryDecorator;
use Germania\OrderDispatcher\ContainerItemFactory;

$inner = new ContainerItemFactory($available, "sku");
$validator = new SkuQtyItemValidator;

$item_factory = ValidatorItemFactoryDecorator($inner, $validator);

渲染订单

渲染器用于从一个订单对象创建字符串表示,通常用于电子邮件。

RendererInterface

渲染器接受一个 template 字符串和一个上下文变量数组。如果出现错误,必须抛出 Germania\OrderDispatcher\Exceptions\RendererExceptionInterface

public function render( string $template, array $context = array()) : ?string;

TwigRenderer

TwigRenderer 实现了 RendererInterface。其构造函数接受一个 Twig 环境对象,并可选地接受一个包含默认上下文变量的数组。

<?php
use Germania\OrderDispatcher\TwigRenderer;

$twig = ... ;

$renderer = new TwigRenderer($twig);

处理订单

OrderHandlerInterface

public function handle( OrderInterface $order, array $context = array()) : bool ;

SwiftMailerOrderHandler

SwiftMailerOrderHandler 实现了 OrderHandlerInterface。其构造函数接受一个 SwiftMailer 实例、一个邮件配置数组和一个 RendererInterface 实例。

通常,您将使用 TwigRenderer 作为 RendererInterface。

邮件配置数组必须包含 tofromtemplatesubject 元素。主题可以包含花括号中的字段变量,这些变量将从处理方法上下文中插入。

邮件配置数组中给出的 Subjecttemplate 可以通过上下文数组中的 mailSubjectmailTemplate 条目来覆盖。

渲染器将传递包含额外 customerorderItemsdatetimeNow 信息的处理程序上下文。

<?php
use Germania\OrderDispatcher\SwiftMailerOrderHandler;

$order = ...;
$renderer = ... ;
$swift_mailer = ...;

$mail_config = array(
	'to' => array("mail@test.com" => "John Doe"),
  'from' => array("webshop@test.com" => "My Webshop"),
  'template' => 'mail.tpl',
  'subject' => "{foo} {bar}"
);
$handler = new SwiftMailerOrderHandler($swift_mailer, $mail_config, $renderer);

$handler->handle($order, [
  'foo' => "Order"
  'bar' => "beverage"
]);

OrderHandlerChain

使用此处理程序通过多个处理程序对订单进行修改。

<?php
use Germania\OrderDispatcher\OrderHandlerChain;

$handlers = array();
$chain = new OrderHandlerChain($handlers);

$handler2 = new ...;
$chain->add( $handler2 );

验证器

ValidatorInterface

验证用户输入并返回清理后的数据。通常使用PHP的 filter_var_array

在编写自己的实现时,应添加缺失的字段并将其设置为 null,任何额外的内容都应合并回去。

public function validate( array $input ): array;

ValidatorTrait

ValidatorInterface 的拦截器。

protected $validator;
public function setValidator( ValidatorInterface $validator );
public function getValidator() : ValidatorInterface;

FilterValidator

此验证器使用PHP的 filter_var_array 检查用户输入。

  • 将添加缺失的字段并将其设置为 null
  • 将合并回额外的“未验证”内容,与原始的 filter_var_array 相反。

FilterValidator 实现 ValidatorInterface

<?php
use Germania\OrderDispatcher\FilterValidator;

$fv = new FilterValidator([
  "email"  =>  FILTER_VALIDATE_EMAIL,
  "company" =>  FILTER_SANITIZE_FULL_SPECIAL_CHARS  
]);

$result = $fv->validate([
  'email' => 9999,
  'company' => 'ACME Corp.',
  'foo' => 'bar'
]);

print_r($result);
// Array
// (
//     [email] => false
//     [company] => ACME Corp.
//     [foo] => bar
// )

SkuQtyItemValidator

这是一个预定义的验证器,用于检查用户输入的 skuquantity 元素。它的工作方式与 FilterValidator:

  • 将添加缺失的字段并将其设置为 null
  • 将合并回额外的“未验证”内容,与原始的 filter_var_array 相反。
异常
  • ItemInvalidUserDataException,当 skuquantity 缺失或为 false
  • ItemNotOrderedException,当 quantityint 0 时。

SkuQtyItemValidator 实现 ValidatorInterface

<?php
use Germania\OrderDispatcher\SkuQtyItemValidator;
use Germania\OrderDispatcher\Exceptions\ItemInvalidUserDataException;
use Germania\OrderDispatcher\Exceptions\ItemNotOrderedException;

$v = new SkuQtyItemValidator();

try {
  $v->validate([
    'sku' => 'foo',
    'quantity' => 100
  ]);
}
catch(ItemInvalidUserDataException $e) {
  
}
catch(ItemNotOrderedException $e) {
  	// quantity was 0 (!== null)
}

异常