Skip to content

Commit

Permalink
Merge pull request #91 from Setono/add-resolvers
Browse files Browse the repository at this point in the history
Add resolvers to make the plugin more extendable
  • Loading branch information
loevgaard authored Apr 18, 2023
2 parents 0beb89a + 4bb07ab commit af8a275
Show file tree
Hide file tree
Showing 28 changed files with 468 additions and 28 deletions.
3 changes: 2 additions & 1 deletion composer-require-checker.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"Sylius\\Component\\Channel\\Context\\ChannelContextInterface",
"Sylius\\Component\\Channel\\Model\\ChannelInterface",
"Sylius\\Component\\Channel\\Model\\ChannelsAwareInterface",
"Sylius\\Component\\Core\\Calculator\\ProductVariantPricesCalculatorInterface",
"Sylius\\Component\\Core\\Model\\ChannelInterface",
"Sylius\\Component\\Core\\Model\\OrderInterface",
"Sylius\\Component\\Core\\Model\\OrderItemInterface",
Expand All @@ -29,6 +30,6 @@
"Sylius\\Component\\Order\\Context\\CartContextInterface",
"Sylius\\Component\\Order\\Repository\\OrderRepositoryInterface",
"Sylius\\Component\\Product\\Resolver\\ProductVariantResolverInterface",
"Sylius\\Component\\Core\\Calculator\\ProductVariantPricesCalculatorInterface"
"Sylius\\Component\\Taxonomy\\Model\\TaxonInterface"
]
}
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"knplabs/knp-menu": "^3.3",
"psr/event-dispatcher": "^1.0",
"psr/log": "^2.0 || ^3.0",
"setono/composite-compiler-pass": "^1.0",
"setono/google-analytics-bundle": "^1.0@alpha",
"setono/google-analytics-measurement-protocol": "^1.0@alpha",
"sylius/resource-bundle": "^1.8",
Expand All @@ -34,6 +35,7 @@
"behat/behat": "^3.12",
"matthiasnoback/symfony-config-test": "^4.3",
"matthiasnoback/symfony-dependency-injection-test": "^4.3",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9.5",
"psalm/plugin-phpunit": "^0.18",
"psalm/plugin-symfony": "^5.0",
Expand Down
4 changes: 2 additions & 2 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function getConfigTreeBuilder(): TreeBuilder
$treeBuilder = new TreeBuilder('setono_sylius_analytics');
$rootNode = $treeBuilder->getRootNode();

/** @psalm-suppress MixedMethodCall,PossiblyNullReference,PossiblyUndefinedMethod */
/** @psalm-suppress MixedMethodCall,PossiblyNullReference,PossiblyUndefinedMethod,UndefinedInterfaceMethod */
$rootNode
->addDefaultsIfNotSet()
->children()
Expand All @@ -43,7 +43,7 @@ public function getConfigTreeBuilder(): TreeBuilder

private function addResourcesSection(ArrayNodeDefinition $node): void
{
/** @psalm-suppress MixedMethodCall,PossiblyNullReference,PossiblyUndefinedMethod */
/** @psalm-suppress MixedMethodCall,PossiblyNullReference,PossiblyUndefinedMethod,UndefinedInterfaceMethod */
$node
->children()
->arrayNode('resources')
Expand Down
10 changes: 10 additions & 0 deletions src/DependencyInjection/SetonoSyliusAnalyticsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Setono\SyliusAnalyticsPlugin\DependencyInjection;

use Setono\SyliusAnalyticsPlugin\Resolver\Brand\BrandResolverInterface;
use Setono\SyliusAnalyticsPlugin\Resolver\Variant\VariantResolverInterface;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractResourceExtension;
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
use Symfony\Component\Config\FileLocator;
Expand Down Expand Up @@ -34,5 +36,13 @@ public function load(array $configs, ContainerBuilder $container): void
}

$this->registerResources('setono_sylius_analytics', SyliusResourceBundle::DRIVER_DOCTRINE_ORM, $config['resources'], $container);

$container->registerForAutoconfiguration(BrandResolverInterface::class)
->addTag('setono_sylius_analytics.brand_resolver')
;

$container->registerForAutoconfiguration(VariantResolverInterface::class)
->addTag('setono_sylius_analytics.variant_resolver')
;
}
}
20 changes: 20 additions & 0 deletions src/Event/ItemResolved.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusAnalyticsPlugin\Event;

use Setono\GoogleAnalyticsMeasurementProtocol\Request\Body\Event\Item\Item;

/**
* Is fired when an item has been resolved. Use this to do common manipulations on the item before it's sent to Google
*/
final class ItemResolved
{
public function __construct(
public Item $item,
/** @var array<string, mixed> $context */
public array $context = [],
) {
}
}
2 changes: 1 addition & 1 deletion src/EventSubscriber/AddPaymentInfoSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Psr\Log\NullLogger;
use Setono\GoogleAnalyticsBundle\Event\ClientSideEvent;
use Setono\GoogleAnalyticsMeasurementProtocol\Request\Body\Event\AddPaymentInfoEvent;
use Setono\SyliusAnalyticsPlugin\Resolver\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Resolver\Items\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Util\FormatAmountTrait;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\OrderInterface;
Expand Down
2 changes: 1 addition & 1 deletion src/EventSubscriber/AddShippingInfoSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Psr\Log\NullLogger;
use Setono\GoogleAnalyticsBundle\Event\ClientSideEvent;
use Setono\GoogleAnalyticsMeasurementProtocol\Request\Body\Event\AddShippingInfoEvent;
use Setono\SyliusAnalyticsPlugin\Resolver\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Resolver\Items\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Util\FormatAmountTrait;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\OrderInterface;
Expand Down
4 changes: 2 additions & 2 deletions src/EventSubscriber/AddToCartSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Psr\Log\NullLogger;
use Setono\GoogleAnalyticsBundle\Event\ClientSideEvent;
use Setono\GoogleAnalyticsMeasurementProtocol\Request\Body\Event\AddToCartEvent;
use Setono\SyliusAnalyticsPlugin\Resolver\ItemResolverInterface;
use Setono\SyliusAnalyticsPlugin\Resolver\Item\ItemResolverInterface;
use Setono\SyliusAnalyticsPlugin\Util\FormatAmountTrait;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\OrderInterface;
Expand Down Expand Up @@ -52,7 +52,7 @@ public function track(ResourceControllerEvent $resourceControllerEvent): void
* https://github.com/Sylius/Sylius/issues/9407
*
* That issue was fixed in Sylius 1.12, but we can't require the order bundle because Sylius doesn't handle
* GitHub repository subtree splits the correct way with regards to packagist therefore we are keeping this
* GitHub repository subtree splits the correct way with regard to packagist therefore we are keeping this
*/
$order = $this->cartContext->getCart();
if (!$order instanceof OrderInterface) {
Expand Down
2 changes: 1 addition & 1 deletion src/EventSubscriber/BeginCheckoutSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Psr\Log\NullLogger;
use Setono\GoogleAnalyticsBundle\Event\ClientSideEvent;
use Setono\GoogleAnalyticsMeasurementProtocol\Request\Body\Event\BeginCheckoutEvent;
use Setono\SyliusAnalyticsPlugin\Resolver\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Resolver\Items\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Util\FormatAmountTrait;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Order\Context\CartContextInterface;
Expand Down
2 changes: 1 addition & 1 deletion src/EventSubscriber/PurchaseSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Psr\Log\NullLogger;
use Setono\GoogleAnalyticsBundle\Event\ClientSideEvent;
use Setono\GoogleAnalyticsMeasurementProtocol\Request\Body\Event\PurchaseEvent;
use Setono\SyliusAnalyticsPlugin\Resolver\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Resolver\Items\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Util\FormatAmountTrait;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Order\Repository\OrderRepositoryInterface;
Expand Down
2 changes: 1 addition & 1 deletion src/EventSubscriber/ViewCartSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Psr\Log\NullLogger;
use Setono\GoogleAnalyticsBundle\Event\ClientSideEvent;
use Setono\GoogleAnalyticsMeasurementProtocol\Request\Body\Event\ViewCartEvent;
use Setono\SyliusAnalyticsPlugin\Resolver\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Resolver\Items\ItemsResolverInterface;
use Setono\SyliusAnalyticsPlugin\Util\FormatAmountTrait;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Order\Context\CartContextInterface;
Expand Down
2 changes: 1 addition & 1 deletion src/EventSubscriber/ViewItemSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Psr\Log\NullLogger;
use Setono\GoogleAnalyticsBundle\Event\ClientSideEvent;
use Setono\GoogleAnalyticsMeasurementProtocol\Request\Body\Event\ViewItemEvent;
use Setono\SyliusAnalyticsPlugin\Resolver\ItemResolverInterface;
use Setono\SyliusAnalyticsPlugin\Resolver\Item\ItemResolverInterface;
use Setono\SyliusAnalyticsPlugin\Util\FormatAmountTrait;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\ProductInterface;
Expand Down
15 changes: 15 additions & 0 deletions src/Resolver/Brand/BrandResolverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusAnalyticsPlugin\Resolver\Brand;

use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;

interface BrandResolverInterface
{
public function resolveFromProduct(ProductInterface $product): ?string;

public function resolveFromProductVariant(ProductVariantInterface $productVariant): ?string;
}
41 changes: 41 additions & 0 deletions src/Resolver/Brand/CompositeBrandResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusAnalyticsPlugin\Resolver\Brand;

use Setono\CompositeCompilerPass\CompositeService;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;

/**
* @property list<BrandResolverInterface> $services
*
* @extends CompositeService<BrandResolverInterface>
*/
final class CompositeBrandResolver extends CompositeService implements BrandResolverInterface
{
public function resolveFromProduct(ProductInterface $product): ?string
{
foreach ($this->services as $brandResolver) {
$val = $brandResolver->resolveFromProduct($product);
if (null !== $val) {
return $val;
}
}

return null;
}

public function resolveFromProductVariant(ProductVariantInterface $productVariant): ?string
{
foreach ($this->services as $brandResolver) {
$val = $brandResolver->resolveFromProductVariant($productVariant);
if (null !== $val) {
return $val;
}
}

return null;
}
}
54 changes: 54 additions & 0 deletions src/Resolver/Category/CategoryResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusAnalyticsPlugin\Resolver\Category;

use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Taxonomy\Model\TaxonInterface;

final class CategoryResolver implements CategoryResolverInterface
{
public function resolveFromProduct(ProductInterface $product): array
{
$taxon = $product->getMainTaxon() ?? $product->getTaxons()->first();
if (!$taxon instanceof TaxonInterface) {
return [];
}

/**
* Presume the $product has this taxon hierarchy: Apparel > Shirts > Crew > Short sleeve
* After the call below, $hierarchy will be ['Crew', 'Shirts', 'Apparel']. Notice that the values will
* actually still be taxon objects and not strings yet, but I am just showing it like this for readability
*/
$hierarchy = $taxon->getAncestors()->toArray();

/**
* Now we prepend the 'Short sleeve' to the $hierarchy variable, so the resulting array is now:
* ['Short sleeve', 'Crew', 'Shirts', 'Apparel']
*/
array_unshift($hierarchy, $taxon);

/**
* Now we just need to reverse the array to make sure the top level taxon is first and so on,
* and finally map the taxon objects to strings and the returned array will be ['Apparel', 'Shirts', 'Crew', 'Short sleeve']
*/
return array_values(array_map(
static function (TaxonInterface $taxon): string {
return (string) $taxon->getName();
},
array_reverse($hierarchy),
));
}

public function resolveFromProductVariant(ProductVariantInterface $productVariant): array
{
$product = $productVariant->getProduct();
if (!$product instanceof ProductInterface) {
return [];
}

return $this->resolveFromProduct($product);
}
}
33 changes: 33 additions & 0 deletions src/Resolver/Category/CategoryResolverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusAnalyticsPlugin\Resolver\Category;

use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;

/**
* A category is used on the item when a purchase event, add to cart, and many similar events are fired.
* It tells Google which category a specific product belongs to.
*
* The methods in this interface must return a list of categories, starting with the top level category at index 0.
* This means if you have a category (breadcrumb) like Apparel > Shirts > Crew > Short sleeve the resulting array would
* look like this:
*
* [
* 'Apparel', 'Shirts', 'Crew', 'Short sleeve'
* ]
*/
interface CategoryResolverInterface
{
/**
* @return list<string>
*/
public function resolveFromProduct(ProductInterface $product): array;

/**
* @return list<string>
*/
public function resolveFromProductVariant(ProductVariantInterface $productVariant): array;
}
Loading

0 comments on commit af8a275

Please sign in to comment.