Skip to content

Commit

Permalink
added more event subscribers
Browse files Browse the repository at this point in the history
  • Loading branch information
loevgaard committed Apr 24, 2019
1 parent 199c43a commit 9badd94
Show file tree
Hide file tree
Showing 18 changed files with 292 additions and 113 deletions.
16 changes: 16 additions & 0 deletions src/Builder/AddToCartBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusFacebookTrackingPlugin\Builder;

final class AddToCartBuilder extends Builder
{
use ContentIdsAwareBuilderTrait,
ContentsAwareBuilderTrait,
ContentTypeAwareBuilderTrait,
ValueAwareBuilderTrait
;

public const EVENT_NAME = 'setono_sylius_facebook_tracking.builder.add_to_cart';
}
38 changes: 3 additions & 35 deletions src/Builder/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
use Safe\Exceptions\JsonException;
use function Safe\json_decode;
use function Safe\json_encode;
use Symfony\Component\DependencyInjection\Container;

abstract class Builder implements BuilderInterface
{
public const CONTENT_TYPE_PRODUCT = 'product';
public const CONTENT_TYPE_PRODUCT_GROUP = 'product_group';

/**
* @var array
*/
Expand Down Expand Up @@ -47,38 +49,4 @@ public function getJson(): string
{
return json_encode($this->data);
}

public function __call($name, array $arguments)
{
if (count($arguments) !== 1) {
return;
}

if (strpos($name, 'set') !== 0) {
return;
}

$key = Container::underscore(substr($name, 3));
$val = $arguments[0];

if (null === $val) {
return;
}

if (is_callable($val)) {
$val = $val();
} elseif ($val instanceof BuilderInterface) {
$val = $val->getData();
} elseif (is_object($val) && method_exists($val, '__toString')) {
$val = (string) $val;
}

if (!is_scalar($val) && !is_array($val)) {
throw new \InvalidArgumentException(sprintf('Unexpected type %s. Expected types are: callable, %s or scalar', is_object($val) ? get_class($val) : gettype($val), BuilderInterface::class));
}

$this->data[$key] = $val;

return $this;
}
}
30 changes: 25 additions & 5 deletions src/Builder/ContentBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,32 @@

namespace Setono\SyliusFacebookTrackingPlugin\Builder;

/**
* @method ContentBuilder setId(string|int $id)
* @method ContentBuilder setQuantity(int $quantity)
* @method ContentBuilder setItemPrice(float $itemPrice)
*/
use Webmozart\Assert\Assert;

final class ContentBuilder extends Builder
{
public const EVENT_NAME = 'setono_sylius_facebook_tracking.builder.item';

public function setId($id): self
{
Assert::scalar($id);

$this->data['id'] = $id;

return $this;
}

public function setQuantity(int $quantity): self
{
$this->data['quantity'] = $quantity;

return $this;
}

public function setItemPrice(float $itemPrice): self
{
$this->data['item_price'] = $itemPrice;

return $this;
}
}
19 changes: 0 additions & 19 deletions src/Builder/ContentIdsAwareBuilderInterface.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Builder/ContentIdsAwareBuilderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ trait ContentIdsAwareBuilderTrait
*/
protected $data = [];

public function addContentId($contentId): BuilderInterface
public function addContentId($contentId): self
{
if (!isset($this->data['content_ids'])) {
$this->data['content_ids'] = [];
Expand Down
20 changes: 20 additions & 0 deletions src/Builder/ContentNameAwareBuilderTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusFacebookTrackingPlugin\Builder;

trait ContentNameAwareBuilderTrait
{
/**
* @var array
*/
protected $data = [];

public function setContentName(string $contentName): self
{
$this->data['content_name'] = $contentName;

return $this;
}
}
19 changes: 0 additions & 19 deletions src/Builder/ContentTypeAwareBuilderInterface.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Builder/ContentTypeAwareBuilderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ trait ContentTypeAwareBuilderTrait
*/
protected $data = [];

public function setContentType(string $contentType): BuilderInterface
public function setContentType(string $contentType): self
{
Assert::oneOf($contentType, ['product', 'product_group']);

Expand Down
19 changes: 0 additions & 19 deletions src/Builder/ContentsAwareBuilderInterface.php

This file was deleted.

10 changes: 5 additions & 5 deletions src/Builder/ContentsAwareBuilderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,8 @@ trait ContentsAwareBuilderTrait
*/
protected $data = [];

public function addContent($content): BuilderInterface
public function addContent($content): self
{
if (!isset($this->data['contents'])) {
$this->data['contents'] = [];
}

if ($content instanceof BuilderInterface) {
$content = $content->getData();
}
Expand All @@ -27,6 +23,10 @@ public function addContent($content): BuilderInterface
throw new InvalidArgumentException(sprintf('The $content parameter needs to be an array or instance of %s', BuilderInterface::class));
}

if (!isset($this->data['contents'])) {
$this->data['contents'] = [];
}

$this->data['contents'][] = $content;

return $this;
Expand Down
14 changes: 6 additions & 8 deletions src/Builder/PurchaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@

namespace Setono\SyliusFacebookTrackingPlugin\Builder;

/**
* todo implement 'contents' field https://developers.facebook.com/docs/facebook-pixel/reference/#object-properties
*
* @method PurchaseBuilder setValue(float $value)
* @method PurchaseBuilder setCurrency(string $currency)
*/
final class PurchaseBuilder extends Builder implements ContentIdsAwareBuilderInterface, ContentsAwareBuilderInterface, ContentTypeAwareBuilderInterface
final class PurchaseBuilder extends Builder
{
use ContentIdsAwareBuilderTrait, ContentsAwareBuilderTrait, ContentTypeAwareBuilderTrait;
use ContentIdsAwareBuilderTrait,
ContentsAwareBuilderTrait,
ContentTypeAwareBuilderTrait,
ValueAwareBuilderTrait
;

public const EVENT_NAME = 'setono_sylius_facebook_tracking.builder.purchase';
}
27 changes: 27 additions & 0 deletions src/Builder/ValueAwareBuilderTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusFacebookTrackingPlugin\Builder;

trait ValueAwareBuilderTrait
{
/**
* @var array
*/
protected $data = [];

public function setCurrency(string $currency): self
{
$this->data['currency'] = $currency;

return $this;
}

public function setValue(float $value): self
{
$this->data['value'] = $value;

return $this;
}
}
17 changes: 17 additions & 0 deletions src/Builder/ViewContentBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusFacebookTrackingPlugin\Builder;

final class ViewContentBuilder extends Builder
{
use ContentIdsAwareBuilderTrait,
ContentNameAwareBuilderTrait,
ContentsAwareBuilderTrait,
ContentTypeAwareBuilderTrait,
ValueAwareBuilderTrait
;

public const EVENT_NAME = 'setono_sylius_facebook_tracking.builder.view_content';
}
91 changes: 91 additions & 0 deletions src/EventListener/AddToCartSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusFacebookTrackingPlugin\EventListener;

use Setono\SyliusFacebookTrackingPlugin\Builder\AddToCartBuilder;
use Setono\SyliusFacebookTrackingPlugin\Builder\ContentBuilder;
use Setono\SyliusFacebookTrackingPlugin\Context\PixelContextInterface;
use Setono\SyliusFacebookTrackingPlugin\Event\BuilderEvent;
use Setono\SyliusFacebookTrackingPlugin\Tag\FbqTag;
use Setono\SyliusFacebookTrackingPlugin\Tag\FbqTagInterface;
use Setono\SyliusFacebookTrackingPlugin\Tag\Tags;
use Setono\TagBagBundle\TagBag\TagBagInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Order\Context\CartContextInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

final class AddToCartSubscriber extends TagSubscriber
{
/**
* @var CartContextInterface
*/
private $cartContext;

public function __construct(
TagBagInterface $tagBag,
PixelContextInterface $pixelContext,
EventDispatcherInterface $eventDispatcher,
CartContextInterface $cartContext
) {
parent::__construct($tagBag, $pixelContext, $eventDispatcher);

$this->cartContext = $cartContext;
}

public static function getSubscribedEvents(): array
{
return [
'sylius.order_item.post_add' => [
'track',
],
];
}

public function track(): void
{
if (!$this->hasPixels()) {
return;
}

$order = $this->cartContext->getCart();

if (!$order instanceof OrderInterface) {
return;
}

$builder = AddToCartBuilder::create()
->setCurrency($order->getCurrencyCode())
->setValue($this->moneyFormatter->format($order->getTotal()))
->setContentType(AddToCartBuilder::CONTENT_TYPE_PRODUCT)
;

foreach ($order->getItems() as $item) {
$variant = $item->getVariant();
if (null === $variant) {
continue;
}

$builder->addContentId($variant->getCode());

$contentBuilder = ContentBuilder::create()
->setId($variant->getCode())
->setQuantity($item->getQuantity())
->setItemPrice($this->moneyFormatter->format($item->getDiscountedUnitPrice()))
;

$this->eventDispatcher->dispatch(ContentBuilder::EVENT_NAME, new BuilderEvent($contentBuilder, $item));

$builder->addContent($contentBuilder);
}

$this->eventDispatcher->dispatch(AddToCartBuilder::EVENT_NAME, new BuilderEvent($builder, $order));

$this->tagBag->add(new FbqTag(
Tags::TAG_ADD_TO_CART,
FbqTagInterface::EVENT_ADD_TO_CART,
$builder
), TagBagInterface::SECTION_BODY_END);
}
}
Loading

0 comments on commit 9badd94

Please sign in to comment.