mothership-ec / cog-mothership-refer-a-friend
Mothership的“推荐好友”功能模块
Requires
- php: >=5.4.0
- mothership-ec/cog: ~4.0
- mothership-ec/cog-mothership-cms: ~4.0
- mothership-ec/cog-mothership-cp: ~3.0
- mothership-ec/cog-user: ~2.0
This package is not auto-updated.
Last update: 2021-03-22 11:07:22 UTC
README
Message\Mothership\ReferAFriend
模块允许用户推荐非用户到网站,并可能因此获得奖励。
推荐
Referral
对象表示用户将某人推荐到网站的实例。用户可以推荐任意多的人,但任何电子邮件地址只能推荐一次。如果用户尝试推荐已经推荐过的人,他们将收到错误消息。他们也可以仅推荐非用户。
推荐由以下信息组成
- 推荐者 - 进行推荐的用户
- 被推荐电子邮件地址 - 被推荐人的电子邮件地址
- 被推荐人姓名 - 被推荐人的姓名
- 奖励配置 - 成功推荐后将授予的奖励的配置
- 状态 - 推荐的状态(待定、完成、错误 或 过期)
- 创建时间 - 推荐的时间
奖励
奖励类型
奖励可以有多种类型。此模块仅包含一种奖励类型:no_reward
。此类型作为简单的推荐,但推荐者在推荐标记为完成时不会获得任何东西。它在用户注册并登录网站时标记为完成。
奖励配置
每种奖励类型都可以通过一组 实体 进行配置,这些实体存储在 Config
类中。可以存储在配置中的实体有三种类型
- 触发器
- 约束
- 奖励选项
这些类型中的每一个都有一个关联的集合,它扩展了 Message\Cog\ValueObject\Collection
类,并且所有实体都在其关联集合的实例中注册到服务容器中。
Message\Mothership\ReferAFriend\Reward\Type\TypeInterface
有三个方法:validTriggers()
、validConstraints()
和 validRewardOptions()
,用于确定哪些实体适用于特定奖励类型。这些返回一个一维数组,包含这些实体的名称(由实体的 getName()
方法返回)。
触发器
触发器确定必须触发哪些事件,才能将推荐标记为可能完成。
它们必须实现 Message\Mothership\ReferAFriend\Reward\Config\Trigger\TriggerInterface
。
推荐对象有一个 hasTriggered()
方法,可以快速确定它是否已触发。它以事件名称作为参数。
为了使触发器有效,必须有一个事件监听器监听加载奖励的事件。然后可以使用电子邮件地址加载推荐,例如:
public function createReward(SomeEvent $event) { $referrals = $this->get('refer.referral.loader')->getByEmail($event->getEmail()); // Return if no referrals were loaded if (empty($referrals)) { return; } foreach ($referrals as $referral) { // Continue if trigger does not apply to event if (false === $referral->hasTriggered('event.name')) { continue; } // code to create reward } }
注意:推荐加载器返回一个数组。除了getByID()
外,所有在加载器上的方法都返回推荐数组。这是为了让控制器在调用加载器时知道应该期待什么,并且为将来做准备,以防模块被修改为允许向一个地址发送多个推荐。
触发器必须通过扩展服务容器中的refer.reward.config.triggers
服务来添加,并通过集合上的add()
方法添加。
$services['refer.reward.config.triggers'] = $services->extend('refer.reward.config.triggers', function($triggers, $c) { $triggers->add(new My\New\Trigger); return $triggers; });
约束条件
约束条件确定了一个规则,必须满足这个规则才能将推荐标记为完成并生成奖励。这以简单的键/值对形式存储在数据库中。
它们必须实现Message\Mothership\ReferAFriend\Reward\Config\Constraint\ConstraintInterface
接口。约束必须与一个Symfony表单类型相关联。这是通过在约束上使用getFormType()
方法来返回的。应该放在此表单字段上的任何选项都应该通过在约束上使用getFormOptions()
方法作为数组返回。
约束还有一个isValid()
方法,它以推荐作为其第一个参数,以及一个Message\Cog\Event\Event
实例,该实例被触发以验证推荐,作为其第二个参数。
因此,为了扩展上面的例子,我们可以通过遍历其约束来检查推荐的合法性。
public function createReward(SomeEvent $event) { $referrals = $this->get('refer.referral.loader')->getByEmail($event->getEmail()); // Return if no referrals were loaded if (empty($referrals)) { return; } foreach ($referrals as $referral) { // Continue if trigger does not apply to event if (false === $referral->hasTriggered('event.name')) { continue; } // Default to $valid being true, loop through constraints and validate $valid = true; foreach ($referral->getRewardConfig()->getConstraints() as $constraint) { // Break out of loop if referral is not valid, and set $valid to false if (false === $constraint->isValid($$referral, $event)) { $valid = false; break; } } // Move on to next referral if invalid if (false === $valid) { continue; } // code to create reward } }
注意:虽然ReferralInterface
有一个hasTriggered()
方法来快速访问触发器并检查是否已触发,但没有isValid()
方法。这是因为可能存在某些情况下,你可能希望忽略某种情况下的约束。
必须通过扩展服务容器中的refer.reward.config.constraints
服务来添加约束,并在集合上调用add()
方法。
$services['refer.reward.config.constraints'] = $services->extend('refer.reward.config.constraints', function($constraints, $c) { $constraints->add(new My\New\Constraint); return $constraints; });
奖励选项
奖励选项用于配置在推荐成功完成时将生成的任何奖励。它们必须实现Message\Mothership\ReferAFriend\Reward\Config\RewardOption\RewardOptionInterface
。
与约束一样,它们以键/值对的形式存储,并且必须与一个Symfony表单类型相关联,这些通过使用getFormType()
和getFormOptions()
方法定义。
必须通过扩展服务容器中的refer.reward.config.reward_options
服务来添加奖励选项,并在集合上调用add()
方法。
$services['refer.reward.config.reward_options'] = $services->extend('refer.reward.config.reward_options', function($rewardOptions, $c) { $rewardOptions->add(new My\New\RewardOption); return $rewardOptions; });
代理
此模块在推荐和奖励配置上都使用了延迟加载,因此存在Message\Mothership\ReferAFriend\Referral\ReferralProxy
和Message\Mothership\ReferAFriend\Reward\Config\ConfigProxy
的类。这些类持有其实体的加载器以及它们可能需要的任何ID,而不是实体本身。它们扩展了getter以调用加载器,从数据库加载实体并将它们设置为自己,在需要时。一旦加载过一次,它们将从此请求的内存中检索它们,而不是从数据库中检索。例如,在ConfigProxy
中。
/** * {@inheritDoc} */ public function getConstraints() { if (null === $this->_constraints) { $constraints = $this->_loaders->get('constraint')->load($this); if (!$constraints) { throw new \LogicException('Could not load constraints!'); } foreach ($constraints as $constraint) { $this->addConstraint($constraint); } } return parent::getConstraints(); }