alancole / 优惠券
一个简单的PHP库,用于生成和验证优惠券码。
This package is auto-updated.
Last update: 2024-09-19 14:53:57 UTC
README
优惠券库
一个用于生成和验证优惠券的PHP库。我们不假设存储方式,而是提供Bag
的概念,它可以包含任意数量的Vouchers
。这些Bag可以验证优惠券,生成新的优惠券,并在整个集合上应用验证规则。
安装
composer require alancole/vouchers
示例
$model = new Vouchers\Voucher\Model([ 'owner' => [ 'required' => true, 'immutable' => true, ], 'claimed_by' => [ 'required' => true, ] ]); $collection = new Vouchers\Bag($model); $collection->fill(1000); $voucher = $collection->pick(); print $voucher; // FHUW-JSUJ-KSIQ-JDUI
优惠券
优惠券可以采取几乎任何形式,但是您可以使用Vouchers\Voucher\Model
来强制验证和结构。唯一的必需属性是code
,默认情况下是不可变的。
$voucher = new Vouchers\Voucher(); print $voucher; // ABCD-EFGH-IJKL
您还可以向优惠券传递一个数组来设置预存在的值。匹配的字段(包括code
)将进行验证。
$voucher = new Voucher(['code' => 'ALAN-COLE-CODE', 'claimed_by' => '', 'claimed_on' => '']); print $voucher; // "ALAN-COLE-CODE"
在创建优惠券时传递的任何值都可以通过优惠券上的get()
和set()
来获取和设置。
$voucher->set('owner', 'Alan'); echo $voucher->get('owner'); // Alan
模型
通过创建模型,您可以设置优惠券创建或加载时的默认值和验证。模型作为数组传递给Vouchers\Voucher\Model
$model = new Vouchers\Voucher\Model([ 'owner' => [ 'required' => true, 'immutable' => true, ], 'claimed_by' => [ 'required' => true, ] ]);
如果您将优惠券属性设置为不可变
,则Voucher
将抛出ImmutableData
异常。
代码
您可以通过在模型上设置生成器来更改代码的生成方式。生成器必须实现Vouchers\Voucher\Code\GeneratorInterface
namespace My\Voucher\Generator; use Vouchers\Voucher\Code\Interface as Generator; class MyCode implements Generator { public function part() { return bin2hex(openssl_random_pseudo_bytes(2)); } public function generate() { return strtoupper(sprintf("%s-%s-%s", $this->part(), $this->part(), $this->part())); } public function validate() { return true; } }
然后告诉模型使用此生成器。
$model = new Vouchers\Voucher\Model([ 'code' => [ 'generator' => \My\Voucher\Generator\MyCode::class ] ]);
Bag
Bag充当优惠券的集合,并允许您对整个集合强制执行验证。Bag还可以充当优惠券的选择器,允许您随机选择优惠券并强制执行规则。Bag也是Iterable
,因此可以在循环中使用。
$collection = new Vouchers\Bag(); $collection->fill(1000); foreach($collection as $voucher) { print $voucher; }
您可以使用Vouchers\Voucher\Model
通过将模型作为构造函数的第一个属性传递,来强制对Bag中的所有项目应用模型。
$collection = new Vouchers\Bag($model);
您可以使用add()
通过add
填充模型中的现有优惠券,该函数只会接受Vouchers\Voucher
的实例。
$vouchers = [$voucher1...$voucher100]; foreach ($vouchers as $voucher) { $collection->add(new Vouchers\Voucher($voucher)); }
您还可以对任何数组运行map,将返回的新优惠券映射到Bag中。如果您需要将数据转换以符合模型,这很有用。
$collection->map($vouchers, function ($voucher) { return new Vouchers\Voucher($voucher); });
您可以通过代码获取优惠券,这可以用来查看优惠券是否存在。
$collection = new Vouchers\Bag(); $voucher = new Vouchers\Voucher(['code' => 'special-voucher']); $collection->add($voucher); $v = $collection->find("special-voucher"); if ($v) { print (string)$v; } else { print "Voucher does not exist."; }
选择
您可以通过在任意Bag上使用pick()
来让Bag随机为您选择一个优惠券。
$collection = new Vouchers\Bag(); $collection->fill(1000); $collection->pick();
如果您希望验证选择,可以传递一个回调给pick
,该回调将运行直到返回true
或抛出Vouchers\Exceptions\NoValidVouchers
异常。
$collection->pick(function ($voucher) { return (bool)$voucher->owner == "Alan"; });
try { $collection->pick(function ($voucher) { return 2 == 1; }); } catch (Exception $e) { print $e->getMessage(); }
您还可以要求pick()
检查此Bag可能拥有的所有验证器(请参阅验证),并且只返回一个有效的优惠券。如果没有找到优惠券,将抛出Vouchers\Exceptions\NoValidVouchers
。
$collection->pickValid();
验证
您可以向Bag添加验证器,这些验证器可以通过在Bag上使用validate()
并传递优惠券代码作为参数来用于验证优惠券的要求。
$collection->validate("ALAN-COLE-CODE");
验证器可以作为回调添加到验证器函数中,或作为实现Vouchers\Voucher\Validator
的类。以下是一个示例,它假设优惠券有一个expire_date
并检查它是否已过期。
$collection->validator(function ($voucher) { return $voucher->expire_date > new DateTime(); }, "Sorry, this voucher is expired"); try { $collection->validate("ALAN-COLE-CODE"); } catch (\Vouchers\Exceptions\VoucherNotValid $e) { return $e->getMessage(); // "Sorry, this voucher is expired"; }
厨房水槽
本例展示了如何从订阅API获取优惠券,选择一个请求的优惠券,验证它并在API上兑换。
$api = new Discovery\Subscriptions\Api(); $api->setApiKey(getenv("SUBS_API_KEY")); $api->setAppId(getenv("SUBS_APP_ID")); $vouchers = $api->getAllVouchers(); $bag = new Vouchers\Bag(); $bag->map($vouchers, function($voucher) { return new Vouchers\Voucher($voucher); }); # Add some validators $bag->validator(function ($voucher) { return $voucher->owner == "Eurosport"; }, "Sorry, this voucher was not valid."); $bag->validator(function ($voucher) { return !$voucher->used; }, "Sorry, this voucher has been used."); $bag->validator(function ($voucher) { return new DateTime($voucher->valid_till) < new DateTime(); }, "Sorry, this voucher is expired."); try { $voucher = $collection->validate(filter_val(INPUT_POST, "voucher_code", FILTER_SANITIZE_STRING)); $voucher->set("used", true // not really needed. $api->putVoucherClaim($voucher); // because this takes care of it. } catch (\Vouchers\Exceptions\VoucherNotValid $e) { echo $e->getMessage(); }